diff --git a/Makefile b/Makefile index b6a203169d6e3e44903d5178e4ce8e49a2354fa3..2229c2993727a3b08657dabeaa8b07093da5a1d0 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ test-backend: test-metadata-service test-analyse-service test-search-sync-agent test-search-sync-agent: build-search-sync-agent mvn -f ./dbrepo-search-sync-agent/pom.xml clean test verify -test-metadata-service: build-metadata-service +test-metadata-service: build-metadata-service teardown mvn -f ./dbrepo-metadata-service/pom.xml clean test verify test-analyse-service: build-analyse-service diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostCreationException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostCreationException.java deleted file mode 100644 index bb3b2690dc7c1348cb33ac0f147d6be320aa7267..0000000000000000000000000000000000000000 --- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostCreationException.java +++ /dev/null @@ -1,20 +0,0 @@ -package at.tuwien.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(code = HttpStatus.NOT_ACCEPTABLE) -public class BrokerVirtualHostCreationException extends Exception { - - public BrokerVirtualHostCreationException(String msg) { - super(msg); - } - - public BrokerVirtualHostCreationException(String msg, Throwable thr) { - super(msg, thr); - } - - public BrokerVirtualHostCreationException(Throwable thr) { - super(thr); - } -} diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostModificationException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostModificationException.java new file mode 100644 index 0000000000000000000000000000000000000000..a9fda0c9d43ffc61ff5205c5f4eabf0ebadd32f0 --- /dev/null +++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/BrokerVirtualHostModificationException.java @@ -0,0 +1,20 @@ +package at.tuwien.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.NOT_ACCEPTABLE) +public class BrokerVirtualHostModificationException extends Exception { + + public BrokerVirtualHostModificationException(String msg) { + super(msg); + } + + public BrokerVirtualHostModificationException(String msg, Throwable thr) { + super(msg, thr); + } + + public BrokerVirtualHostModificationException(Throwable thr) { + super(thr); + } +} 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 2bad13e644869b64b0a24eee67b2abaee7732c0f..c114506501c05e943bb78298dd0a93d0e72d2533 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 @@ -2,7 +2,6 @@ package at.tuwien.endpoints; import at.tuwien.api.database.*; import at.tuwien.api.error.ApiErrorDto; -import at.tuwien.api.user.UserDto; import at.tuwien.entities.database.Database; import at.tuwien.entities.database.DatabaseAccess; import at.tuwien.entities.user.User; @@ -140,7 +139,7 @@ public class DatabaseEndpoint { throws ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException, AmqpException, ContainerConnectionException, UserNotFoundException, DatabaseNotFoundException, DatabaseNameExistsException, DatabaseConnectionException, - QueryMalformedException, NotAllowedException, BrokerVirtualHostCreationException, QueryStoreException, + QueryMalformedException, NotAllowedException, BrokerVirtualHostModificationException, QueryStoreException, BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException { log.debug("endpoint create database, createDto={}, principal={}", createDto, principal); 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 ecd68ec53e613be9739ebbf80b20958aafb4cf28..e2c6b94814aa6eed26b282fd5c8e8d45281322d6 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 @@ -6,6 +6,7 @@ import at.tuwien.api.user.*; import at.tuwien.entities.user.User; import at.tuwien.exception.*; import at.tuwien.mapper.UserMapper; +import at.tuwien.service.AuthenticationService; import at.tuwien.service.DatabaseService; import at.tuwien.service.MessageQueueService; import at.tuwien.service.UserService; @@ -42,15 +43,16 @@ public class UserEndpoint { private final UserService userService; private final DatabaseService databaseService; private final MessageQueueService messageQueueService; - + private final AuthenticationService authenticationService; @Autowired public UserEndpoint(UserMapper userMapper, UserService userService, DatabaseService databaseService, - MessageQueueService messageQueueService) { + MessageQueueService messageQueueService, AuthenticationService authenticationService) { this.userMapper = userMapper; this.userService = userService; this.databaseService = databaseService; this.messageQueueService = messageQueueService; + this.authenticationService = authenticationService; } @GetMapping @@ -106,14 +108,34 @@ public class UserEndpoint { }) public ResponseEntity<UserBriefDto> create(@NotNull @Valid @RequestBody SignupRequestDto data) throws UserAlreadyExistsException, UserEmailAlreadyExistsException, UserNotFoundException, - KeycloakRemoteException, AccessDeniedException, BrokerRemoteException, BrokerVirtualHostCreationException { + KeycloakRemoteException, AccessDeniedException, BrokerRemoteException, + BrokerVirtualHostModificationException { log.debug("endpoint create a user, data={}", data); /* check */ userService.validateUsernameNotExists(data.getUsername()); userService.validateEmailNotExists(data.getEmail()); /* create */ - final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data)); - messageQueueService.createUser(dto.getUsername()); + authenticationService.create(data); + final at.tuwien.api.keycloak.UserDto keycloakUserDto = authenticationService.findByUsername(data.getUsername()); + try { + messageQueueService.createUser(data.getUsername()); + } catch (BrokerRemoteException e) { + try { + authenticationService.delete(keycloakUserDto.getId()); + } catch (UserNotFoundException e2) { + /* ignore */ + } + throw new BrokerRemoteException(e); + } catch (BrokerVirtualHostModificationException e) { + try { + authenticationService.delete(keycloakUserDto.getId()); + } catch (UserNotFoundException e2) { + /* ignore */ + } + throw new BrokerVirtualHostModificationException(e); + } + final User user = userService.create(data, keycloakUserDto.getId()); + final UserBriefDto dto = userMapper.userToUserBriefDto(user); log.trace("create user resulted in dto {}", dto); return ResponseEntity.status(HttpStatus.CREATED) .body(dto); @@ -278,6 +300,7 @@ public class UserEndpoint { } /* modify password */ userService.updatePassword(id, data); + authenticationService.updatePassword(id, data); return ResponseEntity.accepted() .build(); } diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java index 27663c461e14d4eca46a24f1a9476d8f9d4bffc1..0e10da264304a879b6dcf72b2716e16b4fbaba09 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java @@ -245,8 +245,8 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler { @Hidden @ResponseStatus(HttpStatus.NOT_ACCEPTABLE) - @ExceptionHandler(BrokerVirtualHostCreationException.class) - public ResponseEntity<ApiErrorDto> handle(BrokerVirtualHostCreationException e, WebRequest request) { + @ExceptionHandler(BrokerVirtualHostModificationException.class) + public ResponseEntity<ApiErrorDto> handle(BrokerVirtualHostModificationException e, WebRequest request) { final ApiErrorDto response = ApiErrorDto.builder() .status(HttpStatus.NOT_ACCEPTABLE) .message(e.getLocalizedMessage()) diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java index 42e1d3b2bc700df0962a5864c5d6aac99c1a8c3a..1d61a1108d8ceba8c2eaabaee35a6f1efcfd98d3 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbContainerConfig.java @@ -32,7 +32,7 @@ public class MariaDbContainerConfig { private boolean started = false; public static synchronized CustomMariaDBContainer getInstance() { - if(instance == null) { + if (instance == null) { instance = new CustomMariaDBContainer(BaseTest.IMAGE_1_NAME + ":" + BaseTest.IMAGE_1_VERSION); instance.withImagePullPolicy(PullPolicy.alwaysPull()); instance.addFixedExposedPort(BaseTest.CONTAINER_1_PORT, BaseTest.IMAGE_1_PORT); @@ -56,7 +56,8 @@ public class MariaDbContainerConfig { @Override public synchronized void start() { - if(!started) { + if (!started) { + super.stop(); super.start(); started = true; } 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 66aa04b7fbb20344d4cc1d25cd0108814ff062e6..c13d6ed419a8a72ec078fb0c8da92a32a77ed620 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.BaseUnitTest; import at.tuwien.annotations.MockAmqp; import at.tuwien.annotations.MockOpensearch; import at.tuwien.api.database.*; -import at.tuwien.api.user.UserDto; import at.tuwien.entities.container.Container; import at.tuwien.entities.database.Database; import at.tuwien.entities.database.DatabaseAccess; @@ -116,7 +115,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { public void create_succeeds() throws UserNotFoundException, BrokerVirtualHostGrantException, DatabaseNameExistsException, NotAllowedException, ContainerConnectionException, DatabaseMalformedException, QueryStoreException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, - ImageNotSupportedException, AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException, + ImageNotSupportedException, AmqpException, BrokerVirtualHostModificationException, ContainerNotFoundException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException { final DatabaseCreateDto request = DatabaseCreateDto.builder() .cid(CONTAINER_1_ID) @@ -429,7 +428,7 @@ public class DatabaseEndpointUnitTest extends BaseUnitTest { Principal principal) throws UserNotFoundException, DatabaseNameExistsException, NotAllowedException, ContainerConnectionException, DatabaseMalformedException, QueryStoreException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException, - AmqpException, BrokerVirtualHostCreationException, ContainerNotFoundException, + AmqpException, BrokerVirtualHostModificationException, ContainerNotFoundException, BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException { /* mock */ diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java index 030f8e3c446fd9bd02aa1cc604803c651bc9207f..a7ed7c0c77bf08bceb36bf6f59b0e49a69212e2f 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java @@ -7,6 +7,7 @@ import at.tuwien.api.auth.SignupRequestDto; import at.tuwien.api.user.*; import at.tuwien.entities.user.User; import at.tuwien.exception.*; +import at.tuwien.service.AuthenticationService; import at.tuwien.service.MessageQueueService; import at.tuwien.service.UserService; import lombok.extern.log4j.Log4j2; @@ -44,6 +45,9 @@ public class UserEndpointUnitTest extends BaseUnitTest { @MockBean private MessageQueueService messageQueueService; + @MockBean + private AuthenticationService authenticationService; + @Autowired private UserEndpoint userEndpoint; @@ -66,8 +70,8 @@ public class UserEndpointUnitTest extends BaseUnitTest { @Test @WithAnonymousUser public void create_anonymous_succeeds() throws UserNotFoundException, UserEmailAlreadyExistsException, - RealmNotFoundException, UserAlreadyExistsException, KeycloakRemoteException, - at.tuwien.exception.AccessDeniedException, BrokerRemoteException, BrokerVirtualHostCreationException { + UserAlreadyExistsException, KeycloakRemoteException, + at.tuwien.exception.AccessDeniedException, BrokerRemoteException, BrokerVirtualHostModificationException { final SignupRequestDto request = SignupRequestDto.builder() .email(USER_1_EMAIL) .username(USER_1_USERNAME) @@ -75,7 +79,7 @@ public class UserEndpointUnitTest extends BaseUnitTest { .build(); /* test */ - create_generic(request, USER_1); + create_generic(request, USER_1, USER_1_KEYCLOAK_DTO, USER_1_ID); } @Test @@ -89,7 +93,7 @@ public class UserEndpointUnitTest extends BaseUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - create_generic(request, null); + create_generic(request, null, null, null); }); } @@ -302,16 +306,22 @@ public class UserEndpointUnitTest extends BaseUnitTest { assertEquals(2, body.size()); } - protected void create_generic(SignupRequestDto data, User user) throws UserEmailAlreadyExistsException, - RealmNotFoundException, UserAlreadyExistsException, UserNotFoundException, KeycloakRemoteException, - AccessDeniedException, BrokerRemoteException, BrokerVirtualHostCreationException { + protected void create_generic(SignupRequestDto data, User user, at.tuwien.api.keycloak.UserDto userDto, UUID id) + throws UserEmailAlreadyExistsException, UserAlreadyExistsException, UserNotFoundException, + KeycloakRemoteException, AccessDeniedException, BrokerRemoteException, + BrokerVirtualHostModificationException { /* mock */ - when(userService.create(data)) + when(userService.create(data, id)) .thenReturn(user); doNothing() .when(messageQueueService) .createUser(anyString()); + when(authenticationService.findByUsername(data.getUsername())) + .thenReturn(userDto); + doNothing() + .when(authenticationService) + .create(any(SignupRequestDto.class)); /* test */ final ResponseEntity<UserBriefDto> response = userEndpoint.create(data); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java index 567e9cbbc7d3fb9b1b4f953d8f57352cad636e9b..7e1fd0accb8827f49ba149a62e8d653467c14be8 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/gateway/BrokerServiceGatewayTest.java @@ -4,7 +4,7 @@ import at.tuwien.BaseUnitTest; import at.tuwien.annotations.MockAmqp; import at.tuwien.annotations.MockOpensearch; import at.tuwien.exception.BrokerRemoteException; -import at.tuwien.exception.BrokerVirtualHostCreationException; +import at.tuwien.exception.BrokerVirtualHostModificationException; import at.tuwien.exception.BrokerVirtualHostGrantException; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Test; @@ -38,7 +38,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest { private BrokerServiceGateway brokerServiceGateway; @Test - public void createVirtualHost_succeeds() throws BrokerVirtualHostCreationException, BrokerRemoteException { + public void createVirtualHost_succeeds() throws BrokerVirtualHostModificationException, BrokerRemoteException { final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.CREATED) .build(); @@ -60,7 +60,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest { .thenReturn(mock); /* test */ - assertThrows(BrokerVirtualHostCreationException.class, () -> { + assertThrows(BrokerVirtualHostModificationException.class, () -> { brokerServiceGateway.createVirtualHost(VIRTUAL_HOST_CREATE_DTO); }); } @@ -148,7 +148,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest { } @Test - public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostCreationException { + public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostModificationException { final ResponseEntity<Void> mock = ResponseEntity.status(HttpStatus.NO_CONTENT) .build(); @@ -170,7 +170,7 @@ public class BrokerServiceGatewayTest extends BaseUnitTest { .thenReturn(mock); /* test */ - assertThrows(BrokerVirtualHostCreationException.class, () -> { + assertThrows(BrokerVirtualHostModificationException.class, () -> { brokerServiceGateway.createUser(USER_1_USERNAME); }); } 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 new file mode 100644 index 0000000000000000000000000000000000000000..1f4240a8647e00668c77220a93b155622e4c6fa8 --- /dev/null +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/AuthenticationServiceIntegrationTest.java @@ -0,0 +1,87 @@ +package at.tuwien.service; + +import at.tuwien.BaseUnitTest; +import at.tuwien.annotations.MockAmqp; +import at.tuwien.annotations.MockOpensearch; +import at.tuwien.entities.user.User; +import at.tuwien.exception.*; +import at.tuwien.gateway.KeycloakGateway; +import dasniko.testcontainers.keycloak.KeycloakContainer; +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.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +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.assertEquals; + +@Log4j2 +@Testcontainers +@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@SpringBootTest +@ExtendWith(SpringExtension.class) +@MockAmqp +@MockOpensearch +public class AuthenticationServiceIntegrationTest extends BaseUnitTest { + + @Autowired + private AuthenticationService authenticationService; + + @Autowired + private KeycloakGateway keycloakGateway; + + @Container + private static KeycloakContainer keycloakContainer = new KeycloakContainer("quay.io/keycloak/keycloak:21.0") + .withImagePullPolicy(PullPolicy.alwaysPull()) + .withAdminUsername("fda") + .withAdminPassword("fda") + .withRealmImportFile("./dbrepo-realm.json") + .withEnv("KC_HOSTNAME_STRICT_HTTPS", "false"); + + @DynamicPropertySource + static void keycloakProperties(DynamicPropertyRegistry registry) { + registry.add("fda.keycloak.endpoint", () -> "http://localhost:" + keycloakContainer.getMappedPort(8080)); + } + + @Test + public void delete_succeeds() throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException, + UserEmailAlreadyExistsException, UserAlreadyExistsException { + + /* mock */ + try { + keycloakGateway.deleteUser(keycloakGateway.findByUsername(USER_1_USERNAME).getId()); + } catch (Exception e) { + /* ignore */ + } + keycloakGateway.createUser(USER_1_KEYCLOAK_SIGNUP_REQUEST); + + /* test */ + authenticationService.delete(keycloakGateway.findByUsername(USER_1_USERNAME).getId()); + } + + @Test + public void create_succeeds() throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException, + UserEmailAlreadyExistsException, UserAlreadyExistsException { + + /* mock */ + try { + keycloakGateway.deleteUser(keycloakGateway.findByUsername(USER_1_USERNAME).getId()); + } catch (Exception e) { + /* ignore */ + } + + /* test */ + authenticationService.create(USER_1_SIGNUP_REQUEST_DTO); + } + +} diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java index 7c0c8c5b5cafa57a37a87ffa2b498dbeb6093bf5..8e9c2cb7b9609238afdbf9dd0c05b2a301c0d050 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java @@ -5,7 +5,7 @@ import at.tuwien.annotations.MockOpensearch; import at.tuwien.api.amqp.PermissionDto; import at.tuwien.exception.AmqpException; import at.tuwien.exception.BrokerRemoteException; -import at.tuwien.exception.BrokerVirtualHostCreationException; +import at.tuwien.exception.BrokerVirtualHostModificationException; import at.tuwien.exception.BrokerVirtualHostGrantException; import at.tuwien.repository.mdb.DatabaseRepository; import at.tuwien.repository.mdb.TableRepository; @@ -86,7 +86,7 @@ public class MessageQueueServiceIntegrationTest extends BaseUnitTest { } @Test - public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostCreationException { + public void createUser_succeeds() throws BrokerRemoteException, BrokerVirtualHostModificationException { /* test */ messageQueueService.createUser(USER_1_USERNAME); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java index 5628f041c988611bb0cdf0a2bda9f3cb16dfe68f..07fa1e92b65492df0e267077430297d6f82f77ab 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java @@ -23,6 +23,8 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; 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.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.testcontainers.containers.MariaDBContainer; import org.testcontainers.junit.jupiter.Container; diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java index ad229d6aa39d0d6eb4e6d9c8bf8515f8dd2f571d..ba29bea0102b62422c9f725799cf6ec00f21999c 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java @@ -8,7 +8,6 @@ import at.tuwien.api.user.*; import at.tuwien.entities.user.User; import at.tuwien.exception.*; import at.tuwien.repository.mdb.UserRepository; -import dasniko.testcontainers.keycloak.KeycloakContainer; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -18,12 +17,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; -import org.testcontainers.images.PullPolicy; -import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.List; @@ -46,19 +41,6 @@ public class UserServiceIntegrationTest extends BaseUnitTest { @Autowired private UserService userService; - @Container - private static KeycloakContainer keycloakContainer = new KeycloakContainer("quay.io/keycloak/keycloak:21.0") - .withImagePullPolicy(PullPolicy.alwaysPull()) - .withAdminUsername("fda") - .withAdminPassword("fda") - .withRealmImportFile("./dbrepo-realm.json") - .withEnv("KC_HOSTNAME_STRICT_HTTPS", "false"); - - @DynamicPropertySource - static void elasticsearchProperties(DynamicPropertyRegistry registry) { - registry.add("fda.keycloak.endpoint", () -> "http://localhost:" + keycloakContainer.getMappedPort(8080)); - } - @BeforeEach public void beforeEach() { userRepository.save(USER_1); @@ -100,38 +82,10 @@ public class UserServiceIntegrationTest extends BaseUnitTest { .build(); /* test */ - final User response = userService.create(request); + final User response = userService.create(request, USER_2_ID); assertEquals(USER_2_USERNAME, response.getUsername()); } - @Test - public void create_nonUniqueUsername_fails() { - final SignupRequestDto request = SignupRequestDto.builder() - .username(USER_1_USERNAME) - .password(USER_2_PASSWORD) - .email(USER_2_EMAIL) - .build(); - - /* test */ - assertThrows(UserEmailAlreadyExistsException.class, () -> { - userService.create(request); - }); - } - - @Test - public void create_nonUniqueEmail_fails() { - final SignupRequestDto request = SignupRequestDto.builder() - .username(USER_2_USERNAME) - .password(USER_2_PASSWORD) - .email(USER_1_EMAIL) - .build(); - - /* test */ - assertThrows(UserAlreadyExistsException.class, () -> { - userService.create(request); - }); - } - @Test @Transactional public void modify_succeeds() throws UserNotFoundException { @@ -178,7 +132,7 @@ public class UserServiceIntegrationTest extends BaseUnitTest { .username(USER_3_USERNAME) .password(USER_3_PASSWORD) .email(USER_3_EMAIL) - .build()); + .build(), USER_3_ID); /* test */ userService.updatePassword(user.getId(), request); 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 35fc49b369dd59cff21217a05d54bcf8a07f7096..c5660860ded2c91c65ff500e3a912c1b7d588724 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 @@ -92,7 +92,7 @@ public class UserServiceUnitTest extends BaseUnitTest { .thenReturn(USER_1_KEYCLOAK_DTO); /* test */ - final User response = userService.create(USER_1_SIGNUP_REQUEST_DTO); + final User response = userService.create(USER_1_SIGNUP_REQUEST_DTO, USER_1_ID); assertEquals(USER_1_ID, response.getId()); assertEquals(USER_1_USERNAME, response.getUsername()); } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/BrokerServiceGateway.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/BrokerServiceGateway.java index 0484e1c29a30970f2a003b485c33a34ece164bb5..7e55074f7e1197aaa1e60c1e83ee31e8e5905531 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/BrokerServiceGateway.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/BrokerServiceGateway.java @@ -5,7 +5,7 @@ import at.tuwien.api.amqp.CreateVirtualHostDto; import at.tuwien.api.amqp.GrantVirtualHostPermissionsDto; import at.tuwien.api.user.ExchangeUpdatePermissionsDto; import at.tuwien.exception.BrokerRemoteException; -import at.tuwien.exception.BrokerVirtualHostCreationException; +import at.tuwien.exception.BrokerVirtualHostModificationException; import at.tuwien.exception.BrokerVirtualHostGrantException; import java.util.List; @@ -24,10 +24,10 @@ public interface BrokerServiceGateway { * Create virtual host at the queue service. * * @param data The virtual host. - * @throws BrokerVirtualHostCreationException The virtual host could not be created. - * @throws BrokerRemoteException The Broker Service did not respond within the 3s timeout. + * @throws BrokerVirtualHostModificationException The virtual host could not be created. + * @throws BrokerRemoteException The Broker Service did not respond within the 3s timeout. */ - void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostCreationException, BrokerRemoteException; + void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostModificationException, BrokerRemoteException; /** * Grants a user permission at a virtual host in the queue service. @@ -40,13 +40,22 @@ public interface BrokerServiceGateway { void grantPermission(String username, ExchangeUpdatePermissionsDto data) throws BrokerVirtualHostGrantException, BrokerRemoteException; /** - * Create user on the broker service + * Create user on the broker service with given username. * - * @param username The new username. - * @throws BrokerRemoteException The Broker Service did not respond within the 3s timeout. - * @throws BrokerVirtualHostCreationException The user could not be created. + * @param username The username. + * @throws BrokerRemoteException The Broker Service did not respond within the 3s timeout. + * @throws BrokerVirtualHostModificationException The user could not be created. */ - void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostCreationException; + void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException; + + /** + * Deletes a user on the broker service with given username. + * + * @param username The username. + * @throws BrokerRemoteException The Broker Service did not respond within the 3s timeout. + * @throws BrokerVirtualHostModificationException The user could not be deleted. + */ + void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException; /** * Grants a user permission at a virtual host in the queue service. 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 17e779f918ac5788262e7bb58cc7cd6b27a6acb3..3614e43fcbbbc21c8f9808974355b97b0d6750a4 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,6 +20,16 @@ public interface KeycloakGateway { */ void createUser(UserCreateDto data) throws AccessDeniedException, KeycloakRemoteException, UserAlreadyExistsException, UserEmailAlreadyExistsException; + /** + * Deletes a user at the Authentication Service with given user id. + * + * @param id The user id. + * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout. + * @throws AccessDeniedException The admin token could not be obtained. + * @throws UserNotFoundException The user was not found at the Authentication Service. + */ + void deleteUser(UUID id) throws KeycloakRemoteException, AccessDeniedException, UserNotFoundException; + /** * Update the credentials for a given user. * diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/BrokerServiceGatewayImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/BrokerServiceGatewayImpl.java index 23ab2985a1db6482a7c37fa1f07431d0ca13fa52..a13de9f29ccc761a16aaa4dd5cf18ab11283acf1 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/BrokerServiceGatewayImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/BrokerServiceGatewayImpl.java @@ -5,21 +5,16 @@ import at.tuwien.api.amqp.CreateUserDto; import at.tuwien.api.amqp.CreateVirtualHostDto; import at.tuwien.api.amqp.GrantVirtualHostPermissionsDto; import at.tuwien.api.user.ExchangeUpdatePermissionsDto; -import at.tuwien.config.AmqpConfig; import at.tuwien.config.GatewayConfig; import at.tuwien.exception.BrokerRemoteException; -import at.tuwien.exception.BrokerVirtualHostCreationException; +import at.tuwien.exception.BrokerVirtualHostModificationException; import at.tuwien.exception.BrokerVirtualHostGrantException; -import at.tuwien.exception.KeycloakRemoteException; import at.tuwien.gateway.BrokerServiceGateway; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.codec.binary.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.env.Environment; import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,8 +22,6 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.net.URI; -import java.nio.charset.Charset; -import java.util.Arrays; import java.util.List; @Slf4j @@ -48,7 +41,7 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway { } @Override - public void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostCreationException, BrokerRemoteException { + public void createVirtualHost(CreateVirtualHostDto data) throws BrokerVirtualHostModificationException, BrokerRemoteException { final String url = "/api/vhost"; log.trace("POST {}{}", gatewayConfig.getBrokerEndpoint(), url); final ResponseEntity<Void> response; @@ -60,7 +53,7 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway { } if (!response.getStatusCode().equals(HttpStatus.CREATED)) { log.error("Failed to create virtual host: {}", response.getStatusCode()); - throw new BrokerVirtualHostCreationException("Failed to create virtual host"); + throw new BrokerVirtualHostModificationException("Failed to create virtual host"); } log.info("Create virtual host with name {}", data.getName()); } @@ -85,7 +78,7 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway { } @Override - public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostCreationException { + public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException { final CreateUserDto data = CreateUserDto.builder() .passwordHash("") .tags("") @@ -101,11 +94,29 @@ public class BrokerServiceGatewayImpl implements BrokerServiceGateway { } if (!response.getStatusCode().equals(HttpStatus.CREATED) && !response.getStatusCode().equals(HttpStatus.NO_CONTENT)) { log.error("Failed to create user: {}", response.getStatusCode()); - throw new BrokerVirtualHostCreationException("Failed to create user"); + throw new BrokerVirtualHostModificationException("Failed to create user"); } log.info("Created user with username {}", username); } + @Override + public void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException { + final String url = "/api/users/" + username; + log.trace("DELETE {}{}", gatewayConfig.getBrokerEndpoint(), url); + final ResponseEntity<Void> response; + try { + response = restTemplate.exchange(url, HttpMethod.DELETE, new HttpEntity<>(null), Void.class); + } catch (Exception e) { + log.error("Failed to delete user: remote host answered unexpected: {}", e.getMessage()); + throw new BrokerRemoteException("Failed to delete user: remote host answered unexpected", e); + } + if (!response.getStatusCode().equals(HttpStatus.NO_CONTENT)) { + log.error("Failed to delete user: {}", response.getStatusCode()); + throw new BrokerVirtualHostModificationException("Failed to create user"); + } + log.info("Deleted user with username {}", username); + } + @Override public void grantPermission(String username, GrantVirtualHostPermissionsDto data) throws BrokerRemoteException, BrokerVirtualHostGrantException { 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 d887fd8eb27c918dfb7c2889885fe689d84263bd..6f29d138ffb858c526e1e18b0f76c0d27cb5d99c 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 @@ -87,6 +87,35 @@ public class KeycloakGatewayImpl implements KeycloakGateway { log.error("Failed to create user: status {} was not expected", response.getStatusCode().value()); throw new KeycloakRemoteException("Failed to create user: status " + response.getStatusCode().value() + "was not expected"); } + log.info("Created user {} at authentication service", data.getUsername()); + } + + @Override + public void deleteUser(UUID id) throws KeycloakRemoteException, AccessDeniedException, UserNotFoundException { + /* obtain admin token */ + final HttpHeaders headers = new HttpHeaders(); + headers.set("Accept", "application/json"); + headers.set("Authorization", "Bearer " + obtainToken().getAccessToken()); + final String url = keycloakConfig.getKeycloakEndpoint() + "/admin/realms/dbrepo/users/" + id; + log.debug("delete user at url {}", url); + final ResponseEntity<Void> response; + try { + response = restTemplate.exchange(url, HttpMethod.DELETE, new HttpEntity<>(null, headers), Void.class); + } catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) { + log.error("Failed to delete user: {}", e.getMessage()); + throw new KeycloakRemoteException("Failed to delete user: " + e.getMessage()); + } catch (HttpClientErrorException.NotFound e) { + log.error("User does not exist: {}", e.getMessage()); + throw new UserNotFoundException("User does not exist: " + e.getMessage()); + } catch (Exception e) { + log.error("Failed to delete user: remote host answered unexpected: {}", e.getMessage()); + throw new KeycloakRemoteException("Failed to delete user: remote host answered unexpected", e); + } + if (!response.getStatusCode().equals(HttpStatus.NO_CONTENT)) { + log.error("Failed to delete user: status {} was not expected", response.getStatusCode().value()); + throw new KeycloakRemoteException("Failed to delete user: status " + response.getStatusCode().value() + "was not expected"); + } + log.info("Deleted user {} at authentication service", id); } @Override @@ -113,6 +142,7 @@ public class KeycloakGatewayImpl implements KeycloakGateway { log.error("Failed to update user credentials: status {} was not expected", response.getStatusCode().value()); throw new KeycloakRemoteException("Failed to update user credentials: status " + response.getStatusCode().value() + "was not expected"); } + log.info("Updated user {} password at authentication service", id); } @Override 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 new file mode 100644 index 0000000000000000000000000000000000000000..a39e0d66c20348a35d5d2fcafbbd7ab1a364fd85 --- /dev/null +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java @@ -0,0 +1,47 @@ +package at.tuwien.service; + +import at.tuwien.api.auth.SignupRequestDto; +import at.tuwien.api.keycloak.UserDto; +import at.tuwien.api.user.UserPasswordDto; +import at.tuwien.exception.*; + +import java.util.UUID; + +public interface AuthenticationService { + + /** + * Create a user at the Authentication Service with given credentials. + * + * @param data The credentials. + * @throws AccessDeniedException The admin token could not be obtained. + * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout. + * @throws UserAlreadyExistsException The user already exists at the Authentication Service. + * @throws UserEmailAlreadyExistsException The user email already exists in the metadata database. + */ + void create(SignupRequestDto data) throws KeycloakRemoteException, AccessDeniedException, + UserEmailAlreadyExistsException, UserAlreadyExistsException; + + /** + * Deletes a user at the Authentication Service with given user id. + * + * @param userId The user id. + * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout. + * @throws AccessDeniedException The admin token could not be obtained. + * @throws UserNotFoundException The user was not found at the Authentication Service. + */ + void delete(UUID userId) throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException; + + /** + * Finds a user with given username. + * + * @param username The username. + * @return The user, if successful. + * @throws UserNotFoundException The user was not found at the Authentication Service. + * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout. + * @throws AccessDeniedException The admin token could not be obtained. + */ + UserDto findByUsername(String username) throws UserNotFoundException, KeycloakRemoteException, + AccessDeniedException; + + void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException; +} diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java index 50fe5233773cff80774be54bb3c09f7ceb68ef74..3d21c91a521e6e581f1ac7886f5d98bd44fdfc82 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java @@ -1,12 +1,11 @@ package at.tuwien.service; -import at.tuwien.api.user.UserDto; import at.tuwien.entities.database.Database; import at.tuwien.entities.database.table.Table; import at.tuwien.entities.user.User; import at.tuwien.exception.AmqpException; import at.tuwien.exception.BrokerRemoteException; -import at.tuwien.exception.BrokerVirtualHostCreationException; +import at.tuwien.exception.BrokerVirtualHostModificationException; import at.tuwien.exception.BrokerVirtualHostGrantException; import jakarta.annotation.PostConstruct; @@ -44,13 +43,22 @@ public interface MessageQueueService { void create(Table table) throws AmqpException; /** - * Create user on the broker service + * Create user on the broker service with given username. * * @param username The username. - * @throws BrokerRemoteException The user could not be created. + * @throws BrokerRemoteException The user could not be created. + * @throws BrokerVirtualHostModificationException The Broker Service did not respond within the 3s timeout. */ - void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostCreationException; + void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException; + /** + * Delete a user on the broker service with given username. + * + * @param username The username. + * @throws BrokerRemoteException The user could not be deleted. + * @throws BrokerVirtualHostModificationException The Broker Service did not respond within the 3s timeout. + */ + void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException; /** * Updates the virtual host permissions in the Broker Service for a user with given principal. diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java index 3b94ad5d903eb52a0d17a5c869c2af897f205a3f..a5edcc519c9643afc2915217eaebd14df20550ac 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java @@ -42,7 +42,7 @@ public interface UserService { * @return The user, if successful. False otherwise. * @throws UserAlreadyExistsException The user already exists in the metadata database. */ - User create(SignupRequestDto data) throws UserAlreadyExistsException, AccessDeniedException, + User create(SignupRequestDto data, UUID id) throws UserAlreadyExistsException, AccessDeniedException, KeycloakRemoteException, UserNotFoundException, UserEmailAlreadyExistsException; /** @@ -61,7 +61,7 @@ public interface UserService { * @param id The user id. * @param data The new password. */ - void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException, UserNotFoundException; + void updatePassword(UUID id, UserPasswordDto data) throws UserNotFoundException; /** * Updates the user theme for a user with given id. 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 new file mode 100644 index 0000000000000000000000000000000000000000..4a8a6c7fb3e9a195c83fe60c512e2af2ba69a413 --- /dev/null +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AuthenticationServiceImpl.java @@ -0,0 +1,51 @@ +package at.tuwien.service.impl; + +import at.tuwien.api.auth.SignupRequestDto; +import at.tuwien.api.keycloak.UserDto; +import at.tuwien.api.user.UserPasswordDto; +import at.tuwien.exception.*; +import at.tuwien.gateway.KeycloakGateway; +import at.tuwien.mapper.UserMapper; +import at.tuwien.service.AuthenticationService; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Log4j2 +@Service +public class AuthenticationServiceImpl implements AuthenticationService { + + private final UserMapper userMapper; + private final KeycloakGateway keycloakGateway; + + @Autowired + public AuthenticationServiceImpl(UserMapper userMapper, KeycloakGateway keycloakGateway) { + this.userMapper = userMapper; + this.keycloakGateway = keycloakGateway; + } + + @Override + public void create(SignupRequestDto data) throws KeycloakRemoteException, AccessDeniedException, + UserEmailAlreadyExistsException, UserAlreadyExistsException { + keycloakGateway.createUser(userMapper.signupRequestDtoToUserCreateDto(data)); + } + + @Override + public void delete(UUID userId) throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException { + keycloakGateway.deleteUser(userId); + } + + @Override + public UserDto findByUsername(String username) throws UserNotFoundException, KeycloakRemoteException, + AccessDeniedException { + return keycloakGateway.findByUsername(username); + } + + @Override + public void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException { + keycloakGateway.updateUserCredentials(id, data); + } + +} diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/RabbitMqServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/RabbitMqServiceImpl.java index 56c102131aa3a79b72f8b9c18f9f233902bac584..3c7758a8f715ad2d76130108a52b1f36d972ae59 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/RabbitMqServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/RabbitMqServiceImpl.java @@ -9,7 +9,7 @@ import at.tuwien.entities.database.table.Table; import at.tuwien.entities.user.User; import at.tuwien.exception.AmqpException; import at.tuwien.exception.BrokerRemoteException; -import at.tuwien.exception.BrokerVirtualHostCreationException; +import at.tuwien.exception.BrokerVirtualHostModificationException; import at.tuwien.exception.BrokerVirtualHostGrantException; import at.tuwien.gateway.BrokerServiceGateway; import at.tuwien.mapper.AmqpMapper; @@ -104,10 +104,15 @@ public class RabbitMqServiceImpl implements MessageQueueService { } @Override - public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostCreationException { + public void createUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException { brokerServiceGateway.createUser(username); } + @Override + public void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException { + brokerServiceGateway.deleteUser(username); + } + @Override public void updatePermissions(User user) throws BrokerRemoteException, BrokerVirtualHostGrantException { final GrantVirtualHostPermissionsDto permissions = GrantVirtualHostPermissionsDto.builder() diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java index d6862071b92172c548cbecf2650bb5b663ade17c..1baf6ff415e5c5b47c81974bd9d42a2588300a48 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java @@ -63,18 +63,17 @@ public class UserServiceImpl implements UserService { } @Override - public User create(SignupRequestDto data) throws UserAlreadyExistsException, AccessDeniedException, + public User create(SignupRequestDto data, UUID id) throws UserAlreadyExistsException, AccessDeniedException, KeycloakRemoteException, UserNotFoundException, UserEmailAlreadyExistsException { /* create at authentication service */ final User entity = User.builder() + .id(id) .username(data.getUsername()) .email(data.getEmail()) .themeDark(false) .mariadbPassword(getMariaDbPassword(data.getPassword())) .build(); - keycloakGateway.createUser(userMapper.signupRequestDtoToUserCreateDto(data)); /* create at metadata database */ - entity.setId(keycloakGateway.findByUsername(data.getUsername()).getId()); final User user = userRepository.save(entity); log.info("Created user with id {} in metadata database", user.getId()); /* save in open search database */ @@ -96,14 +95,10 @@ public class UserServiceImpl implements UserService { } @Override - public void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException, - UserNotFoundException { + public void updatePassword(UUID id, UserPasswordDto data) throws UserNotFoundException { final User user = find(id); user.setMariadbPassword(getMariaDbPassword(data.getPassword())); userRepository.save(user); - log.debug("updated password in metadata database"); - keycloakGateway.updateUserCredentials(id, data); - log.debug("updated password in keycloak"); log.info("Updated user password with id {}", id); } diff --git a/docker-compose.yml b/docker-compose.yml index 6d7771334b20b2b65c99ddda0a19c6ea35385536..c6e753c4d44122f8cfd38b3f17f28b76454288cb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -157,7 +157,7 @@ services: BASE_URL: "${BASE_URL:-http://localhost}" GRANT_PRIVILEGES: "${GRANT_PRIVILEGES:-SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE}" BROKER_CONSUMERS: "${BROKER_CONSUMERS:-2}" - BROKER_ENDPOINT: "${BROKER_ENDPOINT:-http://broker-service:15672}" + BROKER_ENDPOINT: "${BROKER_ENDPOINT:-http://broker-service:15672/admin/broker}" BROKER_USERNAME: "${BROKER_USERNAME:-fda}" BROKER_PASSWORD: "${BROKER_PASSWORD:-fda}" DELETED_RECORD: "${DELETED_RECORD:-persistent}"