diff --git a/.gitignore b/.gitignore index b8d8c0348731b553074acdf3d0bae56665095d35..021c030c5079def8c7db34167a2b9010a67eba5d 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,9 @@ tmp.yaml site/ final/ +# newer +dbrepo-somapper/ + .$* # Notebooks diff --git a/dbrepo-analyse-service/.gitignore b/dbrepo-analyse-service/.gitignore index eb269965160b9ad33871630e06d6f423b83263fd..b6abc6eae3a67fa889c936b02ee21e58f57a85ad 100644 --- a/dbrepo-analyse-service/.gitignore +++ b/dbrepo-analyse-service/.gitignore @@ -14,6 +14,9 @@ venv/ .venv/ env* +# model +bge-m3/*.bin + # Test report.xml coverage.html @@ -36,4 +39,4 @@ docs/_build/ htmlcov/ .coverage .coverage.* -*,cover \ No newline at end of file +*,cover diff --git a/dbrepo-auth-service/dbrepo-realm.json b/dbrepo-auth-service/dbrepo-realm.json index a39f7de1b0ab0611057af4890ee281bb202609ca..7e8ac843257db6d8a6b3a5d817224f42426f150b 100644 --- a/dbrepo-auth-service/dbrepo-realm.json +++ b/dbrepo-auth-service/dbrepo-realm.json @@ -2143,7 +2143,7 @@ "subType" : "anonymous", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper" ] + "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper" ] } }, { "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1", @@ -2169,7 +2169,7 @@ "subType" : "authenticated", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-attribute-mapper" ] + "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper" ] } } ], "org.keycloak.storage.UserStorageProvider" : [ { @@ -2185,8 +2185,8 @@ "config" : { "ldap.attribute" : [ "createTimestamp" ], "is.mandatory.in.ldap" : [ "false" ], - "always.read.value.from.ldap" : [ "true" ], "read.only" : [ "true" ], + "always.read.value.from.ldap" : [ "true" ], "user.model.attribute" : [ "createTimestamp" ] } }, { @@ -2209,8 +2209,8 @@ "config" : { "ldap.attribute" : [ "cn" ], "is.mandatory.in.ldap" : [ "true" ], - "read.only" : [ "false" ], "always.read.value.from.ldap" : [ "true" ], + "read.only" : [ "false" ], "user.model.attribute" : [ "firstName" ] } }, { @@ -2221,8 +2221,8 @@ "config" : { "ldap.attribute" : [ "mail" ], "is.mandatory.in.ldap" : [ "false" ], - "read.only" : [ "false" ], "always.read.value.from.ldap" : [ "false" ], + "read.only" : [ "false" ], "user.model.attribute" : [ "email" ] } }, { @@ -2238,8 +2238,8 @@ "groups.dn" : [ "ou=users,dc=dbrepo,dc=at" ], "mode" : [ "LDAP_ONLY" ], "user.roles.retrieve.strategy" : [ "LOAD_GROUPS_BY_MEMBER_ATTRIBUTE" ], - "membership.ldap.attribute" : [ "member" ], "ignore.missing.groups" : [ "false" ], + "membership.ldap.attribute" : [ "member" ], "group.object.classes" : [ "groupOfNames" ], "memberof.ldap.attribute" : [ "memberOf" ], "groups.path" : [ "/" ], @@ -2253,8 +2253,8 @@ "config" : { "ldap.attribute" : [ "modifyTimestamp" ], "is.mandatory.in.ldap" : [ "false" ], - "always.read.value.from.ldap" : [ "true" ], "read.only" : [ "true" ], + "always.read.value.from.ldap" : [ "true" ], "user.model.attribute" : [ "modifyTimestamp" ] } }, { @@ -2274,8 +2274,8 @@ } ] }, "config" : { - "pagination" : [ "false" ], "fullSyncPeriod" : [ "-1" ], + "pagination" : [ "false" ], "startTls" : [ "false" ], "usersDn" : [ "ou=users,dc=dbrepo,dc=at" ], "connectionPooling" : [ "true" ], @@ -2284,8 +2284,8 @@ "importEnabled" : [ "true" ], "enabled" : [ "true" ], "usernameLDAPAttribute" : [ "uid" ], - "bindCredential" : [ "admin" ], "bindDn" : [ "cn=admin,dc=dbrepo,dc=at" ], + "bindCredential" : [ "admin" ], "changedSyncPeriod" : [ "-1" ], "lastSync" : [ "1719252666" ], "vendor" : [ "other" ], diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java index b4cb2ff5043c46e1e5ece49a45690ef04782bd3c..85c179801be9892e21d2271a084a1103c2e0292e 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java @@ -14,6 +14,7 @@ import at.tuwien.api.user.UserDto; import at.tuwien.exception.*; import at.tuwien.gateway.MetadataServiceGateway; import at.tuwien.mapper.MetadataMapper; +import at.tuwien.utils.ListUtil; import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; @@ -61,9 +62,10 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find container with id {}: service responded unsuccessful: {}", containerId, response.getStatusCode()); throw new MetadataServiceException("Failed to find container: service responded unsuccessful: " + response.getStatusCode()); } - if (!response.getHeaders().keySet().containsAll(List.of("X-Username", "X-Password"))) { + final List<String> headers = List.of("X-Username", "X-Password"); + if (!response.getHeaders().keySet().containsAll(headers)) { log.error("Failed to find all privileged container headers"); - throw new MetadataServiceException("Failed to find all privileged container headers"); + throw new MetadataServiceException("Failed to find all privileged container headers: missing" + ListUtil.missingHeaders(headers, response.getHeaders().keySet())); } if (response.getBody() == null) { log.error("Failed to find container with id {}: body is empty", containerId); @@ -93,9 +95,10 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find database with id {}: service responded unsuccessful: {}", id, response.getStatusCode()); throw new MetadataServiceException("Failed to find database: service responded unsuccessful: " + response.getStatusCode()); } - if (!response.getHeaders().keySet().containsAll(List.of("X-Username", "X-Password"))) { + final List<String> headers = List.of("X-Username", "X-Password"); + if (!response.getHeaders().keySet().containsAll(headers)) { log.error("Failed to find all privileged database headers"); - throw new MetadataServiceException("Failed to find all privileged database headers"); + throw new MetadataServiceException("Failed to find all privileged database headers: missing" + ListUtil.missingHeaders(headers, response.getHeaders().keySet())); } if (response.getBody() == null) { log.error("Failed to find database with id {}: body is empty", id); @@ -243,9 +246,10 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find user with id {}: service responded unsuccessful: {}", userId, response.getStatusCode()); throw new MetadataServiceException("Failed to find user: service responded unsuccessful: " + response.getStatusCode()); } - if (!response.getHeaders().keySet().containsAll(List.of("X-Username", "X-Password"))) { + final List<String> headers = List.of("X-Username", "X-Password"); + if (!response.getHeaders().keySet().containsAll(headers)) { log.error("Failed to find all privileged user headers"); - throw new MetadataServiceException("Failed to find all privileged user headers"); + throw new MetadataServiceException("Failed to find all privileged user headers: missing " + ListUtil.missingHeaders(headers, response.getHeaders().keySet())); } if (response.getBody() == null) { log.error("Failed to find user with id {}: body is empty", userId); diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/utils/ListUtil.java b/dbrepo-data-service/services/src/main/java/at/tuwien/utils/ListUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..3d679f3aec5a2ef7c5722952fa4a00a331a5b543 --- /dev/null +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/utils/ListUtil.java @@ -0,0 +1,20 @@ +package at.tuwien.utils; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class ListUtil { + + public static List<String> missingHeaders(List<String> expected, Set<String> actual) { + final List<String> missing = new LinkedList<>(); + for (String exp : expected) { + if (actual.contains(exp)) { + continue; + } + missing.add(exp); + } + return missing; + } + +} diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java index 9cdcfdedf9e88fd0138e236db6f15afb959ff2dc..34215aa7ffb5b98908aea898fcd9ef0e49048c12 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java @@ -100,10 +100,11 @@ public class AccessEndpoint { log.debug("endpoint give access to database, databaseId={}, userId={}, access.type={}", databaseId, userId, data.getType()); final Database database = databaseService.findById(databaseId); - final User user = userService.findByUsername(principal.getName()); - if (database.getOwner().equals(user)) { - log.error("Failed to give access to user with id {}: not owner", userId); - throw new NotAllowedException("Failed to give access to user with id " + userId + ": not owner"); + final User caller = userService.findByUsername(principal.getName()); + final User user = userService.findById(userId); + if (!database.getOwner().equals(caller)) { + log.error("Failed to give access to user with id {}: not owner", caller.getId()); + throw new NotAllowedException("Failed to give access to user with id " + caller.getId() + ": not owner"); } try { accessService.find(database, user); @@ -162,10 +163,11 @@ public class AccessEndpoint { log.debug("endpoint modify database access, databaseId={}, userId={}, access.type={}", databaseId, userId, data.getType()); final Database database = databaseService.findById(databaseId); - final User user = userService.findByUsername(principal.getName()); - if (database.getOwner().equals(user)) { - log.error("Failed to give access to user with id {}: not owner", userId); - throw new NotAllowedException("Failed to give access to user with id " + userId + ": not owner"); + final User caller = userService.findByUsername(principal.getName()); + final User user = userService.findById(userId); + if (!database.getOwner().equals(caller)) { + log.error("Failed to give access to user with id {}: not owner", caller.getId()); + throw new NotAllowedException("Failed to give access to user with id " + caller.getId() + ": not owner"); } accessService.find(database, user); accessService.update(database, user, data.getType()); @@ -203,6 +205,7 @@ public class AccessEndpoint { UserNotFoundException, AccessNotFoundException, NotAllowedException { log.debug("endpoint get database access, databaseId={}, userId={}, principal.name={}", databaseId, userId, principal.getName()); + final User user = userService.findById(userId); if (!userId.equals(UserUtil.getId(principal))) { if (!UserUtil.hasRole(principal, "check-foreign-database-access")) { log.error("Failed to find access: foreign user"); @@ -211,7 +214,6 @@ public class AccessEndpoint { log.trace("principal is allowed to check foreign user access"); } final Database database = databaseService.findById(databaseId); - final User user = userService.findById(userId); final DatabaseAccess access = accessService.find(database, user); final DatabaseAccessDto dto = databaseMapper.databaseAccessToDatabaseAccessDto(access); log.trace("check access resulted in dto {}", dto); @@ -261,10 +263,11 @@ public class AccessEndpoint { SearchServiceException, SearchServiceConnectionException { log.debug("endpoint revoke database access, databaseId={}, userId={}", databaseId, userId); final Database database = databaseService.findById(databaseId); - final User user = userService.findByUsername(principal.getName()); - if (!database.getOwner().equals(user)) { - log.error("Failed to revoke access to user with id {}: not owner", user.getId()); - throw new NotAllowedException("Failed to revoke access to user with id " + user.getId() + ": not owner"); + final User caller = userService.findByUsername(principal.getName()); + final User user = userService.findById(userId); + if (!database.getOwner().equals(caller)) { + log.error("Failed to revoke access to user with id {}: not owner", caller.getId()); + throw new NotAllowedException("Failed to revoke access to user with id " + caller.getId() + ": not owner"); } accessService.find(database, user); accessService.delete(database, user); diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java index 294d471e8fefe4ccafcf06f5aac47e23fce6f757..b9460ee12d6922de5a97b8eecbb6e7239c01fca6 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java @@ -145,7 +145,7 @@ public class ContainerEndpoint { log.trace("find container resulted in container {}", dto); final HttpHeaders headers = new HttpHeaders(); if (UserUtil.isSystem(principal)) { - log.trace("attach privileged credential information"); + log.trace("principal matches system-scoped user: expose privileged information"); headers.set("X-Username", container.getPrivilegedUsername()); headers.set("X-Password", container.getPrivilegedPassword()); headers.set("Access-Control-Expose-Headers", "X-Username X-Password"); diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index 8be62ea5c400719b31764b0b931a329481b75018..415b7392a2c7bb7d8272811a5cb327ffea298fda 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -469,6 +469,7 @@ public class DatabaseEndpoint { } final HttpHeaders headers = new HttpHeaders(); if (UserUtil.isSystem(principal)) { + log.trace("principal matches system-scoped user: expose privileged information"); headers.set("X-Username", database.getContainer().getPrivilegedUsername()); headers.set("X-Password", database.getContainer().getPrivilegedPassword()); headers.set("Access-Control-Expose-Headers", "X-Username X-Password"); diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index 4fb8240b1d00f00f39a233cd3492e0b06940314a..0d92d470617d0d3fdc9fe62a7915351a027f2d71 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -407,6 +407,7 @@ public class TableEndpoint { final TableDto dto = metadataMapper.customTableToTableDto(table); final HttpHeaders headers = new HttpHeaders(); if (UserUtil.isSystem(principal)) { + log.trace("principal matches system-scoped user: expose privileged information"); headers.set("X-Username", table.getDatabase().getContainer().getPrivilegedUsername()); headers.set("X-Password", table.getDatabase().getContainer().getPrivilegedPassword()); headers.set("X-Host", table.getDatabase().getContainer().getHost()); diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java index 4be54d5edd1ed39168b97a00177d87d09a7a87ee..ef1cb74a40d2dab3c7dd545d927525ad2c05198e 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java @@ -26,6 +26,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -275,8 +276,16 @@ public class UserEndpoint { throw new NotAllowedException("Failed to find user: foreign user"); } } + final HttpHeaders headers = new HttpHeaders(); + if (UserUtil.isSystem(principal)) { + log.trace("principal matches system-scoped user: expose privileged information"); + headers.set("X-Username", user.getUsername()); + headers.set("X-Password", user.getMariadbPassword()); + headers.set("Access-Control-Expose-Headers", "X-Username X-Password"); + } final UserDto dto = userMapper.userToUserDto(user); return ResponseEntity.ok() + .headers(headers) .body(dto); } diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index 79981ee6d1fdcaaa5344915f7a0f3d3c43514926..04d98578a58bd25927aa600151448cc6ed9f289f 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -184,6 +184,7 @@ public class ViewEndpoint { final View view = viewService.findById(database, viewId); final HttpHeaders headers = new HttpHeaders(); if (UserUtil.isSystem(principal)) { + log.trace("principal matches system-scoped user: expose privileged information"); headers.set("X-Username", view.getDatabase().getContainer().getPrivilegedUsername()); headers.set("X-Password", view.getDatabase().getContainer().getPrivilegedPassword()); headers.set("X-Host", view.getDatabase().getContainer().getHost()); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java index ea58ae16e4ac35931bb5f713b197bacdc37b6958..e6f08ee889a40b4be6240d0eeaf64b385d095938 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceUnitTest.java @@ -346,6 +346,8 @@ public class DatabaseServiceUnitTest extends AbstractUnitTest { /* test */ final Database response = databaseService.modifyOwner(database, newOwner); assertNotNull(response); + assertEquals(newOwner.getId(), response.getOwnedBy()); + assertEquals(newOwner.getId(), response.getOwner().getId()); return response; } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/DataServiceGatewayImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/DataServiceGatewayImpl.java index 886911d9f4a770fe8c620d7cc882cd7b4da05c55..e483c6346a77eeb697a0224166140fee8ff0cdcf 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/DataServiceGatewayImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/DataServiceGatewayImpl.java @@ -55,7 +55,7 @@ public class DataServiceGatewayImpl implements DataServiceGateway { log.error("Failed to create access: {}", e.getMessage()); throw new DataServiceException("Failed to create access: " + e.getMessage(), e); } - if (!response.getStatusCode().equals(HttpStatus.CREATED)) { + if (!response.getStatusCode().equals(HttpStatus.ACCEPTED)) { log.error("Failed to create access: wrong http code: {}", response.getStatusCode()); throw new DataServiceException("Failed to create access: wrong http code: " + response.getStatusCode()); } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java index aaa50251c3dc0dd79e51af1c983bfda07affffaa..f6cf096499a014d5ebdb132ddb195c292da7747b 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java @@ -72,6 +72,7 @@ public class AccessServiceImpl implements AccessService { .hdbid(database.getId()) .database(database) .huserid(user.getId()) + .user(user) .type(metadataMapper.accessTypeDtoToAccessType(type)) .build(); database.getAccesses() diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java index 8c835864db5ed4bf69bd2bd6b29adfe4d409899d..5fc4b851625f22ada35ce8d857575cf675cb14ab 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceImpl.java @@ -170,6 +170,8 @@ public class DatabaseServiceImpl implements DatabaseService { SearchServiceConnectionException { /* update in metadata database */ database.setOwnedBy(user.getId()); + database.setContact(user); + database.setContactPerson(user.getId()); database = databaseRepository.save(database); /* save in search service */ searchServiceGateway.update(database); diff --git a/dbrepo-ui/components/dialogs/EditAccess.vue b/dbrepo-ui/components/dialogs/EditAccess.vue index 8132adddf5935ae357893f8f91a2c4c597e6cf94..97f5dff00329699a5bb1aa1888356d9e72bb2bae 100644 --- a/dbrepo-ui/components/dialogs/EditAccess.vue +++ b/dbrepo-ui/components/dialogs/EditAccess.vue @@ -12,7 +12,7 @@ <v-col> <v-autocomplete v-if="!isModification" - v-model="modify.userId" + v-model="localUserId" :items="eligibleUsers" :disabled="loadingUsers" :loading="loadingUsers" @@ -90,6 +90,7 @@ export default { loadingUsers: false, users: [], error: false, + localUserId: null, types: [ { title: this.$t('pages.database.subpages.access.read'), value: 'read' }, { title: this.$t('pages.database.subpages.access.write-own'), value: 'write_own' }, @@ -169,36 +170,60 @@ export default { }, revokeAccess () { const accessService = useAccessService() - accessService.remove(this.$route.params.database_id, this.userId) + accessService.remove(this.$route.params.database_id, this.localUserId) .then(() => { const toast = useToastInstance() - toast.success(this.$t('notifications.access.revoked')) + toast.success(this.$t('success.access.revoked')) this.$emit('close-dialog', { success: true }) }) + .catch(({code}) => { + this.loading = false + const toast = useToastInstance() + if (typeof code !== 'string') { + return + } + toast.error(this.$t(code)) + }) .finally(() => { this.loading = false }) }, modifyAccess () { const accessService = useAccessService() - accessService.modify(this.$route.params.database_id, this.userId, this.modify) + accessService.modify(this.$route.params.database_id, this.localUserId, this.modify) .then(() => { const toast = useToastInstance() - toast.success(this.$t('notifications.access.modified')) + toast.success(this.$t('success.access.modified')) this.$emit('close-dialog', { success: true }) }) + .catch(({code}) => { + this.loading = false + const toast = useToastInstance() + if (typeof code !== 'string') { + return + } + toast.error(this.$t(code)) + }) .finally(() => { this.loading = false }) }, giveAccess () { const accessService = useAccessService() - accessService.create(this.$route.params.database_id, this.userId, this.modify) + accessService.create(this.$route.params.database_id, this.localUserId, this.modify) .then(() => { const toast = useToastInstance() - toast.success(this.$t('notifications.access.created')) + toast.success(this.$t('success.access.created')) this.$emit('close-dialog', { success: true }) }) + .catch(({code}) => { + this.loading = false + const toast = useToastInstance() + if (typeof code !== 'string') { + return + } + toast.error(this.$t(code)) + }) .finally(() => { this.loading = false }) @@ -218,6 +243,7 @@ export default { if (!this.userId) { this.loadUsers() } + this.localUserId = this.userId if (!this.accessType) { this.modify.type = null } else { diff --git a/dbrepo-ui/composables/access-service.ts b/dbrepo-ui/composables/access-service.ts index c08e5d0b9f6bac53b8d7eaeba993e06234435b31..056efec1171933d7dcf0921c7eff34717d574333 100644 --- a/dbrepo-ui/composables/access-service.ts +++ b/dbrepo-ui/composables/access-service.ts @@ -21,7 +21,7 @@ export const useAccessService = (): any => { const axios = useAxiosInstance() console.debug('create access for user with id', userId, 'of database with id', databaseId) return new Promise<DatabaseAccessDto>((resolve, reject) => { - axios.post<DatabaseAccessDto>(`/api/database/${databaseId}/access`, payload) + axios.post<DatabaseAccessDto>(`/api/database/${databaseId}/access/${userId}`, payload) .then((response) => { console.info('Created access for user with id', userId, 'of database with id', databaseId) resolve(response.data) diff --git a/dbrepo-ui/dto/index.ts b/dbrepo-ui/dto/index.ts index df0babcfe1f310bdff6415f6351a82020ec3cf4e..c1d63fa200c8613a6d7417e5e14db0b42288f269 100644 --- a/dbrepo-ui/dto/index.ts +++ b/dbrepo-ui/dto/index.ts @@ -382,7 +382,7 @@ interface DatabaseModifyVisibilityDto { } interface DatabaseTransferDto { - username: string; + id: string; } interface DatabaseModifyImageDto { diff --git a/dbrepo-ui/locales/en-US.json b/dbrepo-ui/locales/en-US.json index be8ddfcc2317d441d3a8b6edacd4b3f5a663c6af..57f88bb2f9500193e669b55b8a75e0a82cba8361 100644 --- a/dbrepo-ui/locales/en-US.json +++ b/dbrepo-ui/locales/en-US.json @@ -282,8 +282,8 @@ "secure": "secure", "insecure": "insecure", "permissions": { - "write": "You can write to this table", - "read": "You can read all contents of this table" + "write": "Can write to this table", + "read": "Can read all contents of this table" } }, "description": { @@ -611,9 +611,9 @@ "access": { "title": "Database Access", "subtitle": "Overview on users with their access to the database", - "read": "You can read all contents", - "write-own": "You can write own tables and read all contents", - "write-all": "You can write own tables and read all contents", + "read": "Can read all contents", + "write-own": "Can write own tables and read all contents", + "write-all": "Can write own tables and read all contents", "revoke": "Revoke", "action": "Action", "username": { diff --git a/dbrepo-ui/pages/database/[database_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/settings.vue index 09c3d8263bc46bc74eb0fe34b8651e41c6214ccc..e22ad345228dcb3b4e777ba0e38835c7b8c03a3d 100644 --- a/dbrepo-ui/pages/database/[database_id]/settings.vue +++ b/dbrepo-ui/pages/database/[database_id]/settings.vue @@ -95,7 +95,7 @@ <v-btn v-if="item && item.user && item.user.username !== user.username" size="x-small" - variant="flat" + :variant="buttonVariant" :disabled="!canModifyAccess" :text="$t('pages.database.subpages.access.submit.text')" @click="modifyAccess(item)" /> @@ -422,8 +422,8 @@ export default { this.$refs.form.validate() }, closeDialog () { - this.reloadDatabase() this.editAccessDialog = false + this.cacheStore.reloadDatabase() }, updateDatabaseVisibility () { this.loading = true @@ -510,11 +510,11 @@ export default { updateDatabaseOwner () { this.loading = true const databaseService = useDatabaseService() - databaseService.updateOwner(this.$route.params.database_id, this.modifyOwner.id) + databaseService.updateOwner(this.$route.params.database_id, { id: this.modifyOwner.id }) .then(() => { const toast = useToastInstance() toast.success(this.$t('success.database.transfer')) - location.reload() + this.$router.push(`/database/${this.$route.params.database_id}`) }) .catch(() => { this.loading = false diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue index 3a821a730b50c6292f603b67c8b666add18aaa08..68d149ed0822f609e679a403e8c4ff671f7bdc6f 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/schema.vue @@ -200,7 +200,7 @@ export default { if (!this.access) { return false } - return this.roles.includes('modify-table-column-semantics') && (this.access.type === 'write_all' || this.table.owner.username === this.user.username) + return this.roles.includes('modify-table-column-semantics') && (this.access.type === 'write_all' || this.table.owner.id === this.user.id) }, inputVariant () { const runtimeConfig = useRuntimeConfig()