From 7a20c893bbf67ad1cf868f3f0ad819035f1300ec Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Tue, 5 Dec 2023 13:14:23 +0100 Subject: [PATCH] Migrated from JSON to many-to-many --- .github/workflows/actions.yml | 2 +- .gitignore | 1 + client/.nvmrc | 2 +- client/src/api/index.js | 5 - .../java/access/api/ManageController.java | 23 +-- .../main/java/access/api/RoleController.java | 42 ++---- .../main/java/access/model/Application.java | 26 +++- .../model/DistinctManageIdentifiers.java | 22 --- server/src/main/java/access/model/Role.java | 7 +- .../repository/ApplicationRepository.java | 14 ++ .../access/repository/RoleRepository.java | 27 ---- .../java/access/teams/TeamsController.java | 16 ++- ..._0__migrate_many_to_many_applications.java | 38 +++++ .../V12_0__not_null_role_identifier.sql | 4 - .../V12_0__role_many_to_many_applications.sql | 24 ++++ .../V13_0__index_roles_manage_identifiers.sql | 2 - .../V19_0__not_null_role_identifier.sql | 1 + .../V20_0__remove_old_role_manage.sql | 3 + server/src/test/java/access/AbstractTest.java | 131 ++++++++++++++++-- server/src/test/java/access/Seed.java | 107 +------------- .../test/java/access/WithApplicationTest.java | 14 ++ .../AttributeAggregatorControllerTest.java | 2 +- .../access/api/APITokenControllerTest.java | 2 +- .../access/api/InvitationControllerTest.java | 2 +- .../api/InvitationMailControllerTest.java | 4 +- .../java/access/api/ManageControllerTest.java | 4 +- .../java/access/api/RoleControllerTest.java | 73 +--------- .../java/access/api/SystemControllerTest.java | 2 +- .../java/access/api/UserControllerTest.java | 2 +- .../access/api/UserRoleControllerTest.java | 4 +- .../java/access/cron/ResourceCleanerTest.java | 2 +- .../UserLifeCycleControllerTest.java | 2 +- .../test/java/access/mail/MailBoxTest.java | 4 +- .../java/access/model/InvitationTest.java | 10 +- .../src/test/java/access/model/RoleTest.java | 10 +- .../ProvisioningServiceDefaultTest.java | 2 +- .../access/repository/RoleRepositoryTest.java | 5 - .../access/repository/UserRepositoryTest.java | 2 +- .../access/security/UserPermissionsTest.java | 14 +- .../access/teams/TeamsControllerTest.java | 2 +- .../java/access/voot/VootControllerTest.java | 2 +- 41 files changed, 332 insertions(+), 329 deletions(-) delete mode 100644 server/src/main/java/access/model/DistinctManageIdentifiers.java create mode 100644 server/src/main/java/access/repository/ApplicationRepository.java create mode 100644 server/src/main/java/db/mysql/migration/V13_0__migrate_many_to_many_applications.java delete mode 100644 server/src/main/resources/db/mysql/migration/V12_0__not_null_role_identifier.sql create mode 100644 server/src/main/resources/db/mysql/migration/V12_0__role_many_to_many_applications.sql delete mode 100644 server/src/main/resources/db/mysql/migration/V13_0__index_roles_manage_identifiers.sql create mode 100644 server/src/main/resources/db/mysql/migration/V19_0__not_null_role_identifier.sql create mode 100644 server/src/main/resources/db/mysql/migration/V20_0__remove_old_role_manage.sql create mode 100644 server/src/test/java/access/WithApplicationTest.java diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 661dcd72..4e53b6f9 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 20 - name: Yarn Audit client run: yarn audit --level high --groups dependencies working-directory: client diff --git a/.gitignore b/.gitignore index 43f397b5..f694c827 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ IgnoreMeTest.java dependency.tree NOTES.txt private_key_pkcs8.pem +JSON.md diff --git a/client/.nvmrc b/client/.nvmrc index 07c7cf30..a9b234d5 100644 --- a/client/.nvmrc +++ b/client/.nvmrc @@ -1 +1 @@ -v18.14.2 +v20.8.0 diff --git a/client/src/api/index.js b/client/src/api/index.js index d69d8ba8..3cfd11d5 100644 --- a/client/src/api/index.js +++ b/client/src/api/index.js @@ -174,11 +174,6 @@ export function searchRoles(query) { return fetchJson(`/api/v1/roles/search?query=${query}`); } -export function shortNameExists(shortName, manageId, roleId) { - const body = {shortName: shortName, manageId: manageId, id: roleId}; - return postPutJson("/api/v1/roles/validation/short_name", body, "POST"); -} - //User roles export function userRolesByRoleId(roleId) { return fetchJson(`/api/v1/user_roles/roles/${roleId}`, {}, {}, false); diff --git a/server/src/main/java/access/api/ManageController.java b/server/src/main/java/access/api/ManageController.java index c98ae1f3..3ed09b9a 100644 --- a/server/src/main/java/access/api/ManageController.java +++ b/server/src/main/java/access/api/ManageController.java @@ -3,9 +3,10 @@ import access.config.Config; import access.manage.EntityType; import access.manage.Manage; -import access.manage.ManageIdentifier; +import access.model.Application; import access.model.Authority; import access.model.User; +import access.repository.ApplicationRepository; import access.repository.RoleRepository; import access.security.UserPermissions; import io.swagger.v3.oas.annotations.Parameter; @@ -22,7 +23,10 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import static access.SwaggerOpenIdConfig.API_TOKENS_SCHEME_NAME; @@ -41,11 +45,13 @@ public class ManageController { private final Manage manage; private final RoleRepository roleRepository; + private final ApplicationRepository applicationRepository; @Autowired - public ManageController(Manage manage, RoleRepository roleRepository) { + public ManageController(Manage manage, RoleRepository roleRepository, ApplicationRepository applicationRepository) { this.manage = manage; this.roleRepository = roleRepository; + this.applicationRepository = applicationRepository; } @GetMapping("provider/{type}/{id}") @@ -73,16 +79,17 @@ public ResponseEntity>> providers(@Parameter(hidden = t @GetMapping("applications") public ResponseEntity>>> applications(@Parameter(hidden = true) User user) { UserPermissions.assertSuperUser(user); - Set manageIdentifiers = roleRepository.findDistinctManageIdentifiers(); - Map> groupedByManageType = manageIdentifiers.stream().collect(Collectors.groupingBy(ManageIdentifier::manageType)); + List applications = applicationRepository.findAll(); + Map> groupedByManageType = applications.stream().collect(Collectors.groupingBy(Application::getManageType)); + List> providers = groupedByManageType.entrySet().stream() .map(entry -> manage.providersByIdIn( entry.getKey(), - entry.getValue().stream().map(ManageIdentifier::manageId).collect(Collectors.toList()))) + entry.getValue().stream().map(Application::getManageId).collect(Collectors.toList()))) .flatMap(Collection::stream) .toList(); - List> provisionings = manage.provisioning(manageIdentifiers.stream() - .map(ManageIdentifier::manageId) + List> provisionings = manage.provisioning(applications.stream() + .map(Application::getManageId) .toList()); return ResponseEntity.ok(Map.of( "providers", providers, diff --git a/server/src/main/java/access/api/RoleController.java b/server/src/main/java/access/api/RoleController.java index 5fa7242b..ab7e4df5 100644 --- a/server/src/main/java/access/api/RoleController.java +++ b/server/src/main/java/access/api/RoleController.java @@ -2,14 +2,17 @@ import access.config.Config; import access.exception.InvalidInputException; -import access.exception.NotAllowedException; import access.exception.NotFoundException; import access.logging.AccessLogger; import access.logging.Event; import access.manage.Manage; -import access.model.*; +import access.model.Application; +import access.model.Authority; +import access.model.Role; +import access.model.User; import access.provision.ProvisioningService; import access.provision.scim.GroupURN; +import access.repository.ApplicationRepository; import access.repository.RoleRepository; import access.security.UserPermissions; import access.validation.URLFormatValidator; @@ -43,16 +46,18 @@ public class RoleController { private final Config config; private final RoleRepository roleRepository; + private final ApplicationRepository applicationRepository; private final Manage manage; private final ProvisioningService provisioningService; private final URLFormatValidator urlFormatValidator = new URLFormatValidator(); public RoleController(Config config, RoleRepository roleRepository, - Manage manage, + ApplicationRepository applicationRepository, Manage manage, ProvisioningService provisioningService) { this.config = config; this.roleRepository = roleRepository; + this.applicationRepository = applicationRepository; this.manage = manage; this.provisioningService = provisioningService; } @@ -99,30 +104,10 @@ public ResponseEntity> search(@RequestParam(value = "query") String q return ResponseEntity.ok(manage.addManageMetaData(roles)); } - @PostMapping("validation/short_name") - public ResponseEntity> shortNameExists(@RequestBody RoleExists roleExists, - @Parameter(hidden = true) User user) { - UserPermissions.assertAuthority(user, Authority.MANAGER); - String shortName = GroupURN.sanitizeRoleShortName(roleExists.shortName()); - Optional optionalRole = roleRepository.findByShortNameIgnoreCaseAndApplicationsManageId(roleExists.manageId(), shortName); - Map result = optionalRole - .map(role -> Map.of("exists", roleExists.id() == null || !role.getId().equals(roleExists.id()))) - .orElse(Map.of("exists", false)); - return ResponseEntity.ok(result); - } - @PostMapping("") public ResponseEntity newRole(@Validated @RequestBody Role role, @Parameter(hidden = true) User user) { LOG.debug("/newRole"); - String shortName = GroupURN.sanitizeRoleShortName(role.getShortName()); - Optional applicationOptional = role.getApplications().stream() - .filter(application -> roleRepository.findByShortNameIgnoreCaseAndApplicationsManageId(application.getManageId(), shortName).isPresent()) - .findFirst(); - if (applicationOptional.isPresent()) { - Application application = applicationOptional.get(); - throw new NotAllowedException( - String.format("Duplicate name: '%s' for manage entity:'%s'", shortName, application.getManageId())); - } + role.setShortName(GroupURN.sanitizeRoleShortName(role.getShortName())); role.setIdentifier(UUID.randomUUID().toString()); return saveOrUpdate(role, user); } @@ -145,10 +130,6 @@ public ResponseEntity deleteRole(@PathVariable("id") Long id, @Parameter(h return Results.deleteResult(); } - private void addApplicationData(Role role) { - - } - private ResponseEntity saveOrUpdate(Role role, User user) { if (StringUtils.hasText(role.getLandingPage()) && !urlFormatValidator.isValid(role.getLandingPage())) { throw new InvalidInputException(); @@ -165,6 +146,11 @@ private ResponseEntity saveOrUpdate(Role role, User user) { role.setShortName(previousRole.getShortName()); previousManageIdentifiersReference.set(previousRole.applicationIdentifiers()); } + //This is the disadvantage of having to save references from Manage + role.setApplications(role.getApplications().stream() + .map(application -> applicationRepository.findByManageIdAndManageType(application.getManageId(), application.getManageType()) + .orElseGet(() -> applicationRepository.save(application))) + .collect(Collectors.toSet())); Role saved = roleRepository.save(role); if (isNew) { provisioningService.newGroupRequest(saved); diff --git a/server/src/main/java/access/model/Application.java b/server/src/main/java/access/model/Application.java index a38ffeec..331e5fb8 100644 --- a/server/src/main/java/access/model/Application.java +++ b/server/src/main/java/access/model/Application.java @@ -2,8 +2,10 @@ import access.manage.EntityType; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; import lombok.*; import java.io.Serializable; @@ -13,14 +15,36 @@ import java.io.Serializable; import java.util.Set; +@Entity(name = "applications") @NoArgsConstructor @AllArgsConstructor @Getter @Setter -@EqualsAndHashCode +@EqualsAndHashCode(of = {"manageId", "manageType"}) public class Application implements Serializable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "manage_id") + @NotNull private String manageId; + + @Column(name = "manage_type") + @Enumerated(EnumType.STRING) + @NotNull private EntityType manageType; + @Column(name = "landing_page") + private String landingPage; + + @ManyToMany(mappedBy = "applications") + @JsonIgnore + private Set roles; + + public Application(String manageId, EntityType manageType) { + this.manageId = manageId; + this.manageType = manageType; + } } diff --git a/server/src/main/java/access/model/DistinctManageIdentifiers.java b/server/src/main/java/access/model/DistinctManageIdentifiers.java deleted file mode 100644 index 0936a6a5..00000000 --- a/server/src/main/java/access/model/DistinctManageIdentifiers.java +++ /dev/null @@ -1,22 +0,0 @@ -package access.model; - -import access.config.ObjectMapperHolder; -import access.manage.ManageIdentifier; -import com.fasterxml.jackson.core.type.TypeReference; -import lombok.SneakyThrows; - -import java.util.List; -import java.util.Set; - -public interface DistinctManageIdentifiers { - - String getApplications(); - - @SneakyThrows - default List manageIdentifiers() { - String applications = getApplications(); - return ObjectMapperHolder.objectMapper.readValue(applications, new TypeReference<>() { - }); - } - -} diff --git a/server/src/main/java/access/model/Role.java b/server/src/main/java/access/model/Role.java index 376dc454..7fe22eae 100644 --- a/server/src/main/java/access/model/Role.java +++ b/server/src/main/java/access/model/Role.java @@ -69,8 +69,11 @@ public class Role implements Serializable, Provisionable { @Formula(value = "(SELECT COUNT(*) FROM user_roles ur WHERE ur.role_id=id)") private Long userRoleCount; - @Column - @Convert(converter = ApplicationConverter.class) + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable( + name = "roles_applications", + joinColumns = @JoinColumn(name = "role_id"), + inverseJoinColumns = @JoinColumn(name = "application_id")) private Set applications = new HashSet<>(); @OneToMany(mappedBy = "role", diff --git a/server/src/main/java/access/repository/ApplicationRepository.java b/server/src/main/java/access/repository/ApplicationRepository.java new file mode 100644 index 00000000..8901868f --- /dev/null +++ b/server/src/main/java/access/repository/ApplicationRepository.java @@ -0,0 +1,14 @@ +package access.repository; + +import access.manage.EntityType; +import access.model.Application; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface ApplicationRepository extends JpaRepository { + + Optional findByManageIdAndManageType(String manageId, EntityType manageType); +} diff --git a/server/src/main/java/access/repository/RoleRepository.java b/server/src/main/java/access/repository/RoleRepository.java index 4d21447f..47329d89 100644 --- a/server/src/main/java/access/repository/RoleRepository.java +++ b/server/src/main/java/access/repository/RoleRepository.java @@ -1,17 +1,11 @@ package access.repository; -import access.manage.ManageIdentifier; -import access.model.DistinctManageIdentifiers; import access.model.Role; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; -import java.util.Collection; import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; @Repository public interface RoleRepository extends JpaRepository { @@ -21,29 +15,8 @@ public interface RoleRepository extends JpaRepository { nativeQuery = true) List search(String keyWord, int limit); - - @Query(value = "SELECT *, (SELECT COUNT(*) FROM user_roles ur WHERE ur.role_id=r.id) AS userRoleCount " + - "FROM roles r WHERE JSON_CONTAINS(applications->'$[*].manageId', json_array(?1))", - nativeQuery = true) List findByApplicationsManageId(String manageId); - @Query(value = "SELECT DISTINCT applications FROM roles", nativeQuery = true) - List doFindDistinctManageIdentifiers(); - - @Query(value = "SELECT 1", nativeQuery = true) - default Set findDistinctManageIdentifiers() { - return this.doFindDistinctManageIdentifiers() - .stream() - .map(DistinctManageIdentifiers::manageIdentifiers) - .flatMap(Collection::stream) - .collect(Collectors.toSet()); - } - - @Query(value = "SELECT *, (SELECT COUNT(*) FROM user_roles ur WHERE ur.role_id=r.id) as userRoleCount " + - "FROM roles r WHERE JSON_CONTAINS(applications->'$[*].manageId', json_array(?1)) and short_name = ?2", - nativeQuery = true) - Optional findByShortNameIgnoreCaseAndApplicationsManageId(String managerId, String name); - List findByName(String name); } diff --git a/server/src/main/java/access/teams/TeamsController.java b/server/src/main/java/access/teams/TeamsController.java index 3398c745..d1797bf0 100644 --- a/server/src/main/java/access/teams/TeamsController.java +++ b/server/src/main/java/access/teams/TeamsController.java @@ -1,13 +1,13 @@ package access.teams; import access.exception.NotFoundException; -import access.exception.RemoteException; import access.manage.Manage; import access.model.Role; import access.model.*; import access.provision.ProvisioningService; import access.provision.scim.GroupURN; import access.provision.scim.OperationType; +import access.repository.ApplicationRepository; import access.repository.RoleRepository; import access.repository.UserRepository; import access.repository.UserRoleRepository; @@ -21,7 +21,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.rmi.Remote; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.List; @@ -42,17 +41,20 @@ public class TeamsController { private final RoleRepository roleRepository; private final UserRepository userRepository; private final UserRoleRepository userRoleRepository; + private final ApplicationRepository applicationRepository; private final Manage manage; private final ProvisioningService provisioningService; public TeamsController(RoleRepository roleRepository, UserRepository userRepository, UserRoleRepository userRoleRepository, + ApplicationRepository applicationRepository, Manage manage, ProvisioningService provisioningService) { this.roleRepository = roleRepository; this.userRepository = userRepository; this.userRoleRepository = userRoleRepository; + this.applicationRepository = applicationRepository; this.manage = manage; this.provisioningService = provisioningService; } @@ -71,11 +73,17 @@ public ResponseEntity migrateTeam(@RequestBody Team team) { role.setIdentifier(UUID.randomUUID().toString()); role.setTeamsOrigin(true); //Check if the applications exist in Manage - Set applications = team.getApplications().stream().filter(this::applicationExists).collect(Collectors.toSet()); + Set applications = team.getApplications().stream() + .filter(this::applicationExists) + .collect(Collectors.toSet()); if (applications.isEmpty()) { throw new NotFoundException(); } - role.setApplications(applications); + //This is the disadvantage of having to save references from Manage + role.setApplications(team.getApplications().stream() + .map(application -> applicationRepository.findByManageIdAndManageType(application.getManageId(), application.getManageType()) + .orElseGet(() -> applicationRepository.save(application))) + .collect(Collectors.toSet())); Role savedRole = roleRepository.save(role); provisioningService.newGroupRequest(savedRole); diff --git a/server/src/main/java/db/mysql/migration/V13_0__migrate_many_to_many_applications.java b/server/src/main/java/db/mysql/migration/V13_0__migrate_many_to_many_applications.java new file mode 100644 index 00000000..e98bfd9b --- /dev/null +++ b/server/src/main/java/db/mysql/migration/V13_0__migrate_many_to_many_applications.java @@ -0,0 +1,38 @@ +package db.mysql.migration; + +import org.flywaydb.core.api.migration.BaseJavaMigration; +import org.flywaydb.core.api.migration.Context; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.SingleConnectionDataSource; +import org.springframework.jdbc.support.GeneratedKeyHolder; + +import java.sql.PreparedStatement; +import java.sql.Statement; + + +public class V13_0__migrate_many_to_many_applications extends BaseJavaMigration { + + public void migrate(Context context) { + JdbcTemplate jdbcTemplate = + new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), true)); + jdbcTemplate.query("SELECT id, manage_id, manage_type FROM roles", rs -> { + long roleId = rs.getLong("id"); + + GeneratedKeyHolder generatedKeyHolder = new GeneratedKeyHolder(); + + String sql = "INSERT INTO `applications` (`manage_id`, `manage_type`) VALUES(?, ?)"; + jdbcTemplate.update(conn -> { + PreparedStatement preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); + preparedStatement.setString(1, rs.getString("manage_id")); + preparedStatement.setString(2, rs.getString("manage_type")); + return preparedStatement; + }, generatedKeyHolder); + + long applicationId = generatedKeyHolder.getKey().longValue(); + jdbcTemplate.update("INSERT INTO `roles_applications` (`role_id`,`application_id`) VALUES (?, ?)", + roleId, applicationId); + }); + + + } +} diff --git a/server/src/main/resources/db/mysql/migration/V12_0__not_null_role_identifier.sql b/server/src/main/resources/db/mysql/migration/V12_0__not_null_role_identifier.sql deleted file mode 100644 index 60524aa1..00000000 --- a/server/src/main/resources/db/mysql/migration/V12_0__not_null_role_identifier.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE `roles` MODIFY `identifier` varchar(255) NOT NULL; -ALTER TABLE `roles` MODIFY `applications` json NOT NULL; -ALTER TABLE `roles` DROP COLUMN `manage_id`; -ALTER TABLE `roles` DROP COLUMN `manage_type`; \ No newline at end of file diff --git a/server/src/main/resources/db/mysql/migration/V12_0__role_many_to_many_applications.sql b/server/src/main/resources/db/mysql/migration/V12_0__role_many_to_many_applications.sql new file mode 100644 index 00000000..26bbeb60 --- /dev/null +++ b/server/src/main/resources/db/mysql/migration/V12_0__role_many_to_many_applications.sql @@ -0,0 +1,24 @@ +CREATE TABLE `applications` +( + `id` bigint NOT NULL AUTO_INCREMENT, + `manage_id` varchar(255) NOT NULL, + `manage_type` varchar(255) NOT NULL, + `landing_page` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `applications_unique` (`manage_id`, `manage_type`) +) ENGINE = InnoDB + AUTO_INCREMENT = 1 + DEFAULT CHARSET = utf8mb4; + +CREATE TABLE `roles_applications` +( + `id` bigint NOT NULL AUTO_INCREMENT, + `role_id` bigint NOT NULL, + `application_id` bigint NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `roles_applications_unique` (`role_id`, `application_id`), + CONSTRAINT `fk_roles_applications_role` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_roles_applications_application` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`) ON DELETE CASCADE +) ENGINE = InnoDB + AUTO_INCREMENT = 1 + DEFAULT CHARSET = utf8mb4; diff --git a/server/src/main/resources/db/mysql/migration/V13_0__index_roles_manage_identifiers.sql b/server/src/main/resources/db/mysql/migration/V13_0__index_roles_manage_identifiers.sql deleted file mode 100644 index 03856b85..00000000 --- a/server/src/main/resources/db/mysql/migration/V13_0__index_roles_manage_identifiers.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `roles` - ADD INDEX roles_manage_identifiers( (CAST(applications->'$[*].manageId' AS char(255) ARRAY)) ); \ No newline at end of file diff --git a/server/src/main/resources/db/mysql/migration/V19_0__not_null_role_identifier.sql b/server/src/main/resources/db/mysql/migration/V19_0__not_null_role_identifier.sql new file mode 100644 index 00000000..1b6a5b27 --- /dev/null +++ b/server/src/main/resources/db/mysql/migration/V19_0__not_null_role_identifier.sql @@ -0,0 +1 @@ +ALTER TABLE `roles` MODIFY `identifier` varchar(255) NOT NULL; \ No newline at end of file diff --git a/server/src/main/resources/db/mysql/migration/V20_0__remove_old_role_manage.sql b/server/src/main/resources/db/mysql/migration/V20_0__remove_old_role_manage.sql new file mode 100644 index 00000000..def8d75c --- /dev/null +++ b/server/src/main/resources/db/mysql/migration/V20_0__remove_old_role_manage.sql @@ -0,0 +1,3 @@ +ALTER TABLE `roles` DROP `applications`; +ALTER TABLE `roles` DROP `manage_id`; +ALTER TABLE `roles` DROP `manage_type`; \ No newline at end of file diff --git a/server/src/test/java/access/AbstractTest.java b/server/src/test/java/access/AbstractTest.java index 4d1c15a2..c88ba07d 100644 --- a/server/src/test/java/access/AbstractTest.java +++ b/server/src/test/java/access/AbstractTest.java @@ -1,9 +1,9 @@ package access; +import access.config.HashGenerator; import access.manage.EntityType; import access.manage.LocalManage; -import access.model.RemoteProvisionedUser; -import access.model.User; +import access.model.*; import access.repository.*; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -35,6 +35,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.io.ClassPathResource; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.csrf.DefaultCsrfToken; import org.springframework.test.context.ActiveProfiles; @@ -56,6 +57,7 @@ import java.util.*; import java.util.function.Consumer; import java.util.function.UnaryOperator; +import java.util.stream.Collectors; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static io.restassured.RestAssured.given; @@ -82,6 +84,15 @@ public abstract class AbstractTest { Security.addProvider(new BouncyCastleProvider()); } + public static final String SUPER_SUB = "urn:collab:person:example.com:super"; + public static final String MANAGE_SUB = "urn:collab:person:example.com:manager"; + public static final String INSTITUTION_ADMIN = "urn:collab:person:example.com:institution_admin"; + public static final String INVITER_SUB = "urn:collab:person:example.com:inviter"; + public static final String GUEST_SUB = "urn:collab:person:example.com:guest"; + public static final String GRAPH_INVITATION_HASH = "graph_invitation_hash"; + public static final String ORGANISATION_GUID = "ad93daef-0911-e511-80d0-005056956c1a"; + public static final String API_TOKEN_HASH = HashGenerator.generateToken(); + @Autowired protected ObjectMapper objectMapper; @@ -91,6 +102,9 @@ public abstract class AbstractTest { @Autowired protected RoleRepository roleRepository; + @Autowired + protected ApplicationRepository applicationRepository; + @Autowired protected UserRoleRepository userRoleRepository; @@ -125,14 +139,7 @@ protected static void beforeAll() { protected void beforeEach() throws Exception { RestAssured.port = port; if (seedDatabase()) { - new Seed( - invitationRepository, - remoteProvisionedGroupRepository, - remoteProvisionedUserRepository, - roleRepository, - userRepository, - userRoleRepository, - apiTokenRepository).doSeed(); + this.doSeed(); } if (this.localManage == null) { this.localManage = new LocalManage(objectMapper, false); @@ -489,5 +496,109 @@ protected UnaryOperator> institutionalAdminEntitlementOperat }; } + public Set application(String manageId, EntityType entityType) { + Application application = applicationRepository.findByManageIdAndManageType(manageId, entityType). + orElseGet(() -> applicationRepository.save(new Application(manageId, entityType))); + return Set.of(application); + } + + public void doSeed() { + this.invitationRepository.deleteAllInBatch(); + this.remoteProvisionedGroupRepository.deleteAllInBatch(); + this.remoteProvisionedUserRepository.deleteAllInBatch(); + this.roleRepository.deleteAllInBatch(); + this.applicationRepository.deleteAllInBatch(); + this.userRepository.deleteAllInBatch(); + this.userRoleRepository.deleteAllInBatch(); + this.apiTokenRepository.deleteAllInBatch(); + + User superUser = + new User(true, SUPER_SUB, SUPER_SUB, "example.com", "David", "Doe", "david.doe@examole.com"); + User institutionAdmin = + new User(false, INSTITUTION_ADMIN, INSTITUTION_ADMIN, "example.com", "Carl", "Doe", "carl.doe@examole.com"); + institutionAdmin.setInstitutionAdmin(true); + institutionAdmin.setOrganizationGUID(ORGANISATION_GUID); + + User manager = + new User(false, MANAGE_SUB, MANAGE_SUB, "example.com", "Mary", "Doe", "mary.doe@examole.com"); + User inviter = + new User(false, INVITER_SUB, INVITER_SUB, "example.com", "Paul", "Doe", "paul.doe@examole.com"); + User guest = + new User(false, GUEST_SUB, GUEST_SUB, "example.com", "Ann", "Doe", "ann.doe@examole.com"); + doSave(this.userRepository, superUser, institutionAdmin, manager, inviter, guest); + + Role wiki = + new Role("Wiki", "Wiki desc", "https://landingpage.com", + application("1", EntityType.SAML20_SP), 365, false, false); + Role network = + new Role("Network", "Network desc", "https://landingpage.com", + application("2", EntityType.SAML20_SP), 365, false, false); + Set applications = Set.of(new Application("3", EntityType.SAML20_SP), new Application("6", EntityType.OIDC10_RP)); + + Role storage = + new Role("Storage", "Storage desc", "https://landingpage.com", + applications.stream().map(application -> applicationRepository.save(application)).collect(Collectors.toSet()), + 365, false, false); + Role research = + new Role("Research", "Research desc", "https://landingpage.com", + application("4", EntityType.SAML20_SP), 365, false, false); + Role calendar = + new Role("Calendar", "Calendar desc", "https://landingpage.com", + application("5", EntityType.OIDC10_RP), 365, false, false); + Role mail = + new Role("Mail", "Mail desc", "https://landingpage.com", + application("5", EntityType.OIDC10_RP), 365, false, false); + doSave(this.roleRepository, wiki, network, storage, research, calendar, mail); + + UserRole wikiManager = + new UserRole("system", manager, wiki, Authority.MANAGER); + UserRole calendarInviter = + new UserRole("system", inviter, calendar, Authority.INVITER); + UserRole mailInviter = + new UserRole("system", inviter, mail, Authority.INVITER); + UserRole storageGuest = + new UserRole("system", guest, storage, Authority.GUEST); + UserRole wikiGuest = + new UserRole("system", guest, wiki, Authority.GUEST); + UserRole researchGuest = + new UserRole("system", guest, research, Authority.GUEST); + doSave(this.userRoleRepository, wikiManager, calendarInviter, mailInviter, storageGuest, wikiGuest, researchGuest); + + String message = "Please join.."; + Instant roleExpiryDate = Instant.now().plus(365, ChronoUnit.DAYS); + Instant expiryDate = Instant.now().plus(14, ChronoUnit.DAYS); + + Invitation superUserInvitation = + new Invitation(Authority.SUPER_USER, Authority.SUPER_USER.name(), "super_user@new.com", false, false, false, message, + inviter,expiryDate, roleExpiryDate, Set.of()); + Invitation managerInvitation = + new Invitation(Authority.MANAGER, Authority.MANAGER.name(), "manager@new.com", false, false, false, message, + inviter, expiryDate,roleExpiryDate, Set.of(new InvitationRole(research))); + Invitation inviterInvitation = + new Invitation(Authority.INVITER, Authority.INVITER.name(), "inviter@new.com", false, false, true, message, + inviter, expiryDate,roleExpiryDate, Set.of(new InvitationRole(calendar), new InvitationRole(mail))); + inviterInvitation.setEnforceEmailEquality(true); + Invitation guestInvitation = + new Invitation(Authority.GUEST, Authority.GUEST.name(), "guest@new.com", false, false, false, message, + inviter, expiryDate,roleExpiryDate, Set.of(new InvitationRole(mail))); + guestInvitation.setEduIDOnly(true); + //To test graph callback + guestInvitation.setSubInvitee(GUEST_SUB); + + Invitation graphInvitation = + new Invitation(Authority.GUEST, GRAPH_INVITATION_HASH, "graph@new.com", false, false, false, message, + inviter,expiryDate, roleExpiryDate, Set.of(new InvitationRole(network))); + doSave(invitationRepository, superUserInvitation, managerInvitation, inviterInvitation, guestInvitation, graphInvitation); + + APIToken apiToken = new APIToken(ORGANISATION_GUID, HashGenerator.hashToken(API_TOKEN_HASH), "Test-token"); + doSave(apiTokenRepository, apiToken); + } + + @SafeVarargs + private void doSave(JpaRepository repository, M... entities) { + repository.saveAll(Arrays.asList(entities)); + } + + } diff --git a/server/src/test/java/access/Seed.java b/server/src/test/java/access/Seed.java index 448c7cca..3d88fae8 100644 --- a/server/src/test/java/access/Seed.java +++ b/server/src/test/java/access/Seed.java @@ -15,115 +15,10 @@ public record Seed(InvitationRepository invitationRepository, RemoteProvisionedGroupRepository remoteProvisionedGroupRepository, RemoteProvisionedUserRepository remoteProvisionedUserRepository, RoleRepository roleRepository, + ApplicationRepository applicationRepository, UserRepository userRepository, UserRoleRepository userRoleRepository, APITokenRepository apiTokenRepository) { - public static final String SUPER_SUB = "urn:collab:person:example.com:super"; - public static final String MANAGE_SUB = "urn:collab:person:example.com:manager"; - public static final String INSTITUTION_ADMIN = "urn:collab:person:example.com:institution_admin"; - public static final String INVITER_SUB = "urn:collab:person:example.com:inviter"; - public static final String GUEST_SUB = "urn:collab:person:example.com:guest"; - public static final String GRAPH_INVITATION_HASH = "graph_invitation_hash"; - public static final String ORGANISATION_GUID = "ad93daef-0911-e511-80d0-005056956c1a"; - public static final String API_TOKEN_HASH = HashGenerator.generateToken(); - - public void doSeed() { - this.invitationRepository.deleteAllInBatch(); - this.remoteProvisionedGroupRepository.deleteAllInBatch(); - this.remoteProvisionedUserRepository.deleteAllInBatch(); - this.roleRepository.deleteAllInBatch(); - this.userRepository.deleteAllInBatch(); - this.userRoleRepository.deleteAllInBatch(); - this.apiTokenRepository.deleteAllInBatch(); - - User superUser = - new User(true, SUPER_SUB, SUPER_SUB, "example.com", "David", "Doe", "david.doe@examole.com"); - User institutionAdmin = - new User(false, INSTITUTION_ADMIN, INSTITUTION_ADMIN, "example.com", "Carl", "Doe", "carl.doe@examole.com"); - institutionAdmin.setInstitutionAdmin(true); - institutionAdmin.setOrganizationGUID(ORGANISATION_GUID); - - User manager = - new User(false, MANAGE_SUB, MANAGE_SUB, "example.com", "Mary", "Doe", "mary.doe@examole.com"); - User inviter = - new User(false, INVITER_SUB, INVITER_SUB, "example.com", "Paul", "Doe", "paul.doe@examole.com"); - User guest = - new User(false, GUEST_SUB, GUEST_SUB, "example.com", "Ann", "Doe", "ann.doe@examole.com"); - doSave(this.userRepository, superUser, institutionAdmin, manager, inviter, guest); - - Role wiki = - new Role("Wiki", "Wiki desc", "https://landingpage.com", - application("1", EntityType.SAML20_SP), 365, false, false); - Role network = - new Role("Network", "Network desc", "https://landingpage.com", - application("2", EntityType.SAML20_SP), 365, false, false); - Role storage = - new Role("Storage", "Storage desc", "https://landingpage.com", - Set.of(new Application("3", EntityType.SAML20_SP), new Application("6", EntityType.OIDC10_RP)), - 365, false, false); - Role research = - new Role("Research", "Research desc", "https://landingpage.com", - application("4", EntityType.SAML20_SP), 365, false, false); - Role calendar = - new Role("Calendar", "Calendar desc", "https://landingpage.com", - application("5", EntityType.OIDC10_RP), 365, false, false); - Role mail = - new Role("Mail", "Mail desc", "https://landingpage.com", - application("5", EntityType.OIDC10_RP), 365, false, false); - doSave(this.roleRepository, wiki, network, storage, research, calendar, mail); - - UserRole wikiManager = - new UserRole("system", manager, wiki, Authority.MANAGER); - UserRole calendarInviter = - new UserRole("system", inviter, calendar, Authority.INVITER); - UserRole mailInviter = - new UserRole("system", inviter, mail, Authority.INVITER); - UserRole storageGuest = - new UserRole("system", guest, storage, Authority.GUEST); - UserRole wikiGuest = - new UserRole("system", guest, wiki, Authority.GUEST); - UserRole researchGuest = - new UserRole("system", guest, research, Authority.GUEST); - doSave(this.userRoleRepository, wikiManager, calendarInviter, mailInviter, storageGuest, wikiGuest, researchGuest); - - String message = "Please join.."; - Instant roleExpiryDate = Instant.now().plus(365, ChronoUnit.DAYS); - Instant expiryDate = Instant.now().plus(14, ChronoUnit.DAYS); - - Invitation superUserInvitation = - new Invitation(Authority.SUPER_USER, Authority.SUPER_USER.name(), "super_user@new.com", false, false, false, message, - inviter,expiryDate, roleExpiryDate, Set.of()); - Invitation managerInvitation = - new Invitation(Authority.MANAGER, Authority.MANAGER.name(), "manager@new.com", false, false, false, message, - inviter, expiryDate,roleExpiryDate, Set.of(new InvitationRole(research))); - Invitation inviterInvitation = - new Invitation(Authority.INVITER, Authority.INVITER.name(), "inviter@new.com", false, false, true, message, - inviter, expiryDate,roleExpiryDate, Set.of(new InvitationRole(calendar), new InvitationRole(mail))); - inviterInvitation.setEnforceEmailEquality(true); - Invitation guestInvitation = - new Invitation(Authority.GUEST, Authority.GUEST.name(), "guest@new.com", false, false, false, message, - inviter, expiryDate,roleExpiryDate, Set.of(new InvitationRole(mail))); - guestInvitation.setEduIDOnly(true); - //To test graph callback - guestInvitation.setSubInvitee(GUEST_SUB); - - Invitation graphInvitation = - new Invitation(Authority.GUEST, GRAPH_INVITATION_HASH, "graph@new.com", false, false, false, message, - inviter,expiryDate, roleExpiryDate, Set.of(new InvitationRole(network))); - doSave(invitationRepository, superUserInvitation, managerInvitation, inviterInvitation, guestInvitation, graphInvitation); - - APIToken apiToken = new APIToken(ORGANISATION_GUID, HashGenerator.hashToken(API_TOKEN_HASH), "Test-token"); - doSave(apiTokenRepository, apiToken); - } - - @SafeVarargs - private void doSave(JpaRepository repository, M... entities) { - repository.saveAll(Arrays.asList(entities)); - } - - public static Set application(String manageId, EntityType entityType) { - return Set.of(new Application(manageId, entityType)); - } } diff --git a/server/src/test/java/access/WithApplicationTest.java b/server/src/test/java/access/WithApplicationTest.java new file mode 100644 index 00000000..8cde5314 --- /dev/null +++ b/server/src/test/java/access/WithApplicationTest.java @@ -0,0 +1,14 @@ +package access; + +import access.manage.EntityType; +import access.model.Application; + +import java.util.Set; + +public class WithApplicationTest { + + public Set application(String manageId, EntityType entityType) { + return Set.of(new Application(manageId, entityType)); + } + +} diff --git a/server/src/test/java/access/aggregation/AttributeAggregatorControllerTest.java b/server/src/test/java/access/aggregation/AttributeAggregatorControllerTest.java index a2ec5bff..b743d5f2 100644 --- a/server/src/test/java/access/aggregation/AttributeAggregatorControllerTest.java +++ b/server/src/test/java/access/aggregation/AttributeAggregatorControllerTest.java @@ -10,7 +10,7 @@ import java.util.List; import java.util.Map; -import static access.Seed.GUEST_SUB; +import static access.AbstractTest.GUEST_SUB; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/server/src/test/java/access/api/APITokenControllerTest.java b/server/src/test/java/access/api/APITokenControllerTest.java index 001e8a48..374e72cf 100644 --- a/server/src/test/java/access/api/APITokenControllerTest.java +++ b/server/src/test/java/access/api/APITokenControllerTest.java @@ -12,7 +12,7 @@ import java.util.Map; import java.util.UUID; -import static access.Seed.*; +import static access.AbstractTest.*; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; diff --git a/server/src/test/java/access/api/InvitationControllerTest.java b/server/src/test/java/access/api/InvitationControllerTest.java index 48d0d74c..e544d7cb 100644 --- a/server/src/test/java/access/api/InvitationControllerTest.java +++ b/server/src/test/java/access/api/InvitationControllerTest.java @@ -16,7 +16,7 @@ import java.util.List; import java.util.Map; -import static access.Seed.*; +import static access.AbstractTest.*; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/server/src/test/java/access/api/InvitationMailControllerTest.java b/server/src/test/java/access/api/InvitationMailControllerTest.java index 49721348..05b403db 100644 --- a/server/src/test/java/access/api/InvitationMailControllerTest.java +++ b/server/src/test/java/access/api/InvitationMailControllerTest.java @@ -9,8 +9,8 @@ import io.restassured.http.ContentType; import org.junit.jupiter.api.Test; -import static access.Seed.INVITER_SUB; -import static access.Seed.MANAGE_SUB; +import static access.AbstractTest.INVITER_SUB; +import static access.AbstractTest.MANAGE_SUB; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/server/src/test/java/access/api/ManageControllerTest.java b/server/src/test/java/access/api/ManageControllerTest.java index a9e7fe48..8dec30ba 100644 --- a/server/src/test/java/access/api/ManageControllerTest.java +++ b/server/src/test/java/access/api/ManageControllerTest.java @@ -11,8 +11,8 @@ import java.util.Map; import java.util.stream.Stream; -import static access.Seed.MANAGE_SUB; -import static access.Seed.SUPER_SUB; +import static access.AbstractTest.MANAGE_SUB; +import static access.AbstractTest.SUPER_SUB; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static io.restassured.RestAssured.given; diff --git a/server/src/test/java/access/api/RoleControllerTest.java b/server/src/test/java/access/api/RoleControllerTest.java index 3f459d4b..77711f8e 100644 --- a/server/src/test/java/access/api/RoleControllerTest.java +++ b/server/src/test/java/access/api/RoleControllerTest.java @@ -17,7 +17,7 @@ import java.util.Set; import java.util.UUID; -import static access.Seed.*; +import static access.AbstractTest.*; import static access.security.SecurityConfig.API_TOKEN_HEADER; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.*; @@ -27,7 +27,7 @@ class RoleControllerTest extends AbstractTest { @Test void create() throws Exception { AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); - Role role = new Role("New", "New desc", "https://landingpage.com", Seed.application("1", EntityType.SAML20_SP), 365, false, false); + Role role = new Role("New", "New desc", "https://landingpage.com", application("1", EntityType.SAML20_SP), 365, false, false); super.stubForManagerProvidersByIdIn(EntityType.SAML20_SP, List.of("1")); super.stubForManageProvisioning(List.of("1")); @@ -48,7 +48,7 @@ void create() throws Exception { @Test void createInvalidLandingPage() throws Exception { AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); - Role role = new Role("New", "New desc", "javascript:alert(42)", Seed.application("1", EntityType.SAML20_SP), 365, false, false); + Role role = new Role("New", "New desc", "javascript:alert(42)", application("1", EntityType.SAML20_SP), 365, false, false); given() .when() @@ -65,7 +65,7 @@ void createInvalidLandingPage() throws Exception { @Test void createProvisionException() throws Exception { AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); - Role role = new Role("New", "New desc", "https://landingpage.com", Seed.application("1", EntityType.SAML20_SP), 365, false, false); + Role role = new Role("New", "New desc", "https://landingpage.com", application("1", EntityType.SAML20_SP), 365, false, false); super.stubForManagerProvidersByIdIn(EntityType.SAML20_SP, List.of("1")); super.stubForManageProvisioning(List.of("1")); @@ -81,27 +81,11 @@ void createProvisionException() throws Exception { assertNotNull(result.get("reference")); } - @Test - void createWithDuplicateShortName() throws Exception { - AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); - Role role = new Role("Wiki", "New desc", "https://landingpage.com", Seed.application("1", EntityType.SAML20_SP), 365, false, false); - - given() - .when() - .filter(accessCookieFilter.cookieFilter()) - .accept(ContentType.JSON) - .header(accessCookieFilter.csrfToken().getHeaderName(), accessCookieFilter.csrfToken().getToken()) - .contentType(ContentType.JSON) - .body(role) - .post("/api/v1/roles") - .then() - .statusCode(409); - } - @Test void update() throws Exception { AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); super.stubForManagerProvidersByIdIn(EntityType.SAML20_SP, List.of("1")); + super.stubForManageProvisioning(List.of("1")); Role roleDB = roleRepository.search("wiki", 1).get(0); roleDB.setDescription("changed"); roleDB.setShortName("changed"); @@ -145,53 +129,6 @@ void updateApplications() throws Exception { assertEquals(2, updated.getApplications().size()); } - @Test - void nameExistsTransientRole() throws Exception { - AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); - Map result = given() - .when() - .filter(accessCookieFilter.cookieFilter()) - .accept(ContentType.JSON) - .header(accessCookieFilter.csrfToken().getHeaderName(), accessCookieFilter.csrfToken().getToken()) - .contentType(ContentType.JSON) - .body(new RoleExists("WIKI", "1", null)) - .post("/api/v1/roles/validation/short_name") - .as(Map.class); - assertTrue((Boolean) result.get("exists")); - } - - @Test - void nameNotExistsTransientRole() throws Exception { - AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); - Map result = given() - .when() - .filter(accessCookieFilter.cookieFilter()) - .accept(ContentType.JSON) - .header(accessCookieFilter.csrfToken().getHeaderName(), accessCookieFilter.csrfToken().getToken()) - .contentType(ContentType.JSON) - .body(new RoleExists("unique", "1", null)) - .post("/api/v1/roles/validation/short_name") - .as(Map.class); - assertFalse((Boolean) result.get("exists")); - } - - @Test - void nameExists() throws Exception { - AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); - Role wiki = roleRepository.findByShortNameIgnoreCaseAndApplicationsManageId("1", "WIKI").get(); - Role research = roleRepository.findByShortNameIgnoreCaseAndApplicationsManageId("4", "research").get(); - Map result = given() - .when() - .filter(accessCookieFilter.cookieFilter()) - .accept(ContentType.JSON) - .header(accessCookieFilter.csrfToken().getHeaderName(), accessCookieFilter.csrfToken().getToken()) - .contentType(ContentType.JSON) - .body(new RoleExists(research.getShortName(), research.getApplications().iterator().next().getManageId(), wiki.getId())) - .post("/api/v1/roles/validation/short_name") - .as(Map.class); - assertTrue((Boolean) result.get("exists")); - } - @Test void rolesByApplication() throws Exception { AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); diff --git a/server/src/test/java/access/api/SystemControllerTest.java b/server/src/test/java/access/api/SystemControllerTest.java index d197a54a..cb4be9e9 100644 --- a/server/src/test/java/access/api/SystemControllerTest.java +++ b/server/src/test/java/access/api/SystemControllerTest.java @@ -5,7 +5,7 @@ import io.restassured.http.ContentType; import org.junit.jupiter.api.Test; -import static access.Seed.SUPER_SUB; +import static access.AbstractTest.SUPER_SUB; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.*; diff --git a/server/src/test/java/access/api/UserControllerTest.java b/server/src/test/java/access/api/UserControllerTest.java index 67137d35..4545da35 100644 --- a/server/src/test/java/access/api/UserControllerTest.java +++ b/server/src/test/java/access/api/UserControllerTest.java @@ -21,7 +21,7 @@ import java.util.Set; import java.util.stream.Stream; -import static access.Seed.*; +import static access.AbstractTest.*; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.*; diff --git a/server/src/test/java/access/api/UserRoleControllerTest.java b/server/src/test/java/access/api/UserRoleControllerTest.java index abf9dd69..df50ea3d 100644 --- a/server/src/test/java/access/api/UserRoleControllerTest.java +++ b/server/src/test/java/access/api/UserRoleControllerTest.java @@ -13,7 +13,7 @@ import java.time.temporal.ChronoUnit; import java.util.List; -import static access.Seed.*; +import static access.AbstractTest.*; import static access.security.SecurityConfig.API_TOKEN_HEADER; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.*; @@ -23,7 +23,7 @@ class UserRoleControllerTest extends AbstractTest { @Test void byRole() throws Exception { AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); - Role role = roleRepository.findByShortNameIgnoreCaseAndApplicationsManageId("1", "wiki").get(); + Role role = roleRepository.search("wiki", 1).get(0); List userRoles = given() .when() .filter(accessCookieFilter.cookieFilter()) diff --git a/server/src/test/java/access/cron/ResourceCleanerTest.java b/server/src/test/java/access/cron/ResourceCleanerTest.java index 903cad0f..50467828 100644 --- a/server/src/test/java/access/cron/ResourceCleanerTest.java +++ b/server/src/test/java/access/cron/ResourceCleanerTest.java @@ -10,7 +10,7 @@ import java.time.Period; import java.util.List; -import static access.Seed.GUEST_SUB; +import static access.AbstractTest.GUEST_SUB; import static org.junit.jupiter.api.Assertions.*; class ResourceCleanerTest extends AbstractTest { diff --git a/server/src/test/java/access/lifecycle/UserLifeCycleControllerTest.java b/server/src/test/java/access/lifecycle/UserLifeCycleControllerTest.java index 7f2251d3..a4ba2d66 100644 --- a/server/src/test/java/access/lifecycle/UserLifeCycleControllerTest.java +++ b/server/src/test/java/access/lifecycle/UserLifeCycleControllerTest.java @@ -9,7 +9,7 @@ import java.util.List; import java.util.Map; -import static access.Seed.GUEST_SUB; +import static access.AbstractTest.GUEST_SUB; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.*; diff --git a/server/src/test/java/access/mail/MailBoxTest.java b/server/src/test/java/access/mail/MailBoxTest.java index 58a69a34..a7a6883c 100644 --- a/server/src/test/java/access/mail/MailBoxTest.java +++ b/server/src/test/java/access/mail/MailBoxTest.java @@ -33,8 +33,8 @@ void sendInviteMail() { user, Instant.now().plus(30, ChronoUnit.DAYS), Instant.now().plus(365, ChronoUnit.DAYS), - Set.of(new InvitationRole(new Role("name", "desc", "https://landingpage.com", Seed.application("1", EntityType.SAML20_SP), 365, false, false)), - new InvitationRole(new Role("name", "desc", "https://landingpage.com",Seed.application("1", EntityType.SAML20_SP), 365, false, false)))); + Set.of(new InvitationRole(new Role("name", "desc", "https://landingpage.com", application("1", EntityType.SAML20_SP), 365, false, false)), + new InvitationRole(new Role("name", "desc", "https://landingpage.com",application("1", EntityType.SAML20_SP), 365, false, false)))); mailBox.sendInviteMail(user, invitation, List.of( new GroupedProviders( localManage.providerById(EntityType.SAML20_SP, "1"), diff --git a/server/src/test/java/access/model/InvitationTest.java b/server/src/test/java/access/model/InvitationTest.java index c6f3774f..e99e76de 100644 --- a/server/src/test/java/access/model/InvitationTest.java +++ b/server/src/test/java/access/model/InvitationTest.java @@ -1,6 +1,6 @@ package access.model; -import access.Seed; +import access.WithApplicationTest; import access.manage.EntityType; import org.junit.jupiter.api.Test; @@ -11,11 +11,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -class InvitationTest { +class InvitationTest extends WithApplicationTest { @Test void constructorWithoutDefaults() { - Role role = new Role("mail", "description", "https://landingpage.com", Seed.application( "1", EntityType.SAML20_SP), 30, false, false); + Role role = new Role("mail", "description", "https://landingpage.com", application( "1", EntityType.SAML20_SP), 30, false, false); Invitation invitation = new Invitation(Authority.GUEST, "hash", "john@example.com", false, false, false, "Please join..", new User(), null, Instant.now().plus(30, ChronoUnit.DAYS), @@ -27,7 +27,7 @@ void constructorWithoutDefaults() { @Test void constructorWithDefaults() { - Role role = new Role("mail", "description", "https://landingpage.com",Seed.application( "1", EntityType.SAML20_SP), null, false, false); + Role role = new Role("mail", "description", "https://landingpage.com",application( "1", EntityType.SAML20_SP), null, false, false); Invitation invitation = new Invitation(Authority.MANAGER, "hash", "john@example.com", false, false, false, "Please join..", new User(), null, null, Set.of(new InvitationRole(role))); @@ -37,7 +37,7 @@ void constructorWithDefaults() { @Test void roleExpiryDate() { - Role role = new Role("mail", "description", "https://landingpage.com", Seed.application("1", EntityType.SAML20_SP), 30, false, false); + Role role = new Role("mail", "description", "https://landingpage.com", application("1", EntityType.SAML20_SP), 30, false, false); Invitation invitation = new Invitation(Authority.GUEST, "hash", "john@example.com", false, false, false, "Please join..", new User(), null, null, diff --git a/server/src/test/java/access/model/RoleTest.java b/server/src/test/java/access/model/RoleTest.java index 3f3db153..b43a5742 100644 --- a/server/src/test/java/access/model/RoleTest.java +++ b/server/src/test/java/access/model/RoleTest.java @@ -1,6 +1,6 @@ package access.model; -import access.Seed; +import access.WithApplicationTest; import access.manage.EntityType; import access.manage.ManageIdentifier; import org.junit.jupiter.api.Test; @@ -12,14 +12,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -class RoleTest { +class RoleTest extends WithApplicationTest { @Test void groupBy() { List roles = List.of( - new Role("cloud", "cloud", "https://landingpage.com", Seed.application("1", EntityType.OIDC10_RP), 365, false, false), - new Role("mail", "mail", "https://landingpage.com", Seed.application("1", EntityType.OIDC10_RP), 365, false, false), - new Role("wiki", "wiki", "https://landingpage.com", Seed.application("2", EntityType.SAML20_SP), 365, false, false) + new Role("cloud", "cloud", "https://landingpage.com", application("1", EntityType.OIDC10_RP), 365, false, false), + new Role("mail", "mail", "https://landingpage.com", application("1", EntityType.OIDC10_RP), 365, false, false), + new Role("wiki", "wiki", "https://landingpage.com", application("2", EntityType.SAML20_SP), 365, false, false) ); Set rolesByApplication = roles.stream() .map(Role::getApplications) diff --git a/server/src/test/java/access/provision/ProvisioningServiceDefaultTest.java b/server/src/test/java/access/provision/ProvisioningServiceDefaultTest.java index a477d4dc..b0311d68 100644 --- a/server/src/test/java/access/provision/ProvisioningServiceDefaultTest.java +++ b/server/src/test/java/access/provision/ProvisioningServiceDefaultTest.java @@ -10,7 +10,7 @@ import java.util.List; import java.util.UUID; -import static access.Seed.GUEST_SUB; +import static access.AbstractTest.GUEST_SUB; import static org.junit.jupiter.api.Assertions.assertEquals; class ProvisioningServiceDefaultTest extends AbstractTest { diff --git a/server/src/test/java/access/repository/RoleRepositoryTest.java b/server/src/test/java/access/repository/RoleRepositoryTest.java index 047da9f2..809aaf00 100644 --- a/server/src/test/java/access/repository/RoleRepositoryTest.java +++ b/server/src/test/java/access/repository/RoleRepositoryTest.java @@ -18,9 +18,4 @@ void search() { assertEquals(3, roles.size()); } - @Test - void findDistinctByManageId() { - Set manageIdentifiers = roleRepository.findDistinctManageIdentifiers(); - assertEquals(6, manageIdentifiers.size()); - } } \ No newline at end of file diff --git a/server/src/test/java/access/repository/UserRepositoryTest.java b/server/src/test/java/access/repository/UserRepositoryTest.java index 7bc0610e..0bda978f 100644 --- a/server/src/test/java/access/repository/UserRepositoryTest.java +++ b/server/src/test/java/access/repository/UserRepositoryTest.java @@ -7,7 +7,7 @@ import java.util.List; import java.util.Optional; -import static access.Seed.MANAGE_SUB; +import static access.AbstractTest.MANAGE_SUB; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/server/src/test/java/access/security/UserPermissionsTest.java b/server/src/test/java/access/security/UserPermissionsTest.java index 2e732394..3090bedc 100644 --- a/server/src/test/java/access/security/UserPermissionsTest.java +++ b/server/src/test/java/access/security/UserPermissionsTest.java @@ -1,6 +1,6 @@ package access.security; -import access.Seed; +import access.WithApplicationTest; import access.exception.UserRestrictionException; import access.manage.EntityType; import access.model.*; @@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; -class UserPermissionsTest { +class UserPermissionsTest extends WithApplicationTest { private final static Random random = new SecureRandom(); @@ -81,7 +81,7 @@ void assertInvalidManagerInvitation() { @Test void assertInvalidInvitation() { User user = userWithRole(Authority.INVITER, "mail"); - Role role = new Role("name", "description", "https://landingpage.com", Seed.application("manageIdentifier", EntityType.SAML20_SP), 365, false, false); + Role role = new Role("name", "description", "https://landingpage.com", application("manageIdentifier", EntityType.SAML20_SP), 365, false, false); role.setId(random.nextLong()); List roles = List.of(role); assertThrows(UserRestrictionException.class, () -> UserPermissions.assertValidInvitation(user, Authority.GUEST, roles)); @@ -138,7 +138,7 @@ void assertRoleAccess() { void assertRoleAccessManager() { String identifier = UUID.randomUUID().toString(); User user = userWithRole(Authority.MANAGER, identifier); - Role role = new Role("name", "description", "https://landingpage.com",Seed.application(identifier, EntityType.SAML20_SP), 365, false, false); + Role role = new Role("name", "description", "https://landingpage.com", application(identifier, EntityType.SAML20_SP), 365, false, false); role.setId(random.nextLong()); UserPermissions.assertRoleAccess(user, role); } @@ -147,7 +147,7 @@ void assertRoleAccessManager() { void assertNoRoleAccess() { String identifier = UUID.randomUUID().toString(); User user = userWithRole(Authority.GUEST, identifier); - Role role = new Role("name", "description", "https://landingpage.com",Seed.application(identifier, EntityType.SAML20_SP), 365, false, false); + Role role = new Role("name", "description", "https://landingpage.com", application(identifier, EntityType.SAML20_SP), 365, false, false); role.setId(random.nextLong()); assertThrows(UserRestrictionException.class, () -> UserPermissions.assertRoleAccess(user, role)); } @@ -157,9 +157,11 @@ private User userWithRole(Authority authority, String manageIdentifier) { } private User userWithRole(User user, Authority authority, String manageIdentifier) { - Role role = new Role("name", "description", "https://landingpage.com",Seed.application(manageIdentifier, EntityType.SAML20_SP), 365, false, false); + Role role = new Role("name", "description", "https://landingpage.com", application(manageIdentifier, EntityType.SAML20_SP), 365, false, false); role.setId(random.nextLong()); user.addUserRole(new UserRole(authority, role)); return user; } + + } \ No newline at end of file diff --git a/server/src/test/java/access/teams/TeamsControllerTest.java b/server/src/test/java/access/teams/TeamsControllerTest.java index d1dbc948..ada46345 100644 --- a/server/src/test/java/access/teams/TeamsControllerTest.java +++ b/server/src/test/java/access/teams/TeamsControllerTest.java @@ -12,7 +12,7 @@ import java.util.List; import java.util.Map; -import static access.Seed.GUEST_SUB; +import static access.AbstractTest.GUEST_SUB; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/server/src/test/java/access/voot/VootControllerTest.java b/server/src/test/java/access/voot/VootControllerTest.java index 86f2f985..2b3d23f6 100644 --- a/server/src/test/java/access/voot/VootControllerTest.java +++ b/server/src/test/java/access/voot/VootControllerTest.java @@ -8,7 +8,7 @@ import java.util.List; import java.util.Map; -import static access.Seed.GUEST_SUB; +import static access.AbstractTest.GUEST_SUB; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.*;