diff --git a/src/main/java/nl/tudelft/labracore/DevDatabaseLoader.java b/src/main/java/nl/tudelft/labracore/DevDatabaseLoader.java index ebdd42536e5f1d2306e9b61b9f67a6c619533a5e..2b51c5d1cfef7d4c1678665d11bfd16573a825f6 100644 --- a/src/main/java/nl/tudelft/labracore/DevDatabaseLoader.java +++ b/src/main/java/nl/tudelft/labracore/DevDatabaseLoader.java @@ -18,10 +18,10 @@ package nl.tudelft.labracore; import static nl.tudelft.labracore.enums.RoleType.*; +import static nl.tudelft.labracore.enums.UserPermissions.defaultPermissions; import java.time.LocalDateTime; -import java.util.HashSet; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import javax.annotation.PostConstruct; @@ -107,6 +107,12 @@ public class DevDatabaseLoader { @Autowired private AssignmentRepository assignmentRepository; + @Autowired + private PersonRepository pr; + + @Autowired + private RoleRepository rr; + @Getter private APIKey allAccessKey; @@ -328,6 +334,7 @@ public class DevDatabaseLoader { */ private Set<Permission> allPermissions; + /** * Initializes the database for Labracore by delegating to methods initializing individual entity types. * Each initialization method should cover initializing all objects of that type. @@ -355,6 +362,8 @@ public class DevDatabaseLoader { initAssignments(); postInitializePrograms(); + + initUserPermissionsIfNeeded(); } /** @@ -1103,4 +1112,18 @@ public class DevDatabaseLoader { person.setPrograms(programs); personRepository.save(person); } + + @Transactional + public void initUserPermissionsIfNeeded() { + if (rr.findAll().stream().allMatch(r -> r.getPermissions().isEmpty())) { + List<List<Role>> updatePeople = + pr.findAll().stream().filter(p -> p.getDefaultRole() != RoleType.STUDENT).map( person -> rr.findAllByPerson(person).stream().map(r -> { + r.setPermissions(defaultPermissions.get(r.getType())); + return r; + }).collect(Collectors.toList()) + ).collect(Collectors.toList()); + updatePeople.forEach(lr -> rr.saveAll(lr)); + } + + } } diff --git a/src/main/java/nl/tudelft/labracore/ProdDatabaseLoader.java b/src/main/java/nl/tudelft/labracore/ProdDatabaseLoader.java index 6959dd8d10f53ee0c3a4da02ad047ab726ef1bfd..a7a7eba50b84dfc995b32213494efb6d1c5c9cbe 100644 --- a/src/main/java/nl/tudelft/labracore/ProdDatabaseLoader.java +++ b/src/main/java/nl/tudelft/labracore/ProdDatabaseLoader.java @@ -18,13 +18,13 @@ package nl.tudelft.labracore; import java.time.LocalDateTime; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; import javax.annotation.PostConstruct; import nl.tudelft.labracore.enums.RoleType; +import nl.tudelft.labracore.enums.UserPermissions; import nl.tudelft.labracore.model.Permission; import nl.tudelft.labracore.model.Person; import nl.tudelft.labracore.model.person.ConcretePerson; @@ -32,6 +32,7 @@ import nl.tudelft.labracore.model.security.APIKey; import nl.tudelft.labracore.repository.APIKeyRepository; import nl.tudelft.labracore.repository.PermissionRepository; import nl.tudelft.labracore.repository.PersonRepository; +import nl.tudelft.labracore.repository.RoleRepository; import nl.tudelft.labracore.service.PermissionService; import org.apache.commons.lang3.RandomStringUtils; @@ -40,6 +41,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @Profile("production") @@ -61,11 +63,26 @@ public class ProdDatabaseLoader { @Autowired private PermissionService ps; + @Autowired + private RoleRepository rr; + + @PostConstruct private void init() { Person admin = initAdminUserIfNeeded(); Set<Permission> permissions = initPermissionsIfNeeded(); initPortalKeyIfNeeded(admin, permissions); + initUserPermissionsIfNeeded(); + } + + @Transactional + public void initUserPermissionsIfNeeded() { + if (rr.findAll().stream().allMatch(r -> r.getPermissions().isEmpty())) { + pr.findAll().stream().filter(p -> p.getDefaultRole() != RoleType.STUDENT).forEach( person -> + rr.findAllByPerson(person).forEach(r -> r.setPermissions(UserPermissions.defaultPermissions.get(r.getType()))) + ); + } + } /** diff --git a/src/main/java/nl/tudelft/labracore/controller/RoleController.java b/src/main/java/nl/tudelft/labracore/controller/RoleController.java index f5f57de4c1b29d2f6d41226b74e8b33c1202a4e6..80557d754912329d6569efb55fb313bcc3b01f9f 100644 --- a/src/main/java/nl/tudelft/labracore/controller/RoleController.java +++ b/src/main/java/nl/tudelft/labracore/controller/RoleController.java @@ -18,6 +18,7 @@ package nl.tudelft.labracore.controller; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -76,7 +77,6 @@ public class RoleController { public Role.Id patchRole(@PathVariable Long personId, @PathVariable Long editionId, @RequestBody RolePatchDTO patch) { - System.out.println(patch); return patch.apply(rr.findByIdOrThrow(new Role.Id(personId, editionId))).getId(); } @@ -120,4 +120,18 @@ public class RoleController { return View.convert(rr.findAllByEditionInAndPersonIn(editionIds, personIds), RoleDetailsDTO.class); } + /** + * Gets a role for a given id + * @param editionId The id of the edition the role should be in. + * @param personId The id of the person the role should belong to. + * @return The role role for the given id. + */ + @GetMapping("by-id") + @PreAuthorize("hasAuthority('ROLE_READ')") + public RoleDetailsDTO getRoleById(@RequestParam Long editionId, + @RequestParam Long personId) { + return View.convert(rr.findByIdOrThrow(new Role.Id(personId, editionId)), + RoleDetailsDTO.class); + } + } diff --git a/src/main/java/nl/tudelft/labracore/dto/create/RoleCreateDTO.java b/src/main/java/nl/tudelft/labracore/dto/create/RoleCreateDTO.java index 115bbabc61b15892f624719a4e4a0c4d3b65e8f7..394c683d3f55a04660584310aab4cf5d01498c2d 100644 --- a/src/main/java/nl/tudelft/labracore/dto/create/RoleCreateDTO.java +++ b/src/main/java/nl/tudelft/labracore/dto/create/RoleCreateDTO.java @@ -19,13 +19,14 @@ package nl.tudelft.labracore.dto.create; import javax.validation.constraints.NotNull; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import nl.tudelft.labracore.dto.id.EditionIdDTO; import nl.tudelft.labracore.dto.id.PersonIdDTO; import nl.tudelft.labracore.enums.RoleType; +import nl.tudelft.labracore.enums.UserPermissions; import nl.tudelft.labracore.model.Role; import nl.tudelft.librador.dto.create.Create; -import nl.tudelft.librador.enums.UserPermissions; import java.util.ArrayList; import java.util.HashSet; @@ -49,6 +50,7 @@ public class RoleCreateDTO extends Create<Role> { private RoleType type; @NotNull + @Schema(enumAsRef = true) private List<UserPermissions> permissions = new ArrayList<>(); @Override diff --git a/src/main/java/nl/tudelft/labracore/dto/patch/RolePatchDTO.java b/src/main/java/nl/tudelft/labracore/dto/patch/RolePatchDTO.java index 3d8102277883ef4ba9f6f11ac7e9aa7eb5e0fadf..7f4bac6d06074aaf2b9fcfcb0baeefd99f37f1f6 100644 --- a/src/main/java/nl/tudelft/labracore/dto/patch/RolePatchDTO.java +++ b/src/main/java/nl/tudelft/labracore/dto/patch/RolePatchDTO.java @@ -17,11 +17,12 @@ */ package nl.tudelft.labracore.dto.patch; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import nl.tudelft.labracore.enums.RoleType; +import nl.tudelft.labracore.enums.UserPermissions; import nl.tudelft.labracore.model.Role; import nl.tudelft.librador.dto.patch.Patch; -import nl.tudelft.librador.enums.UserPermissions; import java.util.List; @@ -34,6 +35,7 @@ public class RolePatchDTO extends Patch<Role> { private RoleType type; + @Schema(enumAsRef = true) private List<UserPermissions> permissions; @Override diff --git a/src/main/java/nl/tudelft/labracore/dto/view/structured/summary/RoleSummaryDTO.java b/src/main/java/nl/tudelft/labracore/dto/view/structured/summary/RoleSummaryDTO.java index 6c5d50bf731ae35080451a6cc657f847de503f83..870bfe1627ab1e968104ce53437f7e3330e7eb84 100644 --- a/src/main/java/nl/tudelft/labracore/dto/view/structured/summary/RoleSummaryDTO.java +++ b/src/main/java/nl/tudelft/labracore/dto/view/structured/summary/RoleSummaryDTO.java @@ -19,19 +19,18 @@ package nl.tudelft.labracore.dto.view.structured.summary; import javax.validation.constraints.NotNull; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import nl.tudelft.labracore.enums.RoleType; +import nl.tudelft.labracore.enums.UserPermissions; import nl.tudelft.labracore.model.Role; import nl.tudelft.librador.dto.view.View; -import nl.tudelft.librador.enums.UserPermissions; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; @Data @@ -43,7 +42,9 @@ public class RoleSummaryDTO extends View<Role> { private Role.Id id; @NotNull private RoleType type; + @NotNull + @Schema(enumAsRef = true) private List<UserPermissions> permissions = new ArrayList<>(); /** diff --git a/src/main/java/nl/tudelft/labracore/enums/UserPermissions.java b/src/main/java/nl/tudelft/labracore/enums/UserPermissions.java new file mode 100644 index 0000000000000000000000000000000000000000..81bd770ec81f9a76c4ac3591a2f975e621474433 --- /dev/null +++ b/src/main/java/nl/tudelft/labracore/enums/UserPermissions.java @@ -0,0 +1,85 @@ +package nl.tudelft.labracore.enums; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Enum values representing the permissions which can be assigned to a user. + */ +public enum UserPermissions { + /** + * The user can add/remove students from an edition. + */ + CAN_MODIFY_STUDENTS_MEMBERS, + + /** + * The user can add/remove staff members from an edition. + */ + CAN_MODIFY_STAFF_MEMBERS, + + /** + * The user can modify an edition. + */ + CAN_MODIFY_EDITION, + + /** + * The user can create a new edition for a course. + */ + CAN_CREATE_EDITION, + + /** + * The user can create a session for an edition. + */ + CAN_CREATE_SESSION, + + /** + * The user can modify a session for an edition. + */ + CAN_MODIFY_SESSION, + + /** + * The user can create an assignment for an edition. + */ + CAN_CREATE_ASSIGNMENT, + + /** + * The user can modify an assignment for an edition. + */ + CAN_MODIFY_ASSIGNMENT, + + /** + * The user can create a new course. + */ + CAN_CREATE_COURSE, + + /** + * The user can modify an existing course. + */ + CAN_MODIFY_COURSE, + + /** + * The user can create a new cluster. + */ + CAN_CREATE_CLUSTER, + + /** + * The user can modify an existing cluster. + */ + CAN_MODIFY_CLUSTER; + + public static final Map<RoleType, List<UserPermissions>> defaultPermissions = new HashMap<>() {{ + put(RoleType.ADMIN, List.of(UserPermissions.values())); + put(RoleType.TEACHER, List.of(UserPermissions.CAN_MODIFY_STUDENTS_MEMBERS, + UserPermissions.CAN_MODIFY_STAFF_MEMBERS, UserPermissions.CAN_CREATE_EDITION, + UserPermissions.CAN_MODIFY_EDITION, UserPermissions.CAN_CREATE_SESSION, + UserPermissions.CAN_CREATE_ASSIGNMENT, UserPermissions.CAN_MODIFY_ASSIGNMENT)); + put(RoleType.TEACHER_RO, List.of()); + put(RoleType.HEAD_TA, List.of(UserPermissions.CAN_MODIFY_STUDENTS_MEMBERS, + UserPermissions.CAN_CREATE_SESSION, UserPermissions.CAN_MODIFY_SESSION, + UserPermissions.CAN_CREATE_ASSIGNMENT, UserPermissions.CAN_MODIFY_ASSIGNMENT)); + put(RoleType.TA, List.of(UserPermissions.CAN_MODIFY_STUDENTS_MEMBERS)); + put(RoleType.STUDENT, List.of()); + put(RoleType.BLOCKED, List.of()); + }}; +} diff --git a/src/main/java/nl/tudelft/labracore/model/Role.java b/src/main/java/nl/tudelft/labracore/model/Role.java index 2cacc198460071708bad7110018e9991fd422b36..911b591fc9eafe3761d9dda4e014edeb2c3d0632 100644 --- a/src/main/java/nl/tudelft/labracore/model/Role.java +++ b/src/main/java/nl/tudelft/labracore/model/Role.java @@ -28,7 +28,7 @@ import javax.validation.constraints.NotNull; import lombok.*; import nl.tudelft.labracore.enums.RoleType; -import nl.tudelft.librador.enums.UserPermissions; +import nl.tudelft.labracore.enums.UserPermissions; /** * This identifies the role a person has in a course. A person can only have one role per course (this is not diff --git a/src/main/java/nl/tudelft/labracore/repository/RoleRepository.java b/src/main/java/nl/tudelft/labracore/repository/RoleRepository.java index 76e6ad95e3460625206542e60aa9371afb66f6a3..bc7f263ea274c947de99e634b8073c7c037f4753 100644 --- a/src/main/java/nl/tudelft/labracore/repository/RoleRepository.java +++ b/src/main/java/nl/tudelft/labracore/repository/RoleRepository.java @@ -113,6 +113,8 @@ public interface RoleRepository extends JpaRepository<Role, Role.Id>, QuerydslPr return findAll(qr.edition.id.in(editionIds)); } + public List<Role> findAllByPerson(Person person); + /** * Checks whether a person already has a role in the edition. *