Commit ea1460a1 authored by Julien BOUYER's avatar Julien BOUYER
Browse files

Merge branch 'develop' into feature/front_backoffice

parents 842bd58f ad911116
package com.unantes.orientactive.filariane;
import com.unantes.orientactive.security.AuthoritiesConstants;
import com.unantes.orientactive.security.permissions.PermissionService;
import com.unantes.orientactive.service.FormService;
import com.unantes.orientactive.service.ScreenService;
import com.unantes.orientactive.service.dto.FormDTO;
import com.unantes.orientactive.service.dto.ScreenDTO;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* Contrôleur permettant de récupérer le fils d'ariane pour un élément.
*/
@RestController
public class FilArianeController {
/**
* Service des formulaires.
*/
private final FormService formService;
/**
* Service des écrans.
*/
private final ScreenService screenService;
/**
* Elément du fil d'ariane correspondant à l'accueil.
*/
private final FilArianeElement filArianeHome;
/**
* Constructeur.
*
* @param formService Le service des formulaires.
* @param screenService Le service des écrans.
*/
public FilArianeController(
final FormService formService,
final ScreenService screenService,
final ApplicationContext applicationContext
) {
String homeTitle = applicationContext.getMessage("filariane.home.title", new Object[] {}, Locale.getDefault());
this.filArianeHome = new FilArianeElement(homeTitle, Path.HOME);
this.formService = formService;
this.screenService = screenService;
}
/**
* Récupération du fil d'ariane pour la liste des workspaces.
*
* @return Le fil d'ariane.
*/
@GetMapping("/home")
@ResponseBody
public String getUserHome() {
if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_WORKSPACE)) {
return Path.LIST_WORKSPACES;
} else if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORMS)) {
return Path.LIST_FORMS;
} else if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORM)) {
return Path.LIST_FORMS;
}
return "#";
}
/**
* Récupération du fil d'ariane pour la liste des workspaces.
*
* @return Le fil d'ariane.
*/
@GetMapping("/filariane/workspaces")
@ResponseBody
public List<FilArianeElement> getFilArianeForWorkspaces() {
return Collections.singletonList(filArianeHome);
}
/**
* Récupération du fil d'ariane pour un workspace.
*
* @param idWorkspace L'identifiant du workspace.
* @return Le fil d'ariane.
*/
@GetMapping("/filariane/workspace/{idWorkspace}")
@ResponseBody
public List<FilArianeElement> getFilArianeForWorkspace(@PathVariable("idWorkspace") final Long idWorkspace) {
return Collections.singletonList(filArianeHome);
}
/**
* Récupération du fil d'ariane pour un formulaire.
*
* @param idForm L'identifiant du formulaire.
* @return Le fil d'ariane.
*/
@GetMapping("/filariane/form/{idForm}")
@ResponseBody
public List<FilArianeElement> getFilArianeForForm(@PathVariable("idForm") final Long idForm) {
final List<FilArianeElement> filAriane = new LinkedList<>();
filAriane.add(filArianeHome);
addFilArianeWorkspace(filAriane, idForm);
return filAriane;
}
/**
* Récupération du fil d'ariane pour un écran.
*
* @param idScreen L'identifiant de l'écran.
* @return Le fil d'ariane.
*/
@GetMapping("/filariane/screen/{idScreen}")
@ResponseBody
public List<FilArianeElement> getFilArianeForScreen(@PathVariable("idScreen") final Long idScreen) {
final List<FilArianeElement> filAriane = new LinkedList<>();
if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORM)) {
final Optional<ScreenDTO> screenOptional = screenService.findOne(idScreen);
final ScreenDTO screen = screenOptional.orElseThrow(() -> new FilArianeException("L'écran n'existe pas."));
filAriane.add(new FilArianeElement(screen.getFormName(), Path.WORKSPACE + "/" + screen.getFormId()));
addFilArianeWorkspace(filAriane, screen.getFormId());
}
filAriane.add(filArianeHome);
Collections.reverse(filAriane);
return filAriane;
}
/**
* Ajout du fil d'ariane du workspace concerné par le formulaire.
*
* @param filAriane Le fil d'ariane.
* @param formId L'identifiant du formulaire.
*/
private void addFilArianeWorkspace(final List<FilArianeElement> filAriane, final Long formId) {
if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_WORKSPACE)) {
final Optional<FormDTO> formOptional = formService.findOne(formId);
final FormDTO form = formOptional.orElseThrow(() -> new FilArianeException("Le formulaire n'existe pas."));
filAriane.add(new FilArianeElement(form.getWorkspaceName(), Path.WORKSPACE + "/" + form.getWorkspaceId()));
}
}
}
package com.unantes.orientactive.filariane;
import java.io.Serializable;
/**
* Représentation d'un élément dans le fil d'ariane.
*/
public class FilArianeElement implements Serializable {
/**
* Le titre à afficher dans le fil d'ariane.
*/
private final String title;
/**
* Le chemin vers la page de l'élément représenté dans le fil d'ariane.
*/
private final String path;
/**
* Constructeur.
*
* @param title Le titre.
* @param path Le chemin vers l'élément.
*/
public FilArianeElement(String title, String path) {
this.title = title;
this.path = path;
}
public String getTitle() {
return title;
}
public String getPath() {
return path;
}
}
package com.unantes.orientactive.filariane;
/**
* Erreur lors du calcul du fil d'ariane.
*/
public class FilArianeException extends RuntimeException {
/**
* Constructeur.
*
* @param message Le message.
*/
public FilArianeException(String message) {
super(message);
}
}
package com.unantes.orientactive.filariane;
/**
* Chemins de correspondant aux chemins d'affichage des entités dans l'application vuejs.
*/
public class Path {
public static final String HOME = "/home";
public static final String LIST_WORKSPACES = "/workspaces";
public static final String WORKSPACE = "/workspace";
public static final String LIST_FORMS = "/forms";
}
......@@ -2,21 +2,19 @@ package com.unantes.orientactive.repository;
import com.unantes.orientactive.domain.Workspace;
import com.unantes.orientactive.security.permissions.RoleRepository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Spring Data repository for the Workspace entity.
*/
@SuppressWarnings("unused")
@Repository
public interface WorkspaceRepository extends JpaRepository<Workspace, Long>, RoleRepository {
/**
* Ajout d'une permission d'administration d'un workspace à un utilisateur.
* Le scope de l'utilisateur pour le rôle doit déjà être présent, on va aller faire une sélection dessus afin de trouver son identifiant.
......@@ -25,7 +23,10 @@ public interface WorkspaceRepository extends JpaRepository<Workspace, Long>, Rol
* @param idWorkspace L'identifiant du workspace.
* @param idRole L'identifiant du rôle.
*/
@Query(value = "with id_scope as (select id from scope where id_user = :idUser and id_role = :idRole) insert into scope_workspace (id_scope, id_workspace) values ((select id from id_scope), :idWorkspace)", nativeQuery = true)
@Query(
value = "with id_scope as (select id from scope where id_user = :idUser and id_role = :idRole) insert into scope_workspace (id_scope, id_workspace) values ((select id from id_scope), :idWorkspace)",
nativeQuery = true
)
@Modifying
void addPermission(@Param("idUser") Long idUser, @Param("idWorkspace") Long idWorkspace, @Param("idRole") int idRole);
......@@ -35,7 +36,10 @@ public interface WorkspaceRepository extends JpaRepository<Workspace, Long>, Rol
* @param idUser L'identifiant de l'utilisateur.
* @param idWorkspace L'identifiant du workspace.
*/
@Query(value = "delete from scope_workspace sw using scope s where s.id = sw.id_scope and sw.id_workspace = :idWorkspace and s.id_user = :idUser", nativeQuery = true)
@Query(
value = "delete from scope_workspace sw using scope s where s.id = sw.id_scope and sw.id_workspace = :idWorkspace and s.id_user = :idUser",
nativeQuery = true
)
@Modifying
void removePermission(@Param("idUser") Long idUser, @Param("idWorkspace") Long idWorkspace);
......@@ -45,7 +49,10 @@ public interface WorkspaceRepository extends JpaRepository<Workspace, Long>, Rol
* @param idUser L'identifiant de l'utilisateur.
* @return Les workspaces.
*/
@Query(value = "select w.* from workspace w join scope_workspace sw on sw.id_workspace = w.id join scope s on s.id = sw.id_scope and s.id_user = :idUser", nativeQuery = true)
@Query(
value = "select w.* from workspace w join scope_workspace sw on sw.id_workspace = w.id join scope s on s.id = sw.id_scope and s.id_user = :idUser",
nativeQuery = true
)
List<Workspace> findWithPermission(@Param("idUser") Long idUser);
/**
......@@ -55,7 +62,10 @@ public interface WorkspaceRepository extends JpaRepository<Workspace, Long>, Rol
* @param idWorkspace L'identifiant du workspace.
* @return 'true' si l'utilisateur possède les droits d'administrations sur le workspace, sinon 'false'.
*/
@Query(value = "select exists(select sw.* from scope_workspace sw join scope s on sw.id_scope = s.id where sw.id_workspace = :idWorkspace and s.id_user = :idUser)", nativeQuery = true)
@Query(
value = "select exists(select sw.* from scope_workspace sw join scope s on sw.id_scope = s.id where sw.id_workspace = :idWorkspace and s.id_user = :idUser)",
nativeQuery = true
)
boolean existPermission(@Param("idUser") Long idUser, @Param("idWorkspace") Long idWorkspace);
/**
......@@ -67,7 +77,10 @@ public interface WorkspaceRepository extends JpaRepository<Workspace, Long>, Rol
* @param idRole L'identifiant du rôle.
* @param idWorkspace L'identifiant du workspace.
*/
@Query(value = "with new_scope as (insert into scope (id_user, id_role) values (:idUser, :idRole) on conflict on constraint unique_scope do nothing returning id) insert into scope_workspace (id_scope, id_workspace) values (coalesce((select id from new_scope), (select id from scope where id_user = :idUser and id_role = :idRole)), :idWorkspace) on conflict on constraint unique_scope_workspace do nothing", nativeQuery = true)
@Query(
value = "with new_scope as (insert into scope (id_user, id_role) values (:idUser, :idRole) on conflict on constraint unique_scope do nothing returning id) insert into scope_workspace (id_scope, id_workspace) values (coalesce((select id from new_scope), (select id from scope where id_user = :idUser and id_role = :idRole)), :idWorkspace) on conflict on constraint unique_scope_workspace do nothing",
nativeQuery = true
)
@Modifying
void addRoleWithPermission(@Param("idUser") Long idUser, @Param("idRole") int idRole, @Param("idWorkspace") Long idWorkspace);
}
package com.unantes.orientactive.security;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
/**
* Constants for Spring Security authorities.
*/
public final class AuthoritiesConstants {
public static final String USER = "ROLE_USER";
public static final String ANONYMOUS = "ROLE_ANONYMOUS";
public static final String ADMIN = "ADMIN_SAAS";
public static final SimpleGrantedAuthority AUTHORITY_ADMIN = new SimpleGrantedAuthority(ADMIN);
public static final String VIEW_ORGANIZATION = "VIEW_ORGANIZATION";
public static final SimpleGrantedAuthority AUTHORITY_VIEW_ORGANIZATION = new SimpleGrantedAuthority(VIEW_ORGANIZATION);
public static final String EDIT_ORGANIZATION = "EDIT_ORGANIZATION";
public static final SimpleGrantedAuthority AUTHORITY_EDIT_ORGANIZATION = new SimpleGrantedAuthority(EDIT_ORGANIZATION);
public static final String VIEW_WORKSPACE = "VIEW_WORKSPACE";
public static final SimpleGrantedAuthority AUTHORITY_VIEW_WORKSPACE = new SimpleGrantedAuthority(VIEW_WORKSPACE);
public static final String EDIT_WORKSPACE = "EDIT_WORKSPACE";
public static final SimpleGrantedAuthority AUTHORITY_EDIT_WORKSPACE = new SimpleGrantedAuthority(EDIT_WORKSPACE);
public static final String VIEW_FORMS = "VIEW_FORMS";
public static final SimpleGrantedAuthority AUTHORITY_VIEW_FORMS = new SimpleGrantedAuthority(VIEW_FORMS);
public static final String VIEW_FORM = "VIEW_FORM";
public static final SimpleGrantedAuthority AUTHORITY_VIEW_FORM = new SimpleGrantedAuthority(VIEW_FORM);
public static final String EDIT_FORM = "EDIT_FORM";
public static final SimpleGrantedAuthority AUTHORITY_EDIT_FORM = new SimpleGrantedAuthority(EDIT_FORM);
public static final String VIEW_RESULT = "VIEW_RESULT";
public static final SimpleGrantedAuthority AUTHORITY_VIEW_RESULT = new SimpleGrantedAuthority(VIEW_RESULT);
private AuthoritiesConstants() {}
}
......@@ -2,9 +2,11 @@ package com.unantes.orientactive.security.permissions;
import com.unantes.orientactive.domain.User;
import com.unantes.orientactive.service.dto.UserDTO;
import java.util.List;
import java.util.Optional;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* Abstraction des services comprenant la gestion des permissions.
......@@ -139,4 +141,15 @@ public abstract class PermissionService<T extends PermissionEntity> {
* @return Présence ou non du wildcard.
*/
protected abstract boolean hasWildcard(User user);
/**
* Vérification de la présence d'un {@link SimpleGrantedAuthority} pour l'utilisateur courant.
*
* @param authority La {@link SimpleGrantedAuthority} qui doit être présente.
* @return Vrai si l'utilisateur possède la {@link SimpleGrantedAuthority}, sinon faux.
*/
public static boolean currentUserHasAuthority(final SimpleGrantedAuthority authority) {
final Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
return currentUser.getAuthorities().contains(authority);
}
}
package com.unantes.orientactive.web.rest.errors;
import com.unantes.orientactive.filariane.FilArianeException;
import com.unantes.orientactive.navigation.exception.NavigationException;
import com.unantes.orientactive.security.permissions.web.PermissionException;
import java.net.URI;
......@@ -40,6 +41,7 @@ import tech.jhipster.web.util.HeaderUtil;
*/
@ControllerAdvice
public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait {
private static final String FIELD_ERRORS_KEY = "fieldErrors";
private static final String MESSAGE_KEY = "message";
private static final String PATH_KEY = "path";
......@@ -178,6 +180,12 @@ public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait
return create(exception, problem, request);
}
@ExceptionHandler
public ResponseEntity<Problem> handlePermissionException(FilArianeException exception, NativeWebRequest request) {
Problem problem = Problem.builder().withType(null).withStatus(Status.FORBIDDEN).with(MESSAGE_KEY, exception.getMessage()).build();
return create(exception, problem, request);
}
@Override
public ProblemBuilder prepare(final Throwable throwable, final StatusType status, final URI type) {
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
......
......@@ -19,3 +19,5 @@ email.reset.title=orientactive password reset
email.reset.greeting=Dear {0}
email.reset.text1=For your orientactive account a password reset was requested, please click on the URL below to reset it:
email.reset.text2=Regards,
filariane.home.title=Home
......@@ -19,3 +19,5 @@ email.reset.title=orientactive Réinitialisation de mot de passe
email.reset.greeting=Cher {0}
email.reset.text1=Un nouveau mot de passe pour votre compte orientactive a été demandé, veuillez cliquer sur le lien ci-dessous pour le réinitialiser :
email.reset.text2=Cordialement,
filariane.home.title=Accueil
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment