diff --git a/dbrepo-auth-service/listeners/target/create-event-listener.jar b/dbrepo-auth-service/listeners/target/create-event-listener.jar index b117c50b6646de91273c95dc5749cd54868012be..72d17863f14cc38c1fd026dd7e40e56a25fc4318 100644 Binary files a/dbrepo-auth-service/listeners/target/create-event-listener.jar and b/dbrepo-auth-service/listeners/target/create-event-listener.jar differ diff --git a/dbrepo-dashboard-service/Dockerfile b/dbrepo-dashboard-service/Dockerfile index e4d9d8f5056d01714c0fc15c3840f8bf05cac921..d5f64a82fb40c8823bbb7d0e5f8ac0a5426ce888 100644 --- a/dbrepo-dashboard-service/Dockerfile +++ b/dbrepo-dashboard-service/Dockerfile @@ -4,6 +4,5 @@ LABEL org.opencontainers.image.authors="martin.weise@tuwien.ac.at" WORKDIR /app COPY --chown=grafana:grafana ./dashboards /app/dashboards -COPY --chown=grafana:grafana ./provisioning /etc/grafana/provisioning COPY --chown=grafana:grafana ./grafana.ini /etc/grafana/grafana.ini COPY --chown=grafana:grafana ./ldap.toml /etc/grafana/ldap.toml diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java index 7ca50f8aa864f88bd75d873c93e9caa736fde258..9fee9476c9ddbceeeaea54cf20763fdc6af3be9b 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java @@ -110,7 +110,13 @@ public class SubsetEndpoint extends RestEndpoint { QueryNotFoundException, NotAllowedException, MetadataServiceException { log.debug("endpoint find subsets in database, databaseId={}, filterPersisted={}", databaseId, filterPersisted); final DatabaseDto database = cacheService.getDatabase(databaseId); - endpointValidator.validateOnlyPrivateSchemaAccess(database, principal); + if (!database.getIsPublic()) { + if (principal == null) { + log.error("Failed to list queries: no authentication found"); + throw new NotAllowedException("Failed to list queries: no authentication found"); + } + endpointValidator.validateOnlyAccess(database, principal, false); + } final List<QueryDto> queries; try { queries = subsetService.findAll(database, filterPersisted); @@ -171,7 +177,13 @@ public class SubsetEndpoint extends RestEndpoint { log.debug("endpoint find subset in database, databaseId={}, subsetId={}, accept={}, timestamp={}", databaseId, subsetId, accept, timestamp); final DatabaseDto database = cacheService.getDatabase(databaseId); - endpointValidator.validateOnlyPrivateSchemaAccess(database, principal); + if (!database.getIsPublic()) { + if (principal == null) { + log.error("Failed to find query: no authentication found"); + throw new NotAllowedException("Failed to find query: no authentication found"); + } + endpointValidator.validateOnlyAccess(database, principal, false); + } final QueryDto subset; try { subset = subsetService.findById(database, subsetId); @@ -205,7 +217,7 @@ public class SubsetEndpoint extends RestEndpoint { .headers(headers) .body(resource.getResource()); } - throw new FormatNotAvailableException("Must provide either application/json or text/csv value for header 'Accept': provided " + accept + " instead"); + throw new FormatNotAvailableException("Must provide either application/json or text/csv value for header 'Accept': got " + accept + " instead"); } @PostMapping diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java index 17bc60b90aaa3a84988ebfd95a294f6aa2dfb5fb..26f181c39d67fb81e37557f59bbd3522cc5d2278 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -5,7 +5,6 @@ import at.tuwien.service.CredentialService; import lombok.Getter; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/CredentialService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/CredentialService.java new file mode 100644 index 0000000000000000000000000000000000000000..b1c28cf1701772eb16f3c79a8f155faf6e8261a9 --- /dev/null +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/CredentialService.java @@ -0,0 +1,16 @@ +package at.tuwien.service; + +import at.tuwien.api.keycloak.TokenDto; + +public interface CredentialService { + + /** + * Gets credentials for a user with given id in a database with given id either from the cache (if not expired) or + * retrieves them from the Metadata Service. + * + * @param username The username. + * @param password The user password. + * @return The credentials. + */ + TokenDto getAccessToken(String username, String password); +} diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CredentialServiceImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CredentialServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..7cf7d1eff4394ae174b0e724fa8e34455b363578 --- /dev/null +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CredentialServiceImpl.java @@ -0,0 +1,44 @@ +package at.tuwien.service.impl; + +import at.tuwien.api.keycloak.TokenDto; +import at.tuwien.gateway.KeycloakGateway; +import at.tuwien.service.CredentialService; +import com.github.benmanes.caffeine.cache.Cache; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Log4j2 +@Service +public class CredentialServiceImpl implements CredentialService { + + private final KeycloakGateway keycloakGateway; + private final Cache<String, TokenDto> tokenCache; + + @Autowired + public CredentialServiceImpl(KeycloakGateway keycloakGateway, Cache<String, TokenDto> tokenCache) { + this.tokenCache = tokenCache; + this.keycloakGateway = keycloakGateway; + } + + @Override + public TokenDto getAccessToken(String username, String password) { + final TokenDto cacheAccessToken = tokenCache.getIfPresent(username); + if (cacheAccessToken != null) { + log.trace("found access token for user with username {} in cache", username); + return cacheAccessToken; + } + log.debug("access token for user with username {} not it cache (anymore): request new", username); + final TokenDto token = keycloakGateway.obtainUserToken(username, password); + tokenCache.put(username, token); + return token; + } + + /** + * Method for test cases to remove all caches. + */ + public void invalidateAll() { + tokenCache.invalidateAll(); + } + +} diff --git a/dbrepo-ui/pages/database/[database_id]/subset/index.vue b/dbrepo-ui/pages/database/[database_id]/subset/index.vue index d98a8ba2afc6f26466c50e31acfc10ed0f32acd3..d7127d90af180e7f70f497bbdeae395de5fe776a 100644 --- a/dbrepo-ui/pages/database/[database_id]/subset/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/subset/index.vue @@ -1,6 +1,6 @@ <template> <div - v-if="canViewSchema"> + v-if="canView"> <DatabaseToolbar /> <SubsetList /> <v-breadcrumbs :items="items" class="pa-0 mt-2" /> @@ -42,11 +42,11 @@ export default { access () { return this.cacheStore.getAccess }, - canViewSchema () { + canView () { if (!this.database) { return false } - if (this.database.is_schema_public) { + if (this.database.is_public || this.database.is_schema_public) { return true } if (!this.access) { diff --git a/dbrepo-ui/pages/database/[database_id]/table/index.vue b/dbrepo-ui/pages/database/[database_id]/table/index.vue index c2a2b76206918a0882c7e041aa3f38fb19ccfe12..2ff2a96a81cf9f13ff37d45c6440c0697f167f12 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/index.vue @@ -1,6 +1,6 @@ <template> <div - v-if="canViewSchema"> + v-if="canView"> <DatabaseToolbar /> <v-window v-model="tab"> @@ -51,11 +51,11 @@ export default { access () { return this.cacheStore.getAccess }, - canViewSchema () { + canView () { if (!this.database) { return false } - if (this.database.is_schema_public) { + if (this.database.is_public || this.database.is_schema_public) { return true } const userService = useUserService() diff --git a/dbrepo-ui/pages/database/[database_id]/view/index.vue b/dbrepo-ui/pages/database/[database_id]/view/index.vue index b2a2c17a1afe0553777e21e593b8865bfb63efc9..0e452aaa61b3000a5b997add3e1f1ef498a40a3a 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/index.vue @@ -1,6 +1,6 @@ <template> <div - v-if="canViewSchema"> + v-if="canView"> <DatabaseToolbar /> <v-window v-model="tab"> @@ -51,11 +51,11 @@ export default { access () { return this.cacheStore.getAccess }, - canViewSchema () { + canView () { if (!this.database) { return false } - if (this.database.is_schema_public) { + if (this.database.is_public || this.database.is_schema_public) { return true } const userService = useUserService() diff --git a/helm/dbrepo/files/create-event-listener.jar b/helm/dbrepo/files/create-event-listener.jar index b117c50b6646de91273c95dc5749cd54868012be..72d17863f14cc38c1fd026dd7e40e56a25fc4318 100644 Binary files a/helm/dbrepo/files/create-event-listener.jar and b/helm/dbrepo/files/create-event-listener.jar differ