diff --git a/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java index 8fb1f607d9552021598254f1df8e1c36f34d6b33..4b93e2f751ad1f2614bd239ae644733855b7e417 100644 --- a/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java @@ -1138,7 +1138,7 @@ public abstract class BaseTest { public final static Database DATABASE_2 = Database.builder() .id(DATABASE_2_ID) - .created(DATABASE_1_CREATED) + .created(DATABASE_2_CREATED) .lastModified(Instant.now()) .isPublic(DATABASE_2_PUBLIC) .name(DATABASE_2_NAME) @@ -1160,7 +1160,7 @@ public abstract class BaseTest { public final static Database DATABASE_2_SIMPLE = Database.builder() .id(DATABASE_2_ID) - .created(DATABASE_1_CREATED) + .created(DATABASE_2_CREATED) .lastModified(Instant.now()) .isPublic(DATABASE_2_PUBLIC) .name(DATABASE_2_NAME) diff --git a/dbrepo-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index 60f9de04690d74e20234aabe8071fc4de00612b0..b345c7ced3a021bc3aef6707365c7b186016377d 100644 --- a/dbrepo-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -3,10 +3,13 @@ package at.tuwien.endpoints; import at.tuwien.api.database.table.*; import at.tuwien.api.error.ApiErrorDto; import at.tuwien.entities.database.table.Table; +import at.tuwien.entities.user.User; import at.tuwien.exception.*; import at.tuwien.mapper.TableMapper; +import at.tuwien.service.DatabaseService; import at.tuwien.service.MessageQueueService; import at.tuwien.service.TableService; +import at.tuwien.validation.EndpointValidator; import io.micrometer.core.annotation.Timed; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -37,12 +40,15 @@ public class TableEndpoint { private final TableMapper tableMapper; private final TableService tableService; private final MessageQueueService amqpService; + private final EndpointValidator endpointValidator; @Autowired - public TableEndpoint(TableMapper tableMapper, TableService tableService, MessageQueueService amqpService) { + public TableEndpoint(TableMapper tableMapper, TableService tableService, MessageQueueService amqpService, + EndpointValidator endpointValidator) { this.tableMapper = tableMapper; this.amqpService = amqpService; this.tableService = tableService; + this.endpointValidator = endpointValidator; } @GetMapping @@ -69,9 +75,11 @@ public class TableEndpoint { public ResponseEntity<List<TableBriefDto>> list(@NotNull @PathVariable("id") Long containerId, @NotNull @PathVariable("databaseId") Long databaseId, Principal principal) - throws DatabaseNotFoundException { + throws DatabaseNotFoundException, NotAllowedException { log.debug("endpoint list tables, containerId={}, databaseId={}, principal={}", containerId, databaseId, principal); + endpointValidator.validateOnlyPrivateAccess(containerId, databaseId, principal); + endpointValidator.validateOnlyPrivateHasRole(containerId, databaseId, principal, "list-tables"); final List<TableBriefDto> dto = tableService.findAll(containerId, databaseId) .stream() .map(tableMapper::tableToTableBriefDto) @@ -131,6 +139,7 @@ public class TableEndpoint { NotAllowedException { log.debug("endpoint create table, containerId={}, databaseId={}, createDto={}, principal={}", containerId, databaseId, createDto, principal); + endpointValidator.validateOnlyAccess(databaseId, principal, true); final Table table = tableService.createTable(containerId, databaseId, createDto, principal); amqpService.create(table); final TableBriefDto dto = tableMapper.tableToTableBriefDto(table); @@ -170,9 +179,14 @@ public class TableEndpoint { @NotNull @PathVariable("databaseId") Long databaseId, @NotNull @PathVariable("tableId") Long tableId, Principal principal) - throws TableNotFoundException, DatabaseNotFoundException, ContainerNotFoundException { + throws TableNotFoundException, DatabaseNotFoundException, ContainerNotFoundException, NotAllowedException { log.debug("endpoint find table, containerId={}, databaseId={}, tableId={}, principal={}", containerId, databaseId, tableId, principal); + endpointValidator.validateOnlyPrivateAccess(containerId, databaseId, principal); + if (principal != null && User.hasRole(principal, "find-table")) { + log.error("Failed to find table: role is missing"); + throw new NotAllowedException("Failed to find table: role is missing"); + } final Table table = tableService.findById(containerId, databaseId, tableId); final TableDto dto = tableMapper.tableToTableDto(table); log.trace("find table resulted in table {}", dto); @@ -222,13 +236,14 @@ public class TableEndpoint { schema = @Schema(implementation = ApiErrorDto.class))}), }) public ResponseEntity<Void> delete(@NotNull @PathVariable("id") Long containerId, - @NotNull @PathVariable("databaseId") Long databaseId, - @NotNull @PathVariable("tableId") Long tableId, - @NotNull Principal principal) + @NotNull @PathVariable("databaseId") Long databaseId, + @NotNull @PathVariable("tableId") Long tableId, + @NotNull Principal principal) throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException, - DataProcessingException, ContainerNotFoundException, TableMalformedException, QueryMalformedException { + DataProcessingException, ContainerNotFoundException, TableMalformedException, QueryMalformedException, NotAllowedException { log.debug("endpoint delete table, containerId={}, databaseId={}, tableId={}, principal={}", containerId, databaseId, tableId, principal); + endpointValidator.validateOnlyOwner(containerId, databaseId, principal); tableService.deleteTable(containerId, databaseId, tableId); return ResponseEntity.accepted() .build(); diff --git a/dbrepo-table-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java b/dbrepo-table-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..ce238cc55a3eb8833cd7c000ad53f0b52f749c58 --- /dev/null +++ b/dbrepo-table-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java @@ -0,0 +1,97 @@ +package at.tuwien.validation; + +import at.tuwien.entities.database.AccessType; +import at.tuwien.entities.database.Database; +import at.tuwien.entities.database.DatabaseAccess; +import at.tuwien.entities.user.User; +import at.tuwien.exception.DatabaseNotFoundException; +import at.tuwien.exception.NotAllowedException; +import at.tuwien.service.AccessService; +import at.tuwien.service.DatabaseService; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.security.Principal; + +@Log4j2 +@Component +public class EndpointValidator { + + private final AccessService accessService; + private final DatabaseService databaseService; + + @Autowired + public EndpointValidator(AccessService accessService, DatabaseService databaseService) { + this.accessService = accessService; + this.databaseService = databaseService; + } + + public void validateOnlyAccess(Long databaseId, Principal principal) throws NotAllowedException { + validateOnlyAccess(databaseId, principal, false); + } + + public void validateOnlyPrivateAccess(Long containerId, Long databaseId, Principal principal, boolean writeAccessOnly) throws NotAllowedException, DatabaseNotFoundException { + final Database database = databaseService.find(containerId, databaseId); + if (database.getIsPublic()) { + log.trace("database with id {} is public: no access needed", databaseId); + return; + } + validateOnlyAccess(databaseId, principal, writeAccessOnly); + } + + public void validateOnlyPrivateAccess(Long containerId, Long databaseId, Principal principal) throws NotAllowedException, DatabaseNotFoundException { + validateOnlyPrivateAccess(containerId, databaseId, principal, false); + } + + public void validateOnlyAccess(Long databaseId, Principal principal, boolean writeAccessOnly) throws NotAllowedException { + log.trace("database with id {} is private", databaseId); + if (principal == null) { + log.error("Access not allowed: database with id {} is not public and no authorization provided", databaseId); + throw new NotAllowedException("Access not allowed: database with id " + databaseId + " is not public and no authorization provided"); + } + log.trace("principal is {}", principal); + final DatabaseAccess access = accessService.find(databaseId, principal.getName()); + log.trace("found access {}", access); + if (writeAccessOnly && !(access.getType().equals(AccessType.WRITE_OWN) || access.getType().equals(AccessType.WRITE_ALL))) { + log.error("Access not allowed: no write access"); + throw new NotAllowedException("Access not allowed: no write access"); + } + } + + public void validateOnlyOwner(Long containerId, Long databaseId, Principal principal) + throws DatabaseNotFoundException, NotAllowedException { + final Database database = databaseService.find(containerId, databaseId); + if (principal == null) { + log.error("Access not allowed: no authorization provided"); + throw new NotAllowedException("Access not allowed: no authorization provided"); + } + log.trace("principal is {}", principal); + final DatabaseAccess access = accessService.find(databaseId, principal.getName()); + log.trace("found access {}", access); + if (!database.getOwner().equals(principal)) { + log.error("Access not allowed: not the owner of this database with id {}", databaseId); + throw new NotAllowedException("Access not allowed: not the owner of this database"); + } + } + + public void validateOnlyPrivateHasRole(Long containerId, Long databaseId, Principal principal, String role) + throws DatabaseNotFoundException, NotAllowedException { + final Database database = databaseService.find(containerId, databaseId); + if (database.getIsPublic()) { + log.trace("database with id {} is public: no access needed", databaseId); + return; + } + log.trace("database with id {} is private", databaseId); + if (principal == null) { + log.error("Access not allowed: no authorization provided"); + throw new NotAllowedException("Access not allowed: no authorization provided"); + } + log.trace("principal is {}", principal); + if (!User.hasRole(principal, role)) { + log.error("Access not allowed: role {} missing", role); + throw new NotAllowedException("Access not allowed: role " + role + " missing"); + } + log.trace("principal has role '{}': access granted", role); + } +} diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java index 04daf45d0bfd517513bcf1e066307bdcf7a74fb7..08554b354c24ea8081f222c1a2a3d86d30c7e7df 100644 --- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java +++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java @@ -1,28 +1,48 @@ package at.tuwien.endpoint; import at.tuwien.BaseUnitTest; +import at.tuwien.api.database.table.TableBriefDto; +import at.tuwien.api.database.table.TableCreateDto; +import at.tuwien.api.database.table.TableDto; import at.tuwien.config.IndexConfig; import at.tuwien.config.ReadyConfig; import at.tuwien.endpoints.TableEndpoint; -import at.tuwien.exception.DatabaseNotFoundException; +import at.tuwien.entities.database.Database; +import at.tuwien.entities.database.DatabaseAccess; +import at.tuwien.exception.*; import at.tuwien.repository.elastic.TableColumnIdxRepository; import at.tuwien.repository.elastic.TableIdxRepository; import at.tuwien.repository.jpa.*; +import at.tuwien.service.AccessService; import at.tuwien.service.DatabaseService; import com.rabbitmq.client.Channel; +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.autoconfigure.EnableAutoConfiguration; +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.http.HttpStatus; +import org.springframework.http.ResponseEntity; +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 static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; -@ExtendWith(SpringExtension.class) +@Log4j2 +@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @SpringBootTest +@ExtendWith(SpringExtension.class) public class TableEndpointUnitTest extends BaseUnitTest { @MockBean @@ -40,36 +60,267 @@ public class TableEndpointUnitTest extends BaseUnitTest { @MockBean private TableColumnIdxRepository tableColumnidxRepository; - @Autowired - private ContainerRepository containerRepository; - - @Autowired - private ImageRepository imageRepository; + @MockBean + private DatabaseService databaseService; - @Autowired - private UserRepository userRepository; + @MockBean + private TableRepository tableRepository; - @Autowired - private RealmRepository realmRepository; + @MockBean + private AccessService accessService; @Autowired private TableEndpoint tableEndpoint; @BeforeEach public void beforeEach() { - /* metadata database */ - imageRepository.save(IMAGE_1_SIMPLE); - realmRepository.save(REALM_DBREPO); - userRepository.save(USER_1_SIMPLE); - containerRepository.save(CONTAINER_1_SIMPLE); + DATABASE_1.setTables(List.of(TABLE_1, TABLE_2, TABLE_3, TABLE_7)); + DATABASE_3.setTables(List.of(TABLE_8)); + } + + @Test + @WithAnonymousUser + public void list_publicAnonymous_succeeds() throws NotAllowedException, DatabaseNotFoundException { + + /* test */ + generic_list(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, null, null, null); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = "find-table") + public void list_publicHasRoleDatabaseNotFound_fails() { + + /* test */ + assertThrows(DatabaseNotFoundException.class, () -> { + generic_list(CONTAINER_3_ID, DATABASE_3_ID, null, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_3_RESEARCHER_READ_ACCESS); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = "find-table") + public void list_publicHasRole_succeeds() throws DatabaseNotFoundException, NotAllowedException { + + /* test */ + final ResponseEntity<List<TableBriefDto>> response = generic_list(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_READ_ACCESS); + assertEquals(HttpStatus.OK, response.getStatusCode()); + final List<TableBriefDto> body = response.getBody(); + assertNotNull(body); + assertEquals(1, body.size()); + } + + @Test + @WithMockUser(username = USER_4_USERNAME) + public void list_publicNoRole_succeeds() throws NotAllowedException, DatabaseNotFoundException { + + /* test */ + generic_list(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, USER_4_USERNAME, USER_4_PRINCIPAL, null); + } + + @Test + @WithAnonymousUser + public void create_publicAnonymous_fails() { + + /* test */ + assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { + generic_create(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, TABLE_4_CREATE_DTO, null, null, null); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"}) + public void create_publicHasRoleDatabaseNotFound_fails() { + + /* test */ + assertThrows(DatabaseNotFoundException.class, () -> { + generic_create(CONTAINER_3_ID, DATABASE_3_ID, null, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_3_RESEARCHER_WRITE_OWN_ACCESS); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"}) + public void create_publicHasRoleNoAccess_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_create(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, null); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME) + public void create_publicNoRole_fails() { + + /* test */ + assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { + generic_create(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_3_RESEARCHER_WRITE_OWN_ACCESS); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"}) + public void create_publicHasRoleOnlyReadAccess_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_create(CONTAINER_3_ID, DATABASE_3_ID, DATABASE_3, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_3_RESEARCHER_READ_ACCESS); + }); + } + + /* ################################################################################################### */ + /* ## PRIVATE DATABASES ## */ + /* ################################################################################################### */ + + @Test + @WithAnonymousUser + public void list_privateAnonymous_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_list(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, null, null, null); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = "find-table") + public void list_privateHasRoleDatabaseNotFound_fails() { + + /* test */ + assertThrows(DatabaseNotFoundException.class, () -> { + generic_list(CONTAINER_1_ID, DATABASE_1_ID, null, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_READ_ACCESS); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = "find-table") + public void list_privateHasRole_succeeds() throws DatabaseNotFoundException, NotAllowedException { + + /* test */ + final ResponseEntity<List<TableBriefDto>> response = generic_list(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_READ_ACCESS); + assertEquals(HttpStatus.OK, response.getStatusCode()); + final List<TableBriefDto> body = response.getBody(); + assertNotNull(body); + assertEquals(4, body.size()); + } + + @Test + @WithMockUser(username = USER_4_USERNAME) + public void list_privateNoRole_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_list(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, USER_4_USERNAME, USER_4_PRINCIPAL, null); + }); + } + + @Test + @WithAnonymousUser + public void create_privateAnonymous_fails() { + + /* test */ + assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { + generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, TABLE_4_CREATE_DTO, null, null, null); + }); } @Test - public void list_databaseNotFound_fails() { + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"}) + public void create_privateHasRoleDatabaseNotFound_fails() { /* test */ assertThrows(DatabaseNotFoundException.class, () -> { - tableEndpoint.list(CONTAINER_1_ID, DATABASE_1_ID, USER_1_PRINCIPAL); + generic_create(CONTAINER_1_ID, DATABASE_1_ID, null, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_WRITE_OWN_ACCESS); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"}) + public void create_privateHasRoleNoAccess_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, null); }); } + + @Test + @WithMockUser(username = USER_1_USERNAME) + public void create_privateNoRole_fails() { + + /* test */ + assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { + generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_WRITE_OWN_ACCESS); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-table"}) + public void create_privateHasRoleOnlyReadAccess_fails() { + + /* test */ + assertThrows(NotAllowedException.class, () -> { + generic_create(CONTAINER_1_ID, DATABASE_1_ID, DATABASE_1, TABLE_4_CREATE_DTO, USER_1_USERNAME, USER_1_PRINCIPAL, DATABASE_1_RESEARCHER_READ_ACCESS); + }); + } + + /* ################################################################################################### */ + /* ## GENERIC TEST CASES ## */ + /* ################################################################################################### */ + + protected ResponseEntity<List<TableBriefDto>> generic_list(Long containerId, Long databaseId, Database database, String username, Principal principal, DatabaseAccess access) throws DatabaseNotFoundException, NotAllowedException { + + /* when */ + if (database != null) { + when(databaseService.find(containerId, databaseId)) + .thenReturn(database); + log.trace("mock {} tables", database.getTables().size()); + when(tableRepository.findByDatabaseOrderByCreatedDesc(any(Database.class))) + .thenReturn(database.getTables()); + } else { + doThrow(DatabaseNotFoundException.class) + .when(databaseService) + .find(containerId, databaseId); + when(tableRepository.findByDatabaseOrderByCreatedDesc(any(Database.class))) + .thenReturn(List.of()); + } + if (access != null) { + when(accessService.find(databaseId, username)) + .thenReturn(access); + } else { + doThrow(NotAllowedException.class) + .when(accessService) + .find(databaseId, username); + } + + /* test */ + return tableEndpoint.list(containerId, databaseId, principal); + } + + protected ResponseEntity<TableBriefDto> generic_create(Long containerId, Long databaseId, Database database, TableCreateDto data, String username, Principal principal, DatabaseAccess access) throws DatabaseNotFoundException, NotAllowedException, UserNotFoundException, TableMalformedException, QueryMalformedException, ImageNotSupportedException, AmqpException, TableNameExistsException, ContainerNotFoundException { + + /* when */ + if (database != null) { + when(databaseService.find(containerId, databaseId)) + .thenReturn(database); + log.trace("mock {} tables", database.getTables().size()); + when(tableRepository.findByDatabaseOrderByCreatedDesc(any(Database.class))) + .thenReturn(database.getTables()); + } else { + doThrow(DatabaseNotFoundException.class) + .when(databaseService) + .find(containerId, databaseId); + when(tableRepository.findByDatabaseOrderByCreatedDesc(any(Database.class))) + .thenReturn(List.of()); + } + if (access != null) { + when(accessService.find(databaseId, username)) + .thenReturn(access); + } else { + doThrow(NotAllowedException.class) + .when(accessService) + .find(databaseId, username); + } + + /* test */ + return tableEndpoint.create(containerId, databaseId, data, principal); + } } diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/ElasticSearchIndexIntegrationTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/ElasticSearchIndexIntegrationTest.java index 4f1495317503816684bf80a0812d6ff7bc4b9090..3ad760a0b8236f9d1814839af7200546a3179020 100644 --- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/ElasticSearchIndexIntegrationTest.java +++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/ElasticSearchIndexIntegrationTest.java @@ -3,12 +3,15 @@ package at.tuwien.service; import at.tuwien.BaseUnitTest; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.extension.ExtendWith; +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.junit.jupiter.SpringExtension; @Log4j2 @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @SpringBootTest @ExtendWith(SpringExtension.class) public class ElasticSearchIndexIntegrationTest extends BaseUnitTest { diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java index d808459c0808115294b21d7d5c3eb3503254833d..b29d7752a4e410b5e86dbc194ceb818b596572ba 100644 --- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java +++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/MessageQueueServiceIntegrationTest.java @@ -9,16 +9,10 @@ import at.tuwien.exception.*; import at.tuwien.repository.elastic.TableColumnIdxRepository; import at.tuwien.repository.elastic.TableIdxRepository; import at.tuwien.repository.jpa.TableRepository; -import at.tuwien.test.BaseTest; import at.tuwien.utils.AmqpUtils; -import com.github.dockerjava.api.command.CreateContainerResponse; -import com.github.dockerjava.api.exception.NotModifiedException; -import com.github.dockerjava.api.model.Network; -import com.github.dockerjava.api.model.PortBinding; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -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; @@ -26,7 +20,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit.jupiter.SpringExtension; -import java.util.Arrays; import java.util.List; import static org.junit.jupiter.api.Assertions.*; diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java index 0d529abc1c2e72ae8b4a3bcdc33379a0a981b8a3..d6e09d16241553b574ee5061546f32111891ade9 100644 --- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java +++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java @@ -15,6 +15,8 @@ import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.*; 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.boot.test.mock.mockito.MockBean; import org.springframework.test.annotation.DirtiesContext; @@ -28,6 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; @Log4j2 @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @SpringBootTest @ExtendWith(SpringExtension.class) public class TableServiceIntegrationReadTest extends BaseUnitTest { diff --git a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java index f6dabd2250294716a70520a37b2ff77f02485082..4fab7905dd319bed297ef679784c55092b0e66cd 100644 --- a/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java +++ b/dbrepo-table-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java @@ -17,6 +17,8 @@ import org.apache.http.auth.BasicUserPrincipal; import org.junit.jupiter.api.*; 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.boot.test.mock.mockito.MockBean; import org.springframework.test.annotation.DirtiesContext; @@ -26,7 +28,6 @@ import java.io.File; import java.security.Principal; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; @@ -35,6 +36,7 @@ import static org.mockito.Mockito.when; @Log4j2 @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @SpringBootTest @ExtendWith(SpringExtension.class) public class TableServiceIntegrationWriteTest extends BaseUnitTest { diff --git a/dbrepo-table-service/services/src/main/java/at/tuwien/service/AccessService.java b/dbrepo-table-service/services/src/main/java/at/tuwien/service/AccessService.java index 128c4dcb8ca3ce2556d86bb84facb60f207334fe..efe2e564b81eb845098c09d481028a55aaf750f0 100644 --- a/dbrepo-table-service/services/src/main/java/at/tuwien/service/AccessService.java +++ b/dbrepo-table-service/services/src/main/java/at/tuwien/service/AccessService.java @@ -2,9 +2,14 @@ package at.tuwien.service; import at.tuwien.entities.database.DatabaseAccess; import at.tuwien.exception.AccessDeniedException; +import at.tuwien.exception.NotAllowedException; +import org.springframework.transaction.annotation.Transactional; public interface AccessService { + @Transactional(readOnly = true) + DatabaseAccess find(Long databaseId, String username) throws NotAllowedException; + /** * Checks if the user with username has access to the table with given id in database with given id. * diff --git a/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java b/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java index 5a840aa0e6ca89b2131b10a81cf1743635497f93..1a2f71eab8f384919c4cd22fa43526ac4c8d630f 100644 --- a/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java +++ b/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java @@ -2,6 +2,7 @@ package at.tuwien.service.impl; import at.tuwien.entities.database.DatabaseAccess; import at.tuwien.exception.AccessDeniedException; +import at.tuwien.exception.NotAllowedException; import at.tuwien.repository.jpa.DatabaseAccessRepository; import at.tuwien.service.AccessService; import lombok.extern.log4j.Log4j2; @@ -22,6 +23,17 @@ public class AccessServiceImpl implements AccessService { this.databaseAccessRepository = databaseAccessRepository; } + @Override + @Transactional(readOnly = true) + public DatabaseAccess find(Long databaseId, String username) throws NotAllowedException { + final Optional<DatabaseAccess> optional = databaseAccessRepository.findByDatabaseIdAndUsername(databaseId, username); + if (optional.isEmpty()) { + log.error("Failed to find database access for database with id {}", databaseId); + throw new NotAllowedException("Failed to find database access"); + } + return optional.get(); + } + @Override @Transactional(readOnly = true) public DatabaseAccess hasAccess(Long databaseId, Long tableId, String username) throws AccessDeniedException {