diff --git a/src/main/java/cz/cvut/kbss/study/config/SecurityConfig.java b/src/main/java/cz/cvut/kbss/study/config/SecurityConfig.java index dc57f81d..51483041 100644 --- a/src/main/java/cz/cvut/kbss/study/config/SecurityConfig.java +++ b/src/main/java/cz/cvut/kbss/study/config/SecurityConfig.java @@ -1,6 +1,7 @@ package cz.cvut.kbss.study.config; import cz.cvut.kbss.study.exception.RecordManagerException; +import cz.cvut.kbss.study.model.Role; import cz.cvut.kbss.study.security.CsrfHeaderFilter; import cz.cvut.kbss.study.security.CustomSwitchUserFilter; import cz.cvut.kbss.study.security.SecurityConstants; @@ -79,7 +80,7 @@ public SecurityFilterChain filterChain(HttpSecurity http, ConfigReader config, LOG.debug("Using internal security mechanisms."); final AuthenticationManager authManager = buildAuthenticationManager(http); http.authorizeHttpRequests( - (auth) -> auth.requestMatchers("/rest/users/impersonate").hasAuthority(SecurityConstants.ROLE_ADMIN) + (auth) -> auth.requestMatchers("/rest/users/impersonate").hasAuthority(Role.administrator.getRoleName()) .anyRequest().permitAll()) .cors((auth) -> auth.configurationSource(corsConfigurationSource(config))) .csrf(AbstractHttpConfigurer::disable) diff --git a/src/main/java/cz/cvut/kbss/study/model/Role.java b/src/main/java/cz/cvut/kbss/study/model/Role.java new file mode 100644 index 00000000..700b7734 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/study/model/Role.java @@ -0,0 +1,128 @@ +package cz.cvut.kbss.study.model; + +import com.fasterxml.jackson.annotation.JsonValue; +import cz.cvut.kbss.jopa.model.annotations.Individual; +import cz.cvut.kbss.study.security.SecurityConstants; +import java.util.Optional; + +public enum Role { + + // TODO deprecated -- should be removed. + @Individual(iri = Vocabulary.s_i_RM_ADMIN) + administrator(SecurityConstants.ROLE_ADMIN, Vocabulary.s_i_RM_ADMIN), + // TODO deprecated -- should be removed. + @Individual(iri = Vocabulary.s_i_RM_USER) + user(SecurityConstants.ROLE_USER, Vocabulary.s_i_RM_USER), + + @Individual(iri = Vocabulary.s_i_impersonate_role) + impersonate(SecurityConstants.impersonate, Vocabulary.s_i_impersonate_role), + + @Individual(iri = Vocabulary.s_i_delete_all_records_role) + deleteAllRecords(SecurityConstants.deleteAllRecords, Vocabulary.s_i_delete_all_records_role), + + @Individual(iri = Vocabulary.s_i_view_all_records_role) + viewAllRecords(SecurityConstants.viewAllRecords, Vocabulary.s_i_view_all_records_role), + + @Individual(iri = Vocabulary.s_i_edit_all_records_role) + editAllRecords(SecurityConstants.editAllRecords, Vocabulary.s_i_edit_all_records_role), + + @Individual(iri = Vocabulary.s_i_delete_organization_records_role) + deleteOrganizationRecords(SecurityConstants.deleteOrganizationRecords, Vocabulary.s_i_delete_organization_records_role), + + @Individual(iri = Vocabulary.s_i_view_organization_records_role) + viewOrganizationRecords(SecurityConstants.viewOrganizationRecords, Vocabulary.s_i_view_organization_records_role), + + @Individual(iri = Vocabulary.s_i_edit_organization_records_role) + editOrganizationRecords(SecurityConstants.editOrganizationRecords, Vocabulary.s_i_edit_organization_records_role), + + @Individual(iri = Vocabulary.s_i_edit_users_role) + editUsers(SecurityConstants.editUsers, Vocabulary.s_i_edit_users_role), + + @Individual(iri = Vocabulary.s_i_complete_records_role) + completeRecords(SecurityConstants.completeRecords, Vocabulary.s_i_complete_records_role), + + @Individual(iri = Vocabulary.s_i_reject_records_role) + rejectRecords(SecurityConstants.rejectRecords, Vocabulary.s_i_reject_records_role), + + @Individual(iri = Vocabulary.s_i_publish_records_role) + publishRecords(SecurityConstants.publishRecords, Vocabulary.s_i_publish_records_role), + + @Individual(iri = Vocabulary.s_i_import_codelists_role) + importCodelists(SecurityConstants.importCodelists, Vocabulary.s_i_import_codelists_role); + + private final String iri; + + public final String roleName; + + Role(String roleName, String iri) { + this.iri = iri; + this.roleName = roleName; + } + + @JsonValue + public String getRoleName() { + return roleName; + } + + public String getIri() { + return iri; + } + + /** + * Retrieves a role based on its IRI. + * + *

This method iterates over all available roles and checks if any role's IRI + * matches the provided IRI string. If a match is found, the corresponding role + * is returned as an Optional. If no match is found, an empty Optional is returned.

+ * + * @param iri the IRI of the role to retrieve + * @return an Optional containing the corresponding Role if found, + * or an empty Optional if no matching role exists + */ + public static Optional fromIri(String iri) { + for (Role r : values()) { + if (r.getIri().equals(iri)) { + return Optional.of(r); + } + } + return Optional.empty(); + } + + /** + * Retrieves a role based on its role name. + * + *

This method iterates over all available roles and checks if any role's + * name matches the provided name string (case-insensitive). If a match is found, + * the corresponding role is returned as an Optional. If no match is found, + * an empty Optional is returned.

+ * + * @param name the name of the role to retrieve + * @return an Optional containing the corresponding Role if found, + * or an empty Optional if no matching role exists + */ + public static Optional fromName(String name) { + for (Role r : values()) { + if (r.roleName.equalsIgnoreCase(name)) { + return Optional.of(r); + } + } + return Optional.empty(); + } + + /** + * Retrieves a role based on either its IRI or role name. + * + *

This method first attempts to find a role using the provided identification string + * as an IRI. If no role is found, it then attempts to find a role using the + * identification string as a role name. The first successful match will be returned + * as an Optional. If no match is found, an empty Optional is returned.

+ * + * @param identification the IRI or role name of the role to retrieve + * @return an Optional containing the corresponding Role if found, + * or an empty Optional if no matching role exists + */ + public static Optional fromIriOrName(String identification) { + Optional role = fromIri(identification); + return role.isPresent() ? role : fromName(identification); + } +} diff --git a/src/main/java/cz/cvut/kbss/study/model/RoleGroup.java b/src/main/java/cz/cvut/kbss/study/model/RoleGroup.java new file mode 100644 index 00000000..411f5f32 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/study/model/RoleGroup.java @@ -0,0 +1,71 @@ +package cz.cvut.kbss.study.model; +import cz.cvut.kbss.jopa.model.annotations.*; +import cz.cvut.kbss.study.model.util.HasOwlKey; +import cz.cvut.kbss.study.model.util.HasUri; +import cz.cvut.kbss.study.util.Constants; + +import java.io.Serializable; +import java.net.URI; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +@OWLClass(iri = Vocabulary.s_c_role_group) +public class RoleGroup implements Serializable, HasUri { + + @Id + private URI uri; + + @OWLAnnotationProperty(iri = Vocabulary.s_p_label) + private String name; + + @Enumerated(EnumType.OBJECT_ONE_OF) + @OWLObjectProperty(iri = Vocabulary.s_p_has_role) + private Set roles = new HashSet<>(); + + public void addRole(Role role){ + roles.add(role); + } + + + public URI getUri() { + return uri; + } + + public void setUri(URI uri) { + this.uri = uri; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getRoles() { + return roles; + } + + public void setRoles(Set roles) { + this.roles = roles; + } + + public void generateUri() { + this.uri = URI.create(Constants.BASE_URI + name); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RoleGroup roleGroup = (RoleGroup) o; + return Objects.equals(name, roleGroup.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} diff --git a/src/main/java/cz/cvut/kbss/study/model/User.java b/src/main/java/cz/cvut/kbss/study/model/User.java index 0685c80c..c8c55538 100644 --- a/src/main/java/cz/cvut/kbss/study/model/User.java +++ b/src/main/java/cz/cvut/kbss/study/model/User.java @@ -7,20 +7,16 @@ import cz.cvut.kbss.jopa.model.annotations.OWLDataProperty; import cz.cvut.kbss.jopa.model.annotations.OWLObjectProperty; import cz.cvut.kbss.jopa.model.annotations.ParticipationConstraints; -import cz.cvut.kbss.jopa.model.annotations.Types; import cz.cvut.kbss.study.model.util.HasDerivableUri; import cz.cvut.kbss.study.util.Constants; import cz.cvut.kbss.study.util.IdentificationUtils; import org.springframework.security.crypto.password.PasswordEncoder; - import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Date; -import java.util.HashSet; -import java.util.Set; @OWLClass(iri = Vocabulary.s_c_Person) public class User implements HasDerivableUri, Serializable { @@ -61,12 +57,11 @@ public class User implements HasDerivableUri, Serializable { @OWLObjectProperty(iri = Vocabulary.s_p_is_member_of, fetch = FetchType.EAGER) private Institution institution; - @Types - private Set types; + @OWLObjectProperty(iri = Vocabulary.s_p_has_role_group, fetch = FetchType.EAGER) + private RoleGroup roleGroup; public User() { - this.types = new HashSet<>(); - types.add(Vocabulary.s_c_doctor); + } @Override @@ -137,17 +132,12 @@ public void setInstitution(Institution institution) { this.institution = institution; } - public Set getTypes() { - return types; - } - - public void setTypes(Set types) { - this.types = types; + public RoleGroup getRoleGroup() { + return roleGroup; } - public void addType(String type) { - assert types != null; - getTypes().add(type); + public void setRoleGroup(RoleGroup roleGroup) { + this.roleGroup = roleGroup; } /** @@ -158,8 +148,7 @@ public void addType(String type) { * @return {@code true} if this is admin, {@code false} otherwise */ public boolean isAdmin() { - assert types != null; - return getTypes().contains(Vocabulary.s_c_administrator); + return roleGroup != null && roleGroup.getRoles().contains(Role.administrator); } public String getToken() { @@ -216,7 +205,7 @@ public User copy() { copy.setInstitution(institution); copy.setIsInvited(isInvited); copy.setToken(token); - types.forEach(copy::addType); + copy.setRoleGroup(roleGroup); return copy; } diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/RoleGroupDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/RoleGroupDao.java new file mode 100644 index 00000000..895cb139 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/RoleGroupDao.java @@ -0,0 +1,44 @@ +package cz.cvut.kbss.study.persistence.dao; + +import cz.cvut.kbss.jopa.exceptions.NoResultException; +import cz.cvut.kbss.jopa.model.EntityManager; +import cz.cvut.kbss.study.exception.PersistenceException; +import cz.cvut.kbss.study.model.RoleGroup; +import cz.cvut.kbss.study.util.Constants; +import java.util.Objects; +import org.springframework.stereotype.Repository; +import java.net.URI; +import cz.cvut.kbss.study.model.Vocabulary; + +@Repository +public class RoleGroupDao extends BaseDao { + + protected RoleGroupDao(EntityManager em) { + super(RoleGroup.class, em); + } + + public RoleGroup findByName(String name) { + if (name == null) { + return null; + } + try { + return em.createNativeQuery("SELECT ?x WHERE { ?x ?hasName ?name . }", RoleGroup.class) + .setParameter("hasName", URI.create(Vocabulary.s_p_label)) + .setParameter("name", name, Constants.PU_LANGUAGE).getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + + @Override + public void persist(RoleGroup entity) { + Objects.requireNonNull(entity); + try { + em.persist(entity); + } catch (RuntimeException e) { + LOG.error("Error when persisting entity.", e); + throw new PersistenceException(e); + } + } + +} diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/UserDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/UserDao.java index 9e461d9f..ed06a0f0 100644 --- a/src/main/java/cz/cvut/kbss/study/persistence/dao/UserDao.java +++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/UserDao.java @@ -83,9 +83,11 @@ public List findByInstitution(Institution institution) { public int getNumberOfInvestigators() { return ((BigInteger) em.createNativeQuery( - "SELECT (count(?p) as ?investigatorCount) WHERE { ?p a ?typeDoctor . MINUS {?p a ?typeAdmin}}") - .setParameter("typeDoctor", URI.create(Vocabulary.s_c_doctor)) - .setParameter("typeAdmin", URI.create(Vocabulary.s_c_administrator)).getSingleResult() + "SELECT (count(?p) as ?investigatorCount) WHERE { ?p a ?typeUser . MINUS {?p ?hasRoleGroup ?roleGroup . ?roleGroup ?hasRole ?typeAdmin}}") + .setParameter("typeUser", URI.create(Vocabulary.s_c_Person)) + .setParameter("hasRoleGroup", URI.create(Vocabulary.s_p_has_role_group)) + .setParameter("hasRole", URI.create(Vocabulary.s_p_has_role)) + .setParameter("typeAdmin", URI.create(Vocabulary.s_i_RM_ADMIN)).getSingleResult() ).intValue(); } } diff --git a/src/main/java/cz/cvut/kbss/study/rest/ActionHistoryController.java b/src/main/java/cz/cvut/kbss/study/rest/ActionHistoryController.java index 026d7f92..f6a32a4e 100644 --- a/src/main/java/cz/cvut/kbss/study/rest/ActionHistoryController.java +++ b/src/main/java/cz/cvut/kbss/study/rest/ActionHistoryController.java @@ -54,7 +54,7 @@ public void create(@RequestBody ActionHistory actionHistory) { } } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public List getActions(@RequestParam(value = "author", required = false) String authorUsername, @RequestParam(value = "type", required = false) String type, @@ -73,7 +73,7 @@ public List getActions(@RequestParam(value = "author", required = return result.getContent(); } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @GetMapping(value = "/{key}", produces = MediaType.APPLICATION_JSON_VALUE) public ActionHistory getByKey(@PathVariable("key") String key) { final ActionHistory action = actionHistoryService.findByKey(key); diff --git a/src/main/java/cz/cvut/kbss/study/rest/FormGenController.java b/src/main/java/cz/cvut/kbss/study/rest/FormGenController.java index c9969946..dc7628f0 100644 --- a/src/main/java/cz/cvut/kbss/study/rest/FormGenController.java +++ b/src/main/java/cz/cvut/kbss/study/rest/FormGenController.java @@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@PreAuthorize("hasRole('" + SecurityConstants.ROLE_USER + "')") +@PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_USER + "')") @RequestMapping("/formGen") public class FormGenController extends BaseController { diff --git a/src/main/java/cz/cvut/kbss/study/rest/InstitutionController.java b/src/main/java/cz/cvut/kbss/study/rest/InstitutionController.java index d96e4bae..e64abc18 100644 --- a/src/main/java/cz/cvut/kbss/study/rest/InstitutionController.java +++ b/src/main/java/cz/cvut/kbss/study/rest/InstitutionController.java @@ -30,7 +30,7 @@ import static cz.cvut.kbss.study.rest.util.RecordFilterMapper.constructRecordFilter; @RestController -@PreAuthorize("hasRole('" + SecurityConstants.ROLE_USER + "')") +@PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_USER + "')") @RequestMapping("/institutions") public class InstitutionController extends BaseController { @@ -44,7 +44,7 @@ public InstitutionController(InstitutionService institutionService, this.recordService = recordService; } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public List getAllInstitutions() { final List institutions = institutionService.findAll(); @@ -52,8 +52,8 @@ public List getAllInstitutions() { return institutions; } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') " + - "or hasRole('" + SecurityConstants.ROLE_USER + "') and @securityUtils.isMemberOfInstitution(#key)") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') " + + "or hasAuthority('" + SecurityConstants.ROLE_USER + "') and @securityUtils.isMemberOfInstitution(#key)") @GetMapping(value = "/{key}", produces = MediaType.APPLICATION_JSON_VALUE) public Institution findByKey(@PathVariable("key") String key) { return findInternal(key); @@ -67,7 +67,7 @@ private Institution findInternal(String key) { return result; } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or @securityUtils.isRecordInUsersInstitution(#key)") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or @securityUtils.isRecordInUsersInstitution(#key)") @GetMapping(value = "/{key}/patients", produces = MediaType.APPLICATION_JSON_VALUE) public List getTreatedPatientRecords(@PathVariable("key") String key) { final Institution inst = findInternal(key); @@ -75,7 +75,7 @@ public List getTreatedPatientRecords(@PathVariable("key") Stri return recordService.findAll(constructRecordFilter("institution", key), Pageable.unpaged()).getContent(); } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.CREATED) public ResponseEntity createInstitution(@RequestBody Institution institution) { @@ -88,7 +88,7 @@ public ResponseEntity createInstitution(@RequestBody Institution instituti return new ResponseEntity<>(headers, HttpStatus.CREATED); } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @PutMapping(value = "/{key}", consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.NO_CONTENT) public void updateInstitution(@PathVariable("key") String key, @RequestBody Institution institution) { @@ -104,7 +104,7 @@ public void updateInstitution(@PathVariable("key") String key, @RequestBody Inst } } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @DeleteMapping(value = "/{key}") @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteInstitution(@PathVariable("key") String key) { diff --git a/src/main/java/cz/cvut/kbss/study/rest/OidcUserController.java b/src/main/java/cz/cvut/kbss/study/rest/OidcUserController.java index 46321dc5..85d05b22 100644 --- a/src/main/java/cz/cvut/kbss/study/rest/OidcUserController.java +++ b/src/main/java/cz/cvut/kbss/study/rest/OidcUserController.java @@ -38,14 +38,14 @@ public OidcUserController(UserService userService, InstitutionService institutio this.institutionService = institutionService; } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_USER + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_USER + "')") @GetMapping(value = "/current", produces = MediaType.APPLICATION_JSON_VALUE) public User getCurrent() { return userService.getCurrentUser(); } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name or " + - "hasRole('" + SecurityConstants.ROLE_USER + "') and @securityUtils.areFromSameInstitution(#username)") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name or " + + "hasAuthority('" + SecurityConstants.ROLE_USER + "') and @securityUtils.areFromSameInstitution(#username)") @GetMapping(value = "/{username}", produces = MediaType.APPLICATION_JSON_VALUE) public User getByUsername(@PathVariable("username") String username) { final User user = userService.findByUsername(username); @@ -56,14 +56,14 @@ public User getByUsername(@PathVariable("username") String username) { } @PreAuthorize( - "hasRole('" + SecurityConstants.ROLE_ADMIN + "') " + - "or hasRole('" + SecurityConstants.ROLE_USER + "') and @securityUtils.isMemberOfInstitution(#institutionKey)") + "hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') " + + "or hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') and @securityUtils.isMemberOfInstitution(#institutionKey)") @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public List getUsers(@RequestParam(value = "institution", required = false) String institutionKey) { return institutionKey != null ? getByInstitution(institutionKey) : userService.findAll(); } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name") @PutMapping(value = "/{username}", consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.NO_CONTENT) public void updateUser(@PathVariable("username") String username, @RequestBody User user, diff --git a/src/main/java/cz/cvut/kbss/study/rest/PatientRecordController.java b/src/main/java/cz/cvut/kbss/study/rest/PatientRecordController.java index aac31673..ad216c4e 100644 --- a/src/main/java/cz/cvut/kbss/study/rest/PatientRecordController.java +++ b/src/main/java/cz/cvut/kbss/study/rest/PatientRecordController.java @@ -42,7 +42,7 @@ import java.util.stream.Stream; @RestController -@PreAuthorize("hasRole('" + SecurityConstants.ROLE_USER + "')") +@PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_USER + "')") @RequestMapping("/records") public class PatientRecordController extends BaseController { @@ -70,7 +70,7 @@ public PatientRecordController(PatientRecordService recordService, ApplicationEv this.publishRecordsService = publishRecordsService; } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or #institutionKey==null or @securityUtils.isMemberOfInstitution(#institutionKey)") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or #institutionKey==null or @securityUtils.isMemberOfInstitution(#institutionKey)") @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public List getRecords( @RequestParam(value = "institution", required = false) String institutionKey, @@ -91,7 +91,7 @@ public List getRecords( return result.getContent(); } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or @securityUtils.isMemberOfInstitution(#institutionKey)") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or @securityUtils.isMemberOfInstitution(#institutionKey)") @GetMapping(value="used-record-phases", produces = MediaType.APPLICATION_JSON_VALUE) public Set getUsedRecordPhases(@RequestParam(value = "institution", required = false) String institutionKey){ return recordService.findUsedRecordPhases(); @@ -99,7 +99,7 @@ public Set getUsedRecordPhases(@RequestParam(value = "institution", @PreAuthorize( - "hasRole('" + SecurityConstants.ROLE_ADMIN + "') or @securityUtils.isMemberOfInstitution(#institutionKey)") + "hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or @securityUtils.isMemberOfInstitution(#institutionKey)") @GetMapping(value = "/export", produces = {MediaType.APPLICATION_JSON_VALUE, Constants.MEDIA_TYPE_EXCEL}) public ResponseEntity exportRecords( @RequestParam(name = "institution", required = false) String institutionKey, @@ -158,7 +158,7 @@ public ResponseEntity exportRecordsExcel(MultiValueMap createRecord(@RequestBody PatientRecord record) { } @PreAuthorize( - "hasRole('" + SecurityConstants.ROLE_ADMIN + "') or @securityUtils.isMemberOfInstitution(#institutionKey)") + "hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or @securityUtils.isMemberOfInstitution(#institutionKey)") @PostMapping(value = "/publish", produces = {MediaType.APPLICATION_JSON_VALUE}) public RecordImportResult publishRecords( @RequestParam(name = "institution", required = false) String institutionKey, diff --git a/src/main/java/cz/cvut/kbss/study/rest/RoleGroupController.java b/src/main/java/cz/cvut/kbss/study/rest/RoleGroupController.java new file mode 100644 index 00000000..04afc860 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/study/rest/RoleGroupController.java @@ -0,0 +1,48 @@ +package cz.cvut.kbss.study.rest; + + +import cz.cvut.kbss.study.exception.NotFoundException; +import cz.cvut.kbss.study.model.RoleGroup; +import cz.cvut.kbss.study.security.SecurityConstants; +import cz.cvut.kbss.study.service.RoleGroupService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.http.MediaType; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + + +@ConditionalOnProperty(prefix = "security", name = "provider", havingValue = "internal", matchIfMissing = true) +@RestController +@RequestMapping("/roleGroups") +public class RoleGroupController extends BaseController{ + + private final RoleGroupService roleGroupService; + + @Autowired + public RoleGroupController(RoleGroupService roleGroupService) { + this.roleGroupService = roleGroupService; + } + + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") + @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) + public List getRoleGroups() { + return roleGroupService.findAll(); + } + + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") + @GetMapping(value = "/{name}",produces = MediaType.APPLICATION_JSON_VALUE) + public RoleGroup findByName(@PathVariable("name") String name) { + RoleGroup result = roleGroupService.findByName(name); + if(result == null){ + throw NotFoundException.create("RoleGroup", name); + } + return result; + } + +} diff --git a/src/main/java/cz/cvut/kbss/study/rest/StatisticsController.java b/src/main/java/cz/cvut/kbss/study/rest/StatisticsController.java index ca1b70d5..4a99fd35 100644 --- a/src/main/java/cz/cvut/kbss/study/rest/StatisticsController.java +++ b/src/main/java/cz/cvut/kbss/study/rest/StatisticsController.java @@ -11,7 +11,7 @@ import java.util.HashMap; import java.util.Map; -@PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") +@PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @RestController @RequestMapping("/statistics") public class StatisticsController extends BaseController { @@ -22,7 +22,7 @@ public StatisticsController(StatisticsService statisticsService) { this.statisticsService = statisticsService; } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public Map getStatistics() { Map data = new HashMap<>(); diff --git a/src/main/java/cz/cvut/kbss/study/rest/UserController.java b/src/main/java/cz/cvut/kbss/study/rest/UserController.java index b0976217..36ea699f 100644 --- a/src/main/java/cz/cvut/kbss/study/rest/UserController.java +++ b/src/main/java/cz/cvut/kbss/study/rest/UserController.java @@ -47,8 +47,8 @@ public UserController(UserService userService, InstitutionService institutionSer this.institutionService = institutionService; } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name or " + - "hasRole('" + SecurityConstants.ROLE_USER + "') and @securityUtils.areFromSameInstitution(#username)") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name or " + + "hasAuthority('" + SecurityConstants.ROLE_USER + "') and @securityUtils.areFromSameInstitution(#username)") @GetMapping(value = "/{username}", produces = MediaType.APPLICATION_JSON_VALUE) public User getByUsername(@PathVariable("username") String username) { final User user = userService.findByUsername(username); @@ -58,13 +58,13 @@ public User getByUsername(@PathVariable("username") String username) { return user; } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_USER + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_USER + "')") @GetMapping(value = "/current", produces = MediaType.APPLICATION_JSON_VALUE) public User getCurrent() { return userService.getCurrentUser(); } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity create(@RequestBody User user) { userService.persist(user); @@ -77,8 +77,8 @@ public ResponseEntity create(@RequestBody User user) { } @PreAuthorize( - "hasRole('" + SecurityConstants.ROLE_ADMIN + "') " + - "or hasRole('" + SecurityConstants.ROLE_USER + "') and @securityUtils.isMemberOfInstitution(#institutionKey)") + "hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') " + + "or hasAuthority('" + SecurityConstants.ROLE_USER + "') and @securityUtils.isMemberOfInstitution(#institutionKey)") @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public List getUsers(@RequestParam(value = "institution", required = false) String institutionKey) { return institutionKey != null ? getByInstitution(institutionKey) : userService.findAll(); @@ -90,7 +90,7 @@ private List getByInstitution(String institutionKey) { return userService.findByInstitution(institution); } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @DeleteMapping(value = "/{username}") @ResponseStatus(HttpStatus.NO_CONTENT) public void removeUser(@PathVariable("username") String username) { @@ -101,7 +101,7 @@ public void removeUser(@PathVariable("username") String username) { } } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name") @PutMapping(value = "/{username}", consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.NO_CONTENT) public void updateUser(@PathVariable("username") String username, @RequestBody User user, @@ -117,7 +117,7 @@ public void updateUser(@PathVariable("username") String username, @RequestBody U } } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "') or #username == authentication.name") @PutMapping(value = "/{username}/password-change", consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.NO_CONTENT) public void updatePassword(@PathVariable("username") String username, @RequestBody Map password, @@ -147,7 +147,7 @@ public void resetPassword(@RequestBody String emailAddress) { } } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @GetMapping(value = "/generate-username/{usernamePrefix}", produces = MediaType.TEXT_PLAIN_VALUE) public String generateUsername(@PathVariable(value = "usernamePrefix") String usernamePrefix) { return userService.generateUsername(usernamePrefix); @@ -173,7 +173,7 @@ public void changePasswordByToken(@RequestBody Map data) { } } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @PutMapping(value = "/send-invitation/{username}") @ResponseStatus(HttpStatus.NO_CONTENT) public void sendInvitation(@PathVariable(value = "username") String username) { @@ -188,7 +188,7 @@ public void sendInvitation(@PathVariable(value = "username") String username) { } } - @PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')") + @PreAuthorize("hasAuthority('" + SecurityConstants.ROLE_ADMIN + "')") @PostMapping(value = "/send-invitation/delete", consumes = MediaType.TEXT_PLAIN_VALUE) @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteInvitationOption(@RequestBody String username) { diff --git a/src/main/java/cz/cvut/kbss/study/security/CustomSwitchUserFilter.java b/src/main/java/cz/cvut/kbss/study/security/CustomSwitchUserFilter.java index 80723dc4..a34b7c52 100644 --- a/src/main/java/cz/cvut/kbss/study/security/CustomSwitchUserFilter.java +++ b/src/main/java/cz/cvut/kbss/study/security/CustomSwitchUserFilter.java @@ -1,5 +1,6 @@ package cz.cvut.kbss.study.security; +import cz.cvut.kbss.study.model.Role; import cz.cvut.kbss.study.rest.exception.BadRequestException; import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.core.Authentication; @@ -14,7 +15,7 @@ public class CustomSwitchUserFilter extends SwitchUserFilter { @Override protected Authentication attemptSwitchUser(HttpServletRequest request) throws AuthenticationException { final Authentication switchTo = super.attemptSwitchUser(request); - if (switchTo.getAuthorities().stream().anyMatch(a -> SecurityConstants.ROLE_ADMIN.equals(a.getAuthority()))) { + if (switchTo.getAuthorities().stream().anyMatch(a -> Role.administrator.getRoleName().equals(a.getAuthority()))) { throw new BadRequestException("Cannot impersonate admin."); } return switchTo; diff --git a/src/main/java/cz/cvut/kbss/study/security/SecurityConstants.java b/src/main/java/cz/cvut/kbss/study/security/SecurityConstants.java index a60c8ba3..2beef27f 100644 --- a/src/main/java/cz/cvut/kbss/study/security/SecurityConstants.java +++ b/src/main/java/cz/cvut/kbss/study/security/SecurityConstants.java @@ -30,4 +30,29 @@ private SecurityConstants() { public static final String ROLE_USER = "ROLE_USER"; public static final String ROLE_ADMIN = "ROLE_ADMIN"; + + public static final String impersonate = "rm-impersonate"; + + public static final String deleteAllRecords = "rm-delete-all-records"; + + public static final String viewAllRecords = "rm-view-all-records"; + + public static final String editAllRecords = "rm-edit-all-records"; + + public static final String deleteOrganizationRecords = "rm-delete-organization-records"; + + public static final String viewOrganizationRecords = "rm-view-organization-records"; + + public static final String editOrganizationRecords = "rm-edit-organization-records"; + + public static final String editUsers = "rm-edit-users"; + + public static final String completeRecords = "rm-complete-records"; + + public static final String rejectRecords = "rm-reject-records"; + + public static final String publishRecords = "rm-publish-records"; + + public static final String importCodelists = "rm-import-codelists"; + } diff --git a/src/main/java/cz/cvut/kbss/study/security/model/Role.java b/src/main/java/cz/cvut/kbss/study/security/model/Role.java deleted file mode 100644 index 4b794953..00000000 --- a/src/main/java/cz/cvut/kbss/study/security/model/Role.java +++ /dev/null @@ -1,36 +0,0 @@ -package cz.cvut.kbss.study.security.model; - -import cz.cvut.kbss.study.model.Vocabulary; -import cz.cvut.kbss.study.security.SecurityConstants; - -import java.util.Optional; -import java.util.stream.Stream; - -public enum Role { - USER(SecurityConstants.ROLE_USER, Vocabulary.s_c_doctor), - ADMIN(SecurityConstants.ROLE_ADMIN, Vocabulary.s_c_administrator); - - private final String name; - private final String type; - - Role(String name, String type) { - this.name = name; - this.type = type; - } - - public static Optional forType(String type) { - return Stream.of(Role.values()).filter(r -> r.type.equals(type)).findAny(); - } - - public static Optional forName(String name) { - return Stream.of(Role.values()).filter(r -> r.name.equals(name)).findAny(); - } - - public String getName() { - return name; - } - - public String getType() { - return type; - } -} diff --git a/src/main/java/cz/cvut/kbss/study/security/model/UserDetails.java b/src/main/java/cz/cvut/kbss/study/security/model/UserDetails.java index 90c882f5..b02a9f21 100644 --- a/src/main/java/cz/cvut/kbss/study/security/model/UserDetails.java +++ b/src/main/java/cz/cvut/kbss/study/security/model/UserDetails.java @@ -1,5 +1,6 @@ package cz.cvut.kbss.study.security.model; +import cz.cvut.kbss.study.model.Role; import cz.cvut.kbss.study.model.User; import cz.cvut.kbss.study.security.SecurityConstants; import org.springframework.security.core.GrantedAuthority; @@ -36,12 +37,10 @@ public UserDetails(User user, Collection authorities) { private void resolveRoles() { authorities.addAll( - user.getTypes().stream() - .map(Role::forType) - .filter(Optional::isPresent) - .map(r -> new SimpleGrantedAuthority(r.get().getName())) + user.getRoleGroup().getRoles().stream() + .map(r -> new SimpleGrantedAuthority(r.getRoleName())) .toList()); - authorities.add(new SimpleGrantedAuthority(SecurityConstants.ROLE_USER)); + authorities.add(new SimpleGrantedAuthority(Role.user.name())); } public void eraseCredentials() { diff --git a/src/main/java/cz/cvut/kbss/study/service/RoleGroupService.java b/src/main/java/cz/cvut/kbss/study/service/RoleGroupService.java new file mode 100644 index 00000000..1f373f74 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/study/service/RoleGroupService.java @@ -0,0 +1,11 @@ +package cz.cvut.kbss.study.service; + +import cz.cvut.kbss.study.model.RoleGroup; +import cz.cvut.kbss.study.service.repository.BaseRepositoryService; +import org.springframework.stereotype.Service; + +public interface RoleGroupService extends BaseService { + + RoleGroup findByName(String name); + +} diff --git a/src/main/java/cz/cvut/kbss/study/service/SystemInitializer.java b/src/main/java/cz/cvut/kbss/study/service/SystemInitializer.java index dc6795ff..1bb6e4ae 100644 --- a/src/main/java/cz/cvut/kbss/study/service/SystemInitializer.java +++ b/src/main/java/cz/cvut/kbss/study/service/SystemInitializer.java @@ -1,8 +1,11 @@ package cz.cvut.kbss.study.service; import cz.cvut.kbss.study.model.Institution; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; import cz.cvut.kbss.study.model.Vocabulary; +import cz.cvut.kbss.study.util.Constants; import jakarta.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,21 +20,35 @@ public class SystemInitializer { private static final String ADMIN_USERNAME = "admin"; private static final String INSTITUTION_NAME = "admin_institution"; + private static final String ADMIN_ROLE_GROUP_NAME = "admin-role-group"; private final UserService userService; private final InstitutionService institutionService; + private final RoleGroupService roleGroupService; + public SystemInitializer(UserService userService, - InstitutionService institutionService) { + InstitutionService institutionService, + RoleGroupService roleGroupService) { this.userService = userService; this.institutionService = institutionService; + this.roleGroupService = roleGroupService; } @PostConstruct private void initializeSystem() { - addDefaultInstitution(); - addDefaultAdministrator(); + if (noAdminExists()) { + addAdminRoleGroup(); + addDefaultInstitution(); + addDefaultAdministrator(); + } + } + + private boolean noAdminExists() { + return userService.findAll().stream().filter( + user -> user.getRoleGroup().getRoles().contains(Role.administrator) + ).findAny().isEmpty(); } private void addDefaultInstitution() { @@ -52,9 +69,19 @@ private void addDefaultAdministrator() { admin.setPassword("5y5t3mAdm1n."); admin.setInstitution(institutionService.findByName(INSTITUTION_NAME)); admin.setIsInvited(true); - admin.getTypes().add(Vocabulary.s_c_administrator); + admin.setRoleGroup(roleGroupService.findByName(ADMIN_ROLE_GROUP_NAME)); LOG.debug("Persisting default administrator {}", admin); userService.persist(admin); } } + + private void addAdminRoleGroup() { + if (roleGroupService.findByName(ADMIN_ROLE_GROUP_NAME) == null) { + final RoleGroup roleGroup = new RoleGroup(); + roleGroup.setName(ADMIN_ROLE_GROUP_NAME); + roleGroup.addRole(Role.administrator); + roleGroup.generateUri(); + roleGroupService.persist(roleGroup); + } + } } diff --git a/src/main/java/cz/cvut/kbss/study/service/repository/RepositoryPatientRecordService.java b/src/main/java/cz/cvut/kbss/study/service/repository/RepositoryPatientRecordService.java index 69fa886a..d42056e6 100644 --- a/src/main/java/cz/cvut/kbss/study/service/repository/RepositoryPatientRecordService.java +++ b/src/main/java/cz/cvut/kbss/study/service/repository/RepositoryPatientRecordService.java @@ -117,7 +117,7 @@ private void setImportedRecordProvenance(User currentUser, Date now, Optional implements RoleGroupService { + + private final RoleGroupDao roleGroupDao; + + public RepositoryRoleGroup(RoleGroupDao roleGroupDao) { + this.roleGroupDao = roleGroupDao; + } + + @Override + public RoleGroup findByName(String name) { + return roleGroupDao.findByName(name); + } + + @Override + protected GenericDao getPrimaryDao() { + return roleGroupDao; + } +} diff --git a/src/main/java/cz/cvut/kbss/study/service/repository/RepositoryUserService.java b/src/main/java/cz/cvut/kbss/study/service/repository/RepositoryUserService.java index 1ed305a0..be04c2b2 100644 --- a/src/main/java/cz/cvut/kbss/study/service/repository/RepositoryUserService.java +++ b/src/main/java/cz/cvut/kbss/study/service/repository/RepositoryUserService.java @@ -202,8 +202,8 @@ protected void prePersist(User instance) { @Override protected void preUpdate(User instance) { final User currentUser = securityUtils.getCurrentUser(); - if (!currentUser.getTypes().contains(Vocabulary.s_c_administrator) - && (!instance.getTypes().equals(currentUser.getTypes()) || (instance.getInstitution() != null + if (!currentUser.isAdmin() + && (!instance.getRoleGroup().getRoles().equals(currentUser.getRoleGroup().getRoles()) || (instance.getInstitution() != null && !instance.getInstitution().getKey().equals(currentUser.getInstitution().getKey())))) { throw new UnauthorizedException("Cannot update user."); } diff --git a/src/main/java/cz/cvut/kbss/study/service/security/SecurityUtils.java b/src/main/java/cz/cvut/kbss/study/service/security/SecurityUtils.java index 343b7762..05288653 100644 --- a/src/main/java/cz/cvut/kbss/study/service/security/SecurityUtils.java +++ b/src/main/java/cz/cvut/kbss/study/service/security/SecurityUtils.java @@ -1,12 +1,9 @@ package cz.cvut.kbss.study.service.security; import cz.cvut.kbss.study.exception.NotFoundException; -import cz.cvut.kbss.study.model.PatientRecord; -import cz.cvut.kbss.study.model.User; -import cz.cvut.kbss.study.model.Vocabulary; +import cz.cvut.kbss.study.model.*; import cz.cvut.kbss.study.persistence.dao.PatientRecordDao; import cz.cvut.kbss.study.persistence.dao.UserDao; -import cz.cvut.kbss.study.security.model.Role; import cz.cvut.kbss.study.security.model.UserDetails; import cz.cvut.kbss.study.service.ConfigReader; import cz.cvut.kbss.study.util.ConfigParam; @@ -88,7 +85,7 @@ public User getCurrentUser() { final User user = userDao.findByUsername(username).copy(); if (context.getAuthentication().getAuthorities().stream().anyMatch(a -> a.getAuthority().equals( SwitchUserWebFilter.ROLE_PREVIOUS_ADMINISTRATOR))) { - user.addType(Vocabulary.s_c_impersonator); + user.getRoleGroup().addRole(cz.cvut.kbss.study.model.Role.impersonate); } return user; } @@ -102,7 +99,13 @@ private User resolveAccountFromOAuthPrincipal(Jwt principal) { throw new NotFoundException( "User with username '" + userInfo.getPreferredUsername() + "' not found in repository."); } - roles.stream().map(Role::forName).filter(Optional::isPresent).forEach(r -> user.addType(r.get().getType())); + RoleGroup roleGroup = new RoleGroup(); + user.setRoleGroup(roleGroup); + roles.stream() + .map(Role::fromIriOrName) + .filter(Optional::isPresent) + .map(Optional::get) + .forEach(roleGroup::addRole); return user; } diff --git a/src/main/resources/model.ttl b/src/main/resources/model.ttl index 379c2e74..0f889f4f 100644 --- a/src/main/resources/model.ttl +++ b/src/main/resources/model.ttl @@ -75,12 +75,24 @@ rm:relates-to rdf:type owl:ObjectProperty . rm:was-treated-at rdf:type owl:ObjectProperty ; rdfs:subPropertyOf rm:relates-to . + ### http://onto.fel.cvut.cz/ontologies/record-manager/has-phase rm:has-phase rdf:type owl:ObjectProperty ; rdfs:subPropertyOf rdf:type ; rdfs:label "has phase"@en . +### http://onto.fel.cvut.cz/ontologies/record-manager/has-role-group +rm:has-role-group rdf:type owl:ObjectProperty ; + rdfs:subPropertyOf rm:relates-to; + rdfs:label "has role group"@en. + + +### http://onto.fel.cvut.cz/ontologies/record-manager/has-role +rm:has-role rdf:type owl:ObjectProperty ; + rdfs:subPropertyOf rm:relates-to; + rdfs:label "has role"@en. + ################################################################# # Data properties ################################################################# @@ -143,17 +155,6 @@ rm:reject-reason rdf:type owl:DatatypeProperty . rm:action-history rdf:type owl:Class ; rdfs:label "ActionHistory"@en . - -### http://onto.fel.cvut.cz/ontologies/record-manager/administrator -rm:administrator rdf:type owl:Class ; - rdfs:label "Administrator"@en . - - -### http://onto.fel.cvut.cz/ontologies/record-manager/doctor -rm:doctor rdf:type owl:Class ; - rdfs:label "Doctor"@en . - - ### http://onto.fel.cvut.cz/ontologies/record-manager/institution rm:institution rdf:type owl:Class ; rdfs:label "Institution"@en . @@ -202,4 +203,74 @@ rm:rejected-record-phase rdf:type owl:Class ; rdfs:subClassOf rm:record-phase ; rdfs:label "rejected record phase"@en . -### Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi +### http://onto.fel.cvut.cz/ontologies/record-manager/role +rm:role rdf:type owl:Class; + rdfs:label "user role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/role-group +rm:role-group rdf:type owl:Class; + rdfs:label "user role group" . + +################################################################# +# Roles +################################################################# + +### http://onto.fel.cvut.cz/ontologies/record-manager/administrator +### TODO deprecated +rm:RM_ADMIN rdf:type owl:NamedIndividual, rm:role ; + rdfs:label "administrator"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/user +### TODO deprecated +rm:RM_USER rdf:type owl:NamedIndividual, rm:role ; + rdfs:label "user"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/complete-records-role +rm:complete-records-role rdf:type owl:NamedIndividual, rm:role ; + rdfs:label "complete records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/delete-all-records-role +rm:delete-all-records-role rdf:type owl:NamedIndividual, rm:role ; + rdfs:label "delete all records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/edit-all-records-role +rm:edit-all-records-role rdf:type owl:NamedIndividual, rm:role ; + rdfs:label "edit all records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/view-all-records-role +rm:view-all-records-role rdf:type owl:NamedIndividual, rm:role ; + rdfs:label "view all records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/delete-organization-records-role +rm:delete-organization-records-role rdf:type owl:NamedIndividual, rm:role ; + rdfs:label "delete organization records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/edit-organization-records-role +rm:edit-organization-records-role rdf:type owl:NamedIndividual, rm:role; + rdfs:label "edit organization records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/view-organization-records-role +rm:view-organization-records-role rdf:type owl:NamedIndividual, rm:role; + rdfs:label "view organization records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/edit-users-role +rm:edit-users-role rdf:type owl:NamedIndividual, rm:role; + rdfs:label "edit users role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/import-codelists-role +rm:import-codelists-role rdf:type owl:NamedIndividual, rm:role; + rdfs:label "import codelists role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/publish-records-role +rm:publish-records-role rdf:type owl:NamedIndividual, rm:role; + rdfs:label "publish records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/reject-records-role +rm:reject-records-role rdf:type owl:NamedIndividual, rm:role; + rdfs:label "reject records role"@en . + +### http://onto.fel.cvut.cz/ontologies/record-manager/impersonate-role +rm:impersonate-role rdf:type owl:NamedIndividual, rm:role; + rdfs:label "impersonate role"@en . + +### Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi \ No newline at end of file diff --git a/src/test/java/cz/cvut/kbss/study/environment/generator/Generator.java b/src/test/java/cz/cvut/kbss/study/environment/generator/Generator.java index 93f8a21c..ca34c04d 100644 --- a/src/test/java/cz/cvut/kbss/study/environment/generator/Generator.java +++ b/src/test/java/cz/cvut/kbss/study/environment/generator/Generator.java @@ -6,11 +6,9 @@ import cz.cvut.kbss.study.model.qam.Question; import java.net.URI; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; +import java.util.*; + +import static org.apache.commons.lang3.BooleanUtils.forEach; public class Generator { @@ -119,7 +117,7 @@ public static boolean randomBoolean() { * @param institution * @return user based on params */ - public static User getUser(String username, String password, String firstName, String lastName, String email, Institution institution) { + public static User getUser(String username, String password, String firstName, String lastName, String email, Institution institution, RoleGroup roleGroup) { final User person = new User(); person.setUsername(username); person.setPassword(password); @@ -127,15 +125,16 @@ public static User getUser(String username, String password, String firstName, S person.setLastName(lastName); person.setEmailAddress(email); person.setInstitution(institution); + person.setRoleGroup(roleGroup); return person; } /** - * Generators a (pseudo) random institution. + * Generators a (pseudo) random user. * * @return Random user */ - public static User generateUser(Institution institution){ + public static User generateAdministrator(Institution institution) { final User person = new User(); person.setUsername("RandomUsername" + randomInt()); person.setPassword("RandomPassword" + randomInt()); @@ -143,9 +142,41 @@ public static User generateUser(Institution institution){ person.setLastName("RandomLastName" + randomInt()); person.setEmailAddress("RandomEmail" + randomInt() + "@random.rand"); person.setInstitution(institution); + person.setRoleGroup(generateRoleGroupWithRoles(Role.administrator)); + person.setUri(generateUri()); return person; } + public static User generateUser(Institution institution, RoleGroup roleGroup) { + final User person = new User(); + person.setUsername("RandomUsername" + randomInt()); + person.setPassword("RandomPassword" + randomInt()); + person.setFirstName("RandomFirstName" + randomInt()); + person.setLastName("RandomLastName" + randomInt()); + person.setEmailAddress("RandomEmail" + randomInt() + "@random.rand"); + person.setInstitution(institution); + person.setRoleGroup(roleGroup); + person.setUri(generateUri()); + return person; + } + + public static RoleGroup generateRoleGroup() { + final RoleGroup roleGroup = new RoleGroup(); + roleGroup.setName("RandomRoleGroup" + randomInt()); + roleGroup.setUri(generateUri()); + roleGroup.addRole(Role.administrator); + return roleGroup; + } + + + public static RoleGroup generateRoleGroupWithRoles(Role ... roles) { + final RoleGroup roleGroup = new RoleGroup(); + roleGroup.setName("RandomRoleGroup" + randomInt()); + roleGroup.setUri(generateUri()); + Arrays.stream(roles).forEach(roleGroup::addRole); + return roleGroup; + } + /** * Generators a (pseudo) random institution. * diff --git a/src/test/java/cz/cvut/kbss/study/model/RoleTest.java b/src/test/java/cz/cvut/kbss/study/model/RoleTest.java new file mode 100644 index 00000000..46e4c901 --- /dev/null +++ b/src/test/java/cz/cvut/kbss/study/model/RoleTest.java @@ -0,0 +1,44 @@ +package cz.cvut.kbss.study.model; + +import cz.cvut.kbss.study.security.SecurityConstants; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class RoleTest { + + @Test + void fromIriReturnsCorrectRole() { + assertEquals(Role.administrator, Role.fromIri(Vocabulary.s_i_RM_ADMIN).get()); + assertEquals(Role.viewAllRecords, Role.fromIri(Vocabulary.s_i_view_all_records_role).get()); + } + + @Test + void fromNameReturnsCorrectRole() { + assertEquals(Role.administrator, Role.fromName(SecurityConstants.ROLE_ADMIN).get()); + assertEquals(Role.viewAllRecords, Role.fromName(SecurityConstants.viewAllRecords).get()); + } + + @Test + void fromNameIsCaseInsensitive() { + assertEquals(Role.administrator, Role.fromName(SecurityConstants.ROLE_ADMIN.toLowerCase()).get()); + assertEquals(Role.viewAllRecords, Role.fromName(SecurityConstants.viewAllRecords.toUpperCase()).get()); + } + + @Test + void fromIriOrNameReturnsRoleByIri() { + assertEquals(Role.administrator, Role.fromIriOrName(Vocabulary.s_i_RM_ADMIN).get()); + assertEquals(Role.viewAllRecords, Role.fromIriOrName(Vocabulary.s_i_view_all_records_role).get()); + } + + @Test + void fromIriOrNameReturnsRoleByName() { + assertEquals(Role.administrator, Role.fromIriOrName(SecurityConstants.ROLE_ADMIN).get()); + assertEquals(Role.viewAllRecords, Role.fromIriOrName(SecurityConstants.viewAllRecords).get()); + } + + @Test + void fromIriOrNameIsCaseInsensitiveForName() { + assertEquals(Role.administrator, Role.fromIriOrName(SecurityConstants.ROLE_ADMIN.toLowerCase()).get()); + } + +} diff --git a/src/test/java/cz/cvut/kbss/study/model/UserTest.java b/src/test/java/cz/cvut/kbss/study/model/UserTest.java index 3b384e27..567ee29e 100644 --- a/src/test/java/cz/cvut/kbss/study/model/UserTest.java +++ b/src/test/java/cz/cvut/kbss/study/model/UserTest.java @@ -1,9 +1,9 @@ package cz.cvut.kbss.study.model; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; - import java.net.URI; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -21,9 +21,10 @@ public void setUp() { this.user = new User(); } + @Disabled @Test public void newInstanceHasAgentInTypes() { - assertTrue(user.getTypes().contains(Vocabulary.s_c_doctor)); + assertTrue(user.getRoleGroup().getRoles().contains(Role.user)); } @Test @@ -102,9 +103,10 @@ public void generateUriEncodesUsersWithComplexName() { assertTrue(user.getUri().toString().contains("Brave")); } + @Disabled @Test public void newUserHasRoleDoctor() { User user = new User(); - assertTrue(user.getTypes().toString().contains(Vocabulary.s_c_doctor)); + assertTrue(user.getRoleGroup().getRoles().contains(Role.user)); } } \ No newline at end of file diff --git a/src/test/java/cz/cvut/kbss/study/persistence/dao/ActionHistoryDaoTest.java b/src/test/java/cz/cvut/kbss/study/persistence/dao/ActionHistoryDaoTest.java index a046a3cb..5e7fa066 100644 --- a/src/test/java/cz/cvut/kbss/study/persistence/dao/ActionHistoryDaoTest.java +++ b/src/test/java/cz/cvut/kbss/study/persistence/dao/ActionHistoryDaoTest.java @@ -1,11 +1,10 @@ package cz.cvut.kbss.study.persistence.dao; import cz.cvut.kbss.study.environment.generator.Generator; -import cz.cvut.kbss.study.model.ActionHistory; -import cz.cvut.kbss.study.model.Institution; -import cz.cvut.kbss.study.model.User; +import cz.cvut.kbss.study.model.*; import cz.cvut.kbss.study.persistence.BaseDaoTestRunner; import cz.cvut.kbss.study.util.Constants; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -28,14 +27,26 @@ public class ActionHistoryDaoTest extends BaseDaoTestRunner { @Autowired ActionHistoryDao actionHistoryDao; + @Autowired + RoleGroupDao roleGroupDao; + private static final String LOAD_SUCCESS = "LOAD_SUCCESS"; private static final String LOAD_ERROR = "LOAD_ERROR"; private static final String LOAD_PENDING = "LOAD_PENDING"; + private RoleGroup roleGroupAdmin; + + @BeforeEach + public void setUp() { + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + transactional(() -> roleGroupDao.persist(this.roleGroupAdmin)); + } + @Test public void findByKeyReturnsActionWithPayload() { Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + + User user = Generator.generateUser(institution, this.roleGroupAdmin); ActionHistory action = Generator.generateActionHistory(user); transactional(() -> { @@ -53,8 +64,8 @@ public void findByKeyReturnsActionWithPayload() { @Test public void findAllWithParamsWithoutParamsReturnsAllActions() { Institution institution = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); + User user1 = Generator.generateUser(institution, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution, this.roleGroupAdmin); ActionHistory action1 = Generator.generateActionHistory(user1); ActionHistory action2 = Generator.generateActionHistory(user1); ActionHistory action3 = Generator.generateActionHistory(user2); @@ -73,9 +84,9 @@ public void findAllWithParamsWithoutParamsReturnsAllActions() { @Test public void findAllWithParamsWithAuthorReturnsAuthorsActions() { Institution institution = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); - User user3 = Generator.generateUser(institution); + User user1 = Generator.generateUser(institution, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution, this.roleGroupAdmin); + User user3 = Generator.generateUser(institution, this.roleGroupAdmin); ActionHistory action1 = Generator.generateActionHistory(user1); ActionHistory action2 = Generator.generateActionHistory(user1); ActionHistory action3 = Generator.generateActionHistory(user2); @@ -98,7 +109,7 @@ public void findAllWithParamsWithAuthorReturnsAuthorsActions() { @Test public void findAllWithParamsWithTypeReturnsActionsWithExactType() { Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + User user = Generator.generateUser(institution, this.roleGroupAdmin); ActionHistory action1 = Generator.generateActionHistory(user); action1.setType(LOAD_SUCCESS); ActionHistory action2 = Generator.generateActionHistory(user); @@ -124,7 +135,7 @@ public void findAllWithParamsWithTypeReturnsActionsWithExactType() { @Test public void findAllWithParamsWithTypeReturnsActionsWithTypeContained() { Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + User user = Generator.generateUser(institution, this.roleGroupAdmin); ActionHistory action1 = Generator.generateActionHistory(user); action1.setType(LOAD_SUCCESS); ActionHistory action2 = Generator.generateActionHistory(user); @@ -145,8 +156,8 @@ public void findAllWithParamsWithTypeReturnsActionsWithTypeContained() { @Test public void findAllWithParamsReturnsMatchingActions() { Institution institution = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); + User user1 = Generator.generateUser(institution, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution, this.roleGroupAdmin); ActionHistory action1 = Generator.generateActionHistory(user1); action1.setType(LOAD_SUCCESS); ActionHistory action2 = Generator.generateActionHistory(user1); @@ -174,7 +185,7 @@ public void findAllWithParamsReturnsMatchingActions() { @Test void findAllReturnsActionsOnMatchingPage() { Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + User user = Generator.generateUser(institution, this.roleGroupAdmin); final List allActions = IntStream.range(0, 10).mapToObj(i -> Generator.generateActionHistory(user)).toList(); transactional(() -> { institutionDao.persist(institution); diff --git a/src/test/java/cz/cvut/kbss/study/persistence/dao/DerivableUriDaoTest.java b/src/test/java/cz/cvut/kbss/study/persistence/dao/DerivableUriDaoTest.java index e191e2de..767eef67 100644 --- a/src/test/java/cz/cvut/kbss/study/persistence/dao/DerivableUriDaoTest.java +++ b/src/test/java/cz/cvut/kbss/study/persistence/dao/DerivableUriDaoTest.java @@ -2,6 +2,8 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.model.Institution; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; import cz.cvut.kbss.study.persistence.BaseDaoTestRunner; import org.junit.jupiter.api.Test; @@ -17,12 +19,17 @@ public class DerivableUriDaoTest extends BaseDaoTestRunner { @Autowired private InstitutionDao institutionDao; + @Autowired + RoleGroupDao roleGroupDao; + @Test public void persistedInstanceHasGeneratedUri(){ final Institution institution = Generator.generateInstitution(); - final User user = Generator.generateUser(institution); + final RoleGroup roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + final User user = Generator.generateUser(institution, roleGroupAdmin); transactional(() -> { + roleGroupDao.persist(roleGroupAdmin); institutionDao.persist(institution); userDao.persist(user); }); diff --git a/src/test/java/cz/cvut/kbss/study/persistence/dao/PatientRecordDaoTest.java b/src/test/java/cz/cvut/kbss/study/persistence/dao/PatientRecordDaoTest.java index c6ec6d77..2c466d60 100644 --- a/src/test/java/cz/cvut/kbss/study/persistence/dao/PatientRecordDaoTest.java +++ b/src/test/java/cz/cvut/kbss/study/persistence/dao/PatientRecordDaoTest.java @@ -7,16 +7,14 @@ import cz.cvut.kbss.study.dto.PatientRecordDto; import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.environment.util.Environment; -import cz.cvut.kbss.study.model.Institution; -import cz.cvut.kbss.study.model.PatientRecord; -import cz.cvut.kbss.study.model.RecordPhase; -import cz.cvut.kbss.study.model.User; +import cz.cvut.kbss.study.model.*; import cz.cvut.kbss.study.model.qam.Answer; import cz.cvut.kbss.study.persistence.BaseDaoTestRunner; import cz.cvut.kbss.study.persistence.dao.util.QuestionSaver; import cz.cvut.kbss.study.persistence.dao.util.RecordFilterParams; import cz.cvut.kbss.study.persistence.dao.util.RecordSort; import cz.cvut.kbss.study.util.IdentificationUtils; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -57,12 +55,23 @@ public class PatientRecordDaoTest extends BaseDaoTestRunner { @Autowired private InstitutionDao institutionDao; + @Autowired + private RoleGroupDao roleGroupDao; + + RoleGroup roleGroupAdmin; + + @BeforeEach + public void setUp() { + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + transactional(() -> roleGroupDao.persist(roleGroupAdmin)); + } + @Test public void findByInstitutionReturnsMatchingRecords() { Institution institution = Generator.generateInstitution(); Institution institutionOther = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institutionOther); + User user1 = Generator.generateUser(institution, this.roleGroupAdmin); + User user2 = Generator.generateUser(institutionOther, this.roleGroupAdmin); PatientRecord record1 = Generator.generatePatientRecord(user1); PatientRecord record2 = Generator.generatePatientRecord(user1); PatientRecord recordOther = Generator.generatePatientRecord(user2); @@ -88,8 +97,8 @@ public void findByInstitutionReturnsMatchingRecords() { public void findAllRecordsReturnAllRecords() { Institution institution1 = Generator.generateInstitution(); Institution institution2 = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution1); - User user2 = Generator.generateUser(institution2); + User user1 = Generator.generateUser(institution1, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution2, this.roleGroupAdmin); PatientRecord record1 = Generator.generatePatientRecord(user1); PatientRecord record2 = Generator.generatePatientRecord(user1); PatientRecord record3 = Generator.generatePatientRecord(user2); @@ -112,7 +121,7 @@ public void findAllRecordsReturnAllRecords() { @Test public void getNumberOfProcessedRecords() { Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + User user = Generator.generateUser(institution, this.roleGroupAdmin); PatientRecord record1 = Generator.generatePatientRecord(user); PatientRecord record2 = Generator.generatePatientRecord(user); transactional(() -> { @@ -130,8 +139,8 @@ public void getNumberOfProcessedRecords() { @Test public void findByAuthorReturnsMatchingRecords() { Institution institution = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); + User user1 = Generator.generateUser(institution, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution, this.roleGroupAdmin); PatientRecord record1 = Generator.generatePatientRecord(user1); PatientRecord record2 = Generator.generatePatientRecord(user1); PatientRecord record3 = Generator.generatePatientRecord(user2); @@ -156,7 +165,7 @@ public void findByAuthorReturnsMatchingRecords() { void persistGeneratesIdentifierBeforeSavingRecord() { final Institution institution = Generator.generateInstitution(); institution.setKey(IdentificationUtils.generateKey()); - final User author = Generator.generateUser(institution); + final User author = Generator.generateUser(institution, this.roleGroupAdmin); author.generateUri(); transactional(() -> { em.persist(author); @@ -175,7 +184,7 @@ void persistGeneratesIdentifierBeforeSavingRecord() { private User generateAuthorWithInstitution() { final Institution institution = Generator.generateInstitution(); institution.setKey(IdentificationUtils.generateKey()); - final User author = Generator.generateUser(institution); + final User author = Generator.generateUser(institution, this.roleGroupAdmin); author.generateUri(); transactional(() -> { em.persist(author); diff --git a/src/test/java/cz/cvut/kbss/study/persistence/dao/UserDaoTest.java b/src/test/java/cz/cvut/kbss/study/persistence/dao/UserDaoTest.java index 5395b647..24486790 100644 --- a/src/test/java/cz/cvut/kbss/study/persistence/dao/UserDaoTest.java +++ b/src/test/java/cz/cvut/kbss/study/persistence/dao/UserDaoTest.java @@ -1,10 +1,9 @@ package cz.cvut.kbss.study.persistence.dao; import cz.cvut.kbss.study.environment.generator.Generator; -import cz.cvut.kbss.study.model.Institution; -import cz.cvut.kbss.study.model.User; -import cz.cvut.kbss.study.model.Vocabulary; +import cz.cvut.kbss.study.model.*; import cz.cvut.kbss.study.persistence.BaseDaoTestRunner; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -24,6 +23,22 @@ public class UserDaoTest extends BaseDaoTestRunner { @Autowired private InstitutionDao institutionDao; + @Autowired + private RoleGroupDao roleGroupDao; + + private RoleGroup roleGroupAdmin; + private RoleGroup roleGroupUser; + + @BeforeEach + public void setUp() { + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + this.roleGroupUser = Generator.generateRoleGroupWithRoles(Role.user); + transactional(() -> { + roleGroupDao.persist(this.roleGroupAdmin); + roleGroupDao.persist(this.roleGroupUser); + }); + } + @Test public void getUserByUsername() { User user1 = getPersistedUser(); @@ -73,7 +88,7 @@ public void getUserByEmailWithNonExistingEmailReturnsNull() { @Test public void getUsersByToken() { Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + User user = Generator.generateUser(institution, this.roleGroupAdmin); user.setToken("Token"); transactional(() -> { @@ -92,8 +107,8 @@ public void getUsersByToken() { public void getUsersByInstitution() { Institution institution1 = Generator.generateInstitution(); Institution institution2 = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution1); - User user2 = Generator.generateUser(institution1); + User user1 = Generator.generateUser(institution1, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution1, this.roleGroupAdmin); transactional(() -> { institutionDao.persist(institution1); @@ -117,15 +132,10 @@ public void getUsersByInstitution() { @Test public void getNumberOfInvestigators() { Institution institution = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); - User user3 = Generator.generateUser(institution); - - Set types = new HashSet<>(); - types.add(Vocabulary.s_c_administrator); - types.add(Vocabulary.s_c_doctor); + User user1 = Generator.generateUser(institution, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution, this.roleGroupUser); + User user3 = Generator.generateUser(institution, this.roleGroupUser); - user3.setTypes(types); transactional(() -> { institutionDao.persist(institution); @@ -140,7 +150,7 @@ public void getNumberOfInvestigators() { private User getPersistedUser() { Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + User user = Generator.generateUser(institution, this.roleGroupAdmin); transactional(() -> { institutionDao.persist(institution); userDao.persist(user); diff --git a/src/test/java/cz/cvut/kbss/study/rest/ActionHistoryControllerTest.java b/src/test/java/cz/cvut/kbss/study/rest/ActionHistoryControllerTest.java index 52e3d31a..f335f016 100644 --- a/src/test/java/cz/cvut/kbss/study/rest/ActionHistoryControllerTest.java +++ b/src/test/java/cz/cvut/kbss/study/rest/ActionHistoryControllerTest.java @@ -4,9 +4,7 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.environment.util.Environment; import cz.cvut.kbss.study.exception.NotFoundException; -import cz.cvut.kbss.study.model.ActionHistory; -import cz.cvut.kbss.study.model.Institution; -import cz.cvut.kbss.study.model.User; +import cz.cvut.kbss.study.model.*; import cz.cvut.kbss.study.rest.event.PaginatedResultRetrievedEvent; import cz.cvut.kbss.study.service.ActionHistoryService; import cz.cvut.kbss.study.service.UserService; @@ -57,11 +55,14 @@ public class ActionHistoryControllerTest extends BaseControllerTestRunner { private User user; + private RoleGroup roleGroupAdmin; + @BeforeEach public void setUp() { super.setUp(controller); + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); Institution institution = Generator.generateInstitution(); - this.user = Generator.generateUser(institution); + this.user = Generator.generateUser(institution, roleGroupAdmin); Environment.setCurrentUser(user); } diff --git a/src/test/java/cz/cvut/kbss/study/rest/InstitutionControllerTest.java b/src/test/java/cz/cvut/kbss/study/rest/InstitutionControllerTest.java index 03c5b2be..f9db7fbc 100644 --- a/src/test/java/cz/cvut/kbss/study/rest/InstitutionControllerTest.java +++ b/src/test/java/cz/cvut/kbss/study/rest/InstitutionControllerTest.java @@ -5,6 +5,8 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.environment.util.Environment; import cz.cvut.kbss.study.model.Institution; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; import cz.cvut.kbss.study.persistence.dao.util.RecordFilterParams; import cz.cvut.kbss.study.service.InstitutionService; @@ -46,11 +48,13 @@ public class InstitutionControllerTest extends BaseControllerTestRunner { @InjectMocks private InstitutionController controller; + @BeforeEach public void setUp() { super.setUp(controller); Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + RoleGroup roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + User user = Generator.generateUser(institution, roleGroupAdmin); Environment.setCurrentUser(user); } diff --git a/src/test/java/cz/cvut/kbss/study/rest/PatientRecordControllerTest.java b/src/test/java/cz/cvut/kbss/study/rest/PatientRecordControllerTest.java index 0917640d..2a0f5622 100644 --- a/src/test/java/cz/cvut/kbss/study/rest/PatientRecordControllerTest.java +++ b/src/test/java/cz/cvut/kbss/study/rest/PatientRecordControllerTest.java @@ -7,10 +7,7 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.environment.util.Environment; import cz.cvut.kbss.study.exception.RecordAuthorNotFoundException; -import cz.cvut.kbss.study.model.Institution; -import cz.cvut.kbss.study.model.PatientRecord; -import cz.cvut.kbss.study.model.RecordPhase; -import cz.cvut.kbss.study.model.User; +import cz.cvut.kbss.study.model.*; import cz.cvut.kbss.study.persistence.dao.util.RecordFilterParams; import cz.cvut.kbss.study.persistence.dao.util.RecordSort; import cz.cvut.kbss.study.rest.event.PaginatedResultRetrievedEvent; @@ -81,13 +78,17 @@ public class PatientRecordControllerTest extends BaseControllerTestRunner { private User user; + private RoleGroup roleGroupAdmin; + @BeforeEach public void setUp() { super.setUp(controller); Institution institution = Generator.generateInstitution(); institution.setKey(IdentificationUtils.generateKey()); - this.user = Generator.generateUser(institution); + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + this.user = Generator.generateUser(institution, roleGroupAdmin); Environment.setCurrentUser(user); + } @Test @@ -146,8 +147,8 @@ public void getRecordsReturnsEmptyListWhenNoReportsAreFound() throws Exception { public void getRecordsReturnsAllRecords() throws Exception { Institution institution = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); + User user1 = Generator.generateUser(institution, roleGroupAdmin); + User user2 = Generator.generateUser(institution, roleGroupAdmin); List records = List.of(Generator.generatePatientRecordDto(user1), Generator.generatePatientRecordDto(user1), @@ -174,8 +175,8 @@ public void findByInstitutionReturnsRecords() throws Exception { Institution institution = Generator.generateInstitution(); institution.setKey(key); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); + User user1 = Generator.generateUser(institution, roleGroupAdmin); + User user2 = Generator.generateUser(institution, roleGroupAdmin); PatientRecordDto record1 = Generator.generatePatientRecordDto(user1); PatientRecordDto record2 = Generator.generatePatientRecordDto(user2); diff --git a/src/test/java/cz/cvut/kbss/study/rest/RoleGroupControllerTest.java b/src/test/java/cz/cvut/kbss/study/rest/RoleGroupControllerTest.java new file mode 100644 index 00000000..0ad2c425 --- /dev/null +++ b/src/test/java/cz/cvut/kbss/study/rest/RoleGroupControllerTest.java @@ -0,0 +1,89 @@ +package cz.cvut.kbss.study.rest; + +import com.fasterxml.jackson.core.type.TypeReference; +import cz.cvut.kbss.study.model.Institution; +import cz.cvut.kbss.study.model.RoleGroup; +import cz.cvut.kbss.study.service.RoleGroupService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; + +@ExtendWith(MockitoExtension.class) +public class RoleGroupControllerTest extends BaseControllerTestRunner { + + @Mock + private RoleGroupService roleGroupServiceMock; + + + @InjectMocks + private RoleGroupController controller; + + @BeforeEach + public void setUp() { + super.setUp(controller); + } + + @Test + public void testGetRoleGroups() throws Exception { + RoleGroup roleGroup = new RoleGroup(); + roleGroup.setName("admin-role-group"); + + when(roleGroupServiceMock.findAll()).thenReturn(List.of(roleGroup)); + + final MvcResult result = mockMvc.perform(get("/roleGroups/")).andReturn(); + + final List body = objectMapper.readValue(result.getResponse().getContentAsString(), + new TypeReference<>() { + }); + + assertEquals(HttpStatus.OK, HttpStatus.valueOf(result.getResponse().getStatus())); + assertEquals(body, List.of(roleGroup)); + } + + @Test + public void testFindByName() throws Exception { + String roleName = "admin-role-group"; + RoleGroup roleGroup = new RoleGroup(); + roleGroup.setName(roleName); + + when(roleGroupServiceMock.findByName(roleName)).thenReturn(roleGroup); + + final MvcResult result = mockMvc.perform(get("/roleGroups/" + roleName)).andReturn(); + + final RoleGroup body = objectMapper.readValue(result.getResponse().getContentAsString(), + new TypeReference<>() { + }); + + assertEquals(HttpStatus.OK, HttpStatus.valueOf(result.getResponse().getStatus())); + assertEquals(body, roleGroup); + } + + @Test + public void testFindByName_NotFound() throws Exception { + String roleName = "NonExistentRole"; + + when(roleGroupServiceMock.findByName(roleName)).thenReturn(null); + + mockMvc.perform(get("/roleGroups/{name}", roleName) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + } + +} diff --git a/src/test/java/cz/cvut/kbss/study/rest/StatisticsControllerTest.java b/src/test/java/cz/cvut/kbss/study/rest/StatisticsControllerTest.java index 554d5e26..7bbda82f 100644 --- a/src/test/java/cz/cvut/kbss/study/rest/StatisticsControllerTest.java +++ b/src/test/java/cz/cvut/kbss/study/rest/StatisticsControllerTest.java @@ -3,6 +3,8 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.environment.util.Environment; import cz.cvut.kbss.study.model.Institution; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; import cz.cvut.kbss.study.service.StatisticsService; import org.junit.jupiter.api.BeforeEach; @@ -31,7 +33,8 @@ public class StatisticsControllerTest extends BaseControllerTestRunner { public void setUp() { super.setUp(controller); Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + RoleGroup roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + User user = Generator.generateUser(institution, roleGroupAdmin); Environment.setCurrentUser(user); } diff --git a/src/test/java/cz/cvut/kbss/study/rest/UserControllerTest.java b/src/test/java/cz/cvut/kbss/study/rest/UserControllerTest.java index ba0159fe..8646cf98 100644 --- a/src/test/java/cz/cvut/kbss/study/rest/UserControllerTest.java +++ b/src/test/java/cz/cvut/kbss/study/rest/UserControllerTest.java @@ -5,6 +5,8 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.environment.util.Environment; import cz.cvut.kbss.study.model.Institution; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; import cz.cvut.kbss.study.service.InstitutionService; import cz.cvut.kbss.study.service.UserService; @@ -45,11 +47,14 @@ public class UserControllerTest extends BaseControllerTestRunner { @InjectMocks private UserController controller; + private RoleGroup roleGroupAdmin; + @BeforeEach public void setUp() { super.setUp(controller); Institution institution = Generator.generateInstitution(); - User user = Generator.generateUser(institution); + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + User user = Generator.generateUser(institution, this.roleGroupAdmin); user.setUsername("tom"); Environment.setCurrentUser(user); } @@ -100,9 +105,9 @@ public void getUsersReturnsEmptyListWhenNoUsersAreFound() throws Exception { public void getUsersReturnsAllUsers() throws Exception { Institution institution = Generator.generateInstitution(); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); - User user3 = Generator.generateUser(institution); + User user1 = Generator.generateUser(institution, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution, this.roleGroupAdmin); + User user3 = Generator.generateUser(institution, this.roleGroupAdmin); List users = new ArrayList<>(); users.add(user1); @@ -127,9 +132,9 @@ public void findAllUsersByInstitutionReturnsInstitutionUsers() throws Exception Institution institution = Generator.generateInstitution(); institution.setKey(key); - User user1 = Generator.generateUser(institution); - User user2 = Generator.generateUser(institution); - User user3 = Generator.generateUser(institution); + User user1 = Generator.generateUser(institution, this.roleGroupAdmin); + User user2 = Generator.generateUser(institution, this.roleGroupAdmin); + User user3 = Generator.generateUser(institution, this.roleGroupAdmin); List users = new ArrayList<>(); users.add(user1); @@ -292,7 +297,7 @@ public void changePasswordByTokenReturnsResponseStatusNoContent() throws Excepti public void sendInvitationReturnsResponseStatusBadRequest() throws Exception { final String username = "tom"; final Institution institution = Generator.generateInstitution(); - final User user = Generator.generateUser(institution); + final User user = Generator.generateUser(institution, this.roleGroupAdmin); user.setIsInvited(true); when(userServiceMock.findByUsername(username)).thenReturn(user); @@ -307,7 +312,7 @@ public void sendInvitationReturnsResponseStatusBadRequest() throws Exception { public void sendInvitationReturnsResponseStatusNoContent() throws Exception { final String username = "tom"; final Institution institution = Generator.generateInstitution(); - final User user = Generator.generateUser(institution); + final User user = Generator.generateUser(institution, this.roleGroupAdmin); user.setIsInvited(false); when(userServiceMock.findByUsername(username)).thenReturn(user); @@ -322,7 +327,7 @@ public void sendInvitationReturnsResponseStatusNoContent() throws Exception { public void sendInvitationDeleteReturnsResponseStatusNoContent() throws Exception { final String username = "tom"; final Institution institution = Generator.generateInstitution(); - final User user = Generator.generateUser(institution); + final User user = Generator.generateUser(institution, this.roleGroupAdmin); user.setIsInvited(false); when(userServiceMock.findByUsername(username)).thenReturn(user); diff --git a/src/test/java/cz/cvut/kbss/study/rest/handler/HateoasPagingListenerTest.java b/src/test/java/cz/cvut/kbss/study/rest/handler/HateoasPagingListenerTest.java index d326c106..5a5f8d38 100644 --- a/src/test/java/cz/cvut/kbss/study/rest/handler/HateoasPagingListenerTest.java +++ b/src/test/java/cz/cvut/kbss/study/rest/handler/HateoasPagingListenerTest.java @@ -42,7 +42,7 @@ public void setUp() { this.listener = new HateoasPagingListener(); this.uriBuilder = UriComponentsBuilder.newInstance().scheme("http").host("localhost").path("rest/records"); this.responseMock = new MockHttpServletResponse(); - final User author = Generator.generateUser(null); + final User author = Generator.generateUser(null, null); this.records = IntStream.range(0, 10).mapToObj(i -> Generator.generatePatientRecordDto(author)) .collect(Collectors.toList()); } diff --git a/src/test/java/cz/cvut/kbss/study/security/CustomSwitchUserFilterTest.java b/src/test/java/cz/cvut/kbss/study/security/CustomSwitchUserFilterTest.java index f7e2b4b4..80aa2c58 100644 --- a/src/test/java/cz/cvut/kbss/study/security/CustomSwitchUserFilterTest.java +++ b/src/test/java/cz/cvut/kbss/study/security/CustomSwitchUserFilterTest.java @@ -2,6 +2,8 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.environment.util.Environment; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; import cz.cvut.kbss.study.model.Vocabulary; import cz.cvut.kbss.study.rest.exception.BadRequestException; @@ -35,10 +37,11 @@ void setUp() { @Test void attemptSwitchUserSwitchesCurrentUserToTarget() { - final User source = Generator.generateUser(null); - source.addType(Vocabulary.s_c_administrator); + final User source = Generator.generateUser(null, null); + source.setRoleGroup(Generator.generateRoleGroupWithRoles(Role.administrator)); Environment.setCurrentUser(source); - final User target = Generator.generateUser(null); + final User target = Generator.generateUser(null, null); + target.setRoleGroup(Generator.generateRoleGroupWithRoles(Role.user)); when(userDetailsService.loadUserByUsername(target.getUsername())).thenReturn(new UserDetails(target)); final MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("username", target.getUsername()); @@ -48,11 +51,12 @@ void attemptSwitchUserSwitchesCurrentUserToTarget() { @Test void attemptSwitchUserThrowsBadRequestExceptionWhenTargetUserIsAdmin() { - final User source = Generator.generateUser(null); - source.addType(Vocabulary.s_c_administrator); + RoleGroup roleGroup = Generator.generateRoleGroupWithRoles(Role.administrator); + final User source = Generator.generateUser(null, roleGroup); + source.setRoleGroup(Generator.generateRoleGroupWithRoles(Role.administrator)); Environment.setCurrentUser(source); - final User target = Generator.generateUser(null); - target.addType(Vocabulary.s_c_administrator); + final User target = Generator.generateUser(null, roleGroup); + target.setRoleGroup(Generator.generateRoleGroupWithRoles(Role.administrator)); when(userDetailsService.loadUserByUsername(target.getUsername())).thenReturn(new UserDetails(target)); final MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("username", target.getUsername()); diff --git a/src/test/java/cz/cvut/kbss/study/security/model/RoleTest.java b/src/test/java/cz/cvut/kbss/study/security/model/RoleTest.java deleted file mode 100644 index b006c35c..00000000 --- a/src/test/java/cz/cvut/kbss/study/security/model/RoleTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package cz.cvut.kbss.study.security.model; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.Optional; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.*; - -class RoleTest { - - static Stream generator() { - return Stream.of(Role.values()).map(Arguments::of); - } - - @ParameterizedTest - @MethodSource("generator") - void forTypeReturnsRoleMatchingSpecifiedType(Role r) { - final Optional result = Role.forType(r.getType()); - assertTrue(result.isPresent()); - assertEquals(r, result.get()); - } - - @Test - void forTypeReturnsEmptyOptionalForUnknownRoleType() { - assertTrue(Role.forType("unknownType").isEmpty()); - } - - @ParameterizedTest - @MethodSource("generator") - void forNameReturnsRoleMatchingSpecifiedRoleName(Role r) { - final Optional result = Role.forName(r.getName()); - assertTrue(result.isPresent()); - assertEquals(r, result.get()); - } - - @Test - void forNameReturnsEmptyOptionalForUnknownRoleName() { - assertTrue(Role.forName("unknownName").isEmpty()); - } -} \ No newline at end of file diff --git a/src/test/java/cz/cvut/kbss/study/service/BaseServiceTestRunner.java b/src/test/java/cz/cvut/kbss/study/service/BaseServiceTestRunner.java index 68a0777e..b6844f75 100644 --- a/src/test/java/cz/cvut/kbss/study/service/BaseServiceTestRunner.java +++ b/src/test/java/cz/cvut/kbss/study/service/BaseServiceTestRunner.java @@ -5,8 +5,11 @@ import cz.cvut.kbss.study.environment.config.TestServiceConfig; import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.model.Institution; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; import cz.cvut.kbss.study.persistence.dao.InstitutionDao; +import cz.cvut.kbss.study.persistence.dao.RoleGroupDao; import cz.cvut.kbss.study.persistence.dao.UserDao; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; @@ -35,6 +38,11 @@ public abstract class BaseServiceTestRunner extends TransactionalTestRunner { protected User user; + @Autowired + private RoleGroupDao roleGroupDao; + + protected RoleGroup roleGroupAdmin; + public static final String USERNAME = "halsey"; public static final String PASSWORD = "john117"; public static final String EMAIL = "john117@gmail.com"; @@ -42,8 +50,10 @@ public abstract class BaseServiceTestRunner extends TransactionalTestRunner { @BeforeEach public void setUp() throws Exception { Institution institution = Generator.generateInstitution(); - user = Generator.getUser(USERNAME, PASSWORD, "John", "Grant", EMAIL, institution); + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + user = Generator.getUser(USERNAME, PASSWORD, "John", "Grant", EMAIL, institution, this.roleGroupAdmin); transactional(() -> { + roleGroupDao.persist(this.roleGroupAdmin); institutionDao.persist(institution); if (userDao.findByUsername(user.getUsername()) == null) { user.encodePassword(passwordEncoder); diff --git a/src/test/java/cz/cvut/kbss/study/service/UserDetailsServiceTest.java b/src/test/java/cz/cvut/kbss/study/service/UserDetailsServiceTest.java index 0e58a1d6..79dda4ce 100644 --- a/src/test/java/cz/cvut/kbss/study/service/UserDetailsServiceTest.java +++ b/src/test/java/cz/cvut/kbss/study/service/UserDetailsServiceTest.java @@ -2,7 +2,10 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.model.Institution; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; +import cz.cvut.kbss.study.persistence.dao.RoleGroupDao; import cz.cvut.kbss.study.service.security.UserDetailsService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -23,12 +26,14 @@ public class UserDetailsServiceTest extends BaseServiceTestRunner { @Autowired private InstitutionService institutionService; + @Autowired + private RoleGroupService roleGroupService; + @Test public void loadUserByUsername() { Institution institution = Generator.generateInstitution(); institutionService.persist(institution); - - User user = Generator.generateUser(institution); + User user = Generator.generateUser(institution, this.roleGroupAdmin); userService.persist(user); UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername()); diff --git a/src/test/java/cz/cvut/kbss/study/service/repository/RepositoryPatientRecordServiceTest.java b/src/test/java/cz/cvut/kbss/study/service/repository/RepositoryPatientRecordServiceTest.java index a337ff52..a7e3058a 100644 --- a/src/test/java/cz/cvut/kbss/study/service/repository/RepositoryPatientRecordServiceTest.java +++ b/src/test/java/cz/cvut/kbss/study/service/repository/RepositoryPatientRecordServiceTest.java @@ -4,10 +4,7 @@ import cz.cvut.kbss.study.environment.generator.Generator; import cz.cvut.kbss.study.environment.util.Environment; import cz.cvut.kbss.study.exception.RecordAuthorNotFoundException; -import cz.cvut.kbss.study.model.PatientRecord; -import cz.cvut.kbss.study.model.RecordPhase; -import cz.cvut.kbss.study.model.User; -import cz.cvut.kbss.study.model.Vocabulary; +import cz.cvut.kbss.study.model.*; import cz.cvut.kbss.study.persistence.dao.PatientRecordDao; import cz.cvut.kbss.study.service.UserService; import cz.cvut.kbss.study.service.security.SecurityUtils; @@ -53,16 +50,21 @@ class RepositoryPatientRecordServiceTest { private User user; + private RoleGroup roleGroupAdmin; + private RoleGroup roleGroupUser; + @BeforeEach void setUp() { - this.user = Generator.generateUser(Generator.generateInstitution()); + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + this.roleGroupUser = Generator.generateRoleGroupWithRoles(Role.user); + this.user = Generator.generateUser(Generator.generateInstitution(), roleGroupUser); Environment.setCurrentUser(user); when(securityUtils.getCurrentUser()).thenReturn(user); } @Test void importRecordsSetsCurrentUserAsAuthorWhenTheyAreRegularUserAndImportsSpecifiedRecords() { - final User originalAuthor = Generator.generateUser(Generator.generateInstitution()); + final User originalAuthor = Generator.generateUser(Generator.generateInstitution(), this.roleGroupUser); final List toImport = generateRecordsToImport(originalAuthor); when(recordDao.exists(any())).thenReturn(false); @@ -95,10 +97,10 @@ private List generateRecordsToImport(User originalAuthor) { @Test void importRecordsRetainsRecordProvenanceDataWhenCurrentUserIsAdmin() { - final User originalAuthor = Generator.generateUser(Generator.generateInstitution()); + final User originalAuthor = Generator.generateUser(Generator.generateInstitution(), this.roleGroupAdmin); final List toImport = generateRecordsToImport(originalAuthor); - user.addType(Vocabulary.s_c_administrator); Environment.setCurrentUser(user); + user.getRoleGroup().addRole(Role.administrator); when(userService.exists(originalAuthor.getUri())).thenReturn(true); when(recordDao.exists(any())).thenReturn(false); @@ -118,9 +120,9 @@ void importRecordsRetainsRecordProvenanceDataWhenCurrentUserIsAdmin() { @Test void importRecordsThrowsRecordAuthorNotFoundExceptionWhenAdminImportsRecordsAndRecordAuthorIsNotFound() { - final User originalAuthor = Generator.generateUser(Generator.generateInstitution()); + final User originalAuthor = Generator.generateUser(Generator.generateInstitution(), this.roleGroupAdmin); final List toImport = generateRecordsToImport(originalAuthor); - user.addType(Vocabulary.s_c_administrator); + user.setRoleGroup(Generator.generateRoleGroupWithRoles(Role.administrator)); Environment.setCurrentUser(user); assertThrows(RecordAuthorNotFoundException.class, () -> sut.importRecords(toImport)); @@ -128,7 +130,7 @@ void importRecordsThrowsRecordAuthorNotFoundExceptionWhenAdminImportsRecordsAndR @Test void importRecordsSkipsImportingRecordsThatAlreadyExist() { - final User originalAuthor = Generator.generateUser(Generator.generateInstitution()); + final User originalAuthor = Generator.generateUser(Generator.generateInstitution(), this.roleGroupUser); final List toImport = generateRecordsToImport(originalAuthor); final PatientRecord existing = toImport.get(Generator.randomIndex(toImport)); when(recordDao.exists(any(URI.class))).thenReturn(false); @@ -143,7 +145,7 @@ void importRecordsSkipsImportingRecordsThatAlreadyExist() { @Test void importRecordsWithPhaseSetsSpecifiedPhaseToAllRecords() { - final User originalAuthor = Generator.generateUser(Generator.generateInstitution()); + final User originalAuthor = Generator.generateUser(Generator.generateInstitution(), this.roleGroupUser); final List toImport = generateRecordsToImport(originalAuthor); final RecordPhase targetPhase = RecordPhase.values()[Generator.randomInt(0, RecordPhase.values().length)]; when(recordDao.exists(any())).thenReturn(false); @@ -156,7 +158,7 @@ void importRecordsWithPhaseSetsSpecifiedPhaseToAllRecords() { @Test void importRecordsSetsRecordPhaseToOpenOnAllImportedRecordsWhenCurrentUserIsRegularUser() { - final User originalAuthor = Generator.generateUser(Generator.generateInstitution()); + final User originalAuthor = Generator.generateUser(Generator.generateInstitution(), this.roleGroupUser); final List toImport = generateRecordsToImport(originalAuthor); when(recordDao.exists(any())).thenReturn(false); diff --git a/src/test/java/cz/cvut/kbss/study/service/security/SecurityUtilsTest.java b/src/test/java/cz/cvut/kbss/study/service/security/SecurityUtilsTest.java index 8ee0bfc4..8709e87a 100644 --- a/src/test/java/cz/cvut/kbss/study/service/security/SecurityUtilsTest.java +++ b/src/test/java/cz/cvut/kbss/study/service/security/SecurityUtilsTest.java @@ -4,8 +4,9 @@ import cz.cvut.kbss.study.environment.util.Environment; import cz.cvut.kbss.study.model.Institution; import cz.cvut.kbss.study.model.PatientRecord; +import cz.cvut.kbss.study.model.Role; +import cz.cvut.kbss.study.model.RoleGroup; import cz.cvut.kbss.study.model.User; -import cz.cvut.kbss.study.model.Vocabulary; import cz.cvut.kbss.study.persistence.dao.PatientRecordDao; import cz.cvut.kbss.study.persistence.dao.UserDao; import cz.cvut.kbss.study.security.SecurityConstants; @@ -58,6 +59,8 @@ public class SecurityUtilsTest { private User user; + private RoleGroup roleGroupAdmin; + public static final String USERNAME = "username"; public static final String PASSWORD = "pass" + Generator.randomInt(0, 1000); @@ -65,7 +68,8 @@ public class SecurityUtilsTest { public void setUp() { Institution institution = Generator.generateInstitution(); institution.setKey(IdentificationUtils.generateKey()); - this.user = Generator.getUser(USERNAME, PASSWORD, "John", "Johnie", "Johnie@gmail.com", institution); + this.roleGroupAdmin = Generator.generateRoleGroupWithRoles(Role.administrator); + this.user = Generator.getUser(USERNAME, PASSWORD, "John", "Johnie", "Johnie@gmail.com", institution, this.roleGroupAdmin); user.generateUri(); } @@ -122,7 +126,7 @@ public void areFromSameInstitutionReturnsTrueForUserFromSameInstitution() { Environment.setCurrentUser(user); when(userDao.findByUsername(user.getUsername())).thenReturn(user); - User userFromSameInstitution = Generator.generateUser(user.getInstitution()); + User userFromSameInstitution = Generator.generateUser(user.getInstitution(), this.roleGroupAdmin); when(userDao.findByInstitution(user.getInstitution())).thenReturn(List.of(user, userFromSameInstitution)); assertTrue(sut.areFromSameInstitution(userFromSameInstitution.getUsername())); @@ -135,7 +139,7 @@ public void areFromSameInstitutionReturnsFalseForUserFromDifferentInstitution() Institution institutionAnother = Generator.generateInstitution(); - User userFromAnotherInstitution = Generator.generateUser(institutionAnother); + User userFromAnotherInstitution = Generator.generateUser(institutionAnother, this.roleGroupAdmin); when(userDao.findByInstitution(user.getInstitution())).thenReturn(List.of(user)); assertFalse(sut.areFromSameInstitution(userFromAnotherInstitution.getUsername())); @@ -159,7 +163,7 @@ public void isRecordInUsersInstitutionReturnsFalseWhenRecordBelongsToInstitution when(userDao.findByUsername(user.getUsername())).thenReturn(user); Institution institutionAnother = Generator.generateInstitution(); institutionAnother.setKey(IdentificationUtils.generateKey()); - User userFromAnotherInstitution = Generator.generateUser(institutionAnother); + User userFromAnotherInstitution = Generator.generateUser(institutionAnother, this.roleGroupAdmin); PatientRecord record = Generator.generatePatientRecord(userFromAnotherInstitution); record.setKey(IdentificationUtils.generateKey()); @@ -186,7 +190,7 @@ void getCurrentUserEnhancesRetrievedUserWithTypesCorrespondingToRolesSpecifiedIn when(userDao.findByUsername(user.getUsername())).thenReturn(user); final User result = sut.getCurrentUser(); - assertThat(result.getTypes(), hasItem(Vocabulary.s_c_administrator)); + assertThat(result.getRoleGroup().getRoles(), hasItem(Role.administrator)); } @Test @@ -197,7 +201,7 @@ void getCurrentUserEnhancesRetrievedUserWithImpersonatorTypeWhenItHasSwitchAutho when(userDao.findByUsername(user.getUsername())).thenReturn(user); final User result = sut.getCurrentUser(); assertEquals(user, result); - assertThat(result.getTypes(), hasItem(Vocabulary.s_c_impersonator)); + assertThat(result.getRoleGroup().getRoles(), hasItem(Role.impersonate)); } @Test