diff --git a/.gitlab/agents/dev/values.yaml b/.gitlab/agents/dev/values.yaml index 78742e3dc364388f5dc3fc2f87a56509481fac0a..9d23d1350ffaa1c130cda57e89e480c171cdd195 100644 --- a/.gitlab/agents/dev/values.yaml +++ b/.gitlab/agents/dev/values.yaml @@ -139,7 +139,7 @@ ui: server: https://s155.datalab.tuwien.ac.at title: "Database Repository" logo: "https://ec.tuwien.ac.at/~weise/images/DS_white_hiRes.png" - icon: "https://ec.tuwien.ac.at/~weise/images/DS-icon_white_hiRes.png" + icon: "https://ec.tuwien.ac.at/~weise/images/favicon.ico" touch: "https://ec.tuwien.ac.at/~weise/images/DS-icon_white_hiRes.png" broker: host: s155.datalab.tuwien.ac.at diff --git a/dbrepo-auth-service/listeners/target/create-event-listener.jar b/dbrepo-auth-service/listeners/target/create-event-listener.jar index 9a9cd149f84ff92e5292a9fdc19a81edcc9ca7b7..76b1ad02357c308cc312c99ea8bf0e3c3b2e8b62 100644 Binary files a/dbrepo-auth-service/listeners/target/create-event-listener.jar and b/dbrepo-auth-service/listeners/target/create-event-listener.jar differ diff --git a/dbrepo-metadata-service/metrics.md b/dbrepo-metadata-service/metrics.md index 56a69c68f6913ab2e3ea192cde66f329ea336e10..f3e0a3130f23e149a54f1eca8247c559443809da 100644 --- a/dbrepo-metadata-service/metrics.md +++ b/dbrepo-metadata-service/metrics.md @@ -59,8 +59,6 @@ | `dbrepo_user_find` | Get user | | `dbrepo_user_modify` | Update user | | `dbrepo_user_password_modify` | Update user password | -| `dbrepo_user_refresh_token` | Refresh token | -| `dbrepo_user_token` | Create token | | `dbrepo_users_list` | List users | | `dbrepo_view_create` | Create view | | `dbrepo_view_delete` | Delete view | diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index 6ee9fa6c9e4a3e7b7d9882197e8a835eca8e6f9c..50016103d83ccfffab65ddc153e6b88074e34e2c 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -194,7 +194,7 @@ public class DatabaseEndpoint extends AbstractEndpoint { mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), @ApiResponse(responseCode = "404", - description = "Failed to fin user/database in metadata database", + description = "Failed to find database in metadata database", content = {@Content( mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), @@ -211,7 +211,7 @@ public class DatabaseEndpoint extends AbstractEndpoint { }) public ResponseEntity<DatabaseBriefDto> refreshTableMetadata(@NotNull @PathVariable("databaseId") Long databaseId, @NotNull Principal principal) throws DataServiceException, - DataServiceConnectionException, DatabaseNotFoundException, SearchServiceException, UserNotFoundException, + DataServiceConnectionException, DatabaseNotFoundException, SearchServiceException, SearchServiceConnectionException, NotAllowedException, QueryNotFoundException, MalformedException, TableNotFoundException { log.debug("endpoint refresh database metadata, databaseId={}", databaseId); @@ -513,7 +513,7 @@ public class DatabaseEndpoint extends AbstractEndpoint { .findFirst(); if (!database.getIsPublic() && !database.getIsSchemaPublic() && optional.isEmpty() && !isSystem(principal)) { log.error("Failed to find database: not public and no access found"); - throw new DatabaseNotFoundException("Failed to find database: not public and no access found"); + throw new NotAllowedException("Failed to find database: not public and no access found"); } /* reduce metadata */ database.setTables(database.getTables() @@ -534,14 +534,16 @@ public class DatabaseEndpoint extends AbstractEndpoint { throw new NotAllowedException("Failed to find database: not public and not authenticated"); } /* reduce metadata */ - database.setTables(database.getTables() - .stream() - .filter(t -> t.getIsPublic() || t.getIsSchemaPublic()) - .toList()); - database.setViews(database.getViews() - .stream() - .filter(v -> v.getIsPublic() || v.getIsSchemaPublic()) - .toList()); + database.getTables() + .removeAll(database.getTables() + .stream() + .filter(t -> !t.getIsPublic() && !t.getIsSchemaPublic()) + .toList()); + database.getViews() + .removeAll(database.getViews() + .stream() + .filter(v -> !v.getIsPublic() && !v.getIsSchemaPublic()) + .toList()); database.setAccesses(List.of()); } final DatabaseDto dto = databaseMapper.databaseToDatabaseDto(database); diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java index fea215194b7e81711187a122fc5a97e6806db079..51f323c30f1581314df88dab86ec2900775c215e 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java @@ -221,12 +221,16 @@ public class UserEndpoint extends AbstractEndpoint { content = {@Content( mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), + @ApiResponse(responseCode = "503", + description = "Failed to modify user at auth service", + content = {@Content( + mediaType = "application/json", + schema = @Schema(implementation = ApiErrorDto.class))}), }) public ResponseEntity<UserBriefDto> modify(@NotNull @PathVariable("userId") UUID userId, @NotNull @Valid @RequestBody UserUpdateDto data, @NotNull Principal principal) throws NotAllowedException, - UserNotFoundException, DatabaseNotFoundException, AuthServiceException, - AuthServiceConnectionException { + UserNotFoundException, AuthServiceException { log.debug("endpoint modify a user, userId={}, data={}", userId, data); final User user = userService.findById(userId); if (!user.getId().equals(getId(principal))) { @@ -276,9 +280,9 @@ public class UserEndpoint extends AbstractEndpoint { }) public ResponseEntity<Void> password(@NotNull @PathVariable("userId") UUID userId, @NotNull @Valid @RequestBody UserPasswordDto data, - @NotNull Principal principal) throws NotAllowedException, AuthServiceException, - AuthServiceConnectionException, UserNotFoundException, DatabaseNotFoundException, DataServiceException, - DataServiceConnectionException, CredentialsInvalidException { + @NotNull Principal principal) throws NotAllowedException, + UserNotFoundException, DatabaseNotFoundException, DataServiceException, + DataServiceConnectionException { log.debug("endpoint modify a user password, userId={}, principal.name={}", userId, principal.getName()); final User user = userService.findById(userId); if (!user.getUsername().equals(principal.getName())) { 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 3fc9c7216e5ad6f84fa530556708a8453eac2bac..a54f616b01e61edad50d85d4b5f0d494c9e429d6 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 @@ -2,8 +2,8 @@ package at.tuwien.validation; import at.tuwien.SortType; import at.tuwien.api.database.table.CreateTableDto; -import at.tuwien.api.database.table.columns.CreateTableColumnDto; import at.tuwien.api.database.table.columns.ColumnTypeDto; +import at.tuwien.api.database.table.columns.CreateTableColumnDto; import at.tuwien.api.identifier.IdentifierSaveDto; import at.tuwien.endpoints.AbstractEndpoint; import at.tuwien.entities.database.AccessType; @@ -43,15 +43,6 @@ public class EndpointValidator extends AbstractEndpoint { this.accessService = accessService; } - public void validateOnlyPrivateDataAccess(Database database, Principal principal, boolean writeAccessOnly) - throws NotAllowedException, UserNotFoundException, AccessNotFoundException { - if (database.getIsPublic()) { - log.trace("database with id {} is public: no access needed", database.getId()); - return; - } - validateOnlyAccess(database, principal, writeAccessOnly); - } - public void validateOnlyPrivateSchemaAccess(Database database, Principal principal, boolean writeAccessOnly) throws NotAllowedException, UserNotFoundException, AccessNotFoundException { if (database.getIsSchemaPublic()) { @@ -61,11 +52,6 @@ public class EndpointValidator extends AbstractEndpoint { validateOnlyAccess(database, principal, writeAccessOnly); } - public void validateOnlyPrivateDataAccess(Database database, Principal principal) throws NotAllowedException, - UserNotFoundException, AccessNotFoundException { - validateOnlyPrivateDataAccess(database, principal, false); - } - public void validateOnlyPrivateSchemaAccess(Database database, Principal principal) throws NotAllowedException, UserNotFoundException, AccessNotFoundException { validateOnlyPrivateSchemaAccess(database, principal, false); @@ -169,17 +155,6 @@ public class EndpointValidator extends AbstractEndpoint { log.error("Validation failed: column {} type serial demands non-null", optional4a.get().getName()); throw new MalformedException("Validation failed: column " + optional4a.get().getName() + " type serial demands non-null"); } - final Optional<CreateTableColumnDto> optional4b = data.getColumns() - .stream() - .filter(c -> c.getType().equals(ColumnTypeDto.SERIAL) && data.getConstraints() - .getUniques() - .stream() - .noneMatch(uk -> uk.size() == 1 && uk.contains(c.getName()))) - .findFirst(); - if (optional4b.isPresent()) { - log.error("Validation failed: column {} type serial demands a unique constraint", optional4b.get().getName()); - throw new MalformedException("Validation failed: column " + optional4b.get().getName() + " type serial demands a unique constraint"); - } } public boolean validateOnlyMineOrWriteAccessOrHasRole(User owner, Principal principal, DatabaseAccess access, String role) { @@ -204,18 +179,6 @@ public class EndpointValidator extends AbstractEndpoint { return false; } - public boolean validateOnlyMineOrReadAccessOrHasRole(User owner, Principal principal, DatabaseAccess access, String role) { - if (validateOnlyMineOrWriteAccessOrHasRole(owner, principal, access, role)) { - return true; - } - if (access.getType().equals(AccessType.READ)) { - log.debug("validation passed: user {} has read access", principal.getName()); - return true; - } - log.debug("validation failed: user {} has insufficient access {} or role", principal.getName(), access.getType()); - return false; - } - @Transactional(readOnly = true) public void validateOnlyOwnerOrWriteAll(Table table, User user) throws NotAllowedException, AccessNotFoundException { diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierStatusTypeDtoConverterUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierStatusTypeDtoConverterUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8c7316b3d15590979652ea4a04498271f068d2fc --- /dev/null +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierStatusTypeDtoConverterUnitTest.java @@ -0,0 +1,42 @@ +package at.tuwien.converters; + +import at.tuwien.api.identifier.IdentifierStatusTypeDto; +import at.tuwien.test.AbstractUnitTest; +import lombok.extern.log4j.Log4j2; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@Log4j2 +@SpringBootTest +public class IdentifierStatusTypeDtoConverterUnitTest extends AbstractUnitTest { + + @Autowired + private IdentifierStatusTypeDtoConverter identifierStatusTypeDtoConverter; + + @BeforeEach + public void beforeEach() { + genesis(); + } + + @Test + public void identifierStatusTypeDtoConverter_succeeds() { + + /* test */ + final IdentifierStatusTypeDto response = identifierStatusTypeDtoConverter.convert(IdentifierStatusTypeDto.DRAFT.getName()); + assertEquals(IdentifierStatusTypeDto.DRAFT, response); + } + + @Test + public void identifierStatusTypeDtoConverter_fails() { + + /* test */ + assertThrows(IllegalArgumentException.class, () -> { + identifierStatusTypeDtoConverter.convert("i_do_not_exist"); + }); + } +} diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierTypeConverterUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierTypeDtoConverterUnitTest.java similarity index 55% rename from dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierTypeConverterUnitTest.java rename to dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierTypeDtoConverterUnitTest.java index b61a39dc0ea244b2e386b7deaca57e3862628af0..98abd668d8ec0e30a0f420682a0c7b7fd3e5704d 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierTypeConverterUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/converters/IdentifierTypeDtoConverterUnitTest.java @@ -8,14 +8,15 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; @Log4j2 @SpringBootTest -public class IdentifierTypeConverterUnitTest extends AbstractUnitTest { +public class IdentifierTypeDtoConverterUnitTest extends AbstractUnitTest { @Autowired - private IdentifierTypeDtoConverter identifierTypeConverter; + private IdentifierTypeDtoConverter identifierTypeDtoConverter; @BeforeEach public void beforeEach() { @@ -23,19 +24,19 @@ public class IdentifierTypeConverterUnitTest extends AbstractUnitTest { } @Test - public void identifierTypeConverter_succeeds() { + public void IdentifierTypeDtoConverter_succeeds() { /* test */ - final IdentifierTypeDto response = identifierTypeConverter.convert(IdentifierTypeDto.DATABASE.getName()); + final IdentifierTypeDto response = identifierTypeDtoConverter.convert(IdentifierTypeDto.DATABASE.getName()); assertEquals(IdentifierTypeDto.DATABASE, response); } @Test - public void identifierTypeConverter_fails() { + public void IdentifierTypeDtoConverter_fails() { /* test */ assertThrows(IllegalArgumentException.class, () -> { - identifierTypeConverter.convert("i_do_not_exist"); + identifierTypeDtoConverter.convert("i_do_not_exist"); }); } } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/AbstractEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/AbstractEndpointUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dfa4924957b9c300aeda92ad2ed305a4dd29b444 --- /dev/null +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/AbstractEndpointUnitTest.java @@ -0,0 +1,94 @@ +package at.tuwien.endpoints; + +import at.tuwien.api.database.AccessTypeDto; +import at.tuwien.api.database.DatabaseAccessDto; +import at.tuwien.api.user.UserDetailsDto; +import at.tuwien.entities.database.Database; +import at.tuwien.entities.database.DatabaseAccess; +import at.tuwien.entities.user.User; +import at.tuwien.exception.*; +import at.tuwien.mapper.MetadataMapper; +import at.tuwien.service.AccessService; +import at.tuwien.service.DatabaseService; +import at.tuwien.service.UserService; +import at.tuwien.test.AbstractUnitTest; +import lombok.extern.log4j.Log4j2; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.test.context.support.WithAnonymousUser; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.security.Principal; +import java.util.List; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@Log4j2 +@SpringBootTest +@ExtendWith(SpringExtension.class) +public class AbstractEndpointUnitTest extends AbstractUnitTest { + + @Autowired + private AccessEndpoint accessEndpoint; + + @BeforeEach + public void beforeEach() { + genesis(); + } + + @Test + public void hasRole_noPrincipal_fails() { + + /* test */ + assertFalse(accessEndpoint.hasRole(null, "some-role")); + } + + @Test + public void hasRole_noRole_fails() { + + /* test */ + assertFalse(accessEndpoint.hasRole(USER_1_PRINCIPAL, null)); + } + + @Test + public void getId_fails() { + + /* test */ + assertNull(accessEndpoint.getId(null)); + } + + @Test + public void getId_noId_fails() { + final Principal principal = new UsernamePasswordAuthenticationToken(UserDetailsDto.builder() + .id(null) // <<< + .build(), null); + + /* test */ + assertThrows(IllegalArgumentException.class, () -> { + accessEndpoint.getId(principal); + }); + } + + @Test + public void getId_incompatible_fails() { + final Principal principal = new UsernamePasswordAuthenticationToken("", null); + + /* test */ + assertThrows(IllegalArgumentException.class, () -> { + accessEndpoint.getId(principal); + }); + } + +} diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/AccessEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/AccessEndpointUnitTest.java index f4a700e859e68f5705475a63dbc66f2afeaeb5c4..376769e3c318eaabc93e2a65def2673d85d3e7d2 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/AccessEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/AccessEndpointUnitTest.java @@ -219,6 +219,26 @@ public class AccessEndpointUnitTest extends AbstractUnitTest { generic_update(USER_1_PRINCIPAL, USER_1, USER_2_ID, USER_2, DATABASE_1_USER_2_WRITE_OWN_ACCESS); } + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"update-database-access"}) + public void update_ownerNoAccess_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_update(USER_1_PRINCIPAL, USER_1, USER_1_ID, null, null); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"update-database-access"}) + public void update_ownerNoWriteAllAccess_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_update(USER_1_PRINCIPAL, USER_1, USER_LOCAL_ADMIN_ID, USER_LOCAL, null); + }); + } + @Test @WithAnonymousUser public void revoke_anonymous_fails() { @@ -249,6 +269,26 @@ public class AccessEndpointUnitTest extends AbstractUnitTest { }); } + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-database-access"}) + public void revoke_ownerNoAccess_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_revoke(USER_1_PRINCIPAL, USER_1, USER_1_ID, null); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-database-access"}) + public void revoke_ownerNoWriteAllAccess_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_revoke(USER_1_PRINCIPAL, USER_1, USER_LOCAL_ADMIN_ID, USER_LOCAL); + }); + } + @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-database-access"}) public void revoke_succeeds() throws NotAllowedException, DataServiceException, DataServiceConnectionException, diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ContainerEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ContainerEndpointUnitTest.java index 98ece39e1e78b5a2c2719974daf0a9443cd9c2ac..00185d9ea134c33eba73ba7c24a02ff2d606ab1d 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ContainerEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ContainerEndpointUnitTest.java @@ -1,12 +1,14 @@ package at.tuwien.endpoints; -import at.tuwien.api.container.CreateContainerDto; -import at.tuwien.test.AbstractUnitTest; import at.tuwien.api.container.ContainerBriefDto; import at.tuwien.api.container.ContainerDto; +import at.tuwien.api.container.CreateContainerDto; import at.tuwien.entities.container.Container; -import at.tuwien.exception.*; +import at.tuwien.exception.ContainerAlreadyExistsException; +import at.tuwien.exception.ContainerNotFoundException; +import at.tuwien.exception.ImageNotFoundException; import at.tuwien.service.impl.ContainerServiceImpl; +import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -14,6 +16,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.test.context.support.WithAnonymousUser; @@ -52,19 +55,23 @@ public class ContainerEndpointUnitTest extends AbstractUnitTest { } @Test - @WithMockUser(username = USER_1_USERNAME, authorities = {"find-container"}) - public void findById_hasRole_succeeds() throws ContainerNotFoundException { + @WithMockUser(username = USER_1_USERNAME) + public void findById_succeeds() throws ContainerNotFoundException { /* test */ findById_generic(CONTAINER_1_ID, CONTAINER_1, USER_1_PRINCIPAL); } @Test - @WithMockUser(username = USER_4_USERNAME) - public void findById_noRole_succeeds() throws ContainerNotFoundException { + @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME) + public void findById_system_succeeds() throws ContainerNotFoundException { /* test */ - findById_generic(CONTAINER_1_ID, CONTAINER_1, USER_4_PRINCIPAL); + final ResponseEntity<ContainerDto> response = findById_generic(CONTAINER_1_ID, CONTAINER_1, USER_LOCAL_ADMIN_PRINCIPAL); + final HttpHeaders headers = response.getHeaders() ; + assertEquals(List.of(CONTAINER_1_PRIVILEGED_USERNAME), headers.get("X-Username")); + assertEquals(List.of(CONTAINER_1_PRIVILEGED_PASSWORD), headers.get("X-Password")); + assertEquals(List.of("X-Username X-Password"), headers.get("Access-Control-Expose-Headers")); } @Test @@ -171,7 +178,7 @@ public class ContainerEndpointUnitTest extends AbstractUnitTest { /* ## GENERIC TEST CASES ## */ /* ################################################################################################### */ - public void findById_generic(Long containerId, Container container, Principal principal) + public ResponseEntity<ContainerDto> findById_generic(Long containerId, Container container, Principal principal) throws ContainerNotFoundException { /* mock */ @@ -182,6 +189,7 @@ public class ContainerEndpointUnitTest extends AbstractUnitTest { final ResponseEntity<ContainerDto> response = containerEndpoint.findById(containerId, principal); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); + return response; } public void delete_generic(Long containerId, Container container) throws ContainerNotFoundException { diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java index f5db6bf03e7804abf81e77f1adf45bf35c288142..bfe225b87cfb44e5febf617980f6c65eda7509f2 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java @@ -4,7 +4,6 @@ import at.tuwien.api.database.*; import at.tuwien.entities.database.Database; import at.tuwien.entities.user.User; import at.tuwien.exception.*; -import at.tuwien.gateway.KeycloakGateway; import at.tuwien.service.*; import at.tuwien.service.impl.DatabaseServiceImpl; import at.tuwien.test.AbstractUnitTest; @@ -42,9 +41,6 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @MockBean private AccessService accessService; - @MockBean - private KeycloakGateway keycloakGateway; - @MockBean private ContainerService containerService; @@ -144,7 +140,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void refreshTableMetadata_anonymous_succeeds() { + public void refreshTableMetadata_anonymous_fails() { /* test */ assertThrows(AccessDeniedException.class, () -> { @@ -154,7 +150,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME) - public void refreshTableMetadata_noRole_succeeds() { + public void refreshTableMetadata_noRole_fails() { /* test */ assertThrows(AccessDeniedException.class, () -> { @@ -353,7 +349,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"modify-database-visibility"}) public void visibility_hasRole_succeeds() throws NotAllowedException, UserNotFoundException, - DatabaseNotFoundException, SearchServiceException, SearchServiceConnectionException{ + DatabaseNotFoundException, SearchServiceException, SearchServiceConnectionException { final DatabaseModifyVisibilityDto request = DatabaseModifyVisibilityDto.builder() .isPublic(true) .build(); @@ -545,7 +541,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void findById_anonymous_fails() { + public void findById_anonymousPrivateSchemaNoAccess_fails() { /* test */ assertThrows(NotAllowedException.class, () -> { @@ -555,40 +551,51 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void findById_anonymousNotFound_fails() { + public void findById_anonymousPublicSchemaNoAccess_succeeds() throws UserNotFoundException, NotAllowedException, + DataServiceException, DatabaseNotFoundException, ExchangeNotFoundException, DataServiceConnectionException { /* test */ - assertThrows(DatabaseNotFoundException.class, () -> { - findById_generic(DATABASE_1_ID, null, null); - }); + final DatabaseDto database = findById_generic(DATABASE_2_ID, DATABASE_2, null); + assertEquals(3, database.getTables().size()); + assertEquals(1, database.getViews().size()); + assertEquals(0, database.getAccesses().size()); } @Test - @WithMockUser(username = USER_1_USERNAME, authorities = {"find-database"}) - public void findById_hasRole_succeeds() throws DataServiceException, DataServiceConnectionException, - DatabaseNotFoundException, ExchangeNotFoundException, UserNotFoundException, NotAllowedException { - - /* pre-condition */ - assertTrue(DATABASE_3_PUBLIC); + @WithAnonymousUser + public void findById_anonymousPrivateSchemaNoAccessSystem_succeeds() throws UserNotFoundException, + NotAllowedException, DataServiceException, DatabaseNotFoundException, ExchangeNotFoundException, + DataServiceConnectionException { /* test */ - findById_generic(DATABASE_3_ID, DATABASE_3, USER_1_PRINCIPAL); + final DatabaseDto database = findById_generic(DATABASE_1_ID, DATABASE_1, USER_LOCAL_ADMIN_PRINCIPAL); + assertEquals(2, database.getTables().size()); + assertEquals(3, database.getViews().size()); + assertEquals(3, database.getAccesses().size()); } @Test - @WithMockUser(username = USER_1_USERNAME, authorities = {"find-database"}) - public void findById_hasRoleForeign_succeeds() throws DataServiceException, DataServiceConnectionException, - DatabaseNotFoundException, ExchangeNotFoundException, UserNotFoundException, NotAllowedException { + @WithAnonymousUser + public void findById_privateSchema_fails() { - /* pre-condition */ - assertTrue(DATABASE_3_PUBLIC); + /* test */ + assertThrows(NotAllowedException.class, () -> { + findById_generic(DATABASE_1_ID, DATABASE_1, null); + }); + } + + @Test + @WithAnonymousUser + public void findById_anonymousNotFound_fails() { /* test */ - findById_generic(DATABASE_3_ID, DATABASE_3, USER_1_PRINCIPAL); + assertThrows(DatabaseNotFoundException.class, () -> { + findById_generic(DATABASE_1_ID, null, null); + }); } @Test - @WithMockUser(username = USER_1_USERNAME, authorities = {"find-database"}) + @WithMockUser(username = USER_1_USERNAME) public void findById_ownerSeesAccessRights_succeeds() throws DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, ExchangeNotFoundException, UserNotFoundException, NotAllowedException { @@ -597,10 +604,10 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { .thenReturn(List.of(DATABASE_1_USER_1_WRITE_ALL_ACCESS, DATABASE_1_USER_2_READ_ACCESS)); /* test */ - final DatabaseDto response = findById_generic(DATABASE_1_ID, DATABASE_1, USER_1_PRINCIPAL); - final List<DatabaseAccessDto> accessList = response.getAccesses(); - assertNotNull(accessList); - assertEquals(3, accessList.size()); + final DatabaseDto database = findById_generic(DATABASE_1_ID, DATABASE_1, USER_1_PRINCIPAL); + assertEquals(4, database.getTables().size()); + assertEquals(3, database.getViews().size()); + assertEquals(3, database.getAccesses().size()); } @Test diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java index 3b06b974d8a5922c3c929fe3747264d87b1be3f2..419393b485096b84f6495bfcd6ce2910e0c9ae46 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java @@ -124,10 +124,19 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest { public static Stream<Arguments> findAll_anonymousFilterDatabase_parameters() { return Stream.of( - Arguments.arguments("dbid", DATABASE_1_ID, null, null, null, 1), - Arguments.arguments("qid", DATABASE_1_ID, QUERY_1_ID, null, null, 0), - Arguments.arguments("vid", DATABASE_1_ID, null, VIEW_1_ID, null, 0), - Arguments.arguments("tid", DATABASE_1_ID, null, null, TABLE_1_ID, 0) + Arguments.arguments("dbid", DATABASE_1_ID, null, null, null, null, 1), + Arguments.arguments("qid", DATABASE_1_ID, QUERY_1_ID, null, null, null, 0), + Arguments.arguments("vid", DATABASE_1_ID, null, VIEW_1_ID, null, null, 0), + Arguments.arguments("tid", DATABASE_1_ID, null, null, TABLE_1_ID, null, 0), + Arguments.arguments("status_published", DATABASE_1_ID, null, null, null, "PUBLISHED", 1), + Arguments.arguments("status_draft", DATABASE_1_ID, null, null, null, "DRAFT", 0) + ); + } + + public static Stream<Arguments> findAll_filterSubset_parameters() { + return Stream.of( + Arguments.arguments("status_published", DATABASE_2_ID, null, null, null, "PUBLISHED", 0), + Arguments.arguments("status_draft", DATABASE_2_ID, null, null, null, "DRAFT", 1) ); } @@ -201,7 +210,8 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest { @ParameterizedTest @MethodSource("findAll_anonymousFilterDatabase_parameters") @WithAnonymousUser - public void findAll_anonymousFilterDatabase_succeeds(String name, Long databaseId, Long queryId, Long viewId, Long tableId, + public void findAll_anonymousFilterDatabase_succeeds(String name, Long databaseId, Long queryId, Long viewId, + Long tableId, IdentifierStatusTypeDto status, Integer expectedSize) throws ViewNotFoundException, TableNotFoundException, DatabaseNotFoundException { @@ -218,7 +228,26 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest { } /* test */ - final ResponseEntity<?> response = identifierEndpoint.findAll(IdentifierTypeDto.DATABASE, null, databaseId, queryId, viewId, tableId, "application/json", null); + final ResponseEntity<?> response = identifierEndpoint.findAll(IdentifierTypeDto.DATABASE, status, databaseId, queryId, viewId, tableId, "application/json", null); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); + final List<IdentifierBriefDto> identifiers = (List<IdentifierBriefDto>) response.getBody(); + assertNotNull(identifiers); + assertEquals(expectedSize, identifiers.size()); + } + + @ParameterizedTest + @MethodSource("findAll_filterSubset_parameters") + @WithMockUser(username = USER_2_USERNAME) + public void findAll_filterSubset_succeeds(String name, Long databaseId, Long queryId, Long viewId, Long tableId, + IdentifierStatusTypeDto status, Integer expectedSize) { + + /* mock */ + when(identifierService.findAll()) + .thenReturn(List.of(IDENTIFIER_1, IDENTIFIER_2, IDENTIFIER_3, IDENTIFIER_4, IDENTIFIER_5, IDENTIFIER_6, IDENTIFIER_7)); + + /* test */ + final ResponseEntity<?> response = identifierEndpoint.findAll(IdentifierTypeDto.SUBSET, status, databaseId, queryId, viewId, tableId, "application/json", USER_2_PRINCIPAL); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); final List<IdentifierBriefDto> identifiers = (List<IdentifierBriefDto>) response.getBody(); @@ -230,7 +259,8 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest { @MethodSource("findAll_anonymousFilterDatabase_parameters") @WithAnonymousUser public void findAll_wrongPrincipalFilterDatabase_succeeds(String name, Long databaseId, Long queryId, Long viewId, - Long tableId, Integer expectedSize) + Long tableId, IdentifierStatusTypeDto status, + Integer expectedSize) throws ViewNotFoundException, TableNotFoundException, DatabaseNotFoundException { /* mock */ @@ -246,7 +276,7 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest { } /* test */ - final ResponseEntity<?> response = identifierEndpoint.findAll(IdentifierTypeDto.DATABASE, null, databaseId, queryId, viewId, tableId, "application/json", USER_2_PRINCIPAL); + final ResponseEntity<?> response = identifierEndpoint.findAll(IdentifierTypeDto.DATABASE, status, databaseId, queryId, viewId, tableId, "application/json", USER_2_PRINCIPAL); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); final List<IdentifierBriefDto> identifiers = (List<IdentifierBriefDto>) response.getBody(); @@ -334,6 +364,75 @@ public class IdentifierEndpointUnitTest extends AbstractUnitTest { assertEquals(1, identifiers.size()); } + @Test + @WithAnonymousUser + public void find_textCsvDatabase_fails() throws IdentifierNotFoundException { + + /* mock */ + when(identifierService.find(IDENTIFIER_1_ID)) + .thenReturn(IDENTIFIER_1); + + /* test */ + assertThrows(FormatNotAvailableException.class, () -> { + identifierEndpoint.find(IDENTIFIER_1_ID, "text/csv", null); + }); + } + + @Test + @WithAnonymousUser + public void find_draft_fails() throws IdentifierNotFoundException { + + /* mock */ + when(identifierService.find(IDENTIFIER_5_ID)) + .thenReturn(IDENTIFIER_5); + + /* test */ + assertThrows(NotAllowedException.class, () -> { + identifierEndpoint.find(IDENTIFIER_5_ID, "application/json", null); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME) + public void find_draftNotOwner_fails() throws IdentifierNotFoundException { + + /* mock */ + when(identifierService.find(IDENTIFIER_5_ID)) + .thenReturn(IDENTIFIER_5); + + /* test */ + assertThrows(NotAllowedException.class, () -> { + identifierEndpoint.find(IDENTIFIER_5_ID, "application/json", USER_1_PRINCIPAL); + }); + } + + @Test + @WithMockUser(username = USER_2_USERNAME) + public void find_draft_succeeds() throws IdentifierNotFoundException, MalformedException, NotAllowedException, + DataServiceException, QueryNotFoundException, DataServiceConnectionException, FormatNotAvailableException { + + /* mock */ + when(identifierService.find(IDENTIFIER_5_ID)) + .thenReturn(IDENTIFIER_5); + + /* test */ + identifierEndpoint.find(IDENTIFIER_5_ID, "application/json", USER_2_PRINCIPAL); + } + + @Test + @WithAnonymousUser + public void find_defaultHtmlRespondsJson_succeeds() throws IdentifierNotFoundException, MalformedException, + NotAllowedException, DataServiceException, QueryNotFoundException, DataServiceConnectionException, + FormatNotAvailableException { + + /* mock */ + when(identifierService.find(IDENTIFIER_1_ID)) + .thenReturn(IDENTIFIER_1); + + /* test */ + identifierEndpoint.find(IDENTIFIER_1_ID, "text/html", null); + } + @Test @WithMockUser(username = USER_4_USERNAME) public void find_json0_succeeds() throws IOException, MalformedException, DataServiceException, 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 4f1a3da45c87922aabd73ee6e75b1cca3160dd62..d1434ef9e4035cd13d81a4f12ec68bad71683bf1 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 @@ -1,7 +1,7 @@ package at.tuwien.endpoints; -import at.tuwien.api.database.ViewBriefDto; import at.tuwien.api.database.CreateViewDto; +import at.tuwien.api.database.ViewBriefDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.ViewUpdateDto; import at.tuwien.entities.database.Database; @@ -21,6 +21,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.AccessDeniedException; @@ -173,6 +174,25 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { find_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); } + @Test + @WithMockUser(username = USER_2_USERNAME) + public void find_publicSystem_succeeds() throws UserNotFoundException, DatabaseNotFoundException, + AccessNotFoundException, ViewNotFoundException { + + /* test */ + final ResponseEntity<ViewDto> response = find_generic(DATABASE_3_ID, DATABASE_3, USER_LOCAL_ADMIN_PRINCIPAL, + USER_LOCAL_ADMIN_ID, null, null); + final HttpHeaders headers = response.getHeaders(); + assertEquals(List.of(CONTAINER_1_PRIVILEGED_USERNAME), headers.get("X-Username")); + assertEquals(List.of(CONTAINER_1_PRIVILEGED_PASSWORD), headers.get("X-Password")); + assertEquals(List.of(CONTAINER_1_HOST), headers.get("X-Host")); + assertEquals(List.of("" + CONTAINER_1_PORT), headers.get("X-Port")); + assertEquals(List.of(IMAGE_1_JDBC), headers.get("X-Type")); + assertEquals(List.of(DATABASE_3_INTERNALNAME), headers.get("X-Database")); + assertEquals(List.of(VIEW_5_INTERNAL_NAME), headers.get("X-View")); + assertEquals(List.of("X-Username X-Password X-Host X-Port X-Type X-Database X-View"), headers.get("Access-Control-Expose-Headers")); + } + @Test @WithMockUser(username = USER_2_USERNAME) public void find_publicHasRoleHasAccess_succeeds() throws UserNotFoundException, DatabaseNotFoundException, @@ -494,9 +514,9 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { assertEquals(VIEW_1_NAME, response.getBody().getName()); } - protected void find_generic(Long databaseId, Database database, Principal principal, UUID userId, User user, - DatabaseAccess access) throws DatabaseNotFoundException, UserNotFoundException, - AccessNotFoundException, ViewNotFoundException { + protected ResponseEntity<ViewDto> find_generic(Long databaseId, Database database, Principal principal, + UUID userId, User user, DatabaseAccess access) + throws DatabaseNotFoundException, UserNotFoundException, AccessNotFoundException, ViewNotFoundException { /* mock */ when(databaseService.findById(databaseId)) @@ -514,18 +534,18 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { when(userService.findById(userId)) .thenReturn(user); when(viewService.findById(any(Database.class), anyLong())) - .thenReturn(VIEW_1); + .thenReturn(VIEW_5); } else { when(viewService.findById(any(Database.class), anyLong())) - .thenReturn(VIEW_1); + .thenReturn(VIEW_5); } /* test */ - final ResponseEntity<ViewDto> response = viewEndpoint.find(databaseId, VIEW_1_ID, USER_1_PRINCIPAL); + final ResponseEntity<ViewDto> response = viewEndpoint.find(databaseId, VIEW_5_ID, principal); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); - assertEquals(VIEW_1_ID, response.getBody().getId()); - assertEquals(VIEW_1_NAME, response.getBody().getName()); + assertEquals(VIEW_5_ID, response.getBody().getId()); + return response; } protected void delete_generic(Long databaseId, Database database, Long viewId, View view, Principal principal, diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayIntegrationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e72cd7fa7591a7e641c74df6eab07845b0a193ea --- /dev/null +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayIntegrationTest.java @@ -0,0 +1,114 @@ +package at.tuwien.gateway; + +import at.tuwien.exception.UserNotFoundException; +import at.tuwien.gateway.impl.KeycloakGatewayImpl; +import at.tuwien.test.AbstractUnitTest; +import at.tuwien.utils.KeycloakUtils; +import dasniko.testcontainers.keycloak.KeycloakContainer; +import lombok.extern.log4j.Log4j2; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.images.PullPolicy; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +@Log4j2 +@SpringBootTest +@Testcontainers +@ExtendWith(SpringExtension.class) +public class KeycloakGatewayIntegrationTest extends AbstractUnitTest { + + @Autowired + private KeycloakGatewayImpl keycloakGateway; + + @Autowired + private KeycloakUtils keycloakUtils; + + @BeforeEach + public void beforeEach() { + genesis(); + /* auth service */ + keycloakUtils.deleteUser(USER_1_USERNAME); + } + + @Container + private static KeycloakContainer keycloakContainer = new KeycloakContainer(KEYCLOAK_IMAGE) + .withImagePullPolicy(PullPolicy.alwaysPull()) + .withAdminUsername("admin") + .withAdminPassword("admin") + .withRealmImportFile("./init/dbrepo-realm.json") + .withEnv("KC_HOSTNAME_STRICT_HTTPS", "false"); + + @DynamicPropertySource + static void keycloakProperties(DynamicPropertyRegistry registry) { + final String authServiceEndpoint = "http://localhost:" + keycloakContainer.getMappedPort(8080); + log.trace("set auth endpoint: {}", authServiceEndpoint); + registry.add("dbrepo.endpoints.authService", () -> authServiceEndpoint); + } + + @Test + public void deleteUser_succeeds() throws UserNotFoundException { + + /* mock */ + keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST); + + /* test */ + keycloakGateway.deleteUser(keycloakUtils.getUserId(USER_1_USERNAME)); + } + + @Test + public void deleteUser_notFound_fails() { + + /* test */ + assertThrows(UserNotFoundException.class, () -> { + keycloakGateway.deleteUser(USER_1_ID); + }); + } + + @Test + public void findByUsername_succeeds() throws UserNotFoundException { + + /* mock */ + keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST); + + /* test */ + keycloakGateway.findByUsername(USER_1_USERNAME); + } + + @Test + public void findByUsername_notFound_fails() { + + /* test */ + assertThrows(UserNotFoundException.class, () -> { + keycloakGateway.findByUsername(USER_1_USERNAME); + }); + } + + @Test + public void updateUserCredentials_succeeds() throws UserNotFoundException { + + /* mock */ + keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST); + + /* test */ + keycloakGateway.updateUserCredentials(keycloakUtils.getUserId(USER_1_USERNAME), USER_1_PASSWORD_DTO); + } + + @Test + public void updateUserCredentials_notFound_fails() { + + /* test */ + assertThrows(UserNotFoundException.class, () -> { + keycloakGateway.updateUserCredentials(keycloakUtils.getUserId(USER_1_USERNAME), USER_1_PASSWORD_DTO); + }); + } + +} diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayUnitTest.java deleted file mode 100644 index cbb607792eef06e4700d00cd43aefc7a1777d11e..0000000000000000000000000000000000000000 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/KeycloakGatewayUnitTest.java +++ /dev/null @@ -1,195 +0,0 @@ -package at.tuwien.gateway; - -import at.tuwien.api.keycloak.TokenDto; -import at.tuwien.exception.AuthServiceConnectionException; -import at.tuwien.exception.AuthServiceException; -import at.tuwien.exception.UserNotFoundException; -import at.tuwien.gateway.impl.KeycloakGatewayImpl; -import at.tuwien.test.AbstractUnitTest; -import lombok.extern.log4j.Log4j2; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.client.RestTemplate; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.*; - -@Log4j2 -@SpringBootTest -@ExtendWith(SpringExtension.class) -public class KeycloakGatewayUnitTest extends AbstractUnitTest { - - @MockBean - @Qualifier("keycloakRestTemplate") - private RestTemplate keycloakRestTemplate; - - @MockBean - @Qualifier("restTemplate") - private RestTemplate restTemplate; - - @Autowired - private KeycloakGatewayImpl keycloakGateway; - - @Test - public void deleteUser_fails() { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - when(keycloakRestTemplate.exchange(anyString(), eq(HttpMethod.DELETE), any(HttpEntity.class), eq(Void.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .build()); - - /* test */ - assertThrows(AuthServiceException.class, () -> { - keycloakGateway.deleteUser(USER_1_ID); - }); - } - - @Test - public void deleteUser_succeeds() throws UserNotFoundException, AuthServiceException, - AuthServiceConnectionException { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - when(keycloakRestTemplate.exchange(anyString(), eq(HttpMethod.DELETE), any(HttpEntity.class), eq(Void.class))) - .thenReturn(ResponseEntity.status(HttpStatus.NO_CONTENT) - .build()); - - /* test */ - keycloakGateway.deleteUser(USER_1_ID); - } - - @Test - public void deleteUser_notFound_fails() { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - doThrow(HttpClientErrorException.NotFound.class) - .when(keycloakRestTemplate) - .exchange(anyString(), eq(HttpMethod.DELETE), any(HttpEntity.class), eq(Void.class)); - - /* test */ - assertThrows(UserNotFoundException.class, () -> { - keycloakGateway.deleteUser(USER_1_ID); - }); - } - - @Test - public void deleteUser_unexpected_fails() { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - doThrow(HttpClientErrorException.Conflict.class) - .when(keycloakRestTemplate) - .exchange(anyString(), eq(HttpMethod.DELETE), any(HttpEntity.class), eq(Void.class)); - - /* test */ - assertThrows(AuthServiceException.class, () -> { - keycloakGateway.deleteUser(USER_1_ID); - }); - } - - @Test - public void deleteUser_connection_fails() { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - doThrow(HttpServerErrorException.class) - .when(keycloakRestTemplate) - .exchange(anyString(), eq(HttpMethod.DELETE), any(HttpEntity.class), eq(Void.class)); - - /* test */ - assertThrows(AuthServiceConnectionException.class, () -> { - keycloakGateway.deleteUser(USER_1_ID); - }); - } - - @Test - public void updateUserCredentials_succeeds() throws AuthServiceException, AuthServiceConnectionException, - UserNotFoundException { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - when(keycloakRestTemplate.exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) - .thenReturn(ResponseEntity.status(HttpStatus.NO_CONTENT) - .build()); - - /* test */ - keycloakGateway.updateUserCredentials(USER_1_ID, USER_1_PASSWORD_DTO); - } - - @Test - public void updateUserCredentials_fails() { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - when(keycloakRestTemplate.exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .build()); - - /* test */ - assertThrows(AuthServiceException.class, () -> { - keycloakGateway.updateUserCredentials(USER_1_ID, USER_1_PASSWORD_DTO); - }); - } - - @Test - public void updateUserCredentials_connection_fails() { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - doThrow(HttpServerErrorException.class) - .when(keycloakRestTemplate) - .exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class)); - - /* test */ - assertThrows(AuthServiceConnectionException.class, () -> { - keycloakGateway.updateUserCredentials(USER_1_ID, USER_1_PASSWORD_DTO); - }); - } - - @Test - public void updateUserCredentials_unexpected_fails() { - - /* mock */ - when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(TokenDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .body(TOKEN_DTO)); - doThrow(HttpClientErrorException.Conflict.class) - .when(keycloakRestTemplate) - .exchange(anyString(), eq(HttpMethod.PUT), any(HttpEntity.class), eq(Void.class)); - - /* test */ - assertThrows(AuthServiceException.class, () -> { - keycloakGateway.updateUserCredentials(USER_1_ID, USER_1_PASSWORD_DTO); - }); - } - -} 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 7dd25baefca573e20b4dc1a3894bcf97fbf877e4..0365db6c4a09dfaedb742528b3bb08d4784d53f1 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 @@ -9,7 +9,6 @@ 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.test.AbstractUnitTest; import at.tuwien.utils.KeycloakUtils; import dasniko.testcontainers.keycloak.KeycloakContainer; @@ -61,9 +60,6 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest @Autowired private DatabaseRepository databaseRepository; - @Autowired - private AuthenticationService authenticationService; - @Autowired private KeycloakGateway keycloakGateway; @@ -97,7 +93,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest public void findById_database_basicUser_succeeds() throws Exception { /* mock */ - keycloakUtils.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST); /* test */ this.mockMvc.perform(get("/api/database/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) @@ -112,7 +108,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest public void findById_database_basicAdmin_succeeds() throws Exception { /* pre condition */ - keycloakUtils.createUser(USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.createUser(USER_LOCAL_ADMIN_ID, USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); /* test */ this.mockMvc.perform(get("/api/database/1").with(httpBasic(USER_LOCAL_ADMIN_USERNAME, USER_LOCAL_ADMIN_PASSWORD))) @@ -127,7 +123,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest public void findById_database_bearerAdmin_succeeds() throws Exception { /* pre condition */ - keycloakUtils.createUser(USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.createUser(USER_LOCAL_ADMIN_ID, USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); final TokenDto jwt = keycloakGateway.obtainUserToken(USER_LOCAL_ADMIN_USERNAME, USER_LOCAL_ADMIN_PASSWORD); /* test */ @@ -143,7 +139,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest public void findById_table_bearerAdmin_succeeds() throws Exception { /* pre condition */ - keycloakUtils.createUser(USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.createUser(USER_LOCAL_ADMIN_ID, USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); final TokenDto jwt = keycloakGateway.obtainUserToken(USER_LOCAL_ADMIN_USERNAME, USER_LOCAL_ADMIN_PASSWORD); @@ -160,7 +156,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest public void findById_table_basicUser_succeeds() throws Exception { /* mock */ - keycloakUtils.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST); /* test */ this.mockMvc.perform(get("/api/database/1/table/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) @@ -175,7 +171,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest public void findById_table_basicAdmin_succeeds() throws Exception { /* mock */ - keycloakUtils.createUser(USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.createUser(USER_LOCAL_ADMIN_ID, USER_LOCAL_KEYCLOAK_SIGNUP_REQUEST); /* test */ this.mockMvc.perform(get("/api/database/1/table/1").with(httpBasic(USER_LOCAL_ADMIN_USERNAME, USER_LOCAL_ADMIN_PASSWORD))) @@ -190,7 +186,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest public void findById_view_basicUser_succeeds() throws Exception { /* mock */ - keycloakUtils.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST); /* test */ this.mockMvc.perform(get("/api/database/1/view/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) @@ -205,7 +201,7 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest public void findById_container_basicUser_succeeds() throws Exception { /* mock */ - keycloakUtils.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST); /* test */ this.mockMvc.perform(get("/api/container/1").with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java index 61655c6f292df8627f215b2558235e2084230dc6..790262c7399d36fb0d9a3cf6103f7899300daffb 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java @@ -26,7 +26,6 @@ import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; -import org.springframework.security.test.context.support.WithAnonymousUser; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; @@ -594,30 +593,14 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest { } /* test */ - for (String metric : List.of("dbrepo_user_refresh_token", "dbrepo_users_list", - "dbrepo_user_find", "dbrepo_user_modify", "dbrepo_user_password_modify")) { + for (String metric : List.of("dbrepo_users_list", "dbrepo_user_find", "dbrepo_user_modify", + "dbrepo_user_password_modify")) { assertThat(registry) .hasObservationWithNameEqualTo(metric); } generic_openApiDocs(UserEndpoint.class); } - @Test - @WithAnonymousUser - public void prometheusUserEndpoint2_succeeds() { - - /* mock */ - try { - userEndpoint.create(USER_1_SIGNUP_REQUEST_DTO); - } catch (Exception e) { - /* ignore */ - } - - /* test */ - assertThat(registry) - .hasObservationWithNameEqualTo("dbrepo_user_token"); - } - @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"create-database-view", "delete-database-view"}) public void prometheusViewEndpoint_succeeds() { diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/AuthenticationServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/AuthenticationServiceIntegrationTest.java index 712dc951c833b4daf3673b8ca88f3208f4a47c76..d655a25cf1f599b2e92a9fd426cfa343747a3fe1 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/AuthenticationServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/AuthenticationServiceIntegrationTest.java @@ -44,7 +44,7 @@ public class AuthenticationServiceIntegrationTest extends AbstractUnitTest { } @Container - private static KeycloakContainer keycloakContainer = new KeycloakContainer("quay.io/keycloak/keycloak:26.0") + private static KeycloakContainer keycloakContainer = new KeycloakContainer(KEYCLOAK_IMAGE) .withImagePullPolicy(PullPolicy.alwaysPull()) .withAdminUsername("admin") .withAdminPassword("admin") @@ -53,7 +53,9 @@ public class AuthenticationServiceIntegrationTest extends AbstractUnitTest { @DynamicPropertySource static void keycloakProperties(DynamicPropertyRegistry registry) { - registry.add("dbrepo.endpoints.authService", () -> "http://localhost:" + keycloakContainer.getMappedPort(8080)); + final String authServiceEndpoint = "http://localhost:" + keycloakContainer.getMappedPort(8080); + log.trace("set auth endpoint: {}", authServiceEndpoint); + registry.add("dbrepo.endpoints.authService", () -> authServiceEndpoint); } @Test @@ -61,14 +63,10 @@ public class AuthenticationServiceIntegrationTest extends AbstractUnitTest { AuthServiceException, AuthServiceConnectionException, CredentialsInvalidException { /* mock */ - try { - keycloakGateway.deleteUser(UUID.fromString(keycloakGateway.findByUsername(USER_1_USERNAME).getId())); - } catch (Exception e) { - /* ignore */ - } - keycloakUtils.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); + keycloakUtils.deleteUser(USER_1_USERNAME); + keycloakUtils.createUser(USER_1_ID, USER_1_KEYCLOAK_SIGNUP_REQUEST); final User request = User.builder() - .id(UUID.fromString(keycloakGateway.findByUsername(USER_1_USERNAME).getId())) + .keycloakId(UUID.fromString(keycloakGateway.findByUsername(USER_1_USERNAME).getId())) .username(USER_1_USERNAME) .build(); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServicePersistenceTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServicePersistenceTest.java index 7ec6d680e7e046c4028645fbd103e58699acf9c1..e9d6b158ce097fc469694ee1d09e068357120d39 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServicePersistenceTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServicePersistenceTest.java @@ -4,6 +4,7 @@ import at.tuwien.api.user.UserPasswordDto; import at.tuwien.api.user.UserUpdateDto; import at.tuwien.entities.user.User; import at.tuwien.exception.*; +import at.tuwien.gateway.KeycloakGateway; import at.tuwien.repository.UserRepository; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; @@ -12,12 +13,14 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; import java.util.List; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.doNothing; @Log4j2 @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @@ -31,6 +34,9 @@ public class UserServicePersistenceTest extends AbstractUnitTest { @Autowired private UserService userService; + @MockBean + private KeycloakGateway keycloakGateway; + @BeforeEach public void beforeEach() { genesis(); @@ -74,7 +80,7 @@ public class UserServicePersistenceTest extends AbstractUnitTest { } @Test - public void modify_succeeds() throws UserNotFoundException, AuthServiceException, AuthServiceConnectionException { + public void modify_succeeds() throws UserNotFoundException, AuthServiceException { final UserUpdateDto request = UserUpdateDto.builder() .firstname(USER_1_FIRSTNAME) .lastname(USER_1_LASTNAME) @@ -84,6 +90,11 @@ public class UserServicePersistenceTest extends AbstractUnitTest { .language("de") .build(); + /* mock */ + doNothing() + .when(keycloakGateway) + .updateUser(USER_1_ID, request); + /* test */ final User response = userService.modify(USER_1, request); assertEquals(USER_1_ID, response.getId()); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java index 91bcdd330cbdaa432bdee4dd1a28a361c6d7902f..4c423aa25b6fd36f82485d836c190c1b2779e12d 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java @@ -94,7 +94,7 @@ public class UserServiceUnitTest extends AbstractUnitTest { } @Test - public void modify_succeeds() throws UserNotFoundException, AuthServiceException, AuthServiceConnectionException { + public void modify_succeeds() throws UserNotFoundException, AuthServiceException { /* mock */ when(userRepository.findById(USER_1_ID)) @@ -109,8 +109,7 @@ public class UserServiceUnitTest extends AbstractUnitTest { } @Test - public void updatePassword_succeeds() throws AuthServiceException, AuthServiceConnectionException, - UserNotFoundException { + public void updatePassword_succeeds() throws UserNotFoundException { /* mock */ doNothing() 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 469280d1cd0f94a7e822040700df1c8e2e6f920f..b3612fcc0fc306892db006bd12aa6ef483cf45a9 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 @@ -2,6 +2,7 @@ package at.tuwien.utils; import at.tuwien.api.keycloak.UserCreateDto; import at.tuwien.config.KeycloakConfig; +import at.tuwien.exception.UserNotFoundException; import at.tuwien.mapper.MetadataMapper; import jakarta.ws.rs.core.Response; import lombok.extern.log4j.Log4j2; @@ -11,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; +import java.util.UUID; @Log4j2 @Component @@ -27,23 +29,35 @@ public class KeycloakUtils { this.metadataMapper = metadataMapper; } - public void createUser(UserCreateDto data) { + public void createUser(UUID ldapId, UserCreateDto data) { + final UserRepresentation user = metadataMapper.userCreateDtoToUserRepresentation(data); + user.singleAttribute("CUSTOM_ID", ldapId.toString()); try (Response response = keycloak.realm(keycloakConfig.getRealm()) .users() - .create(metadataMapper.userCreateDtoToUserRepresentation(data))) { + .create(user)) { if (response.getStatus() != 201) { - log.error("Failed to create user: {}", response.getStatus()); + log.warn("Failed to create user: {}", response.getStatus()); } } log.debug("Created user {} at auth service", data.getUsername()); } + public UUID getUserId(String username) throws UserNotFoundException { + final List<UserRepresentation> users = keycloak.realm(keycloakConfig.getRealm()) + .users() + .search(username); + if (users.isEmpty()) { + throw new UserNotFoundException("Failed to find user: " + username); + } + return UUID.fromString(users.get(0).getId()); + } + public void deleteUser(String username) { final List<UserRepresentation> users = keycloak.realm(keycloakConfig.getRealm()) .users() .search(username); if (users.isEmpty()) { - log.error("Failed to find user"); + log.warn("Failed to find user"); return; } try (Response response = keycloak.realm(keycloakConfig.getRealm()) diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/validator/EndpointValidatorUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/validator/EndpointValidatorUnitTest.java index fe650589addb6ae15cb3d1d4d4b48f801054eca3..486db28e5945737e776da4b8f0aaf6d6d977715e 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/validator/EndpointValidatorUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/validator/EndpointValidatorUnitTest.java @@ -2,8 +2,8 @@ package at.tuwien.validator; import at.tuwien.SortType; import at.tuwien.api.database.table.CreateTableDto; -import at.tuwien.api.database.table.columns.CreateTableColumnDto; import at.tuwien.api.database.table.columns.ColumnTypeDto; +import at.tuwien.api.database.table.columns.CreateTableColumnDto; import at.tuwien.api.identifier.IdentifierSaveDto; import at.tuwien.entities.database.Database; import at.tuwien.entities.user.User; @@ -70,6 +70,14 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest { endpointValidator.validateDataParams(0L, 1L); } + @Test + public void validateOnlyAccess_system_succeeds() throws UserNotFoundException, NotAllowedException, + AccessNotFoundException { + + /* test */ + endpointValidator.validateOnlyAccess(DATABASE_1, USER_LOCAL_ADMIN_PRINCIPAL, false); + } + @Test public void validateDataParams_bothNull_succeeds() throws PaginationException { @@ -222,6 +230,20 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest { endpointValidator.validateOnlyAccessOrPublic(DATABASE_1, USER_1_PRINCIPAL); } + @Test + public void validateOnlyWriteOwnOrWriteAllAccess_succeeds() throws DatabaseNotFoundException, + TableNotFoundException, AccessNotFoundException, NotAllowedException { + + /* mock */ + when(tableService.findById(DATABASE_1, TABLE_1_ID)) + .thenReturn(TABLE_1); + when(accessService.find(eq(DATABASE_1), any(User.class))) + .thenReturn(DATABASE_1_USER_1_WRITE_ALL_ACCESS); + + /* test */ + endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(TABLE_1, USER_1); + } + @Test public void validateOnlyWriteOwnOrWriteAllAccess_privateHasReadAccess_fails() throws DatabaseNotFoundException, TableNotFoundException, AccessNotFoundException { @@ -323,6 +345,20 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest { }); } + @Test + public void validateOnlyPrivateDataHasRole_publicDatabase_succeeds() throws NotAllowedException { + + /* test */ + endpointValidator.validateOnlyPrivateDataHasRole(DATABASE_4, null, "nobody-role"); + } + + @Test + public void validateOnlyPrivateDataHasRole_privateDatabaseHasRole_succeeds() throws NotAllowedException { + + /* test */ + endpointValidator.validateOnlyPrivateDataHasRole(DATABASE_1, USER_1_PRINCIPAL, "find-database"); + } + @Test public void validateOnlyPrivateDataHasRole_privatePrincipalMissing_fails() { @@ -491,6 +527,13 @@ public class EndpointValidatorUnitTest extends AbstractUnitTest { assertTrue(endpointValidator.validatePublicationDate(request)); } + @Test + public void validateOnlyMineOrWriteAccessOrHasRole_succeeds() { + + /* test */ + assertTrue(endpointValidator.validateOnlyMineOrWriteAccessOrHasRole(USER_1, USER_1_PRINCIPAL, null, "find-database")); + } + @Test public void validateOnlyMineOrWriteAccessOrHasRole_noAccess_fails() { 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 56f2003e961a14d09bcd56832437f915cae04dea..fb6df2007f2c5d50ab9ad744b622e248ea158cde 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 @@ -27,7 +27,7 @@ "oauth2DevicePollingInterval" : 5, "enabled" : true, "sslRequired" : "none", - "registrationAllowed" : false, + "registrationAllowed" : true, "registrationEmailAsUsername" : false, "rememberMe" : false, "verifyEmail" : true, @@ -38,6 +38,7 @@ "bruteForceProtected" : false, "permanentLockout" : false, "maxTemporaryLockouts" : 0, + "bruteForceStrategy" : "MULTIPLE", "maxFailureWaitSeconds" : 900, "minimumQuickLoginWaitSeconds" : 60, "waitIncrementSeconds" : 60, @@ -73,7 +74,7 @@ "description" : "${default-system-roles}", "composite" : true, "composites" : { - "realm" : [ "delete-database-view", "update-semantic-unit", "export-query-data", "default-data-steward-roles", "execute-query", "default-user-handling", "delete-table-data", "find-query", "list-database-views", "persist-query", "update-search-index", "delete-database-access", "view-table-history", "create-ontology", "update-ontology", "modify-user-theme", "default-system-roles", "create-semantic-concept", "default-container-handling", "create-container", "create-table", "default-broker-handling", "default-maintenance-handling", "execute-semantic-query", "uma_authorization", "table-semantic-analyse", "list-containers", "check-database-access", "escalated-query-handling", "delete-identifier", "modify-database-owner", "list-tables", "export-table-data", "create-database-access", "delete-container", "re-execute-query", "create-semantic-unit", "escalated-identifier-handling", "system", "update-table-statistic", "escalated-semantics-handling", "default-database-handling", "delete-ontology", "find-database", "find-database-view", "update-semantic-concept", "find-user", "import-database-data", "publish-identifier", "default-roles-dbrepo", "find-foreign-user", "create-database", "create-maintenance-message", "find-maintenance-message", "escalated-container-handling", "default-researcher-roles", "default-identifier-handling", "escalated-user-handling", "modify-user-information", "create-database-view", "update-maintenance-message", "delete-foreign-table", "offline_access", "modify-foreign-table-column-semantics", "delete-maintenance-message", "find-container", "insert-table-data", "modify-identifier-metadata", "modify-database-image", "escalated-broker-handling", "modify-table-column-semantics", "escalated-database-handling", "default-semantics-handling", "update-database-access", "default-query-handling", "find-table", "list-queries", "default-developer-roles", "create-identifier", "escalated-table-handling", "find-identifier", "view-table-data", "list-licenses", "default-table-handling", "list-identifiers", "create-foreign-identifier", "list-databases", "list-ontologies", "modify-database-visibility", "list-maintenance-messages", "delete-table" ] + "realm" : [ "delete-database-view", "update-semantic-unit", "export-query-data", "check-foreign-database-access", "default-data-steward-roles", "execute-query", "default-user-handling", "delete-table-data", "find-query", "list-database-views", "persist-query", "update-search-index", "delete-database-access", "view-table-history", "create-ontology", "update-ontology", "modify-user-theme", "default-system-roles", "create-semantic-concept", "default-container-handling", "create-container", "create-table", "default-broker-handling", "default-maintenance-handling", "execute-semantic-query", "uma_authorization", "table-semantic-analyse", "list-containers", "check-database-access", "escalated-query-handling", "delete-identifier", "modify-database-owner", "list-tables", "export-table-data", "create-database-access", "delete-container", "re-execute-query", "create-semantic-unit", "escalated-identifier-handling", "system", "update-table-statistic", "escalated-semantics-handling", "default-database-handling", "delete-ontology", "find-database", "find-database-view", "update-semantic-concept", "find-user", "import-database-data", "publish-identifier", "default-roles-dbrepo", "find-foreign-user", "create-database", "create-maintenance-message", "find-maintenance-message", "escalated-container-handling", "default-researcher-roles", "default-identifier-handling", "escalated-user-handling", "modify-user-information", "create-database-view", "update-maintenance-message", "delete-foreign-table", "offline_access", "modify-foreign-table-column-semantics", "delete-maintenance-message", "find-container", "insert-table-data", "modify-identifier-metadata", "modify-database-image", "escalated-broker-handling", "modify-table-column-semantics", "escalated-database-handling", "default-semantics-handling", "update-database-access", "default-query-handling", "find-table", "list-queries", "default-developer-roles", "create-identifier", "escalated-table-handling", "find-identifier", "view-table-data", "list-licenses", "default-table-handling", "list-identifiers", "create-foreign-identifier", "list-databases", "list-ontologies", "modify-database-visibility", "list-maintenance-messages", "delete-table" ] }, "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", @@ -146,19 +147,11 @@ "description" : "${default-table-handling}", "composite" : true, "composites" : { - "realm" : [ "modify-table-column-semantics", "list-tables", "update-table-statistic", "find-table", "create-table", "delete-table" ] + "realm" : [ "modify-table-column-semantics", "list-tables", "update-table-statistic", "find-table", "create-table", "delete-table", "update-table" ] }, "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", "attributes" : { } - }, { - "id" : "b0d66d3d-59b4-4aae-aa66-e3d5a49f28e3", - "name" : "view-database-view-data", - "description" : "${view-database-view-data}", - "composite" : false, - "clientRole" : false, - "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", - "attributes" : { } }, { "id" : "f5ea431a-9b2c-4195-bcb4-9511f38e4b44", "name" : "create-database-view", @@ -219,7 +212,7 @@ "description" : "${default-researcher-roles}", "composite" : true, "composites" : { - "realm" : [ "default-table-handling", "default-semantics-handling", "default-container-handling", "default-query-handling", "default-user-handling", "default-database-handling", "default-broker-handling", "default-identifier-handling" ] + "realm" : [ "default-table-handling", "default-semantics-handling", "default-container-handling", "default-query-handling", "default-user-handling", "default-database-handling", "default-broker-handling", "default-identifier-handling", "default-view-handling" ] }, "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", @@ -264,6 +257,14 @@ "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", "attributes" : { } + }, { + "id" : "22449528-00c9-4e86-9400-4b8ae6fd8f4d", + "name" : "modify-view-visibility", + "description" : "${modify-view-visibility}", + "composite" : false, + "clientRole" : false, + "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", + "attributes" : { } }, { "id" : "c12c1f4e-186f-4153-a795-26e79fb623d6", "name" : "create-ontology", @@ -296,6 +297,17 @@ "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", "attributes" : { } + }, { + "id" : "d75e7938-9d5e-4cb3-8c57-18a446867d3a", + "name" : "default-view-handling", + "description" : "${default-view-handling}", + "composite" : true, + "composites" : { + "realm" : [ "delete-database-view", "update-database-view", "create-database-view", "modify-view-visibility", "find-database-view", "list-database-views" ] + }, + "clientRole" : false, + "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", + "attributes" : { } }, { "id" : "535f1484-4514-4d24-8d97-e3f6c11a426b", "name" : "create-container", @@ -390,6 +402,14 @@ "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", "attributes" : { } + }, { + "id" : "6ae766b0-b8b4-4067-a95d-c8576bc4ac77", + "name" : "update-table", + "description" : "${update-table}", + "composite" : false, + "clientRole" : false, + "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", + "attributes" : { } }, { "id" : "64c16bfb-2015-48ad-a23f-637ff24419cb", "name" : "default-query-handling", @@ -401,6 +421,14 @@ "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", "attributes" : { } + }, { + "id" : "b05e9b2b-748d-490b-949b-e78655bf7805", + "name" : "check-foreign-database-access", + "description" : "${check-foreign-database-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", + "attributes" : { } }, { "id" : "c047d521-cec3-4444-86c4-aef098489b7b", "name" : "delete-maintenance-message", @@ -409,6 +437,14 @@ "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", "attributes" : { } + }, { + "id" : "df20b7d1-8d30-4a99-80eb-e8195fab0e76", + "name" : "update-database-view", + "description" : "${update-database-view}", + "composite" : false, + "clientRole" : false, + "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", + "attributes" : { } }, { "id" : "88f82262-be80-4d18-9fb4-5529da031f33", "name" : "system", @@ -522,7 +558,7 @@ "description" : "${default-container-handling}", "composite" : true, "composites" : { - "realm" : [ "find-container", "list-containers" ] + "realm" : [ "find-container" ] }, "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", @@ -902,7 +938,7 @@ "composite" : true, "composites" : { "client" : { - "realm-management" : [ "query-realms", "view-identity-providers", "manage-identity-providers", "manage-authorization", "query-clients", "view-authorization", "view-users", "manage-users", "view-realm", "query-users", "view-clients", "query-groups", "create-client", "manage-clients", "manage-events", "impersonation", "view-events", "manage-realm" ] + "realm-management" : [ "query-realms", "manage-authorization", "manage-identity-providers", "view-identity-providers", "query-clients", "view-authorization", "view-users", "manage-users", "view-realm", "query-users", "view-clients", "create-client", "query-groups", "impersonation", "manage-clients", "manage-events", "view-events", "manage-realm" ] } }, "clientRole" : true, @@ -1203,12 +1239,13 @@ "frontchannelLogout" : false, "protocol" : "openid-connect", "attributes" : { + "realm_client" : "false", "post.logout.redirect.uris" : "+" }, "authenticationFlowBindingOverrides" : { }, "fullScopeAllowed" : false, "nodeReRegistrationTimeout" : 0, - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] }, { "id" : "d3c4a04e-39ce-4549-a34a-11e25774cd96", @@ -1233,6 +1270,7 @@ "frontchannelLogout" : false, "protocol" : "openid-connect", "attributes" : { + "realm_client" : "false", "post.logout.redirect.uris" : "+", "pkce.code.challenge.method" : "S256" }, @@ -1247,7 +1285,7 @@ "consentRequired" : false, "config" : { } } ], - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] }, { "id" : "81ef0f59-a5ca-4be4-a1d1-0c32edf1cfd6", @@ -1270,12 +1308,14 @@ "frontchannelLogout" : false, "protocol" : "openid-connect", "attributes" : { + "realm_client" : "false", + "client.use.lightweight.access.token.enabled" : "true", "post.logout.redirect.uris" : "+" }, "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : false, + "fullScopeAllowed" : true, "nodeReRegistrationTimeout" : 0, - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] }, { "id" : "88694c91-753d-4c44-9740-ec9ac06bba45", @@ -1298,6 +1338,7 @@ "frontchannelLogout" : false, "protocol" : "openid-connect", "attributes" : { + "realm_client" : "true", "post.logout.redirect.uris" : "+" }, "authenticationFlowBindingOverrides" : { }, @@ -1331,6 +1372,7 @@ "frontchannelLogout" : true, "protocol" : "openid-connect", "attributes" : { + "realm_client" : "false", "oidc.ciba.grant.enabled" : "false", "client.secret.creation.time" : "1680085365", "backchannel.logout.session.required" : "true", @@ -1342,6 +1384,38 @@ "fullScopeAllowed" : true, "nodeReRegistrationTimeout" : -1, "protocolMappers" : [ { + "id" : "266edf62-a19a-483b-b594-81428e4af792", + "name" : "orcid", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "ORCID", + "id.token.claim" : "true", + "lightweight.claim" : "false", + "access.token.claim" : "true", + "claim.name" : "orcid", + "jsonType.label" : "String" + } + }, { + "id" : "1a21798a-38b6-4df5-89f0-86942415246f", + "name" : "theme", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "THEME", + "id.token.claim" : "true", + "lightweight.claim" : "false", + "access.token.claim" : "true", + "claim.name" : "theme", + "jsonType.label" : "String" + } + }, { "id" : "da0b27c1-ae2e-4baa-bf78-db233e15c78d", "name" : "preferred_username", "protocol" : "openid-connect", @@ -1355,27 +1429,77 @@ "userinfo.token.claim" : "true" } }, { - "id" : "7c94de93-f60f-487b-b4b7-1891c67f74cc", - "name" : "aud", + "id" : "1bc6a1f4-4be2-439c-8c7f-b3fb0bb9956a", + "name" : "affiliation", "protocol" : "openid-connect", - "protocolMapper" : "oidc-hardcoded-claim-mapper", + "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "claim.value" : "dbrepo", + "introspection.token.claim" : "true", "userinfo.token.claim" : "true", + "user.attribute" : "AFFILIATION", "id.token.claim" : "true", + "lightweight.claim" : "false", "access.token.claim" : "true", - "claim.name" : "aud", - "access.tokenResponse.claim" : "false" + "claim.name" : "affiliation", + "jsonType.label" : "String" } }, { - "id" : "0b4c644f-0cf0-4794-8395-d5d83009dabe", + "id" : "7cbf6dc6-653e-40a9-9974-0e5bf7a363c3", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "70bbd779-d085-4204-ac4b-3a40abab9d88", + "name" : "language", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "LANGUAGE", + "id.token.claim" : "true", + "lightweight.claim" : "false", + "access.token.claim" : "true", + "claim.name" : "language", + "jsonType.label" : "String" + } + }, { + "id" : "b817424d-7f91-43d8-b7d0-6a32582377fb", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "030a1cd9-53d1-4a62-a375-94d50a2dc6fc", "name" : "uid", "protocol" : "openid-connect", "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { + "aggregate.attrs" : "false", "introspection.token.claim" : "true", + "multivalued" : "false", "userinfo.token.claim" : "true", "user.attribute" : "CUSTOM_ID", "id.token.claim" : "true", @@ -1384,9 +1508,26 @@ "claim.name" : "uid", "jsonType.label" : "String" } + }, { + "id" : "c304ed2f-5952-4772-838d-91998a45f154", + "name" : "aud", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-hardcoded-claim-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "claim.value" : "account", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "lightweight.claim" : "false", + "access.token.claim" : "true", + "claim.name" : "aud", + "jsonType.label" : "String", + "access.tokenResponse.claim" : "false" + } } ], - "defaultClientScopes" : [ "roles", "attributes" ], - "optionalClientScopes" : [ "rabbitmq.read:*/*", "web-origins", "acr", "rabbitmq.write:*/*", "address", "phone", "offline_access", "profile", "microprofile-jwt", "email", "rabbitmq.configure:*/*" ] + "defaultClientScopes" : [ "roles", "basic" ], + "optionalClientScopes" : [ "rabbitmq.read:*/*", "web-origins", "acr", "rabbitmq.write:*/*", "address", "phone", "offline_access", "profile", "attributes", "microprofile-jwt", "email", "rabbitmq.configure:*/*" ] }, { "id" : "25741f6b-4867-4138-8238-6345c6ba8702", "clientId" : "rabbitmq-client", @@ -1413,6 +1554,7 @@ "frontchannelLogout" : true, "protocol" : "openid-connect", "attributes" : { + "realm_client" : "false", "oidc.ciba.grant.enabled" : "false", "client.secret.creation.time" : "1680000860", "backchannel.logout.session.required" : "true", @@ -1430,12 +1572,12 @@ "protocolMapper" : "oidc-usermodel-property-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "false", "user.attribute" : "username", "id.token.claim" : "false", "access.token.claim" : "true", "claim.name" : "client_id", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "false" } }, { "id" : "f1afc22d-f595-403b-ba2e-6ab19d98205e", @@ -1444,15 +1586,15 @@ "protocolMapper" : "oidc-hardcoded-claim-mapper", "consentRequired" : false, "config" : { - "claim.value" : "rabbitmq", - "userinfo.token.claim" : "false", "id.token.claim" : "false", "access.token.claim" : "true", "claim.name" : "aud", + "claim.value" : "rabbitmq", + "userinfo.token.claim" : "false", "access.tokenResponse.claim" : "false" } } ], - "defaultClientScopes" : [ "web-origins", "acr", "rabbitmq.tag:management" ], + "defaultClientScopes" : [ "web-origins", "acr", "rabbitmq.tag:management", "basic" ], "optionalClientScopes" : [ "rabbitmq.read:*/*", "rabbitmq.write:*/*", "address", "phone", "offline_access", "profile", "roles", "microprofile-jwt", "email", "rabbitmq.configure:*/*" ] }, { "id" : "cfffd5d0-aa19-4057-8ca0-f2c51ca0e930", @@ -1475,6 +1617,7 @@ "frontchannelLogout" : false, "protocol" : "openid-connect", "attributes" : { + "realm_client" : "true", "post.logout.redirect.uris" : "+" }, "authenticationFlowBindingOverrides" : { }, @@ -1505,11 +1648,13 @@ "frontchannelLogout" : false, "protocol" : "openid-connect", "attributes" : { + "realm_client" : "false", + "client.use.lightweight.access.token.enabled" : "true", "post.logout.redirect.uris" : "+", "pkce.code.challenge.method" : "S256" }, "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : false, + "fullScopeAllowed" : true, "nodeReRegistrationTimeout" : 0, "protocolMappers" : [ { "id" : "c4d54410-3f22-4259-9571-94da2c43b752", @@ -1518,15 +1663,15 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "locale", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "locale", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } } ], - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] } ], "clientScopes" : [ { @@ -1547,8 +1692,8 @@ "protocol" : "openid-connect", "attributes" : { "include.in.token.scope" : "true", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${emailScopeConsentText}" + "consent.screen.text" : "${emailScopeConsentText}", + "display.on.consent.screen" : "true" }, "protocolMappers" : [ { "id" : "782819fe-ba5d-4ddb-9f95-cabb69d79c8d", @@ -1557,12 +1702,12 @@ "protocolMapper" : "oidc-usermodel-property-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "emailVerified", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "email_verified", - "jsonType.label" : "boolean" + "jsonType.label" : "boolean", + "userinfo.token.claim" : "true" } }, { "id" : "ca613fc8-bbf2-4240-8b33-a1874f1559f3", @@ -1571,12 +1716,12 @@ "protocolMapper" : "oidc-usermodel-property-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "email", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "email", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } } ] }, { @@ -1586,8 +1731,8 @@ "protocol" : "openid-connect", "attributes" : { "include.in.token.scope" : "true", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${profileScopeConsentText}" + "consent.screen.text" : "${profileScopeConsentText}", + "display.on.consent.screen" : "true" }, "protocolMappers" : [ { "id" : "84f0487a-1d7d-470c-9b8e-5835294ae235", @@ -1596,12 +1741,12 @@ "protocolMapper" : "oidc-usermodel-property-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "username", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "preferred_username", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "bbdcdb36-3ec0-443d-b1af-9993d40f0567", @@ -1610,12 +1755,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "gender", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "gender", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "9faa870b-5491-4ce9-b27d-c9ce07d6a95e", @@ -1624,12 +1769,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "birthdate", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "birthdate", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "f0e3c012-9523-4076-83ae-e466e2d08220", @@ -1649,12 +1794,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "profile", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "profile", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "18cfbf4b-0a8e-45c7-a832-c0f72c92f3f3", @@ -1663,12 +1808,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "updatedAt", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "updated_at", - "jsonType.label" : "long" + "jsonType.label" : "long", + "userinfo.token.claim" : "true" } }, { "id" : "841ea785-26ab-429a-a420-09ce3948924d", @@ -1677,12 +1822,12 @@ "protocolMapper" : "oidc-usermodel-property-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "lastName", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "family_name", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "bfba13ff-f952-4e89-bbb1-a693fdebfae8", @@ -1691,12 +1836,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "website", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "website", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "475f071d-5149-4379-b928-76482f5f519c", @@ -1705,12 +1850,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "zoneinfo", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "zoneinfo", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "b8bebfed-b5e9-4604-a0ee-9817f7d439ac", @@ -1719,12 +1864,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "middleName", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "middle_name", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "445232c8-6830-476c-a6f1-8bbef167595a", @@ -1733,12 +1878,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "picture", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "picture", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "65f2e474-6ede-4872-86e4-e49504dd0f2a", @@ -1747,12 +1892,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "locale", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "locale", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "16cd5a27-ccf3-453c-ae1e-8621813ab73c", @@ -1761,12 +1906,12 @@ "protocolMapper" : "oidc-usermodel-property-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "firstName", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "given_name", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "f9efedfc-3388-457c-b10a-1dff4525ff9b", @@ -1775,12 +1920,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "nickname", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "nickname", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } } ] }, { @@ -1814,12 +1959,12 @@ "protocolMapper" : "oidc-usermodel-property-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "username", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "upn", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } } ] }, { @@ -1861,8 +2006,8 @@ "protocol" : "openid-connect", "attributes" : { "include.in.token.scope" : "true", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${phoneScopeConsentText}" + "consent.screen.text" : "${phoneScopeConsentText}", + "display.on.consent.screen" : "true" }, "protocolMappers" : [ { "id" : "dae802fb-9138-408a-b80e-a40eb0f56814", @@ -1871,12 +2016,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "phoneNumber", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "phone_number", - "jsonType.label" : "String" + "jsonType.label" : "String", + "userinfo.token.claim" : "true" } }, { "id" : "feb06a8d-b0eb-4911-8464-368d93f566fa", @@ -1885,12 +2030,12 @@ "protocolMapper" : "oidc-usermodel-attribute-mapper", "consentRequired" : false, "config" : { - "userinfo.token.claim" : "true", "user.attribute" : "phoneNumberVerified", "id.token.claim" : "true", "access.token.claim" : "true", "claim.name" : "phone_number_verified", - "jsonType.label" : "boolean" + "jsonType.label" : "boolean", + "userinfo.token.claim" : "true" } } ] }, { @@ -1900,8 +2045,8 @@ "protocol" : "openid-connect", "attributes" : { "include.in.token.scope" : "false", - "display.on.consent.screen" : "false", - "consent.screen.text" : "" + "consent.screen.text" : "", + "display.on.consent.screen" : "false" }, "protocolMappers" : [ { "id" : "c6411e3b-6478-453d-b530-5fe175a4d786", @@ -1981,6 +2126,61 @@ "gui.order" : "", "consent.screen.text" : "" } + }, { + "id" : "aa5c6ca7-812d-4fff-80b9-f5095ca82ce6", + "name" : "service_account", + "description" : "Specific scope for a client enabled for service accounts", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "bb359b0f-97dc-4d6a-9a2f-89458b53c512", + "name" : "Client IP Address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientAddress", + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientAddress", + "jsonType.label" : "String" + } + }, { + "id" : "7aa3a4d2-3dd1-48dd-8886-562906eadb2a", + "name" : "Client Host", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientHost", + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientHost", + "jsonType.label" : "String" + } + }, { + "id" : "c4882d39-e815-49f5-8a73-eb8b83572eae", + "name" : "Client ID", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "client_id", + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "client_id", + "jsonType.label" : "String" + } + } ] }, { "id" : "210cc792-6c07-45a6-a77e-827cdf3b41ba", "name" : "offline_access", @@ -1997,8 +2197,8 @@ "protocol" : "openid-connect", "attributes" : { "include.in.token.scope" : "true", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${addressScopeConsentText}" + "consent.screen.text" : "${addressScopeConsentText}", + "display.on.consent.screen" : "true" }, "protocolMappers" : [ { "id" : "8d4ffe4d-1d01-4ca1-8ff4-44eacca61b30", @@ -2029,6 +2229,41 @@ "gui.order" : "", "consent.screen.text" : "" } + }, { + "id" : "ba11267a-478b-4b32-872f-4eb2d125d116", + "name" : "basic", + "description" : "OpenID Connect scope for add all basic claims to the token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "1445e14f-49b0-4666-8ddc-691493c24ad9", + "name" : "sub", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-sub-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "846f1ef0-2b86-4e07-9d25-691d25af5fce", + "name" : "auth_time", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "AUTH_TIME", + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "auth_time", + "jsonType.label" : "long" + } + } ] }, { "id" : "37f61543-dad7-4a82-8e10-77acdd1eefdc", "name" : "roles", @@ -2036,8 +2271,8 @@ "protocol" : "openid-connect", "attributes" : { "include.in.token.scope" : "false", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${rolesScopeConsentText}" + "consent.screen.text" : "${rolesScopeConsentText}", + "display.on.consent.screen" : "true" }, "protocolMappers" : [ { "id" : "3b6b6914-8ad1-4a71-88ec-444f754aaacb", @@ -2053,11 +2288,15 @@ "protocolMapper" : "oidc-usermodel-realm-role-mapper", "consentRequired" : false, "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "false", + "multivalued" : "true", "user.attribute" : "foo", + "id.token.claim" : "true", + "lightweight.claim" : "false", "access.token.claim" : "true", "claim.name" : "realm_access.roles", - "jsonType.label" : "String", - "multivalued" : "true" + "jsonType.label" : "String" } }, { "id" : "a7bd6723-e58e-47f7-95c0-2925ce99283d", @@ -2074,7 +2313,7 @@ } } ] } ], - "defaultDefaultClientScopes" : [ "rabbitmq.tag:administrator", "rabbitmq.tag:management" ], + "defaultDefaultClientScopes" : [ "rabbitmq.tag:administrator", "rabbitmq.tag:management", "basic" ], "defaultOptionalClientScopes" : [ "rabbitmq.write:*/*", "offline_access", "rabbitmq.configure:*/*", "roles", "role_list", "address", "phone", "acr", "microprofile-jwt", "email", "attributes", "profile", "rabbitmq.read:*/*", "web-origins" ], "browserSecurityHeaders" : { "contentSecurityPolicyReportOnly" : "", @@ -2087,6 +2326,10 @@ "strictTransportSecurity" : "max-age=31536000; includeSubDomains" }, "smtpServer" : { }, + "loginTheme" : "keycloak", + "accountTheme" : "", + "adminTheme" : "", + "emailTheme" : "", "eventsEnabled" : false, "eventsListeners" : [ "jboss-logging" ], "enabledEventTypes" : [ "SEND_RESET_PASSWORD", "UPDATE_CONSENT_ERROR", "GRANT_CONSENT", "VERIFY_PROFILE_ERROR", "REMOVE_TOTP", "REVOKE_GRANT", "UPDATE_TOTP", "LOGIN_ERROR", "CLIENT_LOGIN", "RESET_PASSWORD_ERROR", "IMPERSONATE_ERROR", "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION", "OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR", "RESTART_AUTHENTICATION", "IMPERSONATE", "UPDATE_PROFILE_ERROR", "LOGIN", "OAUTH2_DEVICE_VERIFY_USER_CODE", "UPDATE_PASSWORD_ERROR", "CLIENT_INITIATED_ACCOUNT_LINKING", "TOKEN_EXCHANGE", "AUTHREQID_TO_TOKEN", "LOGOUT", "REGISTER", "DELETE_ACCOUNT_ERROR", "CLIENT_REGISTER", "IDENTITY_PROVIDER_LINK_ACCOUNT", "DELETE_ACCOUNT", "UPDATE_PASSWORD", "CLIENT_DELETE", "FEDERATED_IDENTITY_LINK_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN", "CLIENT_DELETE_ERROR", "VERIFY_EMAIL", "CLIENT_LOGIN_ERROR", "RESTART_AUTHENTICATION_ERROR", "EXECUTE_ACTIONS", "REMOVE_FEDERATED_IDENTITY_ERROR", "TOKEN_EXCHANGE_ERROR", "PERMISSION_TOKEN", "SEND_IDENTITY_PROVIDER_LINK_ERROR", "EXECUTE_ACTION_TOKEN_ERROR", "SEND_VERIFY_EMAIL", "OAUTH2_DEVICE_AUTH", "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY", "OAUTH2_DEVICE_CODE_TO_TOKEN", "IDENTITY_PROVIDER_POST_LOGIN", "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", "OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR", "UPDATE_EMAIL", "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "EXECUTE_ACTION_TOKEN", "LOGOUT_ERROR", "UPDATE_EMAIL_ERROR", "CLIENT_UPDATE_ERROR", "AUTHREQID_TO_TOKEN_ERROR", "UPDATE_PROFILE", "CLIENT_REGISTER_ERROR", "FEDERATED_IDENTITY_LINK", "SEND_IDENTITY_PROVIDER_LINK", "SEND_VERIFY_EMAIL_ERROR", "RESET_PASSWORD", "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", "OAUTH2_DEVICE_AUTH_ERROR", "UPDATE_CONSENT", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR", "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE", "CUSTOM_REQUIRED_ACTION_ERROR", "IDENTITY_PROVIDER_POST_LOGIN_ERROR", "UPDATE_TOTP_ERROR", "CODE_TO_TOKEN", "VERIFY_PROFILE", "GRANT_CONSENT_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" ], @@ -2136,7 +2379,7 @@ "subType" : "anonymous", "subComponents" : { }, "config" : { - "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" ] + "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "saml-role-list-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper" ] } }, { "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1", @@ -2162,11 +2405,11 @@ "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" ] + "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-role-list-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper" ] } } ], "org.keycloak.userprofile.UserProfileProvider" : [ { - "id" : "fb763636-e1ea-49c7-adca-ea105cdec4ad", + "id" : "a407a1d6-a7f6-4a72-ba3a-149de03d5a43", "providerId" : "declarative-user-profile", "subComponents" : { }, "config" : { @@ -2185,17 +2428,6 @@ "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", @@ -2212,8 +2444,8 @@ "providerId" : "hmac-generated", "subComponents" : { }, "config" : { - "kid" : [ "5034d264-cb50-4006-a59e-2ce636eb5f38" ], - "secret" : [ "ToVIw-a4IE-Yp9JpP8ztb8NAICYO8CT3tUiDPT6DdiBcgzKJ9Ym9vspxGVdmPceX3mAgbnGLAcTx1PkInSVrbZs-tX9QXFwdlyGbewhKiNpH8wEg32Wk4GuUDpTv8JCsymgWyQBY681jvIMv05eCoK2QWpqCzcgP828KM5peCzo" ], + "kid" : [ "7f9f9054-5697-4f60-bdc8-67e3bd0f4db6" ], + "secret" : [ "1SCIY20z3AbAHCL28LuJfBU-7zfsZv5dacgliUeGdRW_WK3vH9fJUpPu1f7iDrdlhF7YQmHxLXsWjxhQId4ShI7QBdgKCArHWqi0GeH37oNXfZFg_uv-K_3JSfxfGBRu5jpRQhhSBxESZWsFVkskhxWUvNe6b5l9dFbMIif72rI" ], "priority" : [ "100" ], "algorithm" : [ "HS256" ] } @@ -2228,12 +2460,23 @@ "certificate" : [ "MIICmzCCAYMCBgGG3GWyBTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZkYnJlcG8wHhcNMjMwMzEzMTkxMzE3WhcNMzMwMzEzMTkxNDU3WjARMQ8wDQYDVQQDDAZkYnJlcG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqqcdDYFZZb28M0tEJzEP77FmD/Xqioyj9zWX6VwUSOMAgmMmn8eqs9hT9T0a+q4YTo9tUW1PNbUpwprA5b4Uk04DcIajxDVMUR/PjcHytmkqwVskq9AZW/Vngdoo+8tSbuIybwe/3Vwt266hbHpDcM97a+DXcYooRl7tQWCEX7RP27wQrMD9epDQ6IgKayZg9vC9/03dsIqwH9jXQRiZlFvwiEKhX2aY7lPGBaCK414JO00K/Z49iov9TRa/IYVbSt5qwgrx6DcqsBSPwOnI6A85UGfeUEZ/7coVJiL7RvBlsllapsL9eWTbQajVh94k9Ei3sibEPbtH+U2OAM78zAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAASnN1Cuif1sdfEK2kWAURSXGJCohCROLWdKFjaeHPRaEfpbFJsgxW0Yj3nwX5O3bUlOWoTyENwnXSsXMQsqnNi+At32CKaKO8+AkhAbgQL9F0B+KeJwmYv3cUj5N/LYkJjBvZBzUZ4Ugu5dcxH0k7AktLAIwimkyEnxTNolOA3UyrGGpREr8MCKWVr10RFuOpF/0CsJNNwbHXzalO9D756EUcRWZ9VSg6QVNso0YYRKTnILWDn9hcTRnqGy3SHo3anFTqQZ+BB57YbgFWy6udC0LYRB3zdp6zNti87eu/VEymiDY/mmo1AB8Tm0b6vxFz4AKcL3ax5qS6YnZ9efSzk=" ], "priority" : [ "100" ] } + }, { + "id" : "addbae10-c6ae-4735-851f-7a5ea035ce25", + "name" : "hmac-generated-hs512", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "352d0ea1-8218-42b5-ab78-e2ca56cf6a95" ], + "secret" : [ "_kr6EZOZ8IKqPWgJltHAAsQ34wCIGPs8oOQLYWwJrSIH7Qie3CEVKZnICyBP1goR-QgUtg25tR8Qu5MkvYkb8assJ8Iok5x_8iYCR4Txkf_mS-emrlAtQajlIjmOfNBtx704dTnZlP9rWzqpW6mrpeiOaiCw1K0XCpY5C_ZjXKw" ], + "priority" : [ "100" ], + "algorithm" : [ "HS512" ] + } } ] }, "internationalizationEnabled" : false, "supportedLocales" : [ ], "authenticationFlows" : [ { - "id" : "88e5d526-2298-413c-a904-133ad839d47f", + "id" : "259dd7b6-01b7-433a-bda4-028857151ecd", "alias" : "Account verification options", "description" : "Method with which to verity the existing account", "providerId" : "basic-flow", @@ -2255,7 +2498,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "a690c715-fbae-4c20-b680-bd4010718761", + "id" : "542ca1d7-9627-4102-b843-98837ce433fb", "alias" : "Browser - Conditional OTP", "description" : "Flow to determine if the OTP is required for the authentication", "providerId" : "basic-flow", @@ -2277,7 +2520,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "ad6d407e-c73e-4439-baf3-d7c99c6cb6ad", + "id" : "4f153b98-6851-440b-a022-0a14e67a9b2f", "alias" : "Direct Grant - Conditional OTP", "description" : "Flow to determine if the OTP is required for the authentication", "providerId" : "basic-flow", @@ -2299,7 +2542,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "e5d03405-e10a-408a-adb2-41dbb4f24515", + "id" : "3d791b35-d35c-40b2-bb3e-e806d72b27ee", "alias" : "First broker login - Conditional OTP", "description" : "Flow to determine if the OTP is required for the authentication", "providerId" : "basic-flow", @@ -2321,7 +2564,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "96b93843-62d0-44f1-84dd-21cc5f95f523", + "id" : "9b746104-9371-4c3f-b69f-9322cead1b08", "alias" : "Handle Existing Account", "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", "providerId" : "basic-flow", @@ -2343,7 +2586,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "088f4051-36ab-4952-a4f2-4ba53c408083", + "id" : "7a164efe-c97b-4fbb-950d-7745359ba9a4", "alias" : "Reset - Conditional OTP", "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", "providerId" : "basic-flow", @@ -2365,7 +2608,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "05f37bb2-779d-4e3f-ad1b-f6eb33bb3de4", + "id" : "4fdc5e1b-1b55-4662-8360-67d75fa22677", "alias" : "User creation or linking", "description" : "Flow for the existing/non-existing user alternatives", "providerId" : "basic-flow", @@ -2388,7 +2631,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "300a5647-7d2c-4348-9f1f-51504bfda1c4", + "id" : "75893341-c338-44d8-ae27-a3fc7bfe8f2d", "alias" : "Verify Existing Account by Re-authentication", "description" : "Reauthentication of existing account", "providerId" : "basic-flow", @@ -2410,7 +2653,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "26afc672-314b-4ad9-9711-7aaeafd7c00c", + "id" : "89626b76-f4cf-4c46-934c-4408c225a44b", "alias" : "browser", "description" : "browser based authentication", "providerId" : "basic-flow", @@ -2446,7 +2689,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "9b301f6c-eda7-4da0-ba09-1a6454ff910d", + "id" : "4112115a-e7a7-44c2-9af5-65d538e4ba0d", "alias" : "clients", "description" : "Base authentication for clients", "providerId" : "client-flow", @@ -2482,7 +2725,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "6e54f1be-dbad-4b6d-8eee-8e048d413c63", + "id" : "f82a9b0a-2c0a-4cb1-96b2-6c78b0b1f14f", "alias" : "direct grant", "description" : "OpenID Connect Resource Owner Grant", "providerId" : "basic-flow", @@ -2511,7 +2754,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "31da4b94-03c4-4d79-9ac3-5df1445c0781", + "id" : "3614e155-e8ce-4958-98fb-a27e4706cc70", "alias" : "docker auth", "description" : "Used by Docker clients to authenticate against the IDP", "providerId" : "basic-flow", @@ -2526,7 +2769,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "2e16651d-681f-4d9b-9dd4-9acdb465cd43", + "id" : "506f9b96-5002-47c0-96e3-3830a0fcfa26", "alias" : "first broker login", "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", "providerId" : "basic-flow", @@ -2549,7 +2792,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "da109a26-fefa-48a4-ae8e-1d49627c2db8", + "id" : "4b7a7e91-36db-4b27-8e2d-01a04a822980", "alias" : "forms", "description" : "Username, password, otp and other auth forms.", "providerId" : "basic-flow", @@ -2571,7 +2814,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "4c983c77-241f-41c5-8b8a-e2cd6fc08914", + "id" : "04c2fe01-5076-4aa4-9596-4efb4004195f", "alias" : "registration", "description" : "registration flow", "providerId" : "basic-flow", @@ -2587,7 +2830,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "d62c8dd6-633c-408a-aa99-43071510efb4", + "id" : "d12f77e1-7733-44a2-98ff-fd75c784d721", "alias" : "registration form", "description" : "registration form", "providerId" : "form-flow", @@ -2616,7 +2859,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "c8ca5be7-e76d-4e16-b5ca-3ced99d92dbb", + "id" : "91f6048c-a376-4809-8f37-c8d7a517830c", "alias" : "reset credentials", "description" : "Reset credentials for a user if they forgot their password or something", "providerId" : "basic-flow", @@ -2652,7 +2895,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "389c1c37-e8af-4610-a507-e1257f55b954", + "id" : "7b8fb487-53b8-4533-a696-76bc05256cb1", "alias" : "saml ecp", "description" : "SAML ECP Profile Authentication Flow", "providerId" : "basic-flow", @@ -2668,13 +2911,13 @@ } ] } ], "authenticatorConfig" : [ { - "id" : "d66ca9d0-1645-4c84-abfe-c0a696f17de4", + "id" : "48372696-0579-45e5-b074-5e8dbdbbe7d6", "alias" : "create unique user config", "config" : { "require.password.update.after.registration" : "false" } }, { - "id" : "061cc6b8-90be-4423-9bf9-974ead709b5d", + "id" : "08df3b83-e522-42a7-9e24-9028b960bf39", "alias" : "review profile config", "config" : { "update.profile.on.first.login" : "missing" @@ -2785,10 +3028,12 @@ "actionTokenGeneratedByUserLifespan-idp-verify-account-via-email" : "", "parRequestUriLifespan" : "60", "clientSessionMaxLifespan" : "0", + "organizationsEnabled" : "false", "shortVerificationUri" : "" }, - "keycloakVersion" : "24.0.5", + "keycloakVersion" : "26.0.4", "userManagedAccessAllowed" : false, + "organizationsEnabled" : false, "clientProfiles" : { "profiles" : [ ] }, diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java index d4963adffac1b3f6497d112a49f3e25bf42e715b..cd5fd08a7ef64e88134a1fc19aa0840ad1e98020 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java @@ -20,7 +20,7 @@ public interface KeycloakGateway { * * @param id The user id. */ - void deleteUser(UUID id) throws AuthServiceException; + void deleteUser(UUID id) throws UserNotFoundException; /** * Update the credentials for a given user. @@ -28,7 +28,7 @@ public interface KeycloakGateway { * @param id The user id. * @param password The user credential. */ - void updateUserCredentials(UUID id, UserPasswordDto password); + void updateUserCredentials(UUID id, UserPasswordDto password) throws UserNotFoundException; void updateUser(UUID id, UserUpdateDto data) throws AuthServiceException, UserNotFoundException; } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java index a8e3acbf5b63341540c208ad5b2bec059d82300c..af54651d6c36197e136134003291ea88f5df2a49 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java @@ -8,6 +8,7 @@ import at.tuwien.exception.AuthServiceException; import at.tuwien.exception.UserNotFoundException; import at.tuwien.gateway.KeycloakGateway; import at.tuwien.mapper.MetadataMapper; +import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.ForbiddenException; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.Response; @@ -66,27 +67,33 @@ public class KeycloakGatewayImpl implements KeycloakGateway { } @Override - public void deleteUser(UUID id) throws AuthServiceException { + public void deleteUser(UUID id) throws UserNotFoundException { try (Response response = keycloak.realm(keycloakConfig.getRealm()) .users() .delete(String.valueOf(id))) { - if (response.getStatus() != 200) { - log.error("Failed to delete user: unexpected response status: {}", response.getStatus()); - throw new AuthServiceException("Unexpected response status: " + response.getStatus()); + if (response.getStatus() == 404) { + log.error("Failed to delete user: not found"); + throw new UserNotFoundException("Failed to delete user: not found"); } } log.info("Deleted user {} at auth service", id); } @Override - public void updateUserCredentials(UUID id, UserPasswordDto data) { + public void updateUserCredentials(UUID id, UserPasswordDto data) throws UserNotFoundException { final CredentialRepresentation credential = new CredentialRepresentation(); - credential.setCredentialData(data.getPassword()); + credential.setTemporary(false); + credential.setValue(data.getPassword()); credential.setType(CredentialRepresentation.PASSWORD); - keycloak.realm(keycloakConfig.getRealm()) - .users() - .get(String.valueOf(id)) - .resetPassword(credential); + try { + keycloak.realm(keycloakConfig.getRealm()) + .users() + .get(String.valueOf(id)) + .resetPassword(credential); + } catch (NotFoundException e) { + log.error("Failed to update user password: not found"); + throw new UserNotFoundException("Failed to update user password: not found", e); + } log.info("Updated user {} password at auth service", id); } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java index e914b0f1abb1b48de00c4cee0e449e13d8913638..75b647bf954fd638dfde8ffa8b7f650d03ce7c49 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java @@ -24,9 +24,7 @@ public interface AuthenticationService { * * @param user The user. * @param data The new password. - * @throws AuthServiceException The auth service responded with unexpected behavior. - * @throws AuthServiceConnectionException The connection with the auth service could not be established. + * @throws UserNotFoundException The user was not found after creation in the auth database. */ - void updatePassword(User user, UserPasswordDto data) throws AuthServiceException, AuthServiceConnectionException, - CredentialsInvalidException, UserNotFoundException; + void updatePassword(User user, UserPasswordDto data) throws UserNotFoundException; } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AuthenticationServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AuthenticationServiceImpl.java index 5e007cebc7bf7dd17bd5d7f9e05e2dfc6f188db9..1159913039ef59227758006f28d678db99329386 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AuthenticationServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AuthenticationServiceImpl.java @@ -24,14 +24,12 @@ public class AuthenticationServiceImpl implements AuthenticationService { } @Override - public void delete(User user) throws AuthServiceException, AuthServiceConnectionException, UserNotFoundException, - CredentialsInvalidException { + public void delete(User user) throws AuthServiceException, UserNotFoundException { keycloakGateway.deleteUser(user.getKeycloakId()); } @Override - public void updatePassword(User user, UserPasswordDto data) throws AuthServiceException, - AuthServiceConnectionException, CredentialsInvalidException, UserNotFoundException { + public void updatePassword(User user, UserPasswordDto data) throws UserNotFoundException { keycloakGateway.updateUserCredentials(user.getKeycloakId(), data); } 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 932a1a598c49f5f2a70f95b8c8264f5433a9cc13..96b8bd83963cca91e4731812ee0812a54a4630dc 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 @@ -287,7 +287,7 @@ public class IdentifierServiceImpl implements IdentifierService { /* save identifier */ switch (identifier.getType()) { case SUBSET -> { - log.debug("identifier type: subset with id {} and database with id {}", identifier.getQueryId(), identifier.getDatabase().getId()); + log.debug("identifier type: subset with id {}", identifier.getQueryId()); final QueryDto query = dataServiceGateway.findQuery(identifier.getDatabase().getId(), identifier.getQueryId()); identifier.setQuery(query.getQuery()); identifier.setQueryId(query.getId()); @@ -298,14 +298,14 @@ public class IdentifierServiceImpl implements IdentifierService { identifier.setResultHash(query.getResultHash()); } case VIEW -> { - log.debug("identifier type: view with id {} and database with id {}", identifier.getViewId(), identifier.getDatabase().getId()); + log.debug("identifier type: view with id {}", identifier.getViewId()); final View view = viewService.findById(identifier.getDatabase(), identifier.getViewId()); identifier.setViewId(view.getId()); identifier.setQuery(view.getQuery()); identifier.setQueryNormalized(view.getQuery()); identifier.setQueryHash(view.getQueryHash()); } - case DATABASE -> log.debug("identifier type: database with id {}", identifier.getDatabase()); + case DATABASE -> log.debug("identifier type: database with id {}", identifier.getDatabase().getId()); case TABLE -> log.debug("identifier type: table with id {}", identifier.getTableId()); } /* save identifier in metadata database */ 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 d8850b5589959c0f5241d59870d1b629fcff8b59..57ae996453427cfd52a2212be08b8842e5b9c376 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 @@ -46,7 +46,6 @@ import at.tuwien.api.orcid.person.name.OrcidNameDto; import at.tuwien.api.orcid.person.name.OrcidValueDto; import at.tuwien.api.semantics.*; import at.tuwien.api.user.UserAttributesDto; -import at.tuwien.api.user.UserDto; import at.tuwien.api.user.*; import at.tuwien.api.user.internal.UpdateUserPasswordDto; import at.tuwien.entities.container.Container; @@ -99,12 +98,12 @@ import static java.time.temporal.ChronoUnit.MINUTES; * <ul> * <li>Table 1 (Private Data, Private Schema)</li> * <li>Table 2 (Private Data, Public Schema)</li> - * <li>Table 3</li> - * <li>Table 4</li> + * <li>Table 3 (Private Data, Private Schema)</li> + * <li>Table 4 (Public Data, Private Schema)</li> * <li>Query 1</li> - * <li>View 1</li> - * <li>View 2</li> - * <li>View 3</li> + * <li>View 1 (Private Data, Private Schema)</li> + * <li>View 2 (Public Data, Public Schema)</li> + * <li>View 3 (Public Data, Private Schema)</li> * <li>Identifier 1 (Title=en, Description=en, type=database)</li> * <li>Identifier 2 (Title=en, Description=en, type=subset, queryId=1)</li> * <li>Identifier 3 (Title=en, Description=en, type=view, viewId=1)</li> @@ -113,22 +112,22 @@ import static java.time.temporal.ChronoUnit.MINUTES; * <p> * Database 2 (Private Data, Public Schema, User 2) -> Container 1 * <ul> - * <li>Table 5</li> - * <li>Table 6</li> - * <li>Table 7</li> + * <li>Table 5 (Public Data, Public Schema)</li> + * <li>Table 6 (Public Data, Private Schema)</li> + * <li>Table 7 (Public Data, Public Schema)</li> * <li>Query 2</li> * <li>Query 6</li> - * <li>View 4</li> + * <li>View 4 (Public Data, Private Schema)</li> * <li>Identifier 5 (Title=de, Description=de)</li> * </ul> * <p> * Database 3 (Public Data, Private Schema, User 3) -> Container 1 * <ul> - * <li>Table 8</li> + * <li>Table 8 (Private Data, Private Schema)</li> * <li>Query 3</li> * <li>Query 4</li> * <li>Query 5</li> - * <li>View 5</li> + * <li>View 5 (Public Data, Public Schema)</li> * <li>Identifier 6 (Title=en, Description=en, Query=3)</li> * </ul> * <p> @@ -153,7 +152,7 @@ public abstract class BaseTest { public final static String RABBITMQ_IMAGE = "rabbitmq:3.13.7"; - public final static String KEYCLOAK_IMAGE = "quay.io/keycloak/keycloak:24.0"; + public final static String KEYCLOAK_IMAGE = "quay.io/keycloak/keycloak:26.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"}; @@ -166,7 +165,7 @@ public abstract class BaseTest { "update-semantic-unit", "create-ontology", "update-ontology"}; public final static String[] DEFAULT_CONTAINER_HANDLING = new String[]{"default-container-handling", - "create-container", "list-containers", "modify-container-state", "find-container"}; + "create-container", "list-containers", "modify-container-state"}; public final static String[] ESCALATED_CONTAINER_HANDLING = new String[]{"escalated-container-handling", "modify-foreign-container-state", "delete-container"}; @@ -217,7 +216,7 @@ public abstract class BaseTest { public final static String[] DEFAULT_DATA_STEWARD_ROLES = ArrayUtils.merge(List.of(new String[]{"default-data-steward-roles"}, ESCALATED_IDENTIFIER_HANDLING, DEFAULT_SEMANTICS_HANDLING, ESCALATED_SEMANTICS_HANDLING, DEFAULT_VIEW_HANDLING)); - public final static String[] DEFAULT_LOCAL_ADMIN_ROLES = new String[]{"admin"}; + public final static String[] DEFAULT_LOCAL_ADMIN_ROLES = new String[]{"system"}; public final static List<GrantedAuthorityDto> AUTHORITY_LOCAL_ADMIN_ROLES = Arrays.stream(DEFAULT_LOCAL_ADMIN_ROLES) .map(GrantedAuthorityDto::new) @@ -440,6 +439,7 @@ public abstract class BaseTest { public final static String USER_BROKER_PASSWORD = "guest"; public final static UUID USER_LOCAL_ADMIN_ID = UUID.fromString("a54dcb2e-a644-4e82-87e7-05a96413983d"); + public final static UUID USER_LOCAL_ADMIN_KEYCLOAK_ID = UUID.fromString("703c2ca0-8fc3-4c03-9bc5-4dae6b211e78"); public final static String USER_LOCAL_ADMIN_USERNAME = "admin"; @SuppressWarnings("java:S2068") public final static String USER_LOCAL_ADMIN_PASSWORD = "admin"; @@ -455,7 +455,7 @@ public abstract class BaseTest { .build(); public final static UserDetails USER_LOCAL_ADMIN_DETAILS = UserDetailsDto.builder() - .id(String.valueOf(USER_LOCAL_ADMIN_ID)) + .id(USER_LOCAL_ADMIN_ID.toString()) .username(USER_LOCAL_ADMIN_USERNAME) .password(USER_LOCAL_ADMIN_PASSWORD) .authorities(AUTHORITY_DEFAULT_LOCAL_ADMIN_AUTHORITIES) @@ -463,6 +463,7 @@ public abstract class BaseTest { public final static User USER_LOCAL = User.builder() .id(USER_LOCAL_ADMIN_ID) + .keycloakId(USER_LOCAL_ADMIN_KEYCLOAK_ID) .username(USER_LOCAL_ADMIN_USERNAME) .mariadbPassword(USER_LOCAL_ADMIN_MARIADB_PASSWORD) .theme(USER_LOCAL_ADMIN_THEME) @@ -2031,7 +2032,7 @@ public abstract class BaseTest { public final static String TABLE_6_INTERNALNAME = "names"; public final static Boolean TABLE_6_VERSIONED = true; public final static Boolean TABLE_6_IS_PUBLIC = true; - public final static Boolean TABLE_6_SCHEMA_PUBLIC = true; + public final static Boolean TABLE_6_SCHEMA_PUBLIC = false; public final static Boolean TABLE_6_PROCESSED_CONSTRAINTS = true; public final static String TABLE_6_DESCRIPTION = "Some names dataset"; public final static String TABLE_6_QUEUE_NAME = TABLE_6_INTERNALNAME; @@ -2150,9 +2151,8 @@ public abstract class BaseTest { public final static String TABLE_4_NAME = "Sensor 2"; public final static String TABLE_4_INTERNALNAME = "sensor_2"; public final static Boolean TABLE_4_VERSIONED = true; - public final static Boolean TABLE_4_IS_PUBLIC = false; + public final static Boolean TABLE_4_IS_PUBLIC = true; public final static Boolean TABLE_4_SCHEMA_PUBLIC = false; - public final static Boolean TABLE_4_PROCESSED_CONSTRAINTS = true; public final static String TABLE_4_DESCRIPTION = "Hello sensor"; public final static String TABLE_4_QUEUE_NAME = TABLE_4_INTERNALNAME; public final static String TABLE_4_ROUTING_KEY = "dbrepo\\." + DATABASE_1_ID + "\\." + TABLE_4_ID; @@ -2330,7 +2330,6 @@ public abstract class BaseTest { public final static Boolean TABLE_8_VERSIONED = true; public final static Boolean TABLE_8_IS_PUBLIC = false; public final static Boolean TABLE_8_SCHEMA_PUBLIC = false; - public final static Boolean TABLE_8_PROCESSED_CONSTRAINTS = true; public final static String TABLE_8_DESCRIPTION = "Hello mfcc"; public final static String TABLE_8_QUEUE_NAME = TABLE_8_INTERNAL_NAME; public final static String TABLE_8_ROUTING_KEY = "dbrepo\\." + DATABASE_3_ID + "\\." + TABLE_8_ID; @@ -5357,7 +5356,7 @@ public abstract class BaseTest { public final static String VIEW_3_INTERNAL_NAME = "junit3"; public final static Long VIEW_3_CONTAINER_ID = CONTAINER_1_ID; public final static Long VIEW_3_DATABASE_ID = DATABASE_1_ID; - public final static Boolean VIEW_3_PUBLIC = false; + public final static Boolean VIEW_3_PUBLIC = true; public final static Boolean VIEW_3_SCHEMA_PUBLIC = false; public final static String VIEW_3_QUERY = "select w.`mintemp`, w.`rainfall`, w.`location`, m.`date` from `weather_aus` w join `junit2` m on m.`location` = w.`location` and m.`date` = w.`date`"; public final static String VIEW_3_QUERY_HASH = "bbbaa56a5206b3dc3e6cf9301b0db9344eb6f19b100c7b88550ffb597a0bd255"; @@ -5519,7 +5518,7 @@ public abstract class BaseTest { public final static Long VIEW_4_TABLE_ID = TABLE_5_ID; public final static Table VIEW_4_TABLE = TABLE_5; public final static Boolean VIEW_4_PUBLIC = true; - public final static Boolean VIEW_4_SCHEMA_PUBLIC = true; + public final static Boolean VIEW_4_SCHEMA_PUBLIC = false; public final static String VIEW_4_QUERY = "SELECT `animal_name`, `hair`, `feathers`, `eggs`, `milk`, `airborne`, `aquatic`, `predator`, `backbone`, `breathes`, `venomous`, `fins`, `legs`, `tail`, `domestic`, `catsize`, `class_type` FROM `zoo` WHERE `class_type` = 1"; public final static String VIEW_4_QUERY_HASH = "3561cd0bb0b0e94d6f15ae602134252a5760d09d660a71a4fb015b6991c8ba0b";