Skip to content
Snippets Groups Projects
Unverified Commit 95bf2406 authored by Martin Weise's avatar Martin Weise
Browse files

Reworked the rollback

parent 73057787
No related branches found
No related tags found
4 merge requests!231CI: Remove build for log-service,!228Better error message handling in the frontend,!223Release of version 1.4.0,!194Hotfix
Showing
with 315 additions and 105 deletions
......@@ -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
......
......@@ -4,17 +4,17 @@ import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(code = HttpStatus.NOT_ACCEPTABLE)
public class BrokerVirtualHostCreationException extends Exception {
public class BrokerVirtualHostModificationException extends Exception {
public BrokerVirtualHostCreationException(String msg) {
public BrokerVirtualHostModificationException(String msg) {
super(msg);
}
public BrokerVirtualHostCreationException(String msg, Throwable thr) {
public BrokerVirtualHostModificationException(String msg, Throwable thr) {
super(msg, thr);
}
public BrokerVirtualHostCreationException(Throwable thr) {
public BrokerVirtualHostModificationException(Throwable thr) {
super(thr);
}
}
......@@ -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);
......
......@@ -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();
}
......
......@@ -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())
......
......@@ -57,6 +57,7 @@ public class MariaDbContainerConfig {
@Override
public synchronized void start() {
if (!started) {
super.stop();
super.start();
started = true;
}
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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);
});
}
......
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);
}
}
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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());
}
......
......@@ -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 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.
* @param username The username.
* @throws BrokerRemoteException The Broker Service did not respond within the 3s timeout.
* @throws BrokerVirtualHostCreationException The user could not be created.
* @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.
......
......@@ -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.
*
......
......@@ -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 {
......
......@@ -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
......
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;
}
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 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.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment