diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/keycloak/UserCreateAttributesDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/keycloak/UserCreateAttributesDto.java new file mode 100644 index 0000000000000000000000000000000000000000..6df8ce5e8f733313e9c9f2534e6cef03adb0d5e5 --- /dev/null +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/keycloak/UserCreateAttributesDto.java @@ -0,0 +1,19 @@ +package at.tuwien.api.keycloak; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import lombok.extern.jackson.Jacksonized; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Jacksonized +@ToString +public class UserCreateAttributesDto { + + @JsonProperty("CUSTOM_ID") + private String ldapId; + +} diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/keycloak/UserCreateDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/keycloak/UserCreateDto.java index fe4b69550259023b135bf2ae43a70c85c888cce0..2a80811b6247cd18fde5b3eadea1921b1ab2c3a9 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/keycloak/UserCreateDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/keycloak/UserCreateDto.java @@ -1,6 +1,5 @@ package at.tuwien.api.keycloak; -import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.*; @@ -36,4 +35,6 @@ public class UserCreateDto { private List<String> groups; + private UserCreateAttributesDto attributes; + } diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/user/User.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/user/User.java index 40756005068946c89da1250c3c6f7734593abaf3..bc17ab9bc925cd92954c05bd10aa56457dd730e4 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/user/User.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/user/User.java @@ -63,7 +63,7 @@ public class User { @Column(name = "mariadb_password", nullable = false) private String mariadbPassword; - @Column(name = "is_internal", nullable = false, insertable = false, updatable = false) + @Column(name = "is_internal", nullable = false, updatable = false) private Boolean isInternal; } diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AbstractEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AbstractEndpoint.java index b41cc089a7f13965305aa94fd671fdc24d95f44d..4779a6428e33bde6be581921a9d15bd81a25c5b6 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AbstractEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AbstractEndpoint.java @@ -1,7 +1,10 @@ package at.tuwien.endpoints; import at.tuwien.api.user.UserDetailsDto; +import at.tuwien.exception.UserNotFoundException; +import at.tuwien.service.UserService; import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; import java.security.Principal; import java.util.UUID; @@ -33,11 +36,13 @@ public abstract class AbstractEndpoint { return null; } final Authentication authentication = (Authentication) principal; - final UserDetailsDto user = (UserDetailsDto) authentication.getPrincipal(); - if (user.getId() == null) { - return null; + if (authentication.getPrincipal() instanceof UserDetailsDto user) { + if (user.getId() == null) { + throw new IllegalArgumentException("Principal has no id"); + } + return UUID.fromString(user.getId()); } - return UUID.fromString(user.getId()); + throw new IllegalArgumentException("Unknown principal instance: " + authentication.getPrincipal().getClass()); } } diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java index 7c194bd979657f9f084124f98a918969361d9e26..f184ffc3372ac10e35f2d6686b0c79e2ecaca818 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java @@ -28,7 +28,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.security.Principal; -import java.util.List; import java.util.UUID; @Log4j2 diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index 99a2856d448ffc0d00b6b83565b8ddf1805499e4..8a4a087da20e4578a40801ac670a7ed5a3826521 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -252,7 +252,7 @@ public class ViewEndpoint extends AbstractEndpoint { @NotNull @PathVariable("viewId") Long viewId, @NotNull Principal principal) throws NotAllowedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, ViewNotFoundException, SearchServiceException, - SearchServiceConnectionException { + SearchServiceConnectionException, UserNotFoundException { log.debug("endpoint delete view, databaseId={}, viewId={}", databaseId, viewId); final Database database = databaseService.findById(databaseId); if (!database.getOwner().getId().equals(getId(principal))) { @@ -306,7 +306,7 @@ public class ViewEndpoint extends AbstractEndpoint { @NotNull @Valid @RequestBody ViewUpdateDto data, @NotNull Principal principal) throws NotAllowedException, DataServiceConnectionException, DatabaseNotFoundException, ViewNotFoundException, SearchServiceException, - SearchServiceConnectionException { + SearchServiceConnectionException, UserNotFoundException { log.debug("endpoint update view, databaseId={}, viewId={}", databaseId, viewId); final Database database = databaseService.findById(databaseId); final View view = viewService.findById(database, viewId); diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java index b8716532b022ebc0602cb20dc8119a3ffbcc8504..1f7c391bd2ef63d49ed1acd5255409a1564af0ca 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java @@ -76,6 +76,9 @@ public class EndpointValidator extends AbstractEndpoint { if (principal == null) { throw new NotAllowedException("No principal provided"); } + if (isSystem(principal)) { + return; + } final DatabaseAccess access = accessService.find(database, userService.findById(getId(principal))); log.trace("found access: {}", access); if (writeAccessOnly && !(access.getType().equals(AccessType.WRITE_OWN) || access.getType().equals(AccessType.WRITE_ALL))) { diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java index 68ea32083b8c8846845b10e459e098c5aa58342f..2815dd6c0557a31490dff959bcff7f60e559b805 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java @@ -214,9 +214,9 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"delete-database-view"}) - public void delete_publicOwner_succeeds() throws NotAllowedException, DataServiceException, - DataServiceConnectionException, DatabaseNotFoundException, AccessNotFoundException, - SearchServiceException, SearchServiceConnectionException, ViewNotFoundException { + public void delete_publicOwner_succeeds() throws NotAllowedException, DataServiceException, UserNotFoundException, + DataServiceConnectionException, DatabaseNotFoundException, AccessNotFoundException, ViewNotFoundException, + SearchServiceException, SearchServiceConnectionException { /* test */ delete_generic(DATABASE_3_ID, DATABASE_3, VIEW_5_ID, VIEW_5, USER_3_PRINCIPAL, USER_3_ID, USER_3, DATABASE_3_USER_1_WRITE_ALL_ACCESS); @@ -372,7 +372,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-database-view"}) public void delete_privateOwner_succeeds() throws NotAllowedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, AccessNotFoundException, SearchServiceException, - SearchServiceConnectionException, ViewNotFoundException { + SearchServiceConnectionException, ViewNotFoundException, UserNotFoundException { /* test */ delete_generic(DATABASE_1_ID, DATABASE_1, VIEW_1_ID, VIEW_1, USER_1_PRINCIPAL, USER_1_ID, USER_1, DATABASE_1_USER_1_WRITE_ALL_ACCESS); @@ -411,7 +411,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"modify-view-visibility"}) public void update_succeeds() throws NotAllowedException, DataServiceConnectionException, DatabaseNotFoundException, - SearchServiceException, SearchServiceConnectionException, ViewNotFoundException { + SearchServiceException, SearchServiceConnectionException, ViewNotFoundException, UserNotFoundException { /* test */ update_generic(USER_1_PRINCIPAL); @@ -531,7 +531,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { protected void delete_generic(Long databaseId, Database database, Long viewId, View view, Principal principal, UUID userId, User user, DatabaseAccess access) throws NotAllowedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, AccessNotFoundException, - SearchServiceException, SearchServiceConnectionException, ViewNotFoundException { + SearchServiceException, SearchServiceConnectionException, ViewNotFoundException, UserNotFoundException { /* mock */ when(databaseService.findById(databaseId)) @@ -556,7 +556,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { protected void update_generic(Principal principal) throws SearchServiceException, NotAllowedException, DatabaseNotFoundException, SearchServiceConnectionException, DataServiceConnectionException, - ViewNotFoundException { + ViewNotFoundException, UserNotFoundException { final ViewUpdateDto request = ViewUpdateDto.builder() .isPublic(true) .isSchemaPublic(true) diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java index 3f69453649dac695a7939ffe2881eb02d855c79d..eec5aebf4bea668164c51bae655c074cb306e4c2 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java @@ -1,5 +1,6 @@ package at.tuwien.mvc; +import at.tuwien.api.keycloak.TokenDto; import at.tuwien.exception.AuthServiceConnectionException; import at.tuwien.exception.AuthServiceException; import at.tuwien.exception.CredentialsInvalidException; @@ -8,6 +9,8 @@ import at.tuwien.repository.ContainerRepository; import at.tuwien.repository.DatabaseRepository; import at.tuwien.repository.LicenseRepository; import at.tuwien.repository.UserRepository; +import at.tuwien.service.AuthenticationService; +import at.tuwien.service.UserService; import at.tuwien.test.AbstractUnitTest; import at.tuwien.utils.KeycloakUtils; import dasniko.testcontainers.keycloak.KeycloakContainer; @@ -18,7 +21,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -28,10 +30,8 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; -import java.util.Optional; -import static org.mockito.Mockito.when; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; @@ -65,8 +65,11 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest @Autowired private DatabaseRepository databaseRepository; + @Autowired + private AuthenticationService authenticationService; + @Container - private static KeycloakContainer keycloakContainer = new KeycloakContainer("quay.io/keycloak/keycloak:24.0") + private static KeycloakContainer keycloakContainer = new KeycloakContainer(KEYCLOAK_IMAGE) .withImagePullPolicy(PullPolicy.alwaysPull()) .withAdminUsername("admin") .withAdminPassword("admin") @@ -88,10 +91,11 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest databaseRepository.save(DATABASE_1); /* keycloak */ keycloakUtils.deleteUser(USER_1_USERNAME); + keycloakUtils.deleteUser(USER_LOCAL_ADMIN_USERNAME); } @Test - public void findById_database_basicUser_fails() throws Exception { + public void findById_database_basicUser_succeeds() throws Exception { /* mock */ keycloakGateway.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); @@ -108,11 +112,11 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest @Test public void findById_database_basicAdmin_succeeds() throws Exception { - /* mock */ - keycloakGateway.createUser(USER_1_KEYCLOAK_SYSTEM_SIGNUP_REQUEST); + /* pre condition */ + keycloakGateway.createUser(USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); /* test */ - this.mockMvc.perform(get("/api/database/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) + this.mockMvc.perform(get("/api/database/1").with(httpBasic(USER_LOCAL_ADMIN_USERNAME, USER_LOCAL_ADMIN_PASSWORD))) .andDo(print()) .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) @@ -123,11 +127,14 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest } @Test - @WithMockUser(username = "admin", authorities = {"system"}) public void findById_database_bearerAdmin_succeeds() throws Exception { + /* pre condition */ + keycloakGateway.createUser(USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); + final TokenDto jwt = authenticationService.obtainToken(USER_LOCAL_ADMIN_LOGIN_REQUEST_DTO); + /* test */ - this.mockMvc.perform(get("/api/database/1")) + this.mockMvc.perform(get("/api/database/1").header("Authorization", "Bearer " + jwt.getAccessToken())) .andDo(print()) .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) @@ -138,51 +145,15 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest } @Test - public void findById_table_basicUser_fails() throws Exception { - - /* mock */ - keycloakGateway.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); - - /* test */ - this.mockMvc.perform(get("/api/database/1/table/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) - .andDo(print()) - .andExpect(header().doesNotExist("X-Username")) - .andExpect(header().doesNotExist("X-Password")) - .andExpect(header().doesNotExist("X-Host")) - .andExpect(header().doesNotExist("X-Port")) - .andExpect(header().doesNotExist("X-Type")) - .andExpect(header().doesNotExist("X-Database")) - .andExpect(header().doesNotExist("X-Table")) - .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) - .andExpect(status().isOk()); - } - - @Test - public void findById_table_basicAdmin_succeeds() throws Exception { + public void findById_table_bearerAdmin_succeeds() throws Exception { - /* mock */ - keycloakGateway.createUser(USER_1_KEYCLOAK_SYSTEM_SIGNUP_REQUEST); + /* pre condition */ + keycloakGateway.createUser(USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); + final TokenDto jwt = authenticationService.obtainToken(USER_LOCAL_ADMIN_LOGIN_REQUEST_DTO); - /* test */ - this.mockMvc.perform(get("/api/database/1/table/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) - .andDo(print()) - .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) - .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) - .andExpect(header().string("X-Host", CONTAINER_1_HOST)) - .andExpect(header().string("X-Port", "" + CONTAINER_1_PORT)) - .andExpect(header().string("X-Type", IMAGE_1_JDBC)) - .andExpect(header().string("X-Database", DATABASE_1_INTERNALNAME)) - .andExpect(header().string("X-Table", TABLE_1_INTERNAL_NAME)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-Table")) - .andExpect(status().isOk()); - } - - @Test - @WithMockUser(username = "admin", authorities = {"system"}) - public void findById_table_bearerAdmin_succeeds() throws Exception { /* test */ - this.mockMvc.perform(get("/api/database/1/table/1")) + this.mockMvc.perform(get("/api/database/1/table/1").header("Authorization", "Bearer " + jwt.getAccessToken())) .andDo(print()) .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) @@ -196,13 +167,13 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest } @Test - public void findById_view_basicUser_fails() throws Exception { + public void findById_table_basicUser_succeeds() throws Exception { /* mock */ keycloakGateway.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); /* test */ - this.mockMvc.perform(get("/api/database/1/view/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) + this.mockMvc.perform(get("/api/database/1/table/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) .andDo(print()) .andExpect(header().doesNotExist("X-Username")) .andExpect(header().doesNotExist("X-Password")) @@ -210,37 +181,19 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest .andExpect(header().doesNotExist("X-Port")) .andExpect(header().doesNotExist("X-Type")) .andExpect(header().doesNotExist("X-Database")) - .andExpect(header().doesNotExist("X-View")) + .andExpect(header().doesNotExist("X-Table")) .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } @Test - public void findById_view_basicAdmin_succeeds() throws Exception { + public void findById_table_basicAdmin_succeeds() throws Exception { /* mock */ - keycloakGateway.createUser(USER_1_KEYCLOAK_SYSTEM_SIGNUP_REQUEST); - - /* test */ - this.mockMvc.perform(get("/api/database/1/view/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) - .andDo(print()) - .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) - .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) - .andExpect(header().string("X-Host", CONTAINER_1_HOST)) - .andExpect(header().string("X-Port", "" + CONTAINER_1_PORT)) - .andExpect(header().string("X-Type", IMAGE_1_JDBC)) - .andExpect(header().string("X-Database", DATABASE_1_INTERNALNAME)) - .andExpect(header().string("X-View", VIEW_1_INTERNAL_NAME)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-View")) - .andExpect(status().isOk()); - } - - @Test - @WithMockUser(username = "admin", authorities = {"system"}) - public void findById_view_bearerAdmin_succeeds() throws Exception { + keycloakGateway.createUser(USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); /* test */ - this.mockMvc.perform(get("/api/database/1/view/1")) + this.mockMvc.perform(get("/api/database/1/table/1").with(httpBasic(USER_LOCAL_ADMIN_USERNAME, USER_LOCAL_ADMIN_PASSWORD))) .andDo(print()) .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) @@ -248,51 +201,43 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest .andExpect(header().string("X-Port", "" + CONTAINER_1_PORT)) .andExpect(header().string("X-Type", IMAGE_1_JDBC)) .andExpect(header().string("X-Database", DATABASE_1_INTERNALNAME)) - .andExpect(header().string("X-View", VIEW_1_INTERNAL_NAME)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-View")) + .andExpect(header().string("X-Table", TABLE_1_INTERNAL_NAME)) + .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-Table")) .andExpect(status().isOk()); } @Test - public void findById_container_basicUser_fails() throws Exception { + public void findById_view_basicUser_succeeds() throws Exception { /* mock */ keycloakGateway.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); /* test */ - this.mockMvc.perform(get("/api/container/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) + this.mockMvc.perform(get("/api/database/1/view/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) .andDo(print()) .andExpect(header().doesNotExist("X-Username")) .andExpect(header().doesNotExist("X-Password")) + .andExpect(header().doesNotExist("X-Host")) + .andExpect(header().doesNotExist("X-Port")) + .andExpect(header().doesNotExist("X-Type")) + .andExpect(header().doesNotExist("X-Database")) + .andExpect(header().doesNotExist("X-View")) .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } @Test - public void findById_container_basicAdmin_succeeds() throws Exception { + public void findById_container_basicUser_succeeds() throws Exception { /* mock */ - keycloakGateway.createUser(USER_1_KEYCLOAK_SYSTEM_SIGNUP_REQUEST); + keycloakGateway.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); /* test */ this.mockMvc.perform(get("/api/container/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) .andDo(print()) - .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) - .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password")) - .andExpect(status().isOk()); - } - - @Test - @WithMockUser(username = "admin", authorities = {"system"}) - public void findById_container_bearerAdmin_succeeds() throws Exception { - - /* test */ - this.mockMvc.perform(get("/api/container/1")) - .andDo(print()) - .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) - .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password")) + .andExpect(header().doesNotExist("X-Username")) + .andExpect(header().doesNotExist("X-Password")) + .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServicePersistenceTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServicePersistenceTest.java index 4fb6f0f0b2a30f8ebc300b3d56aa46bb483bbec7..9240da4c96f0865711b7a66107597a9fd0d401a4 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServicePersistenceTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServicePersistenceTest.java @@ -1,5 +1,6 @@ package at.tuwien.service; +import at.tuwien.entities.container.Container; import at.tuwien.entities.database.Database; import at.tuwien.exception.DatabaseNotFoundException; import at.tuwien.repository.ContainerRepository; @@ -31,6 +32,9 @@ public class DatabaseServicePersistenceTest extends AbstractUnitTest { @Autowired private DatabaseService databaseService; + @Autowired + private AccessService accessService; + @Autowired private UserRepository userRepository; @@ -67,9 +71,43 @@ public class DatabaseServicePersistenceTest extends AbstractUnitTest { public void findAllPublicByInternalName_succeeds() { /* test */ - final List<Database> response = databaseService.findAllPublicByInternalName(DATABASE_1_INTERNALNAME); + final List<Database> response = databaseService.findAllPublicByInternalName(DATABASE_3_INTERNALNAME); assertEquals(1, response.size()); - assertEquals(DATABASE_1, response.get(0)); + assertEquals(DATABASE_3, response.get(0)); + } + + @Test + @Transactional(readOnly = true) + public void findAllPublicByInternalName_privateEmpty_succeeds() { + + /* test */ + final List<Database> response = databaseService.findAllPublicByInternalName(DATABASE_1_INTERNALNAME); + assertEquals(0, response.size()); + } + + @Test + @Transactional(readOnly = true) + public void findAllPublicOrReadAccess_privateNoAccessEmpty_succeeds() { + + /* test */ + final List<Database> response = databaseService.findAllPublicOrReadAccess(USER_4_ID); + assertEquals(3, response.size()); + assertEquals(DATABASE_4, response.get(0)); + assertEquals(DATABASE_3, response.get(1)); + assertEquals(DATABASE_2, response.get(2)); + } + + @Test + @Transactional(readOnly = true) + public void findAllPublicOrReadAccess_privateAccess_succeeds() { + + /* test */ + final List<Database> response = databaseService.findAllPublicOrReadAccess(USER_2_ID); + assertEquals(4, response.size()); + assertEquals(DATABASE_4, response.get(0)); + assertEquals(DATABASE_3, response.get(1)); + assertEquals(DATABASE_2, response.get(2)); + assertEquals(DATABASE_1, response.get(3)); } } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java index d7f768239814693146b9d029fcec26a914502be6..9a80ec1e423ae0e38e45528c73fffe61508ee8e0 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java @@ -87,19 +87,6 @@ public class DatabaseServiceUnitTest extends AbstractUnitTest { }); } - @Test - public void findAllPublicByInternalName_notFound_fails() { - - /* mock */ - when(databaseRepository.findAllPublicByInternalNameDesc(DATABASE_1_INTERNALNAME)) - .thenReturn(List.of()); - - /* test */ - assertThrows(DatabaseNotFoundException.class, () -> { - databaseService.findAllPublicByInternalName(DATABASE_1_INTERNALNAME); - }); - } - @Test public void updatePassword_succeeds() throws DataServiceException, DatabaseNotFoundException, DataServiceConnectionException { diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/utils/KeycloakUtils.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/utils/KeycloakUtils.java index 49694e6fd1dc49eb0f4bc8df35f1b6cd4965bf5e..f5ad18b694081ed50b879d6690e2a85748b3bece 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/utils/KeycloakUtils.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/utils/KeycloakUtils.java @@ -1,18 +1,13 @@ package at.tuwien.utils; -import at.tuwien.api.keycloak.RoleRepresentationDto; -import at.tuwien.exception.*; +import at.tuwien.exception.AuthServiceConnectionException; +import at.tuwien.exception.AuthServiceException; +import at.tuwien.exception.UserNotFoundException; import at.tuwien.gateway.KeycloakGateway; -import at.tuwien.gateway.impl.KeycloakGatewayImpl; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.*; import org.springframework.stereotype.Component; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.client.RestTemplate; -import java.util.List; import java.util.UUID; @Log4j2 @@ -28,8 +23,7 @@ public class KeycloakUtils { this.keycloakGateway = keycloakGateway; } - public void deleteUser(String username) throws AuthServiceException, AuthServiceConnectionException, - CredentialsInvalidException { + public void deleteUser(String username) throws AuthServiceException, AuthServiceConnectionException { try { final UUID userId = keycloakGateway.findByUsername(username).getId(); keycloakGateway.deleteUser(userId); diff --git a/dbrepo-metadata-service/rest-service/src/test/resources/init/dbrepo-realm.json b/dbrepo-metadata-service/rest-service/src/test/resources/init/dbrepo-realm.json index 588053e15fa6d5872c4cb83da42d71859b5f7a64..7ee28b34a4f2d662bb43979930732dec74da8a63 100644 --- a/dbrepo-metadata-service/rest-service/src/test/resources/init/dbrepo-realm.json +++ b/dbrepo-metadata-service/rest-service/src/test/resources/init/dbrepo-realm.json @@ -37,6 +37,7 @@ "editUsernameAllowed" : false, "bruteForceProtected" : false, "permanentLockout" : false, + "maxTemporaryLockouts" : 0, "maxFailureWaitSeconds" : 900, "minimumQuickLoginWaitSeconds" : 60, "waitIncrementSeconds" : 60, @@ -1096,34 +1097,34 @@ "id" : "f2ce17fe-7b15-47a4-bbf8-86f415298fa9", "name" : "data-stewards", "path" : "/data-stewards", + "subGroups" : [ ], "attributes" : { }, "realmRoles" : [ "default-data-steward-roles" ], - "clientRoles" : { }, - "subGroups" : [ ] + "clientRoles" : { } }, { "id" : "124d9888-0b6e-46aa-8225-077dcedaf16e", "name" : "developers", "path" : "/developers", + "subGroups" : [ ], "attributes" : { }, "realmRoles" : [ "default-developer-roles" ], - "clientRoles" : { }, - "subGroups" : [ ] + "clientRoles" : { } }, { "id" : "f467c38e-9041-4faa-ae0b-39cec65ff4db", "name" : "researchers", "path" : "/researchers", + "subGroups" : [ ], "attributes" : { }, "realmRoles" : [ "default-researcher-roles" ], - "clientRoles" : { }, - "subGroups" : [ ] + "clientRoles" : { } }, { "id" : "2b9f94b4-d434-4a98-8eab-25678cfee983", "name" : "system", "path" : "/system", + "subGroups" : [ ], "attributes" : { }, "realmRoles" : [ "default-system-roles" ], - "clientRoles" : { }, - "subGroups" : [ ] + "clientRoles" : { } } ], "defaultRole" : { "id" : "abd2d9ee-ebc4-4d0a-839e-6b588a6d442a", @@ -1142,7 +1143,8 @@ "otpPolicyLookAheadWindow" : 1, "otpPolicyPeriod" : 30, "otpPolicyCodeReusable" : false, - "otpSupportedApplications" : [ "totpAppGoogleName", "totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName" ], + "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ], + "localizationTexts" : { }, "webAuthnPolicyRpEntityName" : "keycloak", "webAuthnPolicySignatureAlgorithms" : [ "ES256" ], "webAuthnPolicyRpId" : "", @@ -1153,6 +1155,7 @@ "webAuthnPolicyCreateTimeout" : 0, "webAuthnPolicyAvoidSameAuthenticatorRegister" : false, "webAuthnPolicyAcceptableAaguids" : [ ], + "webAuthnPolicyExtraOrigins" : [ ], "webAuthnPolicyPasswordlessRpEntityName" : "keycloak", "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ], "webAuthnPolicyPasswordlessRpId" : "", @@ -1163,6 +1166,7 @@ "webAuthnPolicyPasswordlessCreateTimeout" : 0, "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false, "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ], + "webAuthnPolicyPasswordlessExtraOrigins" : [ ], "scopeMappings" : [ { "clientScope" : "rabbitmq.tag:administrator", "roles" : [ "escalated-broker-handling" ] @@ -1365,19 +1369,20 @@ "access.tokenResponse.claim" : "false" } }, { - "id" : "030a1cd9-53d1-4a62-a375-94d50a2dc6fc", + "id" : "0b4c644f-0cf0-4794-8395-d5d83009dabe", "name" : "uid", "protocol" : "openid-connect", "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "aggregate.attrs" : "false", - "multivalued" : "false", + "introspection.token.claim" : "true", "userinfo.token.claim" : "true", - "user.attribute" : "LDAP_ID", + "user.attribute" : "CUSTOM_ID", "id.token.claim" : "true", + "lightweight.claim" : "false", "access.token.claim" : "true", - "claim.name" : "uid" + "claim.name" : "uid", + "jsonType.label" : "String" } } ], "defaultClientScopes" : [ "roles", "attributes" ], @@ -2074,6 +2079,7 @@ "browserSecurityHeaders" : { "contentSecurityPolicyReportOnly" : "", "xContentTypeOptions" : "nosniff", + "referrerPolicy" : "no-referrer", "xRobotsTag" : "none", "xFrameOptions" : "SAMEORIGIN", "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", @@ -2107,23 +2113,6 @@ "config" : { "allow-default-scopes" : [ "true" ] } - }, { - "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1", - "name" : "Trusted Hosts", - "providerId" : "trusted-hosts", - "subType" : "anonymous", - "subComponents" : { }, - "config" : { - "host-sending-registration-request-must-match" : [ "true" ], - "client-uris-must-match" : [ "true" ] - } - }, { - "id" : "f565cb47-3bcf-4078-8f94-eb4179c375b8", - "name" : "Full Scope Disabled", - "providerId" : "scope", - "subType" : "anonymous", - "subComponents" : { }, - "config" : { } }, { "id" : "0efa669d-1017-4b4a-82e1-c2eaf72de2c9", "name" : "Allowed Client Scopes", @@ -2141,25 +2130,73 @@ "subComponents" : { }, "config" : { } }, { - "id" : "104ec5a9-025b-4c44-8ac0-82d22887ca3e", + "id" : "3ab11d74-5e76-408a-b85a-26bf8950f979", "name" : "Allowed Protocol Mapper Types", "providerId" : "allowed-protocol-mappers", - "subType" : "authenticated", + "subType" : "anonymous", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper" ] + "allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "saml-role-list-mapper" ] } }, { - "id" : "3ab11d74-5e76-408a-b85a-26bf8950f979", + "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "f565cb47-3bcf-4078-8f94-eb4179c375b8", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "104ec5a9-025b-4c44-8ac0-82d22887ca3e", "name" : "Allowed Protocol Mapper Types", "providerId" : "allowed-protocol-mappers", - "subType" : "anonymous", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper" ] + } + } ], + "org.keycloak.userprofile.UserProfileProvider" : [ { + "id" : "fb763636-e1ea-49c7-adca-ea105cdec4ad", + "providerId" : "declarative-user-profile", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-attribute-mapper", "saml-role-list-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper" ] + "kc.user.profile.config" : [ "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}],\"unmanagedAttributePolicy\":\"ENABLED\"}" ] } } ], "org.keycloak.keys.KeyProvider" : [ { + "id" : "2f53ccf3-37b0-4d34-83e7-ed497499ee51", + "name" : "rsa-enc-generated", + "providerId" : "rsa-enc-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEowIBAAKCAQEA3b1tNLfcjFLUw9UShVDNf+ZD8sQqb4YBaIXcSJTX/zDQUPiCp176BBGI3s4VplDArnOW+LumozmKogeoHEnGEIDW8ovgK5uMU9tSA2p0qqGBUMOdR8YATTIfCJe7qGiiuGa3WZy3sQLM70SuRzx02YU8gvUcvl2Js4KyqAziOUX/w3Wa59H9jjGNUXYyqaPWJp73eHzbVYWySzyLG22mVlcUtBx5siL5T2/Xu0p9z4l7/bapwwmOVi1ZrcHjbEAwdGEiSMGI/uWqAF+r1BRpmJLR7HNXcL3eK4/56VYLaiwSejfyYeRFMITEn/UxGYhcXZ5xMUUCG0TxjBhLYpTBuwIDAQABAoIBAA4dwebcxkrH99Poa8+WkiE7JgaS9sahx9OBI2xwJANoIU2TpzGuNLQZ76uLgB+rPWZTD9Xm5a1iJjwOyQ9/937TzPCk91D0tpgcusRikb8jx/6TGB9acL4kBjYUVCCHr3BA2G75MKKGtJ2OMvAbCQSosZj+r2VDwYFEPUkV2jheE5JHSBkwyIRrus3JCwu8gu5fyCg9z8ljcxJxI5HIsi4v8Z21aCw/cLj7h5cMt44wCjQz4rOfYNBEFeHDtlfR1QtWKgjm4ZHHJbKrzf9b2kQXclziceEbSM0tYbROEXKi+s0Zc+z3HEG89vv0vfN400clmzzIAijKY6gg3pPRWdECgYEA+lnWYbSlXDMNYx6RBXm1RnlMUYIm4oy4/9ljgnoGJ6WCn3SjFkgaDtiKfGIG1BSB85r04pAPANgcWHf5tWDnq0ARvBVG0BX2bKd++7B3D4d3CRYKCwm88SslJXv9dfHVhq4+zViFPiUWwT20A72jCuUCvL88y5fh/YBecfdh+jECgYEA4r5RD0NB9dMaeg5/jk/GEHIo4Z9KLc6FrSoOFo2xFkPOy1sgDpDOiNtypuWvniO7k7Ose3DS3hlfTMsKzIW/CgQJ20+Y4cvBWDaOsRxfjj7w3d+jH5OSJdKKSzTrgLKc9ZhlRzVXy0J0hipIA6HG5kdVdLXmh85ITmf1CbJhE6sCgYBjPVeBNbXTHZ2x6/z62aslO5IoQVqetb/kE82hfDOSZcao5Ph9Lam+ttH2ynkAevykj4mBgi+gWwqpey2uW7KaLPSaxShj9kDQA3mP1fzsV/u0y1rB02Nlin/YIxVvOqU1FT9p8SwoXVVu1sHUNck62VtDbN9xqUx5S/ikXrclEQKBgQCoTssOwEcK+Vty9KYcdfy4onTUHZBLdjxl8Iyqkxy7QTQUYRznkvesQPDXEDGO+kk3dyx2KKZt9Hl4IFNww2quPZcvcuMx4DQxjbXXpA8OIIxcta95NepLJwA+mRai3nKCH1A2TlNP7pFeMa5o+8IPly3Ix2lKr4Wepa4PN5i1pwKBgCZ1QP6XAOERl9NznNmU0rXVcvYNP4PIIfQWfvGsldZ4QKkmjjAGiS0/oYqdWs+UDRZyCRChaVjDXO9fk0PEG5OGKAj9nyiYCT/M8xtJ3UeP5ffZZvJ/vnye3QdDIo1e38ZzsWwJHmLYw7fRqY9W5Vxo0Vsy22U3CJY70KTxVdTy" ], + "keyUse" : [ "ENC" ], + "certificate" : [ "MIICmzCCAYMCBgGG3GWycDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZkYnJlcG8wHhcNMjMwMzEzMTkxMzE3WhcNMzMwMzEzMTkxNDU3WjARMQ8wDQYDVQQDDAZkYnJlcG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdvW00t9yMUtTD1RKFUM1/5kPyxCpvhgFohdxIlNf/MNBQ+IKnXvoEEYjezhWmUMCuc5b4u6ajOYqiB6gcScYQgNbyi+Arm4xT21IDanSqoYFQw51HxgBNMh8Il7uoaKK4ZrdZnLexAszvRK5HPHTZhTyC9Ry+XYmzgrKoDOI5Rf/DdZrn0f2OMY1RdjKpo9Ymnvd4fNtVhbJLPIsbbaZWVxS0HHmyIvlPb9e7Sn3PiXv9tqnDCY5WLVmtweNsQDB0YSJIwYj+5aoAX6vUFGmYktHsc1dwvd4rj/npVgtqLBJ6N/Jh5EUwhMSf9TEZiFxdnnExRQIbRPGMGEtilMG7AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAK3kQ1VkQrzvSWvmXmazmNoA1ZiPzRDs1XhGUWxgsxzgPylr3dGBuqQbKvgnLUBQLSqlJHpI4fZflHswu1qrvVZYtekPcGef4WhcKAu2i1RwxrKa6RJQ1tRbrLuVYCzPv5p/DWgltWVn88aoLnqQn0SK/0PB/o4a4Cm7Kq2ZzCr1dACBr06LvOHsc7249OySmbG4HH+pLK6jVURhZ9VaObqAHe2FJBVVoIzURbdiRRURqumrIvbnpeaU1aFyg6ED5wTnXvmMPmVPt9F79mcB33bASO5wyu00X8t1hyN2Show2l2vxLACGUzVkTQt15s7uDLKE7qLmKSR3EuSGXWv3wA=" ], + "priority" : [ "100" ], + "algorithm" : [ "RSA-OAEP" ] + } + }, { + "id" : "230cb681-9ceb-4b1b-8a4c-929a11b08de0", + "name" : "hmac-generated-hs512", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "8a489935-9a95-459b-9059-59b438ef0fa8" ], + "secret" : [ "xSCVgBlrLPWoF54gKQdR7BqXlfNaCD43xtS_ZgQRC0tGNAbqhy2Q9y8LdD2IR7K__8VGaDGYtyZayopgTebhDBb4gHDjDOBX7flhFYRrm0G3aTIuCIyFG-bPULwmyP_oHeC6tjwdQhqx5G0tE2mQQqPC9dDZuUA5I7QREIGK8cI" ], + "priority" : [ "100" ], + "algorithm" : [ "HS512" ] + } + }, { "id" : "28ca0b6d-b2e2-4785-b04b-2391e6344e30", "name" : "aes-generated", "providerId" : "aes-generated", @@ -2175,23 +2212,11 @@ "providerId" : "hmac-generated", "subComponents" : { }, "config" : { - "kid" : [ "c8500166-5cc4-4085-ad0f-853c3b0b0233" ], - "secret" : [ "TI3xg__G2Qy8C47DracpYir2X4ItQZSrhgr5KSlwRNISDbBqZ-ky3OcAyokSXMcpweSOaCPvbivpvzJNklUBvw" ], + "kid" : [ "5034d264-cb50-4006-a59e-2ce636eb5f38" ], + "secret" : [ "ToVIw-a4IE-Yp9JpP8ztb8NAICYO8CT3tUiDPT6DdiBcgzKJ9Ym9vspxGVdmPceX3mAgbnGLAcTx1PkInSVrbZs-tX9QXFwdlyGbewhKiNpH8wEg32Wk4GuUDpTv8JCsymgWyQBY681jvIMv05eCoK2QWpqCzcgP828KM5peCzo" ], "priority" : [ "100" ], "algorithm" : [ "HS256" ] } - }, { - "id" : "2f53ccf3-37b0-4d34-83e7-ed497499ee51", - "name" : "rsa-enc-generated", - "providerId" : "rsa-enc-generated", - "subComponents" : { }, - "config" : { - "privateKey" : [ "MIIEowIBAAKCAQEA3b1tNLfcjFLUw9UShVDNf+ZD8sQqb4YBaIXcSJTX/zDQUPiCp176BBGI3s4VplDArnOW+LumozmKogeoHEnGEIDW8ovgK5uMU9tSA2p0qqGBUMOdR8YATTIfCJe7qGiiuGa3WZy3sQLM70SuRzx02YU8gvUcvl2Js4KyqAziOUX/w3Wa59H9jjGNUXYyqaPWJp73eHzbVYWySzyLG22mVlcUtBx5siL5T2/Xu0p9z4l7/bapwwmOVi1ZrcHjbEAwdGEiSMGI/uWqAF+r1BRpmJLR7HNXcL3eK4/56VYLaiwSejfyYeRFMITEn/UxGYhcXZ5xMUUCG0TxjBhLYpTBuwIDAQABAoIBAA4dwebcxkrH99Poa8+WkiE7JgaS9sahx9OBI2xwJANoIU2TpzGuNLQZ76uLgB+rPWZTD9Xm5a1iJjwOyQ9/937TzPCk91D0tpgcusRikb8jx/6TGB9acL4kBjYUVCCHr3BA2G75MKKGtJ2OMvAbCQSosZj+r2VDwYFEPUkV2jheE5JHSBkwyIRrus3JCwu8gu5fyCg9z8ljcxJxI5HIsi4v8Z21aCw/cLj7h5cMt44wCjQz4rOfYNBEFeHDtlfR1QtWKgjm4ZHHJbKrzf9b2kQXclziceEbSM0tYbROEXKi+s0Zc+z3HEG89vv0vfN400clmzzIAijKY6gg3pPRWdECgYEA+lnWYbSlXDMNYx6RBXm1RnlMUYIm4oy4/9ljgnoGJ6WCn3SjFkgaDtiKfGIG1BSB85r04pAPANgcWHf5tWDnq0ARvBVG0BX2bKd++7B3D4d3CRYKCwm88SslJXv9dfHVhq4+zViFPiUWwT20A72jCuUCvL88y5fh/YBecfdh+jECgYEA4r5RD0NB9dMaeg5/jk/GEHIo4Z9KLc6FrSoOFo2xFkPOy1sgDpDOiNtypuWvniO7k7Ose3DS3hlfTMsKzIW/CgQJ20+Y4cvBWDaOsRxfjj7w3d+jH5OSJdKKSzTrgLKc9ZhlRzVXy0J0hipIA6HG5kdVdLXmh85ITmf1CbJhE6sCgYBjPVeBNbXTHZ2x6/z62aslO5IoQVqetb/kE82hfDOSZcao5Ph9Lam+ttH2ynkAevykj4mBgi+gWwqpey2uW7KaLPSaxShj9kDQA3mP1fzsV/u0y1rB02Nlin/YIxVvOqU1FT9p8SwoXVVu1sHUNck62VtDbN9xqUx5S/ikXrclEQKBgQCoTssOwEcK+Vty9KYcdfy4onTUHZBLdjxl8Iyqkxy7QTQUYRznkvesQPDXEDGO+kk3dyx2KKZt9Hl4IFNww2quPZcvcuMx4DQxjbXXpA8OIIxcta95NepLJwA+mRai3nKCH1A2TlNP7pFeMa5o+8IPly3Ix2lKr4Wepa4PN5i1pwKBgCZ1QP6XAOERl9NznNmU0rXVcvYNP4PIIfQWfvGsldZ4QKkmjjAGiS0/oYqdWs+UDRZyCRChaVjDXO9fk0PEG5OGKAj9nyiYCT/M8xtJ3UeP5ffZZvJ/vnye3QdDIo1e38ZzsWwJHmLYw7fRqY9W5Vxo0Vsy22U3CJY70KTxVdTy" ], - "keyUse" : [ "ENC" ], - "certificate" : [ "MIICmzCCAYMCBgGG3GWycDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZkYnJlcG8wHhcNMjMwMzEzMTkxMzE3WhcNMzMwMzEzMTkxNDU3WjARMQ8wDQYDVQQDDAZkYnJlcG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdvW00t9yMUtTD1RKFUM1/5kPyxCpvhgFohdxIlNf/MNBQ+IKnXvoEEYjezhWmUMCuc5b4u6ajOYqiB6gcScYQgNbyi+Arm4xT21IDanSqoYFQw51HxgBNMh8Il7uoaKK4ZrdZnLexAszvRK5HPHTZhTyC9Ry+XYmzgrKoDOI5Rf/DdZrn0f2OMY1RdjKpo9Ymnvd4fNtVhbJLPIsbbaZWVxS0HHmyIvlPb9e7Sn3PiXv9tqnDCY5WLVmtweNsQDB0YSJIwYj+5aoAX6vUFGmYktHsc1dwvd4rj/npVgtqLBJ6N/Jh5EUwhMSf9TEZiFxdnnExRQIbRPGMGEtilMG7AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAK3kQ1VkQrzvSWvmXmazmNoA1ZiPzRDs1XhGUWxgsxzgPylr3dGBuqQbKvgnLUBQLSqlJHpI4fZflHswu1qrvVZYtekPcGef4WhcKAu2i1RwxrKa6RJQ1tRbrLuVYCzPv5p/DWgltWVn88aoLnqQn0SK/0PB/o4a4Cm7Kq2ZzCr1dACBr06LvOHsc7249OySmbG4HH+pLK6jVURhZ9VaObqAHe2FJBVVoIzURbdiRRURqumrIvbnpeaU1aFyg6ED5wTnXvmMPmVPt9F79mcB33bASO5wyu00X8t1hyN2Show2l2vxLACGUzVkTQt15s7uDLKE7qLmKSR3EuSGXWv3wA=" ], - "priority" : [ "100" ], - "algorithm" : [ "RSA-OAEP" ] - } }, { "id" : "2293ff99-3c6d-46d1-8635-5e679d5b134a", "name" : "rsa-generated", @@ -2229,35 +2254,6 @@ "flowAlias" : "Verify Existing Account by Re-authentication", "userSetupAllowed" : false } ] - }, { - "id" : "bc0b483f-4a3f-4c15-bf65-b26f5320e6c9", - "alias" : "Authentication Options", - "description" : "Authentication options.", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "basic-auth", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "basic-auth-otp", - "authenticatorFlow" : false, - "requirement" : "DISABLED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "auth-spnego", - "authenticatorFlow" : false, - "requirement" : "DISABLED", - "priority" : 30, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] }, { "id" : "a690c715-fbae-4c20-b680-bd4010718761", "alias" : "Browser - Conditional OTP", @@ -2574,28 +2570,6 @@ "flowAlias" : "Browser - Conditional OTP", "userSetupAllowed" : false } ] - }, { - "id" : "b8f1f963-6813-4875-bae8-ce48a813763b", - "alias" : "http challenge", - "description" : "An authentication flow based on challenge-response HTTP Authentication Schemes", - "providerId" : "basic-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "no-cookie-redirect", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : true, - "flowAlias" : "Authentication Options", - "userSetupAllowed" : false - } ] }, { "id" : "4c983c77-241f-41c5-8b8a-e2cd6fc08914", "alias" : "registration", @@ -2626,13 +2600,6 @@ "priority" : 20, "autheticatorFlow" : false, "userSetupAllowed" : false - }, { - "authenticator" : "registration-profile-action", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 40, - "autheticatorFlow" : false, - "userSetupAllowed" : false }, { "authenticator" : "registration-password-action", "authenticatorFlow" : false, @@ -2777,6 +2744,14 @@ "defaultAction" : false, "priority" : 80, "config" : { } + }, { + "alias" : "delete_credential", + "name" : "Delete Credential", + "providerId" : "delete_credential", + "enabled" : true, + "defaultAction" : false, + "priority" : 100, + "config" : { } }, { "alias" : "update_user_locale", "name" : "Update User Locale", @@ -2792,6 +2767,7 @@ "resetCredentialsFlow" : "reset credentials", "clientAuthenticationFlow" : "clients", "dockerAuthenticationFlow" : "docker auth", + "firstBrokerLoginFlow" : "first broker login", "attributes" : { "cibaBackchannelTokenDeliveryMode" : "poll", "cibaAuthRequestedUserHint" : "login_hint", @@ -2811,7 +2787,7 @@ "clientSessionMaxLifespan" : "0", "shortVerificationUri" : "" }, - "keycloakVersion" : "21.0.2", + "keycloakVersion" : "24.0.5", "userManagedAccessAllowed" : false, "clientProfiles" : { "profiles" : [ ] diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java index 35e55797ebffb688f801bfcf64163d3a4a630049..35dd5fe2b6b4f54b882d20c5685c57847dfc2c1d 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java @@ -73,6 +73,7 @@ public class AuthTokenFilter extends OncePerRequestFilter { final JWTVerifier verifier = verification.build(); final DecodedJWT jwt = verifier.verify(token); final RealmAccessDto realmAccess = jwt.getClaim("realm_access").as(RealmAccessDto.class); + log.trace("token contains uid: {}", jwt.getClaim("uid").asString()); return UserDetailsDto.builder() .id(jwt.getClaim("uid").asString()) .username(jwt.getClaim("preferred_username").asString()) diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java index 80fdd15f1daff7625508eb8d46d9b54332a5150f..b9fea2b54b1c242f58dbc0cd578e9dff328ba49c 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java @@ -32,6 +32,7 @@ public class BasicAuthenticationProvider implements AuthenticationManager { try { final TokenDto tokenDto = keycloakGateway.obtainUserToken(auth.getName(), auth.getCredentials().toString()); final UserDetails userDetails = authTokenFilter.verifyJwt(tokenDto.getAccessToken()); + log.debug("set basic auth principal: {}", userDetails); return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); } catch (ServletException | CredentialsInvalidException | AccountNotSetupException | AuthServiceConnectionException e) { diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java index bf7498d4bb164991e5006a9e52f0c52dd10d3cd3..39e4824706a6d89a3588c6748c46ee2c3935b63e 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java @@ -184,42 +184,42 @@ public class IdentifierServiceImpl implements IdentifierService { identifier.setType(metadataMapper.identifierTypeDtoToIdentifierType(data.getType())); /* create in metadata database */ if (data.getCreators() != null) { - identifier.setCreators(data.getCreators() + identifier.setCreators(new LinkedList<>(data.getCreators() .stream() .map(metadataMapper::creatorCreateDtoToCreator) - .toList()); + .toList())); identifier.getCreators() .forEach(c -> c.setIdentifier(identifier)); } if (data.getRelatedIdentifiers() != null) { - identifier.setRelatedIdentifiers(data.getRelatedIdentifiers() + identifier.setRelatedIdentifiers(new LinkedList<>(data.getRelatedIdentifiers() .stream() .map(metadataMapper::relatedIdentifierCreateDtoToRelatedIdentifier) - .toList()); + .toList())); identifier.getRelatedIdentifiers() .forEach(r -> r.setIdentifier(identifier)); } if (data.getTitles() != null) { - identifier.setTitles(data.getTitles() + identifier.setTitles(new LinkedList<>(data.getTitles() .stream() .map(metadataMapper::identifierCreateTitleDtoToIdentifierTitle) - .toList()); + .toList())); identifier.getTitles() .forEach(t -> t.setIdentifier(identifier)); } if (data.getDescriptions() != null) { - identifier.setDescriptions(data.getDescriptions() + identifier.setDescriptions(new LinkedList<>(data.getDescriptions() .stream() .map(metadataMapper::identifierCreateDescriptionDtoToIdentifierDescription) - .toList()); + .toList())); identifier.getDescriptions() .forEach(d -> d.setIdentifier(identifier)); } if (data.getFunders() != null) { - identifier.setFunders(data.getFunders() + identifier.setFunders(new LinkedList<>(data.getFunders() .stream() .map(metadataMapper::identifierFunderSaveDtoToIdentifierFunder) - .toList()); + .toList())); identifier.getFunders() .forEach(f -> f.setIdentifier(identifier)); } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java index aa75200cc94a553513a82db6af9e89db4a749643..6f9f43aeda934ecd7065ead11077ad529597e118 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java @@ -73,6 +73,7 @@ public class UserServiceImpl implements UserService { .theme("light") .mariadbPassword(getMariaDbPassword(data.getPassword())) .language("en") + .isInternal(false) .build(); /* create at metadata database */ final User user = userRepository.save(entity); diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java index ccd12292bab2bc4905b1573ab8102dc4f47c6f5d..ee38a1d6b06ac386defb773badcbb30810aeb59b 100644 --- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java @@ -40,10 +40,7 @@ import at.tuwien.api.datacite.DataCiteBody; import at.tuwien.api.datacite.DataCiteData; import at.tuwien.api.datacite.doi.DataCiteDoi; import at.tuwien.api.identifier.*; -import at.tuwien.api.keycloak.CredentialDto; -import at.tuwien.api.keycloak.CredentialTypeDto; -import at.tuwien.api.keycloak.TokenDto; -import at.tuwien.api.keycloak.UserCreateDto; +import at.tuwien.api.keycloak.*; import at.tuwien.api.maintenance.BannerMessageCreateDto; import at.tuwien.api.maintenance.BannerMessageTypeDto; import at.tuwien.api.maintenance.BannerMessageUpdateDto; @@ -60,6 +57,8 @@ import at.tuwien.api.orcid.person.name.OrcidValueDto; import at.tuwien.api.semantics.EntityDto; import at.tuwien.api.semantics.OntologyCreateDto; import at.tuwien.api.semantics.OntologyModifyDto; +import at.tuwien.api.user.UserAttributesDto; +import at.tuwien.api.user.UserDto; import at.tuwien.api.user.*; import at.tuwien.api.user.internal.PrivilegedUserDto; import at.tuwien.api.user.internal.UpdateUserPasswordDto; @@ -164,6 +163,8 @@ public abstract class BaseTest { public final static String MARIADB_IMAGE = "mariadb:11.3.2"; + public final static String KEYCLOAK_IMAGE = "quay.io/keycloak/keycloak:24.0"; + public final static String[] DEFAULT_SEMANTICS_HANDLING = new String[]{"default-semantics-handling", "create-semantic-unit", "execute-semantic-query", "table-semantic-analyse", "create-semantic-concept"}; @@ -426,11 +427,18 @@ public abstract class BaseTest { public final static String USER_LOCAL_ADMIN_PASSWORD = "admin"; public final static String USER_LOCAL_ADMIN_THEME = "dark"; public final static Boolean USER_LOCAL_ADMIN_IS_INTERNAL = true; + public final static Boolean USER_LOCAL_ADMIN_ENABLED = true; public final static String USER_LOCAL_ADMIN_EMAIL = "admin@local"; @SuppressWarnings("java:S2068") public final static String USER_LOCAL_ADMIN_MARIADB_PASSWORD = "*440BA4FD1A87A0999647DB67C0EE258198B247BA"; + public final static LoginRequestDto USER_LOCAL_ADMIN_LOGIN_REQUEST_DTO = LoginRequestDto.builder() + .username(USER_LOCAL_ADMIN_USERNAME) + .password(USER_LOCAL_ADMIN_PASSWORD) + .build(); + public final static UserDetails USER_LOCAL_ADMIN_DETAILS = UserDetailsDto.builder() + .id(String.valueOf(USER_LOCAL_ADMIN_ID)) .username(USER_LOCAL_ADMIN_USERNAME) .password(USER_LOCAL_ADMIN_PASSWORD) .authorities(AUTHORITY_DEFAULT_LOCAL_ADMIN_AUTHORITIES) @@ -449,7 +457,7 @@ public abstract class BaseTest { USER_LOCAL_ADMIN_PASSWORD, USER_LOCAL_ADMIN_DETAILS.getAuthorities()); public final static UUID USER_1_ID = UUID.fromString("cd5bab0d-7799-4069-85fb-c5d738572a0b"); - public final static UUID USER_1_LDAP_ID = UUID.fromString("8e541e05-f45c-4d40-ba1b-0e62f04ba3f8"); + public final static UUID USER_1_LDAP_ID = UUID.fromString("cd5bab0d-7799-4069-85fb-c5d738572a0b"); public final static String USER_1_EMAIL = "john.doe@example.com"; public final static String USER_1_USERNAME = "junit1"; @SuppressWarnings("java:S2068") @@ -496,19 +504,31 @@ public abstract class BaseTest { .value(USER_1_PASSWORD) .build(); + public final static CredentialDto USER_LOCAL_KEYCLOAK_CREDENTIAL_1 = CredentialDto.builder() + .type(CredentialTypeDto.PASSWORD) + .temporary(false) + .value(USER_LOCAL_ADMIN_PASSWORD) + .build(); + public final static UserCreateDto USER_1_KEYCLOAK_SIGNUP_REQUEST = UserCreateDto.builder() .username(USER_1_USERNAME) .email(USER_1_EMAIL) .enabled(USER_1_ENABLED) - .credentials(List.of(USER_1_KEYCLOAK_CREDENTIAL_1)) + .credentials(new LinkedList<>(List.of(USER_1_KEYCLOAK_CREDENTIAL_1))) + .attributes(UserCreateAttributesDto.builder() + .ldapId(String.valueOf(USER_1_ID)) + .build()) .build(); - public final static UserCreateDto USER_1_KEYCLOAK_SYSTEM_SIGNUP_REQUEST = UserCreateDto.builder() - .username(USER_1_USERNAME) - .email(USER_1_EMAIL) - .enabled(USER_1_ENABLED) - .credentials(List.of(USER_1_KEYCLOAK_CREDENTIAL_1)) - .groups(List.of("system")) + public final static UserCreateDto USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST = UserCreateDto.builder() + .username(USER_LOCAL_ADMIN_USERNAME) + .email(USER_LOCAL_ADMIN_EMAIL) + .enabled(USER_LOCAL_ADMIN_ENABLED) + .credentials(new LinkedList<>(List.of(USER_LOCAL_KEYCLOAK_CREDENTIAL_1))) + .groups(new LinkedList<>(List.of("system"))) + .attributes(UserCreateAttributesDto.builder() + .ldapId(String.valueOf(USER_LOCAL_ADMIN_ID)) + .build()) .build(); public final static PrivilegedUserDto USER_1_PRIVILEGED_DTO = PrivilegedUserDto.builder() @@ -605,6 +625,7 @@ public abstract class BaseTest { .build(); public final static UUID USER_2_ID = UUID.fromString("eeb9a51b-4cd8-4039-90bf-e24f17372f7c"); + public final static UUID USER_2_LDAP_ID = UUID.fromString("eeb9a51b-4cd8-4039-90bf-e24f17372f7c"); public final static String USER_2_EMAIL = "jane.doe@example.com"; public final static String USER_2_USERNAME = "junit2"; public final static String USER_2_FIRSTNAME = "Jane"; @@ -712,6 +733,7 @@ public abstract class BaseTest { USER_2_PASSWORD, USER_2_DETAILS.getAuthorities()); public final static UUID USER_3_ID = UUID.fromString("7b080e33-d8db-4276-9d53-47208e657006"); + public final static UUID USER_3_LDAP_ID = UUID.fromString("7b080e33-d8db-4276-9d53-47208e657006"); public final static String USER_3_USERNAME = "junit3"; public final static String USER_3_FIRSTNAME = "System"; public final static String USER_3_LASTNAME = "System"; @@ -751,7 +773,7 @@ public abstract class BaseTest { .orcid(USER_3_ORCID_URL) .theme(USER_3_THEME) .mariadbPassword(USER_3_DATABASE_PASSWORD) - .isInternal(USER_2_IS_INTERNAL) + .isInternal(USER_3_IS_INTERNAL) .build(); public final static UserDto USER_3_DTO = UserDto.builder() @@ -807,6 +829,7 @@ public abstract class BaseTest { .build(); public final static UUID USER_4_ID = UUID.fromString("791d58c5-bfab-4520-b4fc-b44d4ab9feb0"); + public final static UUID USER_4_LDAP_ID = UUID.fromString("791d58c5-bfab-4520-b4fc-b44d4ab9feb0"); public final static String USER_4_USERNAME = "junit4"; public final static String USER_4_FIRSTNAME = "JUnit"; public final static String USER_4_LASTNAME = "4"; @@ -884,6 +907,7 @@ public abstract class BaseTest { .build(); public final static UUID USER_5_ID = UUID.fromString("28ff851d-d7bc-4422-959c-edd7a5b15630"); + public final static UUID USER_5_LDAP_ID = UUID.fromString("28ff851d-d7bc-4422-959c-edd7a5b15630"); public final static String USER_5_USERNAME = "system"; public final static String USER_5_FIRSTNAME = "System"; public final static String USER_5_LASTNAME = "System"; @@ -1152,7 +1176,7 @@ public abstract class BaseTest { .host(CONTAINER_2_HOST) .port(CONTAINER_2_PORT) .quota(CONTAINER_2_QUOTA) - .databases(List.of()) + .databases(new LinkedList<>(List.of())) .privilegedUsername(CONTAINER_2_PRIVILEGED_USERNAME) .privilegedPassword(CONTAINER_2_PRIVILEGED_PASSWORD) .build(); @@ -1206,7 +1230,7 @@ public abstract class BaseTest { .host(CONTAINER_3_HOST) .port(CONTAINER_3_PORT) .quota(CONTAINER_3_QUOTA) - .databases(List.of()) + .databases(new LinkedList<>(List.of())) .privilegedUsername(CONTAINER_3_PRIVILEGED_USERNAME) .privilegedPassword(CONTAINER_3_PRIVILEGED_PASSWORD) .build(); @@ -1310,10 +1334,6 @@ public abstract class BaseTest { public final static Instant DATABASE_3_CREATED = Instant.ofEpochSecond(1677399792L) /* 2023-02-26 08:23:12 (UTC) */; public final static Instant DATABASE_3_LAST_MODIFIED = Instant.ofEpochSecond(1677399792L) /* 2023-02-26 08:23:12 (UTC) */; public final static UUID DATABASE_3_OWNER = USER_3_ID; - public final static UUID DATABASE_3_CREATOR_ID = USER_3_ID; - public final static User DATABASE_3_CREATOR = USER_3; - public final static UserDto DATABASE_3_CREATOR_DTO = USER_3_DTO; - public final static UserDto DATABASE_3_OWNER_DTO = USER_3_DTO; public final static DatabaseDto DATABASE_3_DTO = DatabaseDto.builder() .id(DATABASE_3_ID) @@ -1443,13 +1463,13 @@ public abstract class BaseTest { .name("col13") .type(ColumnTypeDto.ENUM) .nullAllowed(true) - .enums(List.of("val1", "val2")) + .enums(new LinkedList<>(List.of("val1", "val2"))) .build(), ColumnCreateDto.builder() .name("col14") .type(ColumnTypeDto.SET) .nullAllowed(true) - .sets(List.of("val1", "val2")) + .sets(new LinkedList<>(List.of("val1", "val2"))) .build(), ColumnCreateDto.builder() .name("col15") @@ -1902,8 +1922,9 @@ public abstract class BaseTest { .uniques(new LinkedList<>()) .foreignKeys(List.of(ForeignKeyCreateDto.builder() .referencedTable("weather_location") - .columns(List.of("fahrzeug")) - .referencedColumns(List.of("doesnotexist")).build())) + .columns(new LinkedList<>(List.of("fahrzeug"))) + .referencedColumns(new LinkedList<>(List.of("doesnotexist"))) + .build())) .build(); public final static TableCreateDto TABLE_3_CREATE_DTO = TableCreateDto.builder() @@ -2242,7 +2263,7 @@ public abstract class BaseTest { .checks(new LinkedHashSet<>()) .primaryKey(new LinkedHashSet<>(Set.of("Timestamp"))) .foreignKeys(new LinkedList<>()) - .uniques(List.of(List.of("Timestamp"))) + .uniques(new LinkedList<>(List.of(List.of("Timestamp")))) .build(); public final static TableCreateDto TABLE_4_CREATE_DTO = TableCreateDto.builder() @@ -2799,7 +2820,7 @@ public abstract class BaseTest { put(COLUMN_8_3_INTERNAL_NAME, null); }} )); - + @SuppressWarnings("java:S3599") public final static TableStatisticDto TABLE_8_STATISTIC_DTO = TableStatisticDto.builder() .columns(new HashMap<>() {{ @@ -3126,14 +3147,14 @@ public abstract class BaseTest { .checks(new LinkedHashSet<>()) .primaryKey(new LinkedHashSet<>(List.of("id"))) .foreignKeys(new LinkedList<>()) - .uniques(List.of(List.of("date"))) + .uniques(new LinkedList<>(List.of(List.of("date")))) .build(); public final static ConstraintsCreateDto TABLE_1_CONSTRAINTS_CREATE_INVALID_DTO = ConstraintsCreateDto.builder() .checks(new LinkedHashSet<>()) .primaryKey(new LinkedHashSet<>()) .foreignKeys(new LinkedList<>()) - .uniques(List.of(List.of("date"))) + .uniques(new LinkedList<>(List.of(List.of("date")))) .build(); public final static TableCreateDto TABLE_1_CREATE_DTO = TableCreateDto.builder() @@ -4597,9 +4618,9 @@ public abstract class BaseTest { .build()); public final static List<ForeignKeyCreateDto> TABLE_5_FOREIGN_KEYS_INVALID_CREATE = List.of(ForeignKeyCreateDto.builder() - .columns(List.of("somecolumn")) + .columns(new LinkedList<>(List.of("somecolumn"))) .referencedTable("sometable") - .referencedColumns(List.of("someothercolumn")) + .referencedColumns(new LinkedList<>(List.of("someothercolumn"))) .build()); public final static ConstraintsCreateDto TABLE_5_CONSTRAINTS_INVALID_CREATE = ConstraintsCreateDto.builder() @@ -4714,7 +4735,7 @@ public abstract class BaseTest { public final static ConstraintsCreateDto TABLE_5_CREATE_CONSTRAINTS_DTO = ConstraintsCreateDto.builder() .primaryKey(Set.of("id")) - .uniques(List.of(List.of("id"))) + .uniques(new LinkedList<>(List.of(List.of("id")))) .checks(new LinkedHashSet<>()) .foreignKeys(new LinkedList<>()) .build(); @@ -4860,9 +4881,9 @@ public abstract class BaseTest { List.of("firstname", "lastname")); public final static List<ForeignKeyCreateDto> TABLE_6_FOREIGN_KEYS_CREATE = List.of(ForeignKeyCreateDto.builder() - .columns(List.of("ref_id")) + .columns(new LinkedList<>(List.of("ref_id"))) .referencedTable("zoo") - .referencedColumns(List.of("id")) + .referencedColumns(new LinkedList<>(List.of("id"))) .build()); public final static Set<String> TABLE_6_CHECKS_CREATE = Set.of("firstname != lastname"); @@ -6276,8 +6297,8 @@ public abstract class BaseTest { public final static Identifier IDENTIFIER_1_WITH_DOI = Identifier.builder() .id(IDENTIFIER_1_ID) .queryId(IDENTIFIER_1_QUERY_ID) - .descriptions(List.of(IDENTIFIER_1_DESCRIPTION_1)) - .titles(List.of(IDENTIFIER_1_TITLE_1, IDENTIFIER_1_TITLE_2)) + .descriptions(new LinkedList<>(List.of(IDENTIFIER_1_DESCRIPTION_1))) + .titles(new LinkedList<>(List.of(IDENTIFIER_1_TITLE_1, IDENTIFIER_1_TITLE_2))) .doi(IDENTIFIER_1_DOI) .database(null /* for jpa */) .created(IDENTIFIER_1_CREATED) @@ -6293,9 +6314,9 @@ public abstract class BaseTest { .publisher(IDENTIFIER_1_PUBLISHER) .type(IDENTIFIER_1_TYPE) .owner(USER_1) - .licenses(List.of(LICENSE_1)) - .creators(List.of(IDENTIFIER_1_CREATOR_1)) - .funders(List.of(IDENTIFIER_1_FUNDER_1)) + .licenses(new LinkedList<>(List.of(LICENSE_1))) + .creators(new LinkedList<>(List.of(IDENTIFIER_1_CREATOR_1))) + .funders(new LinkedList<>(List.of(IDENTIFIER_1_FUNDER_1))) .status(IDENTIFIER_1_STATUS_TYPE) .build(); @@ -6303,8 +6324,8 @@ public abstract class BaseTest { .id(IDENTIFIER_1_ID) .databaseId(DATABASE_1_ID) .queryId(IDENTIFIER_1_QUERY_ID) - .descriptions(List.of(IDENTIFIER_1_DESCRIPTION_1_DTO)) - .titles(List.of(IDENTIFIER_1_TITLE_1_DTO, IDENTIFIER_1_TITLE_2_DTO)) + .descriptions(new LinkedList<>(List.of(IDENTIFIER_1_DESCRIPTION_1_DTO))) + .titles(new LinkedList<>(List.of(IDENTIFIER_1_TITLE_1_DTO, IDENTIFIER_1_TITLE_2_DTO))) .doi(IDENTIFIER_1_DOI) .execution(IDENTIFIER_1_EXECUTION) .publicationYear(IDENTIFIER_1_PUBLICATION_YEAR) @@ -6317,9 +6338,9 @@ public abstract class BaseTest { .publisher(IDENTIFIER_1_PUBLISHER) .type(IDENTIFIER_1_TYPE_DTO) .owner(USER_1_DTO) - .licenses(List.of(LICENSE_1_DTO)) - .creators(List.of(IDENTIFIER_1_CREATOR_1_DTO)) - .funders(List.of(IDENTIFIER_1_FUNDER_1_DTO)) + .licenses(new LinkedList<>(List.of(LICENSE_1_DTO))) + .creators(new LinkedList<>(List.of(IDENTIFIER_1_CREATOR_1_DTO))) + .funders(new LinkedList<>(List.of(IDENTIFIER_1_FUNDER_1_DTO))) .status(IDENTIFIER_1_STATUS_TYPE_DTO) .build(); @@ -6327,7 +6348,7 @@ public abstract class BaseTest { .id(IDENTIFIER_1_ID) .databaseId(DATABASE_1_ID) .queryId(IDENTIFIER_1_QUERY_ID) - .titles(List.of(IDENTIFIER_1_TITLE_1_DTO, IDENTIFIER_1_TITLE_2_DTO)) + .titles(new LinkedList<>(List.of(IDENTIFIER_1_TITLE_1_DTO, IDENTIFIER_1_TITLE_2_DTO))) .doi(IDENTIFIER_1_DOI) .publicationYear(IDENTIFIER_1_PUBLICATION_YEAR) .publisher(IDENTIFIER_1_PUBLISHER) @@ -6340,16 +6361,16 @@ public abstract class BaseTest { .type(IDENTIFIER_1_TYPE_DTO) .publicationYear(IDENTIFIER_1_PUBLICATION_YEAR) .publisher(IDENTIFIER_1_PUBLISHER) - .descriptions(List.of(IDENTIFIER_1_DESCRIPTION_1_CREATE_DTO)) - .titles(List.of(IDENTIFIER_1_TITLE_1_CREATE_DTO, IDENTIFIER_1_TITLE_2_CREATE_DTO)) + .descriptions(new LinkedList<>(List.of(IDENTIFIER_1_DESCRIPTION_1_CREATE_DTO))) + .titles(new LinkedList<>(List.of(IDENTIFIER_1_TITLE_1_CREATE_DTO, IDENTIFIER_1_TITLE_2_CREATE_DTO))) .publicationYear(IDENTIFIER_1_PUBLICATION_YEAR) .publicationMonth(IDENTIFIER_1_PUBLICATION_MONTH) .publisher(IDENTIFIER_1_PUBLISHER) .type(IDENTIFIER_1_TYPE_DTO) .doi(IDENTIFIER_1_DOI) - .licenses(List.of(LICENSE_1_DTO)) - .creators(List.of(IDENTIFIER_1_CREATOR_1_CREATE_DTO)) - .funders(List.of(IDENTIFIER_1_FUNDER_1_CREATE_DTO)) + .licenses(new LinkedList<>(List.of(LICENSE_1_DTO))) + .creators(new LinkedList<>(List.of(IDENTIFIER_1_CREATOR_1_CREATE_DTO))) + .funders(new LinkedList<>(List.of(IDENTIFIER_1_FUNDER_1_CREATE_DTO))) .build(); public final static IdentifierCreateDto IDENTIFIER_1_CREATE_WITH_DOI_DTO = IdentifierCreateDto.builder() @@ -6358,45 +6379,45 @@ public abstract class BaseTest { .doi(IDENTIFIER_1_DOI) .publicationYear(IDENTIFIER_1_PUBLICATION_YEAR) .publisher(IDENTIFIER_1_PUBLISHER) - .descriptions(List.of(IDENTIFIER_1_DESCRIPTION_1_CREATE_DTO)) - .titles(List.of(IDENTIFIER_1_TITLE_1_CREATE_DTO, IDENTIFIER_1_TITLE_2_CREATE_DTO)) + .descriptions(new LinkedList<>(List.of(IDENTIFIER_1_DESCRIPTION_1_CREATE_DTO))) + .titles(new LinkedList<>(List.of(IDENTIFIER_1_TITLE_1_CREATE_DTO, IDENTIFIER_1_TITLE_2_CREATE_DTO))) .publicationYear(IDENTIFIER_1_PUBLICATION_YEAR) .publicationMonth(IDENTIFIER_1_PUBLICATION_MONTH) .publisher(IDENTIFIER_1_PUBLISHER) .type(IDENTIFIER_1_TYPE_DTO) - .licenses(List.of(LICENSE_1_DTO)) - .creators(List.of(IDENTIFIER_1_CREATOR_1_CREATE_DTO)) - .funders(List.of(IDENTIFIER_1_FUNDER_1_CREATE_DTO)) + .licenses(new LinkedList<>(List.of(LICENSE_1_DTO))) + .creators(new LinkedList<>(List.of(IDENTIFIER_1_CREATOR_1_CREATE_DTO))) + .funders(new LinkedList<>(List.of(IDENTIFIER_1_FUNDER_1_CREATE_DTO))) .build(); public final static IdentifierSaveDto IDENTIFIER_1_SAVE_DTO = IdentifierSaveDto.builder() .id(IDENTIFIER_1_ID) .databaseId(IDENTIFIER_1_DATABASE_ID) - .descriptions(List.of(IDENTIFIER_1_DESCRIPTION_1_CREATE_DTO)) - .titles(List.of(IDENTIFIER_1_TITLE_1_CREATE_DTO, IDENTIFIER_1_TITLE_2_CREATE_DTO)) + .descriptions(new LinkedList<>(List.of(IDENTIFIER_1_DESCRIPTION_1_CREATE_DTO))) + .titles(new LinkedList<>(List.of(IDENTIFIER_1_TITLE_1_CREATE_DTO, IDENTIFIER_1_TITLE_2_CREATE_DTO))) .relatedIdentifiers(new LinkedList<>()) .publicationMonth(IDENTIFIER_1_PUBLICATION_MONTH) .publicationYear(IDENTIFIER_1_PUBLICATION_YEAR) - .creators(List.of(IDENTIFIER_1_CREATOR_1_CREATE_DTO)) - .funders(List.of(IDENTIFIER_1_FUNDER_1_CREATE_DTO)) + .creators(new LinkedList<>(List.of(IDENTIFIER_1_CREATOR_1_CREATE_DTO))) + .funders(new LinkedList<>(List.of(IDENTIFIER_1_FUNDER_1_CREATE_DTO))) .publisher(IDENTIFIER_1_PUBLISHER) .type(IDENTIFIER_1_TYPE_DTO) - .licenses(List.of(LICENSE_1_DTO)) + .licenses(new LinkedList<>(List.of(LICENSE_1_DTO))) .build(); public final static IdentifierSaveDto IDENTIFIER_1_SAVE_MODIFY_DTO = IdentifierSaveDto.builder() .id(IDENTIFIER_1_ID) .databaseId(IDENTIFIER_1_DATABASE_ID) - .descriptions(List.of()) // <<< - .titles(List.of(IDENTIFIER_1_TITLE_1_CREATE_DTO)) // <<< + .descriptions(new LinkedList<>(List.of())) // <<< + .titles(new LinkedList<>(List.of(IDENTIFIER_1_TITLE_1_CREATE_DTO))) // <<< .relatedIdentifiers(new LinkedList<>()) .publicationMonth(IDENTIFIER_1_PUBLICATION_MONTH) .publicationYear(IDENTIFIER_1_PUBLICATION_YEAR) - .creators(List.of()) // <<< - .funders(List.of()) // <<< + .creators(new LinkedList<>(List.of())) // <<< + .funders(new LinkedList<>(List.of())) // <<< .publisher(IDENTIFIER_1_PUBLISHER) .type(IDENTIFIER_1_TYPE_DTO) - .licenses(List.of()) // <<< + .licenses(new LinkedList<>(List.of())) // <<< .build(); public final static Long IDENTIFIER_5_ID = 5L; @@ -6591,8 +6612,8 @@ public abstract class BaseTest { .id(IDENTIFIER_5_ID) .databaseId(DATABASE_2_ID) .queryId(IDENTIFIER_5_QUERY_ID) - .descriptions(List.of(IDENTIFIER_5_DESCRIPTION_1_DTO)) - .titles(List.of(IDENTIFIER_5_TITLE_1_DTO)) + .descriptions(new LinkedList<>(List.of(IDENTIFIER_5_DESCRIPTION_1_DTO))) + .titles(new LinkedList<>(List.of(IDENTIFIER_5_TITLE_1_DTO))) .doi(IDENTIFIER_5_DOI) .execution(IDENTIFIER_5_EXECUTION) .publicationDay(IDENTIFIER_5_PUBLICATION_DAY) @@ -6606,14 +6627,14 @@ public abstract class BaseTest { .publisher(IDENTIFIER_5_PUBLISHER) .type(IDENTIFIER_5_TYPE_DTO) .owner(USER_2_DTO) - .creators(List.of(IDENTIFIER_5_CREATOR_1_DTO, IDENTIFIER_5_CREATOR_2_DTO)) + .creators(new LinkedList<>(List.of(IDENTIFIER_5_CREATOR_1_DTO, IDENTIFIER_5_CREATOR_2_DTO))) .build(); public final static IdentifierBriefDto IDENTIFIER_5_BRIEF_DTO = IdentifierBriefDto.builder() .id(IDENTIFIER_5_ID) .databaseId(DATABASE_2_ID) .queryId(IDENTIFIER_5_QUERY_ID) - .titles(List.of(IDENTIFIER_5_TITLE_1_DTO)) + .titles(new LinkedList<>(List.of(IDENTIFIER_5_TITLE_1_DTO))) .doi(IDENTIFIER_5_DOI) .publicationYear(IDENTIFIER_5_PUBLICATION_YEAR) .publisher(IDENTIFIER_5_PUBLISHER) @@ -6652,15 +6673,15 @@ public abstract class BaseTest { .id(IDENTIFIER_5_ID) .queryId(IDENTIFIER_5_QUERY_ID) .databaseId(IDENTIFIER_5_DATABASE_ID) - .descriptions(List.of(IDENTIFIER_5_DESCRIPTION_1_CREATE_DTO)) - .titles(List.of(IDENTIFIER_5_TITLE_1_CREATE_DTO)) - .relatedIdentifiers(List.of(IDENTIFIER_1_RELATED_IDENTIFIER_5_CREATE_DTO)) + .descriptions(new LinkedList<>(List.of(IDENTIFIER_5_DESCRIPTION_1_CREATE_DTO))) + .titles(new LinkedList<>(List.of(IDENTIFIER_5_TITLE_1_CREATE_DTO))) + .relatedIdentifiers(new LinkedList<>(List.of(IDENTIFIER_1_RELATED_IDENTIFIER_5_CREATE_DTO))) .publicationDay(IDENTIFIER_5_PUBLICATION_DAY) .publicationMonth(IDENTIFIER_5_PUBLICATION_MONTH) .publicationYear(IDENTIFIER_5_PUBLICATION_YEAR) - .creators(List.of(IDENTIFIER_5_CREATOR_1_CREATE_DTO, IDENTIFIER_5_CREATOR_2_CREATE_DTO)) + .creators(new LinkedList<>(List.of(IDENTIFIER_5_CREATOR_1_CREATE_DTO, IDENTIFIER_5_CREATOR_2_CREATE_DTO))) .publisher(IDENTIFIER_5_PUBLISHER) - .licenses(List.of(LICENSE_1_DTO)) + .licenses(new LinkedList<>(List.of(LICENSE_1_DTO))) .type(IDENTIFIER_5_TYPE_DTO) .build(); @@ -6827,7 +6848,10 @@ public abstract class BaseTest { .creatorName(CREATOR_3_NAME) .nameIdentifier(CREATOR_3_ORCID) .nameIdentifierScheme(NameIdentifierSchemeType.ORCID) + .affiliation(CREATOR_3_AFFIL) .affiliationIdentifier(CREATOR_3_AFFIL_ROR) + .affiliationIdentifierScheme(AffiliationIdentifierSchemeType.ROR) + .affiliationIdentifierSchemeUri("https://ror.org/") .build(); public final static CreatorDto IDENTIFIER_6_CREATOR_3_DTO = CreatorDto.builder() @@ -6871,8 +6895,8 @@ public abstract class BaseTest { .id(IDENTIFIER_6_ID) .databaseId(DATABASE_3_ID) .queryId(IDENTIFIER_6_QUERY_ID) - .descriptions(List.of(IDENTIFIER_6_DESCRIPTION_1_DTO)) - .titles(List.of(IDENTIFIER_6_TITLE_1_DTO)) + .descriptions(new LinkedList<>(List.of(IDENTIFIER_6_DESCRIPTION_1_DTO))) + .titles(new LinkedList<>(List.of(IDENTIFIER_6_TITLE_1_DTO))) .doi(IDENTIFIER_6_DOI) .execution(IDENTIFIER_6_EXECUTION) .publicationDay(IDENTIFIER_6_PUBLICATION_DAY) @@ -6896,7 +6920,7 @@ public abstract class BaseTest { .id(IDENTIFIER_6_ID) .databaseId(DATABASE_3_ID) .queryId(IDENTIFIER_6_QUERY_ID) - .titles(List.of(IDENTIFIER_6_TITLE_1_DTO)) + .titles(new LinkedList<>(List.of(IDENTIFIER_6_TITLE_1_DTO))) .doi(IDENTIFIER_6_DOI) .publicationYear(IDENTIFIER_6_PUBLICATION_YEAR) .publisher(IDENTIFIER_6_PUBLISHER) @@ -7022,7 +7046,7 @@ public abstract class BaseTest { .relatedIdentifiers(new LinkedList<>()) .publicationMonth(IDENTIFIER_7_PUBLICATION_MONTH) .publicationYear(IDENTIFIER_7_PUBLICATION_YEAR) - .creators(List.of(IDENTIFIER_7_CREATOR_1_CREATE_DTO)) + .creators(new LinkedList<>(List.of(IDENTIFIER_7_CREATOR_1_CREATE_DTO))) .funders(new LinkedList<>()) .licenses(new LinkedList<>()) .publisher(IDENTIFIER_7_PUBLISHER) @@ -7134,7 +7158,7 @@ public abstract class BaseTest { .creators(new LinkedList<>()) .publisher(IDENTIFIER_2_PUBLISHER) .type(IDENTIFIER_2_TYPE_DTO) - .licenses(List.of(LICENSE_1_DTO)) + .licenses(new LinkedList<>(List.of(LICENSE_1_DTO))) .queryId(QUERY_1_ID) .build(); @@ -7424,7 +7448,7 @@ public abstract class BaseTest { .isSchemaPublic(DATABASE_1_SCHEMA_PUBLIC) .name(DATABASE_1_NAME) .description(DATABASE_1_DESCRIPTION) - .identifiers(List.of(IDENTIFIER_1, IDENTIFIER_2, IDENTIFIER_3, IDENTIFIER_4)) + .identifiers(new LinkedList<>(List.of(IDENTIFIER_1, IDENTIFIER_2, IDENTIFIER_3, IDENTIFIER_4))) .cid(CONTAINER_1_ID) .container(CONTAINER_1) .internalName(DATABASE_1_INTERNALNAME) @@ -7452,9 +7476,9 @@ public abstract class BaseTest { .container(CONTAINER_1_BRIEF_DTO) .internalName(DATABASE_1_INTERNALNAME) .exchangeName(DATABASE_1_EXCHANGE) - .identifiers(List.of(IDENTIFIER_1_BRIEF_DTO, IDENTIFIER_2_BRIEF_DTO, IDENTIFIER_3_BRIEF_DTO, IDENTIFIER_4_BRIEF_DTO)) - .tables(List.of(TABLE_1_BRIEF_DTO, TABLE_2_BRIEF_DTO, TABLE_3_BRIEF_DTO, TABLE_4_BRIEF_DTO)) - .views(List.of(VIEW_1_BRIEF_DTO, VIEW_2_BRIEF_DTO, VIEW_3_BRIEF_DTO)) + .identifiers(new LinkedList<>(List.of(IDENTIFIER_1_BRIEF_DTO, IDENTIFIER_2_BRIEF_DTO, IDENTIFIER_3_BRIEF_DTO, IDENTIFIER_4_BRIEF_DTO))) + .tables(new LinkedList<>(List.of(TABLE_1_BRIEF_DTO, TABLE_2_BRIEF_DTO, TABLE_3_BRIEF_DTO, TABLE_4_BRIEF_DTO))) + .views(new LinkedList<>(List.of(VIEW_1_BRIEF_DTO, VIEW_2_BRIEF_DTO, VIEW_3_BRIEF_DTO))) .build(); public final static PrivilegedDatabaseDto DATABASE_1_PRIVILEGED_DTO = PrivilegedDatabaseDto.builder() @@ -7464,9 +7488,9 @@ public abstract class BaseTest { .container(CONTAINER_1_PRIVILEGED_DTO) .internalName(DATABASE_1_INTERNALNAME) .exchangeName(DATABASE_1_EXCHANGE) - .identifiers(List.of(IDENTIFIER_1_DTO, IDENTIFIER_2_DTO, IDENTIFIER_3_DTO, IDENTIFIER_4_DTO)) - .tables(List.of(TABLE_1_DTO, TABLE_2_DTO, TABLE_3_DTO, TABLE_4_DTO)) - .views(List.of(VIEW_1_DTO, VIEW_2_DTO, VIEW_3_DTO)) + .identifiers(new LinkedList<>(List.of(IDENTIFIER_1_DTO, IDENTIFIER_2_DTO, IDENTIFIER_3_DTO, IDENTIFIER_4_DTO))) + .tables(new LinkedList<>(List.of(TABLE_1_DTO, TABLE_2_DTO, TABLE_3_DTO, TABLE_4_DTO))) + .views(new LinkedList<>(List.of(VIEW_1_DTO, VIEW_2_DTO, VIEW_3_DTO))) .owner(USER_1_BRIEF_DTO) .lastRetrieved(Instant.now()) .build(); @@ -7609,9 +7633,9 @@ public abstract class BaseTest { .container(CONTAINER_1_PRIVILEGED_DTO) .internalName(DATABASE_2_INTERNALNAME) .exchangeName(DATABASE_2_EXCHANGE) - .identifiers(List.of(IDENTIFIER_5_DTO)) - .tables(List.of(TABLE_5_DTO, TABLE_6_DTO, TABLE_7_DTO)) - .views(List.of(VIEW_4_DTO)) + .identifiers(new LinkedList<>(List.of(IDENTIFIER_5_DTO))) + .tables(new LinkedList<>(List.of(TABLE_5_DTO, TABLE_6_DTO, TABLE_7_DTO))) + .views(new LinkedList<>(List.of(VIEW_4_DTO))) .owner(USER_2_BRIEF_DTO) .lastRetrieved(Instant.now()) .build(); @@ -7623,9 +7647,9 @@ public abstract class BaseTest { .container(CONTAINER_1_BRIEF_DTO) .internalName(DATABASE_2_INTERNALNAME) .exchangeName(DATABASE_2_EXCHANGE) - .identifiers(List.of(IDENTIFIER_5_BRIEF_DTO)) - .tables(List.of(TABLE_5_BRIEF_DTO, TABLE_6_BRIEF_DTO, TABLE_7_BRIEF_DTO)) - .views(List.of(VIEW_4_BRIEF_DTO)) + .identifiers(new LinkedList<>(List.of(IDENTIFIER_5_BRIEF_DTO))) + .tables(new LinkedList<>(List.of(TABLE_5_BRIEF_DTO, TABLE_6_BRIEF_DTO, TABLE_7_BRIEF_DTO))) + .views(new LinkedList<>(List.of(VIEW_4_BRIEF_DTO))) .identifiers(new LinkedList<>()) .owner(USER_2_BRIEF_DTO) .build(); @@ -7743,7 +7767,7 @@ public abstract class BaseTest { .tables(new LinkedList<>()) .views(new LinkedList<>()) .accesses(new LinkedList<>()) /* DATABASE_3_USER_1_WRITE_ALL_ACCESS */ - .identifiers(new LinkedList<>()) + .identifiers(new LinkedList<>()) /* IDENTIFIER_6 */ .build(); public final static DatabaseAccess DATABASE_3_USER_1_READ_ACCESS = DatabaseAccess.builder() @@ -7860,9 +7884,9 @@ public abstract class BaseTest { .container(CONTAINER_1_PRIVILEGED_DTO) .internalName(DATABASE_3_INTERNALNAME) .exchangeName(DATABASE_3_EXCHANGE) - .identifiers(List.of(IDENTIFIER_6_DTO)) - .tables(List.of(TABLE_8_DTO)) - .views(List.of(VIEW_5_DTO)) + .identifiers(new LinkedList<>(List.of(IDENTIFIER_6_DTO))) + .tables(new LinkedList<>(List.of(TABLE_8_DTO))) + .views(new LinkedList<>(List.of(VIEW_5_DTO))) .owner(USER_3_BRIEF_DTO) .lastRetrieved(Instant.now()) .build(); @@ -8149,6 +8173,7 @@ public abstract class BaseTest { public final static Constraints TABLE_7_CONSTRAINTS = Constraints.builder() .checks(new LinkedHashSet<>()) .foreignKeys(new LinkedList<>(List.of(ForeignKey.builder() + .id(8L) .name("fk_name_id") .onDelete(ReferenceType.NO_ACTION) .references(new LinkedList<>(List.of(ForeignKeyReference.builder() @@ -8162,6 +8187,7 @@ public abstract class BaseTest { .onUpdate(ReferenceType.NO_ACTION) .build(), ForeignKey.builder() + .id(9L) .name("fk_zoo_id") .onDelete(ReferenceType.NO_ACTION) .references(new LinkedList<>(List.of(ForeignKeyReference.builder()