From 19d613f582b6cee4e7b9b2ff1a41475b8f238fcc Mon Sep 17 00:00:00 2001 From: Martin Weise <martin.weise@tuwien.ac.at> Date: Sun, 6 Feb 2022 14:37:56 +0100 Subject: [PATCH] Updated permissions and endpoints for auth service Former-commit-id: 2ded327f10a5cc57613d5f1e72ae45ec614bd308 --- .../tuwien/endpoints/ContainerEndpoint.java | 6 ++++ .../at/tuwien/endpoints/ImageEndpoint.java | 8 +++++- .../src/main/resources/application-docker.yml | 2 +- .../src/main/resources/application.yml | 2 +- .../java/at/tuwien/config/GatewayConfig.java | 6 ++-- .../endpoints/ContainerDatabaseEndpoint.java | 5 ++++ .../src/main/resources/application-docker.yml | 2 +- .../src/main/resources/application.yml | 2 +- .../java/at/tuwien/config/GatewayConfig.java | 6 ++-- .../at/tuwien/config/WebSecurityConfig.java | 2 +- .../src/main/resources/application-docker.yml | 2 -- .../src/main/resources/application.yml | 2 -- .../java/at/tuwien/config/GatewayConfig.java | 6 ++-- .../java/at/tuwien/endpoint/DataEndpoint.java | 7 +++++ .../at/tuwien/endpoint/QueryEndpoint.java | 8 ++++++ .../at/tuwien/endpoint/StoreEndpoint.java | 3 ++ .../at/tuwien/endpoint/VersionEndpoint.java | 5 ++-- .../java/at/tuwien/config/GatewayConfig.java | 6 ++-- .../at/tuwien/config/WebSecurityConfig.java | 2 ++ .../at/tuwien/endpoints/TableEndpoint.java | 5 ++++ .../src/main/resources/application-docker.yml | 8 ++---- .../src/main/resources/application.yml | 10 ++----- .../java/at/tuwien/config/GatewayConfig.java | 6 ++-- fda-ui/components/dialogs/CreateDB.vue | 5 ++-- fda-ui/components/dialogs/TimeTravel.vue | 28 ++++++------------- .../_database_id/table/_table_id/import.vue | 12 ++++++-- .../_database_id/table/_table_id/index.vue | 8 +++--- .../database/_database_id/table/create.vue | 7 ++++- .../database/_database_id/table/import.vue | 18 +++++++++--- fda-ui/pages/login.vue | 1 + fda-ui/pages/signup.vue | 1 + 31 files changed, 116 insertions(+), 75 deletions(-) diff --git a/fda-container-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java b/fda-container-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java index 1bbd9be6a3..9eb1460800 100644 --- a/fda-container-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java +++ b/fda-container-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java @@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -38,6 +39,7 @@ public class ContainerEndpoint { } @GetMapping + @Transactional(readOnly = true) @ApiOperation(value = "List all containers", notes = "Lists the containers in the metadata database.") @ApiResponses({ @ApiResponse(code = 200, message = "All containers are listed."), @@ -52,6 +54,7 @@ public class ContainerEndpoint { } @PostMapping + @Transactional @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "Creates a new container", notes = "Creates a new container whose image is registered in the metadata database too.") @ApiResponses({ @@ -69,6 +72,7 @@ public class ContainerEndpoint { } @GetMapping("/{id}") + @Transactional(readOnly = true) @ApiOperation(value = "Get all information about a container", notes = "Since we follow the REST-principle, this method provides more information than the findAll method.") @ApiResponses({ @ApiResponse(code = 200, message = "Get information about container."), @@ -83,6 +87,7 @@ public class ContainerEndpoint { } @PutMapping("/{id}") + @Transactional @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "Change the state of a container", notes = "The new state can only be one of START/STOP.") @ApiResponses({ @@ -105,6 +110,7 @@ public class ContainerEndpoint { } @DeleteMapping("/{id}") + @Transactional @ApiOperation(value = "Delete a container") @PreAuthorize("hasRole('ROLE_DATA_STEWARD')") @ApiResponses({ diff --git a/fda-container-service/rest-service/src/main/java/at/tuwien/endpoints/ImageEndpoint.java b/fda-container-service/rest-service/src/main/java/at/tuwien/endpoints/ImageEndpoint.java index 701cb98379..104200fab7 100644 --- a/fda-container-service/rest-service/src/main/java/at/tuwien/endpoints/ImageEndpoint.java +++ b/fda-container-service/rest-service/src/main/java/at/tuwien/endpoints/ImageEndpoint.java @@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -43,6 +44,7 @@ public class ImageEndpoint { } @GetMapping + @Transactional(readOnly = true) @ApiOperation(value = "List all images", notes = "Lists the images in the metadata database.") @ApiResponses({ @ApiResponse(code = 200, message = "All images are listed."), @@ -57,6 +59,7 @@ public class ImageEndpoint { } @PostMapping + @Transactional @PreAuthorize("hasRole('ROLE_DEVELOPER')") @ApiOperation(value = "Creates a new image", notes = "Creates a new image in the metadata database.") @ApiResponses({ @@ -73,6 +76,7 @@ public class ImageEndpoint { } @GetMapping("/{id}") + @Transactional(readOnly = true) @ApiOperation(value = "Get all informations about a image", notes = "Since we follow the REST-principle, this method provides more information than the findAll method.") @ApiResponses({ @ApiResponse(code = 200, message = "Get information about container."), @@ -86,6 +90,7 @@ public class ImageEndpoint { } @PutMapping("/{id}") + @Transactional @PreAuthorize("hasRole('DEVELOPER')") @ApiOperation(value = "Update image information", notes = "Polls new information about an image") @ApiResponses({ @@ -94,12 +99,13 @@ public class ImageEndpoint { @ApiResponse(code = 404, message = "No container found with this id in metadata database."), }) public ResponseEntity<ImageDto> update(@NotNull @PathVariable Long id, @RequestBody @Valid ImageChangeDto changeDto) - throws ImageNotFoundException, DockerClientException { + throws ImageNotFoundException { return ResponseEntity.status(HttpStatus.ACCEPTED) .body(imageMapper.containerImageToImageDto(imageService.update(id, changeDto))); } @DeleteMapping("/{id}") + @Transactional @PreAuthorize("hasRole('DEVELOPER')") @ApiOperation(value = "Delete a image") @ApiResponses({ diff --git a/fda-container-service/rest-service/src/main/resources/application-docker.yml b/fda-container-service/rest-service/src/main/resources/application-docker.yml index 4cebc5d734..d442d6cf56 100644 --- a/fda-container-service/rest-service/src/main/resources/application-docker.yml +++ b/fda-container-service/rest-service/src/main/resources/application-docker.yml @@ -26,4 +26,4 @@ eureka: client.serviceUrl.defaultZone: http://fda-discovery-service:9090/eureka/ fda: ready.path: /ready - auth.endpoint: http://fda-authentication-service:9097 \ No newline at end of file + gateway.endpoint: http://fda-gateway-service:9095 \ No newline at end of file diff --git a/fda-container-service/rest-service/src/main/resources/application.yml b/fda-container-service/rest-service/src/main/resources/application.yml index 9d042c907b..8d198d4a7c 100644 --- a/fda-container-service/rest-service/src/main/resources/application.yml +++ b/fda-container-service/rest-service/src/main/resources/application.yml @@ -26,4 +26,4 @@ eureka: client.serviceUrl.defaultZone: http://localhost:9090/eureka/ fda: ready.path: ./ready - auth.endpoint: http://localhost:9097 \ No newline at end of file + gateway.endpoint: http://localhost:9095 \ No newline at end of file diff --git a/fda-container-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/fda-container-service/services/src/main/java/at/tuwien/config/GatewayConfig.java index 252235a1eb..a6a8a2003e 100644 --- a/fda-container-service/services/src/main/java/at/tuwien/config/GatewayConfig.java +++ b/fda-container-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -9,13 +9,13 @@ import org.springframework.web.util.DefaultUriBuilderFactory; @Configuration public class GatewayConfig { - @Value("${fda.auth.endpoint}") - private String authEndpoint; + @Value("${fda.gateway.endpoint}") + private String gatewayEndpoint; @Bean public RestTemplate restTemplate() { final RestTemplate restTemplate = new RestTemplate(); - restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(authEndpoint)); + restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint)); return restTemplate; } diff --git a/fda-database-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerDatabaseEndpoint.java b/fda-database-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerDatabaseEndpoint.java index db25122bef..c6270d28f2 100644 --- a/fda-database-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerDatabaseEndpoint.java +++ b/fda-database-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerDatabaseEndpoint.java @@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -38,6 +39,7 @@ public class ContainerDatabaseEndpoint { } @GetMapping + @Transactional(readOnly = true) @ApiOperation(value = "List all databases", notes = "Currently a container supports only databases of the same image, e.g. there is one PostgreSQL engine running with multiple databases inside a container.") @ApiResponses({ @ApiResponse(code = 200, message = "All databases running in all containers are listed."), @@ -52,6 +54,7 @@ public class ContainerDatabaseEndpoint { } @PostMapping + @Transactional @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "Creates a new database in a container", notes = "Creates a new database in a container. Note that the backend distincts between numerical (req: categories), nominal (req: max_length) and categorical (req: max_length, siUnit, min, max, mean, median, standard_deviation, histogram) column types.") @ApiResponses({ @@ -71,6 +74,7 @@ public class ContainerDatabaseEndpoint { } @GetMapping("/{databaseId}") + @Transactional(readOnly = true) @ApiOperation(value = "Get all information about a database") @ApiResponses({ @ApiResponse(code = 200, message = "The database information is displayed."), @@ -83,6 +87,7 @@ public class ContainerDatabaseEndpoint { } @DeleteMapping("/{databaseId}") + @Transactional @PreAuthorize("hasRole('ROLE_DEVELOPER') or hasRole('ROLE_DATA_STEWARD')") @ApiOperation(value = "Delete a database") @ApiResponses({ diff --git a/fda-database-service/rest-service/src/main/resources/application-docker.yml b/fda-database-service/rest-service/src/main/resources/application-docker.yml index 6a012e4034..0f9b52e921 100644 --- a/fda-database-service/rest-service/src/main/resources/application-docker.yml +++ b/fda-database-service/rest-service/src/main/resources/application-docker.yml @@ -31,4 +31,4 @@ eureka: fda: elastic.endpoint: fda-search-service:9200 ready.path: /ready - auth.endpoint: http://fda-authentication-service:9097 \ No newline at end of file + gateway.endpoint: http://fda-gateway-service:9095 \ No newline at end of file diff --git a/fda-database-service/rest-service/src/main/resources/application.yml b/fda-database-service/rest-service/src/main/resources/application.yml index 970d401a59..e823378b7f 100644 --- a/fda-database-service/rest-service/src/main/resources/application.yml +++ b/fda-database-service/rest-service/src/main/resources/application.yml @@ -31,4 +31,4 @@ eureka: fda: elastic.endpoint: localhost:9200 ready.path: ./ready - auth.endpoint: http://localhost:9097 \ No newline at end of file + gateway.endpoint: http://fda-gateway-service:9095 \ No newline at end of file diff --git a/fda-database-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/fda-database-service/services/src/main/java/at/tuwien/config/GatewayConfig.java index 252235a1eb..a6a8a2003e 100644 --- a/fda-database-service/services/src/main/java/at/tuwien/config/GatewayConfig.java +++ b/fda-database-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -9,13 +9,13 @@ import org.springframework.web.util.DefaultUriBuilderFactory; @Configuration public class GatewayConfig { - @Value("${fda.auth.endpoint}") - private String authEndpoint; + @Value("${fda.gateway.endpoint}") + private String gatewayEndpoint; @Bean public RestTemplate restTemplate() { final RestTemplate restTemplate = new RestTemplate(); - restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(authEndpoint)); + restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint)); return restTemplate; } diff --git a/fda-database-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java b/fda-database-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java index 6eca39eaf5..9372169bd8 100644 --- a/fda-database-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java +++ b/fda-database-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java @@ -57,7 +57,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { /* set permissions on endpoints */ http.authorizeRequests() /* our public endpoints */ - .antMatchers(HttpMethod.GET, "container/**/database/**").permitAll() + .antMatchers(HttpMethod.GET, "/api/container/**/database/**").permitAll() /* our private endpoints */ .anyRequest().authenticated(); /* add JWT token filter */ diff --git a/fda-identifier-service/rest-service/src/main/resources/application-docker.yml b/fda-identifier-service/rest-service/src/main/resources/application-docker.yml index fde2763954..18e50d1abc 100644 --- a/fda-identifier-service/rest-service/src/main/resources/application-docker.yml +++ b/fda-identifier-service/rest-service/src/main/resources/application-docker.yml @@ -26,6 +26,4 @@ eureka: client.serviceUrl.defaultZone: http://fda-discovery-service:9090/eureka/ fda: ready.path: /ready - mapping.path: /root - table.path: /root gateway.endpoint: http://fda-gateway-service:9095 \ No newline at end of file diff --git a/fda-identifier-service/rest-service/src/main/resources/application.yml b/fda-identifier-service/rest-service/src/main/resources/application.yml index f7e4da1077..908ca280f1 100644 --- a/fda-identifier-service/rest-service/src/main/resources/application.yml +++ b/fda-identifier-service/rest-service/src/main/resources/application.yml @@ -26,6 +26,4 @@ eureka: client.serviceUrl.defaultZone: http://localhost:9090/eureka/ fda: ready.path: ~/ - mapping.path: rest-service/src/main/resources - table.path: rest-service/src/main/java/at/tuwien/userdb gateway.endpoint: http://fda-gateway-service:9095 \ No newline at end of file diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/fda-identifier-service/services/src/main/java/at/tuwien/config/GatewayConfig.java index 252235a1eb..a6a8a2003e 100644 --- a/fda-identifier-service/services/src/main/java/at/tuwien/config/GatewayConfig.java +++ b/fda-identifier-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -9,13 +9,13 @@ import org.springframework.web.util.DefaultUriBuilderFactory; @Configuration public class GatewayConfig { - @Value("${fda.auth.endpoint}") - private String authEndpoint; + @Value("${fda.gateway.endpoint}") + private String gatewayEndpoint; @Bean public RestTemplate restTemplate() { final RestTemplate restTemplate = new RestTemplate(); - restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(authEndpoint)); + restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint)); return restTemplate; } diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/DataEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/DataEndpoint.java index ca5838d528..a8e7468865 100644 --- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/DataEndpoint.java +++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/DataEndpoint.java @@ -13,6 +13,8 @@ import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -34,6 +36,8 @@ public class DataEndpoint { } @PostMapping("/api/container/{id}/database/{databaseId}/table/{tableId}/data") + @PreAuthorize("hasRole('ROLE_RESEARCHER')") + @Transactional @ApiOperation(value = "Insert values", notes = "Insert Data into a Table in the database. When the location string is set, the data argument is ignored and the location is used as data input") @ApiResponses({ @ApiResponse(code = 201, message = "Updated the table."), @@ -64,6 +68,7 @@ public class DataEndpoint { } @GetMapping("/api/container/{id}/database/{databaseId}/table/{tableId}/data") + @Transactional(readOnly = true) @ApiOperation(value = "Get values", notes = "Get Data from a Table in the database.") @ApiResponses({ @ApiResponse(code = 200, message = "Get data from the table."), @@ -100,6 +105,7 @@ public class DataEndpoint { } @RequestMapping(value = "/api/container/{id}/database/{databaseId}/table/{tableId}/data", method = RequestMethod.HEAD) + @Transactional(readOnly = true) @ApiOperation(value = "Get values", notes = "Get Data Count from a Table in the database.") @ApiResponses({ @ApiResponse(code = 200, message = "Get data from the table."), @@ -125,6 +131,7 @@ public class DataEndpoint { * todo use dbs internal export functionality */ @GetMapping(value = "/api/container/{id}/database/{databaseId}/table/{tableId}/export") + @Transactional(readOnly = true) @ApiOperation(value = "Download export", notes = "Get Data from a Table in the database.") @ApiResponses({ @ApiResponse(code = 200, message = "Get data from the table."), diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java index 2bdaddedb3..f4e1c82b55 100644 --- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java +++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java @@ -13,6 +13,8 @@ import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -35,6 +37,8 @@ public class QueryEndpoint { } @PutMapping("/execute") + @Transactional + @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "executes a query and save the results") @ApiResponses(value = { @ApiResponse(code = 200, message = "Executed the query, Saved it and return the results"), @@ -63,6 +67,8 @@ public class QueryEndpoint { } @PostMapping("/save") + @Transactional + @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "saves a query without execution") @ApiResponses(value = { @ApiResponse(code = 200, message = "Executed the query, Saved it and return the results"), @@ -81,6 +87,8 @@ public class QueryEndpoint { } @PutMapping("/execute/{queryId}") + @Transactional + @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "re-executes a query by given id") @ApiResponses(value = { @ApiResponse(code = 200, message = "Re-Execute a saved query and return the results"), diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/StoreEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/StoreEndpoint.java index 91267f48f8..a81c23b076 100644 --- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/StoreEndpoint.java +++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/StoreEndpoint.java @@ -10,6 +10,7 @@ import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.NotNull; @@ -29,6 +30,7 @@ public class StoreEndpoint { } @GetMapping + @Transactional(readOnly = true) @ApiOperation(value = "List all queries", notes = "Lists all already executed queries") @ApiResponses({ @ApiResponse(code = 200, message = "All queries are listed."), @@ -43,6 +45,7 @@ public class StoreEndpoint { } @GetMapping("/{queryId}") + @Transactional(readOnly = true) @ApiOperation(value = "Find a query", notes = "Find a query") @ApiResponses({ @ApiResponse(code = 200, message = "All queries are listed."), diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/VersionEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/VersionEndpoint.java index 3dbcdbb3b6..561a9c4d06 100644 --- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/VersionEndpoint.java +++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/VersionEndpoint.java @@ -1,7 +1,6 @@ package at.tuwien.endpoint; import at.tuwien.api.database.VersionDto; -import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.exception.*; import at.tuwien.mapper.StoreMapper; import at.tuwien.querystore.Version; @@ -12,9 +11,9 @@ import io.swagger.annotations.ApiResponses; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; -import javax.transaction.Transactional; import javax.validation.constraints.NotNull; import java.util.List; import java.util.stream.Collectors; @@ -34,8 +33,8 @@ public class VersionEndpoint { this.storeMapper = storeMapper; } - @Transactional @GetMapping + @Transactional(readOnly = true) @ApiOperation(value = "Get values", notes = "Get Data from a Table in the database.") @ApiResponses({ @ApiResponse(code = 200, message = "Get data from the table."), diff --git a/fda-query-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/fda-query-service/services/src/main/java/at/tuwien/config/GatewayConfig.java index 252235a1eb..a6a8a2003e 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/config/GatewayConfig.java +++ b/fda-query-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -9,13 +9,13 @@ import org.springframework.web.util.DefaultUriBuilderFactory; @Configuration public class GatewayConfig { - @Value("${fda.auth.endpoint}") - private String authEndpoint; + @Value("${fda.gateway.endpoint}") + private String gatewayEndpoint; @Bean public RestTemplate restTemplate() { final RestTemplate restTemplate = new RestTemplate(); - restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(authEndpoint)); + restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint)); return restTemplate; } diff --git a/fda-query-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java b/fda-query-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java index b26f8e2994..0f3d1e2b2a 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java +++ b/fda-query-service/services/src/main/java/at/tuwien/config/WebSecurityConfig.java @@ -58,6 +58,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { http.authorizeRequests() /* our public endpoints */ .antMatchers(HttpMethod.GET, "/api/container/**/database/data/**").permitAll() + .antMatchers(HttpMethod.GET, "/api/container/**/database/**/table/**/data/**").permitAll() + .antMatchers(HttpMethod.GET, "/api/container/**/database/**/table/**/export/**").permitAll() .antMatchers(HttpMethod.GET, "/api/container/**/database/query/**").permitAll() .antMatchers(HttpMethod.GET, "/api/container/**/database/**/query/**").permitAll() .antMatchers(HttpMethod.GET, "/api/container/**/database/**/version/**").permitAll() diff --git a/fda-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/fda-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index 78f9cb54d6..ba119b721e 100644 --- a/fda-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/fda-table-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -42,6 +42,7 @@ public class TableEndpoint { } @GetMapping + @Transactional(readOnly = true) @ApiOperation(value = "List all tables", notes = "Lists the tables in the metadata database for this database.") @ApiResponses({ @ApiResponse(code = 200, message = "All tables are listed."), @@ -57,6 +58,7 @@ public class TableEndpoint { } @PostMapping + @Transactional @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "Create a table", notes = "Creates a new table for a database, requires a running container.") @ApiResponses({ @@ -81,6 +83,7 @@ public class TableEndpoint { @GetMapping("/{tableId}") + @Transactional(readOnly = true) @ApiOperation(value = "Get information about table", notes = "Lists the information of a table from the metadata database for this database.") @ApiResponses({ @ApiResponse(code = 200, message = "All tables are listed."), @@ -96,6 +99,7 @@ public class TableEndpoint { } @PutMapping("/{tableId}") + @Transactional @ApiOperation(value = "Update a table", notes = "Update a table in the database.") @ApiResponses({ @ApiResponse(code = 200, message = "Updated the table."), @@ -111,6 +115,7 @@ public class TableEndpoint { } @DeleteMapping("/{tableId}") + @Transactional @PreAuthorize("hasRole('ROLE_DEVELOPER') or hasRole('ROLE_DATA_STEWARD')") @ApiOperation(value = "Delete a table", notes = "Delete a table in the database.") @ApiResponses({ diff --git a/fda-table-service/rest-service/src/main/resources/application-docker.yml b/fda-table-service/rest-service/src/main/resources/application-docker.yml index 8c2bac3f34..35f0ddc160 100644 --- a/fda-table-service/rest-service/src/main/resources/application-docker.yml +++ b/fda-table-service/rest-service/src/main/resources/application-docker.yml @@ -29,10 +29,6 @@ eureka: instance.hostname: fda-table-service client.serviceUrl.defaultZone: http://fda-discovery-service:9090/eureka/ fda: - mapping.path: /root - table.path: /root ready.path: /ready - elastic.endpoint: fda-search-service:9200 -unleash: - api.url: https://gitlab.phaidra.org/api/v4/feature_flags/unleash/450 - instance.id: "${INSTANCE_ID}" \ No newline at end of file + gateway.endpoint: http://fda-gateway-service:9095 + elastic.endpoint: fda-search-service:9200 \ No newline at end of file diff --git a/fda-table-service/rest-service/src/main/resources/application.yml b/fda-table-service/rest-service/src/main/resources/application.yml index f8ffb391ea..dd3fdf502b 100644 --- a/fda-table-service/rest-service/src/main/resources/application.yml +++ b/fda-table-service/rest-service/src/main/resources/application.yml @@ -30,10 +30,6 @@ eureka: instance.hostname: fda-table-service client.serviceUrl.defaultZone: http://localhost:9090/eureka/ fda: - mapping.path: rest-service/src/main/resources - table.path: rest-service/src/main/java/at/tuwien/userdb - ready.path: ./ready - elastic.endpoint: fda-search-service:9200 -unleash: - api.url: https://gitlab.phaidra.org/api/v4/feature_flags/unleash/450 - instance.id: "${INSTANCE_ID}" \ No newline at end of file + ready.path: ./readyalhost:9090/eureka/ + gateway.endpoint: http://localhost:9095 + elastic.endpoint: fda-search-service:9200 \ No newline at end of file diff --git a/fda-table-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/fda-table-service/services/src/main/java/at/tuwien/config/GatewayConfig.java index 252235a1eb..a6a8a2003e 100644 --- a/fda-table-service/services/src/main/java/at/tuwien/config/GatewayConfig.java +++ b/fda-table-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -9,13 +9,13 @@ import org.springframework.web.util.DefaultUriBuilderFactory; @Configuration public class GatewayConfig { - @Value("${fda.auth.endpoint}") - private String authEndpoint; + @Value("${fda.gateway.endpoint}") + private String gatewayEndpoint; @Bean public RestTemplate restTemplate() { final RestTemplate restTemplate = new RestTemplate(); - restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(authEndpoint)); + restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint)); return restTemplate; } diff --git a/fda-ui/components/dialogs/CreateDB.vue b/fda-ui/components/dialogs/CreateDB.vue index 3172bb337f..587f6980fb 100644 --- a/fda-ui/components/dialogs/CreateDB.vue +++ b/fda-ui/components/dialogs/CreateDB.vue @@ -17,6 +17,7 @@ v-model="database" name="database" label="Name *" + autofocus :rules="[v => !!v || $t('Required')]" required /> <v-textarea @@ -104,9 +105,7 @@ export default { try { this.loading = true this.error = false - res = await this.$axios.get('/api/image', { - headers: { Authorization: `Bearer ${this.token}` } - }) + res = await this.$axios.get('/api/image') this.engines = res.data console.debug('engines', this.engines) this.loading = false diff --git a/fda-ui/components/dialogs/TimeTravel.vue b/fda-ui/components/dialogs/TimeTravel.vue index 5b53d5d29a..45258f63f9 100644 --- a/fda-ui/components/dialogs/TimeTravel.vue +++ b/fda-ui/components/dialogs/TimeTravel.vue @@ -9,24 +9,13 @@ View data for other version </v-card-subtitle> <v-card-text> - <v-list dense> - <v-list-item-group - v-model="version" - color="primary"> - <v-list-item - v-for="(v, i) in versions" - :key="i"> - <v-list-item-content> - <v-list-item-title> - Version {{ v.id }} - </v-list-item-title> - <v-list-item-subtitle> - {{ v.created }} - </v-list-item-subtitle> - </v-list-item-content> - </v-list-item> - </v-list-item-group> - </v-list> + <v-date-picker + v-model="picker" + no-title /> + <v-time-picker + v-model="time" + format="24hr" + no-title /> </v-card-text> <v-card-actions> <v-spacer /> @@ -38,9 +27,8 @@ <v-btn class="mb-2" color="blue-grey white--text" - :disabled="$parent.$parent.$parent.$parent.version.id === null" @click="reset"> - Disable + Now </v-btn> <v-btn id="version" diff --git a/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/import.vue b/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/import.vue index 9e76236b68..fae453656e 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/import.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/import.vue @@ -116,6 +116,9 @@ export default { }, databaseId () { return this.$route.params.database_id + }, + token () { + return this.$store.state.token } }, mounted () { @@ -141,7 +144,10 @@ export default { data.append('file', this.file) try { const res = await this.$axios.post(url, data, { - headers: { 'Content-Type': 'multipart/form-data' } + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: `Bearer ${this.token}` + } }) if (res.data.success) { this.fileLocation = res.data.file.filename @@ -157,7 +163,9 @@ export default { const insertUrl = `/api/container/${this.$route.params.container_id}/database/${this.databaseId}/table/${this.tableId}/data?location=${encodeURI('/tmp/' + this.fileLocation)}` let insertResult try { - insertResult = await this.$axios.post(insertUrl) + insertResult = await this.$axios.post(insertUrl, { + headers: { Authorization: `Bearer ${this.token}` } + }) console.debug('inserted table', insertResult.data) } catch (err) { console.error('Could not insert data.', err) diff --git a/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/index.vue b/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/index.vue index 5b955c90ed..25c5f8223d 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/index.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/index.vue @@ -144,8 +144,8 @@ export default { url += `×tamp=${this.version.created}` } const res = await this.$axios.get(url) - this.rows = res.data.result console.debug('version', this.datetime, 'table data', res.data) + this.rows = res.data.result } catch (err) { console.error('failed to load data', err) this.$toast.error('Could not load table data.') @@ -155,10 +155,10 @@ export default { async loadDataCount () { try { this.loading = true - const url = `/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/table/${this.$route.params.table_id}/data?total=1` - const res = await this.$axios.get(url) - this.total = res.data.count + const url = `/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/table/${this.$route.params.table_id}/data` + const res = await this.$axios.head(url) console.debug('data count', res.data) + this.total = res.data.count } catch (err) { console.error('failed to load total count', err) } diff --git a/fda-ui/pages/container/_container_id/database/_database_id/table/create.vue b/fda-ui/pages/container/_container_id/database/_database_id/table/create.vue index 0100576401..358667084e 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/table/create.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/table/create.vue @@ -100,6 +100,9 @@ export default { databaseId () { return this.$route.params.database_id }, + token () { + return this.$store.state.token + }, loadingColor () { return this.error ? 'red lighten-2' : 'primary' }, @@ -168,7 +171,9 @@ export default { } try { this.loading = true - const res = await this.$axios.post(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/table`, data) + const res = await this.$axios.post(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/table`, data, { + headers: { Authorization: `Bearer ${this.token}` } + }) if (res.status === 201) { this.error = false this.$toast.success('Table created.') diff --git a/fda-ui/pages/container/_container_id/database/_database_id/table/import.vue b/fda-ui/pages/container/_container_id/database/_database_id/table/import.vue index ff3df18634..8d68af6f48 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/table/import.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/table/import.vue @@ -3,7 +3,7 @@ <v-toolbar flat> <v-toolbar-title>Create Table Schema (and Import Data) from .csv</v-toolbar-title> </v-toolbar> - <v-stepper v-model="step" vertical> + <v-stepper v-model="step" vertical flat> <v-stepper-step :complete="step > 1" step="1"> Table Information </v-stepper-step> @@ -250,6 +250,9 @@ export default { computed: { step1Valid () { return this.tableCreate.name !== null && this.tableCreate.name.length > 0 && this.tableCreate.description !== null && this.tableCreate.description.length > 0 + }, + token () { + return this.$store.state.token } }, mounted () { @@ -263,7 +266,10 @@ export default { data.append('file', this.file) try { const res = await this.$axios.post(url, data, { - headers: { 'Content-Type': 'multipart/form-data' } + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: `Bearer ${this.token}` + } }) console.log(res.data) @@ -322,7 +328,9 @@ export default { let createResult try { this.loading = true - createResult = await this.$axios.post(createUrl, this.tableCreate) + createResult = await this.$axios.post(createUrl, this.tableCreate, { + headers: { Authorization: `Bearer ${this.token}` } + }) this.newTableId = createResult.data.id console.debug('created table', createResult.data) } catch (err) { @@ -338,7 +346,9 @@ export default { const insertUrl = `/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/table/${createResult.data.id}/data?location=${encodeURI('/tmp/' + this.fileLocation)}` let insertResult try { - insertResult = await this.$axios.post(insertUrl) + insertResult = await this.$axios.post(insertUrl, { + headers: { Authorization: `Bearer ${this.token}` } + }) console.debug('inserted table', insertResult.data) } catch (err) { this.loading = false diff --git a/fda-ui/pages/login.vue b/fda-ui/pages/login.vue index f6a07b3f4d..fc8331c06f 100644 --- a/fda-ui/pages/login.vue +++ b/fda-ui/pages/login.vue @@ -17,6 +17,7 @@ <v-text-field v-model="loginAccount.username" autocomplete="off" + autofocus required :rules="[v => !!v || $t('Required')]" label="Username *" /> diff --git a/fda-ui/pages/signup.vue b/fda-ui/pages/signup.vue index 15b318ac80..7dd77d9331 100644 --- a/fda-ui/pages/signup.vue +++ b/fda-ui/pages/signup.vue @@ -18,6 +18,7 @@ v-model="createAccount.email" type="email" autocomplete="off" + autofocus required :rules="[v => !!v || $t('Required')]" hint="e.g. max.mustermann@work.com" -- GitLab