diff --git a/dbrepo-analyse-service/Pipfile.lock b/dbrepo-analyse-service/Pipfile.lock index f177d904cb25228548dbc3ee5e0bef46919d6698..239b3d7c010b8b868b456961ec4c97ca7102060e 100644 --- a/dbrepo-analyse-service/Pipfile.lock +++ b/dbrepo-analyse-service/Pipfile.lock @@ -159,11 +159,11 @@ }, "attrs": { "hashes": [ - "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", - "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308" + "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", + "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a" ], "markers": "python_version >= '3.8'", - "version": "==24.3.0" + "version": "==25.1.0" }, "blinker": { "hashes": [ @@ -175,20 +175,20 @@ }, "boto3": { "hashes": [ - "sha256:53a5307f6a3526ee2f8590e3c45efa504a3ea4532c1bfe4926c0c19bf188d141", - "sha256:f9843a5d06f501d66ada06f5a5417f671823af2cf319e36ceefa1bafaaaaa953" + "sha256:6d473f0f340d02b4e9ad5b8e68786a09728101a8b950231b89ebdaf72b6dca21", + "sha256:b36feae061dc0793cf311468956a0a9e99215ce38bc99a1a4e55a5b105f16297" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.36.3" + "version": "==1.36.6" }, "botocore": { "hashes": [ - "sha256:536ab828e6f90dbb000e3702ac45fd76642113ae2db1b7b1373ad24104e89255", - "sha256:775b835e979da5c96548ed1a0b798101a145aec3cd46541d62e27dda5a94d7f8" + "sha256:4864c53d638da191a34daf3ede3ff1371a3719d952cc0c6bd24ce2836a38dd77", + "sha256:f77bbbb03fb420e260174650fb5c0cc142ec20a96967734eed2b0ef24334ef34" ], "markers": "python_version >= '3.8'", - "version": "==1.36.3" + "version": "==1.36.6" }, "certifi": { "hashes": [ @@ -412,7 +412,7 @@ }, "dbrepo": { "hashes": [ - "sha256:a41ca60353510cbecf8fb647cf2483acb100258743794a16bc8ad6f8e9ea4481" + "sha256:181e3da705d8f61ef26a743e0a445c5363b68c671c63f655791d340efdd7aac0" ], "path": "./lib/dbrepo-1.6.2.tar.gz" }, @@ -1230,12 +1230,12 @@ }, "pydantic": { "hashes": [ - "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff", - "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53" + "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", + "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.10.5" + "version": "==2.10.6" }, "pydantic-core": { "hashes": [ @@ -1427,11 +1427,11 @@ }, "referencing": { "hashes": [ - "sha256:363d9c65f080d0d70bc41c721dce3c7f3e77fc09f269cd5c8813da18069a6794", - "sha256:ca2e6492769e3602957e9b831b94211599d2aade9477f5d44110d2530cf9aade" + "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", + "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0" ], "markers": "python_version >= '3.9'", - "version": "==0.36.1" + "version": "==0.36.2" }, "requests": { "hashes": [ @@ -1553,11 +1553,11 @@ }, "s3transfer": { "hashes": [ - "sha256:3f25c900a367c8b7f7d8f9c34edc87e300bde424f779dc9f0a8ae4f9df9264f6", - "sha256:8fa0aa48177be1f3425176dfe1ab85dcd3d962df603c3dbfc585e6bf857ef0ff" + "sha256:3b39185cb72f5acc77db1a58b6e25b977f28d20496b6e58d6813d75f464d632f", + "sha256:be6ecb39fadd986ef1701097771f87e4d2f821f27f6071c872143884d2950fbc" ], "markers": "python_version >= '3.8'", - "version": "==0.11.1" + "version": "==0.11.2" }, "setuptools": { "hashes": [ @@ -1612,7 +1612,7 @@ "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.10'", + "markers": "python_version >= '3.9'", "version": "==2.3.0" }, "werkzeug": { @@ -2236,7 +2236,7 @@ "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.10'", + "markers": "python_version >= '3.9'", "version": "==2.3.0" }, "wrapt": { diff --git a/dbrepo-analyse-service/lib/dbrepo-1.6.2-py3-none-any.whl b/dbrepo-analyse-service/lib/dbrepo-1.6.2-py3-none-any.whl index 24256263e2fb3156ac0eea01079116e4b40e36fd..256d325e8bdbdacd8c967d852c98e39d8d3b9eb9 100644 Binary files a/dbrepo-analyse-service/lib/dbrepo-1.6.2-py3-none-any.whl and b/dbrepo-analyse-service/lib/dbrepo-1.6.2-py3-none-any.whl differ diff --git a/dbrepo-analyse-service/lib/dbrepo-1.6.2.tar.gz b/dbrepo-analyse-service/lib/dbrepo-1.6.2.tar.gz index 2ae1ea50b1610050f5bd5746f7e9596b1c483c9d..ad4d6f9c5590836360d1a919f4be84b5cc5f9ade 100644 Binary files a/dbrepo-analyse-service/lib/dbrepo-1.6.2.tar.gz and b/dbrepo-analyse-service/lib/dbrepo-1.6.2.tar.gz differ diff --git a/dbrepo-auth-service/create-event-listener.jar b/dbrepo-auth-service/create-event-listener.jar new file mode 100644 index 0000000000000000000000000000000000000000..fd07f62a743ee039a934e33de6d18ae9e28ac653 Binary files /dev/null and b/dbrepo-auth-service/create-event-listener.jar differ diff --git a/dbrepo-auth-service/create-event-listener/.gitignore b/dbrepo-auth-service/create-event-listener/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5d6e1ae3b181727bbd28cdb0107283899c3a0fd2 --- /dev/null +++ b/dbrepo-auth-service/create-event-listener/.gitignore @@ -0,0 +1,30 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ +target/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/dbrepo-auth-service/create-event-listener/pom.xml b/dbrepo-auth-service/create-event-listener/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..47abc9561373c10805d5cd04224a7bd5e5f48c1a --- /dev/null +++ b/dbrepo-auth-service/create-event-listener/pom.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-parent</artifactId> + <version>24.0.5</version> + </parent> + + <groupId>at.tuwien</groupId> + <artifactId>create-event-listener</artifactId> + <name>dbrepo-auth-service</name> + <version>24.0.5</version> + + <description>Create event listener</description> + + <url>https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/</url> + <developers> + <developer> + <name>Martin Weise</name> + <email>martin.weise@tuwien.ac.at</email> + <organization>TU Wien</organization> + </developer> + </developers> + + <properties> + <java.version>17</java.version> + <maven.version>3.9.8</maven.version> + <maven.compiler.source>${java.version}</maven.compiler.source> + <maven.compiler.target>${java.version}</maven.compiler.target> + <maven.compiler.release>${java.version}</maven.compiler.release> + <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-server-spi</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-server-spi-private</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-services</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-saml-core-public</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jboss.logging</groupId> + <artifactId>jboss-logging</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jboss.spec.javax.ws.rs</groupId> + <artifactId>jboss-jaxrs-api_2.1_spec</artifactId> + </dependency> + </dependencies> + + <build> + <finalName>create-event-listener</finalName> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${maven-compiler-plugin.version}</version> + <configuration> + <source>${java.version}</source> + <target>${java.version}</target> + </configuration> + </plugin> + <plugin> + <groupId>org.wildfly.plugins</groupId> + <artifactId>wildfly-maven-plugin</artifactId> + <configuration> + <skip>false</skip> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/Client.java b/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/Client.java new file mode 100644 index 0000000000000000000000000000000000000000..acba01a663f59526ce8c967c7122c99b6bbf1413 --- /dev/null +++ b/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/Client.java @@ -0,0 +1,53 @@ +package at.tuwien; + +import org.jboss.logging.Logger; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; + +public class Client { + private static final Logger log = Logger.getLogger(Client.class); + private static final String WEBHOOK_URL = "WEBHOOK_URL"; + + public static void postService(String data) throws IOException { + try { + final String urlString = System.getenv(WEBHOOK_URL); + log.debugf("WEBHOOK_URL: %s", urlString); + + if (urlString == null || urlString.isEmpty()) { + throw new IllegalArgumentException("Environment variable WEBHOOK_URL is not set or is empty."); + } + + URL url = URI.create(urlString).toURL(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setDoOutput(true); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/json; utf-8"); + + OutputStream os = conn.getOutputStream(); + os.write(data.getBytes()); + os.flush(); + + final int responseCode = conn.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_CREATED && responseCode != HttpURLConnection.HTTP_OK) { + throw new RuntimeException("Failed : HTTP error code : " + responseCode); + } + + final BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String output; + log.debugf("Output from Server .... \n"); + while ((output = br.readLine()) != null) { + System.out.println(output); + log.debugf("Input from Server: %s", output); + } + conn.disconnect(); + } catch (IOException e) { + throw new IOException("Failed to post service: " + e.getMessage(), e); + } + } +} diff --git a/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/CreateEventListenerProvider.java b/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/CreateEventListenerProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..8ff079f8c3f562d645a3d8488c5e33b30717f738 --- /dev/null +++ b/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/CreateEventListenerProvider.java @@ -0,0 +1,124 @@ +package at.tuwien; + +import org.jboss.logging.Logger; +import org.keycloak.events.Event; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.EventType; +import org.keycloak.events.admin.AdminEvent; +import org.keycloak.events.admin.OperationType; +import org.keycloak.events.admin.ResourceType; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RealmProvider; +import org.keycloak.models.UserModel; + +import java.util.StringJoiner; + +public class CreateEventListenerProvider implements EventListenerProvider { + + private static final Logger log = Logger.getLogger(CreateEventListenerProvider.class); + + private final KeycloakSession session; + private final RealmProvider model; + + public CreateEventListenerProvider(KeycloakSession session) { + this.session = session; + this.model = session.realms(); + } + + @Override + public void onEvent(Event event) { + + log.debugf("New %s Event", event.getType()); + log.debugf("onEvent-> %s", toString(event)); + + if (EventType.REGISTER.equals(event.getType())) { + + event.getDetails().forEach((key, value) -> log.debugf("%s : %s", key, value)); + + RealmModel realm = this.model.getRealm(event.getRealmId()); + UserModel user = this.session.users().getUserById(realm, event.getUserId()); + sendUserData(user); + } + + } + + @Override + public void onEvent(AdminEvent adminEvent, boolean b) { + log.debug("onEvent(AdminEvent)"); + log.debugf("Resource path: %s", adminEvent.getResourcePath()); + log.debugf("Resource type: %s", adminEvent.getResourceType()); + log.debugf("Operation type: %s", adminEvent.getOperationType()); + log.debugf("AdminEvent.toString(): %s", toString(adminEvent)); + if (ResourceType.USER.equals(adminEvent.getResourceType()) + && OperationType.CREATE.equals(adminEvent.getOperationType())) { + RealmModel realm = this.model.getRealm(adminEvent.getRealmId()); + UserModel user = this.session.users().getUserById(realm, adminEvent.getResourcePath().substring(6)); + + sendUserData(user); + } + } + + private void sendUserData(UserModel user) { + try { + Client.postService("{\"ldap\":\"" + user.getFirstAttribute("LDAP_ID") + "\", \"id\":\"" + user.getId() + "\",\"username\":\"" + user.getUsername() + "\"}"); + log.debug("A new user has been created and post API"); + } catch (Exception e) { + log.errorf("Failed to call API: %s", e); + } + } + + @Override + public void close() { + } + + private String toString(Event event) { + final StringJoiner joiner = new StringJoiner(", "); + joiner.add("type=" + event.getType()) + .add("realmId=" + event.getRealmId()) + .add("clientId=" + event.getClientId()) + .add("userId=" + event.getUserId()) + .add("ipAddress=" + event.getIpAddress()); + if (event.getError() != null) { + joiner.add("error=" + event.getError()); + } + if (event.getDetails() != null) { + event.getDetails().forEach((key, value) -> { + if (value == null || !value.contains(" ")) { + joiner.add(key + "=" + value); + } else { + joiner.add(key + "='" + value + "'"); + } + }); + } + return joiner.toString(); + } + + private String toString(AdminEvent event) { + RealmModel realm = this.model.getRealm(event.getRealmId()); + UserModel newRegisteredUser = this.session.users().getUserById(realm, event.getAuthDetails().getUserId()); + + StringJoiner joiner = new StringJoiner(", "); + + joiner.add("operationType=" + event.getOperationType()) + .add("realmId=" + event.getAuthDetails().getRealmId()) + .add("clientId=" + event.getAuthDetails().getClientId()) + .add("userId=" + event.getAuthDetails().getUserId()); + + if (newRegisteredUser != null) { + joiner.add("email=" + newRegisteredUser.getEmail()) + .add("username=" + newRegisteredUser.getUsername()) + .add("firstName=" + newRegisteredUser.getFirstName()) + .add("lastName=" + newRegisteredUser.getLastName()); + } + + joiner.add("ipAddress=" + event.getAuthDetails().getIpAddress()) + .add("resourcePath=" + event.getResourcePath()); + + if (event.getError() != null) { + joiner.add("error=" + event.getError()); + } + + return joiner.toString(); + } +} diff --git a/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/CreateEventListenerProviderFactory.java b/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/CreateEventListenerProviderFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..61477ffa33169504a3368d11d0750c9c1404e160 --- /dev/null +++ b/dbrepo-auth-service/create-event-listener/src/main/java/at/tuwien/CreateEventListenerProviderFactory.java @@ -0,0 +1,36 @@ +package at.tuwien; + +import org.keycloak.Config; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.EventListenerProviderFactory; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; + +public class CreateEventListenerProviderFactory implements EventListenerProviderFactory { + + @Override + public EventListenerProvider create(KeycloakSession keycloakSession) { + return new CreateEventListenerProvider(keycloakSession); + } + + @Override + public void init(Config.Scope scope) { + + } + + @Override + public void postInit(KeycloakSessionFactory keycloakSessionFactory) { + + } + + @Override + public void close() { + + } + + @Override + public String getId() { + return "create-event-listener"; + } + +} diff --git a/dbrepo-auth-service/create-event-listener/src/main/resources/META-INF/jboss-deployment-structure.xml b/dbrepo-auth-service/create-event-listener/src/main/resources/META-INF/jboss-deployment-structure.xml new file mode 100644 index 0000000000000000000000000000000000000000..c0330ba082479a3bd9d0caf86508b5067251ed84 --- /dev/null +++ b/dbrepo-auth-service/create-event-listener/src/main/resources/META-INF/jboss-deployment-structure.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<jboss-deployment-structure> + <deployment> + <dependencies> + <module name="org.keycloak.keycloak-services" /> + </dependencies> + </deployment> +</jboss-deployment-structure> \ No newline at end of file diff --git a/dbrepo-auth-service/create-event-listener/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory b/dbrepo-auth-service/create-event-listener/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory new file mode 100644 index 0000000000000000000000000000000000000000..df3c5521f0958fed5fadb4f006d8ee6eb50f97c2 --- /dev/null +++ b/dbrepo-auth-service/create-event-listener/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory @@ -0,0 +1 @@ +at.tuwien.CreateEventListenerProviderFactory \ No newline at end of file diff --git a/dbrepo-auth-service/dbrepo-realm.json b/dbrepo-auth-service/dbrepo-realm.json index cf3fcadb2ffa27513bc60323aab4ebccf1e0aff4..4dbc95d0992ff10a3abeafec8131b04d43d5a279 100644 --- a/dbrepo-auth-service/dbrepo-realm.json +++ b/dbrepo-auth-service/dbrepo-realm.json @@ -2175,7 +2175,7 @@ "adminTheme" : "", "emailTheme" : "", "eventsEnabled" : false, - "eventsListeners" : [ "jboss-logging" ], + "eventsListeners" : [ "create-event-listener", "jboss-logging" ], "enabledEventTypes" : [ "SEND_RESET_PASSWORD", "UPDATE_CONSENT_ERROR", "GRANT_CONSENT", "VERIFY_PROFILE_ERROR", "REMOVE_TOTP", "REVOKE_GRANT", "UPDATE_TOTP", "LOGIN_ERROR", "CLIENT_LOGIN", "RESET_PASSWORD_ERROR", "IMPERSONATE_ERROR", "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION", "OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR", "RESTART_AUTHENTICATION", "IMPERSONATE", "UPDATE_PROFILE_ERROR", "LOGIN", "OAUTH2_DEVICE_VERIFY_USER_CODE", "UPDATE_PASSWORD_ERROR", "CLIENT_INITIATED_ACCOUNT_LINKING", "TOKEN_EXCHANGE", "AUTHREQID_TO_TOKEN", "LOGOUT", "REGISTER", "DELETE_ACCOUNT_ERROR", "CLIENT_REGISTER", "IDENTITY_PROVIDER_LINK_ACCOUNT", "DELETE_ACCOUNT", "UPDATE_PASSWORD", "CLIENT_DELETE", "FEDERATED_IDENTITY_LINK_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN", "CLIENT_DELETE_ERROR", "VERIFY_EMAIL", "CLIENT_LOGIN_ERROR", "RESTART_AUTHENTICATION_ERROR", "EXECUTE_ACTIONS", "REMOVE_FEDERATED_IDENTITY_ERROR", "TOKEN_EXCHANGE_ERROR", "PERMISSION_TOKEN", "SEND_IDENTITY_PROVIDER_LINK_ERROR", "EXECUTE_ACTION_TOKEN_ERROR", "SEND_VERIFY_EMAIL", "OAUTH2_DEVICE_AUTH", "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY", "OAUTH2_DEVICE_CODE_TO_TOKEN", "IDENTITY_PROVIDER_POST_LOGIN", "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", "OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR", "UPDATE_EMAIL", "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "EXECUTE_ACTION_TOKEN", "LOGOUT_ERROR", "UPDATE_EMAIL_ERROR", "CLIENT_UPDATE_ERROR", "AUTHREQID_TO_TOKEN_ERROR", "UPDATE_PROFILE", "CLIENT_REGISTER_ERROR", "FEDERATED_IDENTITY_LINK", "SEND_IDENTITY_PROVIDER_LINK", "SEND_VERIFY_EMAIL_ERROR", "RESET_PASSWORD", "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", "OAUTH2_DEVICE_AUTH_ERROR", "UPDATE_CONSENT", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR", "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE", "CUSTOM_REQUIRED_ACTION_ERROR", "IDENTITY_PROVIDER_POST_LOGIN_ERROR", "UPDATE_TOTP_ERROR", "CODE_TO_TOKEN", "VERIFY_PROFILE", "GRANT_CONSENT_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" ], "adminEventsEnabled" : false, "adminEventsDetailsEnabled" : false, @@ -2223,7 +2223,7 @@ "subType" : "anonymous", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "saml-role-list-mapper" ] + "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "saml-role-list-mapper", "oidc-address-mapper", "saml-user-property-mapper", "oidc-full-name-mapper" ] } }, { "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1", @@ -2249,7 +2249,7 @@ "subType" : "authenticated", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper" ] + "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-full-name-mapper" ] } } ], "org.keycloak.storage.UserStorageProvider" : [ { @@ -2265,8 +2265,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" ] } }, { @@ -2322,8 +2322,8 @@ "membership.ldap.attribute" : [ "member" ], "memberof.ldap.attribute" : [ "memberOf" ], "group.object.classes" : [ "groupOfNames" ], - "drop.non.existing.groups.during.sync" : [ "false" ], - "groups.path" : [ "/" ] + "groups.path" : [ "/" ], + "drop.non.existing.groups.during.sync" : [ "false" ] } }, { "id" : "b6ff3285-35af-4e86-8bb4-d94b8e0d70bb", @@ -2354,8 +2354,8 @@ } ] }, "config" : { - "fullSyncPeriod" : [ "-1" ], "pagination" : [ "false" ], + "fullSyncPeriod" : [ "-1" ], "startTls" : [ "false" ], "connectionPooling" : [ "true" ], "usersDn" : [ "ou=users,dc=dbrepo,dc=at" ], @@ -2363,15 +2363,15 @@ "useKerberosForPasswordAuthentication" : [ "false" ], "importEnabled" : [ "true" ], "enabled" : [ "true" ], - "changedSyncPeriod" : [ "-1" ], "bindCredential" : [ "admin" ], "bindDn" : [ "cn=admin,dc=dbrepo,dc=at" ], + "changedSyncPeriod" : [ "-1" ], "usernameLDAPAttribute" : [ "uid" ], "lastSync" : [ "1719252666" ], "vendor" : [ "other" ], "uuidLDAPAttribute" : [ "entryUUID" ], - "allowKerberosAuthentication" : [ "false" ], "connectionUrl" : [ "ldap://identity-service:1389" ], + "allowKerberosAuthentication" : [ "false" ], "syncRegistrations" : [ "true" ], "authType" : [ "simple" ], "useTruststoreSpi" : [ "always" ], diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index d4eccd0772eba12e007c6e99ae42a60b1304fca5..25dfd50dd434df444a45c4f7850fcdd803f0e9de 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -214,7 +214,7 @@ public class ViewEndpoint extends RestEndpoint { @RequestMapping(value = "/{viewId}/data", method = {RequestMethod.GET, RequestMethod.HEAD}) @Observed(name = "dbrepo_view_data") @Operation(summary = "Get view data", - description = "Gets data from a view of a database. For private databases, the user needs at least *READ* access to the associated database. Requires role `view-database-view-data`.", + description = "Gets data from a view of a database. For private databases, the user needs at least *READ* access to the associated database.", security = {@SecurityRequirement(name = "basicAuth"), @SecurityRequirement(name = "bearerAuth")}) @ApiResponses(value = { @ApiResponse(responseCode = "200", diff --git a/dbrepo-metadata-service/pom.xml b/dbrepo-metadata-service/pom.xml index 04af8a795f25072c5756489d3b7c42a1828c6b59..e08d81603dbf7b1f5d8e2d3d3fdff18db2273ebd 100644 --- a/dbrepo-metadata-service/pom.xml +++ b/dbrepo-metadata-service/pom.xml @@ -27,7 +27,7 @@ <module>report</module> </modules> - <url>https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.5/</url> + <url>https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6/</url> <developers> <developer> <name>Martin Weise</name> diff --git a/dbrepo-metadata-service/rest-service/src/test/resources/init/dbrepo-realm.json b/dbrepo-metadata-service/rest-service/src/test/resources/init/dbrepo-realm.json index 7ee28b34a4f2d662bb43979930732dec74da8a63..56f2003e961a14d09bcd56832437f915cae04dea 100644 --- a/dbrepo-metadata-service/rest-service/src/test/resources/init/dbrepo-realm.json +++ b/dbrepo-metadata-service/rest-service/src/test/resources/init/dbrepo-realm.json @@ -73,7 +73,7 @@ "description" : "${default-system-roles}", "composite" : true, "composites" : { - "realm" : [ "delete-database-view", "update-semantic-unit", "export-query-data", "default-data-steward-roles", "execute-query", "default-user-handling", "delete-table-data", "find-query", "list-database-views", "persist-query", "update-search-index", "delete-database-access", "view-table-history", "create-ontology", "update-ontology", "modify-user-theme", "default-system-roles", "create-semantic-concept", "default-container-handling", "create-container", "create-table", "default-broker-handling", "default-maintenance-handling", "execute-semantic-query", "uma_authorization", "table-semantic-analyse", "list-containers", "check-database-access", "escalated-query-handling", "delete-identifier", "modify-database-owner", "list-tables", "export-table-data", "create-database-access", "delete-container", "re-execute-query", "create-semantic-unit", "escalated-identifier-handling", "system", "update-table-statistic", "escalated-semantics-handling", "default-database-handling", "delete-ontology", "find-database", "find-database-view", "update-semantic-concept", "find-user", "import-database-data", "publish-identifier", "default-roles-dbrepo", "find-foreign-user", "create-database", "create-maintenance-message", "find-maintenance-message", "escalated-container-handling", "default-researcher-roles", "default-identifier-handling", "escalated-user-handling", "modify-user-information", "create-database-view", "update-maintenance-message", "delete-foreign-table", "offline_access", "modify-foreign-table-column-semantics", "delete-maintenance-message", "find-container", "insert-table-data", "modify-identifier-metadata", "modify-database-image", "escalated-broker-handling", "modify-table-column-semantics", "escalated-database-handling", "default-semantics-handling", "update-database-access", "default-query-handling", "find-table", "list-queries", "default-developer-roles", "create-identifier", "escalated-table-handling", "find-identifier", "view-database-view-data", "view-table-data", "list-licenses", "default-table-handling", "list-identifiers", "create-foreign-identifier", "list-databases", "list-ontologies", "modify-database-visibility", "list-maintenance-messages", "delete-table" ] + "realm" : [ "delete-database-view", "update-semantic-unit", "export-query-data", "default-data-steward-roles", "execute-query", "default-user-handling", "delete-table-data", "find-query", "list-database-views", "persist-query", "update-search-index", "delete-database-access", "view-table-history", "create-ontology", "update-ontology", "modify-user-theme", "default-system-roles", "create-semantic-concept", "default-container-handling", "create-container", "create-table", "default-broker-handling", "default-maintenance-handling", "execute-semantic-query", "uma_authorization", "table-semantic-analyse", "list-containers", "check-database-access", "escalated-query-handling", "delete-identifier", "modify-database-owner", "list-tables", "export-table-data", "create-database-access", "delete-container", "re-execute-query", "create-semantic-unit", "escalated-identifier-handling", "system", "update-table-statistic", "escalated-semantics-handling", "default-database-handling", "delete-ontology", "find-database", "find-database-view", "update-semantic-concept", "find-user", "import-database-data", "publish-identifier", "default-roles-dbrepo", "find-foreign-user", "create-database", "create-maintenance-message", "find-maintenance-message", "escalated-container-handling", "default-researcher-roles", "default-identifier-handling", "escalated-user-handling", "modify-user-information", "create-database-view", "update-maintenance-message", "delete-foreign-table", "offline_access", "modify-foreign-table-column-semantics", "delete-maintenance-message", "find-container", "insert-table-data", "modify-identifier-metadata", "modify-database-image", "escalated-broker-handling", "modify-table-column-semantics", "escalated-database-handling", "default-semantics-handling", "update-database-access", "default-query-handling", "find-table", "list-queries", "default-developer-roles", "create-identifier", "escalated-table-handling", "find-identifier", "view-table-data", "list-licenses", "default-table-handling", "list-identifiers", "create-foreign-identifier", "list-databases", "list-ontologies", "modify-database-visibility", "list-maintenance-messages", "delete-table" ] }, "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", @@ -396,7 +396,7 @@ "description" : "${default-query-handling}", "composite" : true, "composites" : { - "realm" : [ "delete-database-view", "export-query-data", "execute-query", "delete-table-data", "export-table-data", "list-queries", "find-query", "list-database-views", "persist-query", "view-database-view-data", "view-table-data", "re-execute-query", "view-table-history", "create-database-view", "find-database-view", "insert-table-data" ] + "realm" : [ "delete-database-view", "export-query-data", "execute-query", "delete-table-data", "export-table-data", "list-queries", "find-query", "list-database-views", "persist-query", "view-table-data", "re-execute-query", "view-table-history", "create-database-view", "find-database-view", "insert-table-data" ] }, "clientRole" : false, "containerId" : "82c39861-d877-4667-a0f3-4daa2ee230e0", diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java index f4b89de5852dc4008d365835a5e29ccd1db7231c..5c60849dc16a1cde9e7c2c1057d6f97d923bc8db 100644 --- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java @@ -186,9 +186,9 @@ public abstract class BaseTest { "modify-identifier-metadata", "update-foreign-identifier", "create-foreign-identifier"}; public final static String[] DEFAULT_QUERY_HANDLING = new String[]{"default-query-handling", "view-table-data", - "execute-query", "view-table-history", "list-database-views", "view-database-view-data", - "export-query-data", "create-database-view", "delete-database-view", "delete-table-data", - "export-table-data", "persist-query", "re-execute-query", "insert-table-data", "find-database-view"}; + "execute-query", "view-table-history", "list-database-views", "export-query-data", "create-database-view", + "delete-database-view", "delete-table-data", "export-table-data", "persist-query", "re-execute-query", + "insert-table-data", "find-database-view"}; public final static String[] ESCALATED_QUERY_HANDLING = new String[]{"escalated-query-handling"}; diff --git a/dbrepo-search-service/Pipfile.lock b/dbrepo-search-service/Pipfile.lock index d75a0069a1a39cd64ff953624e9bbb8adb61c78a..ded9023e433ea6654c4630c37e17ff5077b267b6 100644 --- a/dbrepo-search-service/Pipfile.lock +++ b/dbrepo-search-service/Pipfile.lock @@ -124,11 +124,11 @@ }, "attrs": { "hashes": [ - "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", - "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308" + "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", + "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a" ], "markers": "python_version >= '3.8'", - "version": "==24.3.0" + "version": "==25.1.0" }, "blinker": { "hashes": [ @@ -360,7 +360,7 @@ }, "dbrepo": { "hashes": [ - "sha256:a41ca60353510cbecf8fb647cf2483acb100258743794a16bc8ad6f8e9ea4481" + "sha256:181e3da705d8f61ef26a743e0a445c5363b68c671c63f655791d340efdd7aac0" ], "path": "./lib/dbrepo-1.6.2.tar.gz" }, @@ -1099,11 +1099,11 @@ }, "pydantic": { "hashes": [ - "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff", - "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53" + "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", + "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236" ], "markers": "python_version >= '3.8'", - "version": "==2.10.5" + "version": "==2.10.6" }, "pydantic-core": { "hashes": [ @@ -1330,11 +1330,11 @@ }, "referencing": { "hashes": [ - "sha256:363d9c65f080d0d70bc41c721dce3c7f3e77fc09f269cd5c8813da18069a6794", - "sha256:ca2e6492769e3602957e9b831b94211599d2aade9477f5d44110d2530cf9aade" + "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", + "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0" ], "markers": "python_version >= '3.9'", - "version": "==0.36.1" + "version": "==0.36.2" }, "requests": { "hashes": [ diff --git a/dbrepo-search-service/init/Pipfile.lock b/dbrepo-search-service/init/Pipfile.lock index e4a2e7d71877f6d44a929b2e344390bbf1117db0..ef08434670ef0b34b7eaf90cde228a75f57d81b5 100644 --- a/dbrepo-search-service/init/Pipfile.lock +++ b/dbrepo-search-service/init/Pipfile.lock @@ -124,11 +124,11 @@ }, "attrs": { "hashes": [ - "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", - "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308" + "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", + "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a" ], "markers": "python_version >= '3.8'", - "version": "==24.3.0" + "version": "==25.1.0" }, "blinker": { "hashes": [ @@ -254,7 +254,7 @@ }, "dbrepo": { "hashes": [ - "sha256:a41ca60353510cbecf8fb647cf2483acb100258743794a16bc8ad6f8e9ea4481" + "sha256:181e3da705d8f61ef26a743e0a445c5363b68c671c63f655791d340efdd7aac0" ], "path": "./lib/dbrepo-1.6.2.tar.gz" }, @@ -808,11 +808,11 @@ }, "pydantic": { "hashes": [ - "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff", - "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53" + "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", + "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236" ], "markers": "python_version >= '3.8'", - "version": "==2.10.5" + "version": "==2.10.6" }, "pydantic-core": { "hashes": [ diff --git a/dbrepo-search-service/init/lib/dbrepo-1.6.2-py3-none-any.whl b/dbrepo-search-service/init/lib/dbrepo-1.6.2-py3-none-any.whl index 24256263e2fb3156ac0eea01079116e4b40e36fd..256d325e8bdbdacd8c967d852c98e39d8d3b9eb9 100644 Binary files a/dbrepo-search-service/init/lib/dbrepo-1.6.2-py3-none-any.whl and b/dbrepo-search-service/init/lib/dbrepo-1.6.2-py3-none-any.whl differ diff --git a/dbrepo-search-service/init/lib/dbrepo-1.6.2.tar.gz b/dbrepo-search-service/init/lib/dbrepo-1.6.2.tar.gz index 2ae1ea50b1610050f5bd5746f7e9596b1c483c9d..ad4d6f9c5590836360d1a919f4be84b5cc5f9ade 100644 Binary files a/dbrepo-search-service/init/lib/dbrepo-1.6.2.tar.gz and b/dbrepo-search-service/init/lib/dbrepo-1.6.2.tar.gz differ diff --git a/dbrepo-search-service/lib/dbrepo-1.6.2-py3-none-any.whl b/dbrepo-search-service/lib/dbrepo-1.6.2-py3-none-any.whl index 24256263e2fb3156ac0eea01079116e4b40e36fd..256d325e8bdbdacd8c967d852c98e39d8d3b9eb9 100644 Binary files a/dbrepo-search-service/lib/dbrepo-1.6.2-py3-none-any.whl and b/dbrepo-search-service/lib/dbrepo-1.6.2-py3-none-any.whl differ diff --git a/dbrepo-search-service/lib/dbrepo-1.6.2.tar.gz b/dbrepo-search-service/lib/dbrepo-1.6.2.tar.gz index 2ae1ea50b1610050f5bd5746f7e9596b1c483c9d..ad4d6f9c5590836360d1a919f4be84b5cc5f9ade 100644 Binary files a/dbrepo-search-service/lib/dbrepo-1.6.2.tar.gz and b/dbrepo-search-service/lib/dbrepo-1.6.2.tar.gz differ diff --git a/dbrepo-ui/components/identifier/Select.vue b/dbrepo-ui/components/identifier/Select.vue index ca5f3ce21ea995a6cffcd8caa10b6524de0d4d29..4ef13b2ca7eb3d287d1fe2c8f0dbad5d894fa5cb 100644 --- a/dbrepo-ui/components/identifier/Select.vue +++ b/dbrepo-ui/components/identifier/Select.vue @@ -70,14 +70,17 @@ export default { } }, computed: { + cacheUser () { + return this.cacheUser.getUser + }, displayIdentifiers () { if (!this.identifiers) { return [] } - if (!this.userInfo) { + if (!this.cacheUser) { return this.identifiers.filter(i => i.status === 'published') } - return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.userInfo.uid) + return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.cacheUser.uid) }, listVariant () { const runtimeConfig = useRuntimeConfig() diff --git a/dbrepo-ui/layouts/default.vue b/dbrepo-ui/layouts/default.vue index 816d74c26afcd018101ea48d054115adfe196837..935178357471594e74b917152961fea215f03846 100644 --- a/dbrepo-ui/layouts/default.vue +++ b/dbrepo-ui/layouts/default.vue @@ -251,7 +251,7 @@ export default { if (this.accessError) { return this.accessError } - if (!this.user) { + if (!this.cacheUser) { return null } if (this.table && !this.table.is_public && !this.table.is_schema_public && this.table.owner.id !== this.cacheUser.uid) { diff --git a/dbrepo-ui/pages/database/[database_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/info.vue index 9da8daab62a2f2c98572df67865d84660c038e03..8340dfe955f4dc21f19f1af70c23d19d1ed9b1ef 100644 --- a/dbrepo-ui/pages/database/[database_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/info.vue @@ -229,6 +229,9 @@ export default { database () { return this.cacheStore.getDatabase }, + cacheUser () { + return this.cacheStore.getUser + }, identifiers () { if (!this.database) { return [] @@ -239,10 +242,10 @@ export default { if (!this.identifiers) { return [] } - if (!this.user) { + if (!this.cacheUser) { return this.identifiers.filter(i => i.status === 'published') } - return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.userInfo.uid) + return this.identifiers.filter(i => i.status === 'published' || i.owner.id === this.cacheUser.uid) }, identifier () { if (this.pid) { @@ -339,7 +342,11 @@ export default { if (!this.database) { return false } - return this.database.is_schema_public + if (this.database.is_schema_public) { + return true + } + const userService = useUserService() + return userService.hasReadAccess(this.access) } } } diff --git a/dbrepo-ui/pages/database/[database_id]/persist/[identifier_id]/index.vue b/dbrepo-ui/pages/database/[database_id]/persist/[identifier_id]/index.vue index 75f267944f7f9f91daaddefcc46d8ce4e4dd4374..61d34fb5c2a35947fd9af695c140d6a83099b347 100644 --- a/dbrepo-ui/pages/database/[database_id]/persist/[identifier_id]/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/persist/[identifier_id]/index.vue @@ -51,6 +51,13 @@ export default { cacheUser () { return this.cacheStore.getUser }, + identifier () { + if (!this.database) { + return false + } + const filter = this.database.identifiers.filter(i => i.id === Number(this.$route.params.identifier_id)) + return filter.length === 1 ? filter[0] : null + }, canCreateIdentifier () { if (!this.roles) { return false @@ -58,13 +65,19 @@ export default { if (this.roles.includes('create-foreign-identifier')) { return true } - return this.roles.includes('create-identifier') + if (!this.database) { + return false + } + return this.roles.includes('create-identifier') && this.database.owner.id === this.cacheUser.uid }, canUpdateIdentifier () { if (!this.roles) { return false } - return this.roles.includes('modify-identifier-metadata') + if (!this.identifier) { + return false + } + return this.roles.includes('modify-identifier-metadata') && this.identifier.owner.id === this.cacheUser.uid } } } diff --git a/dbrepo-ui/pages/database/[database_id]/persist/index.vue b/dbrepo-ui/pages/database/[database_id]/persist/index.vue index 570c5d9da57943bc6555aa3562ae58d8d43a4c4b..52e36cd0d50fd25ef459fcd8d14ec8696f916cf9 100644 --- a/dbrepo-ui/pages/database/[database_id]/persist/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/persist/index.vue @@ -1,6 +1,6 @@ <template> <div - v-if="canCreateIdentifier || canUpdateIdentifier"> + v-if="canPersistDatabase"> <Persist type="database" :database="database" /> @@ -44,32 +44,24 @@ export default { cacheUser () { return this.cacheStore.getUser }, - hasIdentifier () { - if (this.database && 'identifier' in this.database && this.database.identifier) { - return 'id' in this.database.identifier - } - return false - }, isOwner () { if (!this.database || !this.cacheUser) { return false } return this.database.owner.id === this.cacheUser.uid }, - canCreateIdentifier () { - if (!this.roles || this.hasIdentifier) { + canPersistDatabase () { + if (!this.database || !this.roles) { return false } if (this.roles.includes('create-foreign-identifier')) { return true } - return this.roles.includes('create-identifier') && this.isOwner - }, - canUpdateIdentifier () { - if (!this.roles) { + if (!this.roles.includes('create-identifier') || !this.cacheUser || !this.access) { return false } - return this.hasIdentifier && this.roles.includes('modify-identifier-metadata') + const userService = useUserService() + return userService.hasReadAccess(this.access) && this.database.owner.id === this.cacheUser.uid } } } diff --git a/dbrepo-ui/pages/database/[database_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/settings.vue index 1d71474805123a41956bbe032fa5dd9f3ab96336..26ddf9478cc158a03d9b2bc71480de9b9c0e345a 100644 --- a/dbrepo-ui/pages/database/[database_id]/settings.vue +++ b/dbrepo-ui/pages/database/[database_id]/settings.vue @@ -1,14 +1,13 @@ <template> <div - v-if="canView"> + v-if="canViewSettings"> <DatabaseToolbar ref="toolbar" /> <v-window - v-if="user" v-model="tab"> <v-window-item> <v-card - v-if="isOwner && canModifyImage" + v-if="canModifyImage" variant="flat" rounded="0" :title="$t('pages.database.subpages.settings.title')" @@ -89,7 +88,6 @@ </v-card> <v-divider /> <v-card - v-if="isOwner" variant="flat" rounded="0" :title="$t('pages.database.subpages.access.title')" @@ -106,7 +104,7 @@ </template> <template v-slot:item.action="{ item }"> <v-btn - v-if="item && item.user && item.user.username !== user.username" + v-if="item && item.user && item.user.username !== cacheUser.username" size="x-small" variant="flat" color="warning" @@ -244,13 +242,6 @@ </div> </template> -<script setup> -import { ref } from 'vue' - -const { loggedIn, user, login, logout } = useOidcAuth() -const userInfo = ref(loggedIn ? user.value?.userInfo : null) -const roles = ref(loggedIn ? user.value?.claims?.realm_access?.roles : []) -</script> <script> import DatabaseToolbar from '@/components/database/DatabaseToolbar.vue' import EditAccess from '@/components/dialogs/EditAccess.vue' @@ -342,23 +333,20 @@ export default { access () { return this.cacheStore.getAccess }, + roles () { + return this.cacheStore.getRoles + }, + cacheUser () { + return this.cacheStore.getUser + }, uploadProgress () { return this.cacheStore.getUploadProgress }, - isOwner () { - if (!this.database || !this.user) { - return false - } - if (this.database.owner.id === null || this.userInfo.uid === null) { - return false - } - return this.database.owner.id === this.userInfo.uid - }, isSameOwner () { - if (!this.modifyOwner || !this.userInfo) { + if (!this.modifyOwner || !this.cacheUser) { return false } - return this.modifyOwner.id === this.userInfo.uid + return this.modifyOwner.id === this.cacheUser.uid }, isSameVisibility () { if (!this.modifyVisibility || !this.database) { @@ -367,52 +355,47 @@ export default { return this.modifyVisibility.is_public === this.database.is_public && this.modifyVisibility.is_schema_public === this.database.is_schema_public }, canModifyVisibility () { - if (!this.isOwner) { + if (!this.roles) { return false } return this.roles.includes('modify-database-visibility') }, canModifyOwnership () { - if (!this.isOwner) { + if (!this.roles) { return false } return this.roles.includes('modify-database-owner') }, canUpdateScheme () { - if (!this.isOwner) { + if (!this.roles) { return false } return this.roles.includes('find-database') }, canModifyAccess () { - if (!this.isOwner) { + if (!this.roles) { return false } return this.roles.includes('update-database-access') }, canCreateAccess () { - if (!this.isOwner) { + if (!this.roles) { return false } return this.roles.includes('create-database-access') }, canModifyImage () { - if (!this.isOwner) { + if (!this.roles) { return false } return this.roles.includes('modify-database-image') }, - canView () { - if (this.error) { - return false - } - if (!this.database) { + canViewSettings () { + if (this.error || !this.database || !this.cacheUser || !this.access) { return false } - if (!this.cacheUser) { - return false - } - return this.database.owner.id === this.cacheUser.uid + const userService = useUserService() + return userService.hasReadAccess(this.access) && this.database.owner.id === this.cacheUser.uid }, previewImage () { if (this.file) { diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue index ee6d25eda74fbad4cf063a094b01397f6d370399..30bebeb2b8112032e00c4397a2007352171a356b 100644 --- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue +++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue @@ -1,5 +1,6 @@ <template> - <div> + <div + v-if="canViewSubsetData"> <SubsetToolbar /> <v-toolbar color="secondary" @@ -117,6 +118,19 @@ export default { } return this.subset.owner.username === this.username }, + canViewSubsetData () { + if (this.error || !this.subset) { + return false + } + if (this.subset.is_public) { + return true + } + if (!this.access) { + return false + } + const userService = useUserService() + return userService.hasReadAccess(this.access) + } }, mounted () { this.loadSubset() diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/[identifier_id]/index.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/[identifier_id]/index.vue index 65154f38a508506fb823223bd01959e285526bc1..f50b9788c7f6389e07f9cfea02b7d1f31fcc62af 100644 --- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/[identifier_id]/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/[identifier_id]/index.vue @@ -56,6 +56,16 @@ export default { roles () { return this.cacheStore.getRoles }, + subset () { + return this.cacheStore.getSubset + }, + identifier () { + if (!this.subset) { + return false + } + const filter = this.subset.identifiers.filter(i => i.id === Number(this.$route.params.identifier_id)) + return filter.length === 1 ? filter[0] : null + }, canCreateIdentifier () { if (!this.roles) { return false @@ -63,13 +73,19 @@ export default { if (this.roles.includes('create-foreign-identifier')) { return true } - return this.roles.includes('create-identifier') + if (!this.subset) { + return false + } + return this.roles.includes('create-identifier') && this.subset.owner.id === this.cacheUser.uid }, canUpdateIdentifier () { if (!this.roles) { return false } - return this.roles.includes('modify-identifier-metadata') + if (!this.identifier) { + return false + } + return this.roles.includes('modify-identifier-metadata') && this.identifier.owner.id === this.cacheUser.uid } } } diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/index.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/index.vue index 82a4ba5f70c4176f7f707f54bdd3c6dcc027ef0d..d8e751078731bad1c0fdaebf9658254a71ffc675 100644 --- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/persist/index.vue @@ -1,6 +1,6 @@ <template> <div - v-if="canPersistQuery"> + v-if="canPersistSubset"> <Persist type="subset" :database="database" @@ -56,12 +56,21 @@ export default { access () { return this.cacheStore.getAccess }, - canPersistQuery () { - if (this.loadingQuery || !this.query) { + subset () { + return this.cacheStore.getSubset + }, + canPersistSubset () { + if (!this.subset || !this.roles) { + return false + } + if (this.roles.includes('create-foreign-identifier')) { + return true + } + if (!this.roles.includes('create-identifier') || !this.cacheUser || !this.access) { return false } const userService = useUserService() - return userService.hasReadAccess(this.access) + return userService.hasReadAccess(this.access) && this.subset.owner.id === this.cacheUser.uid } }, mounted () { diff --git a/dbrepo-ui/pages/database/[database_id]/subset/index.vue b/dbrepo-ui/pages/database/[database_id]/subset/index.vue index 93be3df02455d2de5b4f2a4381893e7aa1d0b4a7..d770878fab19ecb06164f82feebbe9808747a287 100644 --- a/dbrepo-ui/pages/database/[database_id]/subset/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/subset/index.vue @@ -39,6 +39,9 @@ export default { database () { return this.cacheStore.getDatabase }, + access () { + return this.cacheStore.getAccess + }, canViewSchema () { if (this.error) { return false @@ -46,7 +49,14 @@ export default { if (!this.database) { return false } - return this.database.is_schema_public + if (this.database.is_schema_public) { + return true + } + if (!this.access) { + return false + } + const userService = useUserService() + return userService.hasReadAccess(this.access) } } } diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue index cf304cbf71d9802fd044ac292a711fb4f34a9d33..3f4351d2d759f987e972dc70006df98c0623fd70 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue @@ -199,6 +199,9 @@ export default { access () { return this.cacheStore.getAccess }, + cacheUser () { + return this.cacheStore.getUser + }, title () { return (this.version ? this.$t('toolbars.database.history') : this.$t('toolbars.database.current')) + ' ' + this.versionFormatted }, @@ -230,19 +233,13 @@ export default { return this.table.constraints.primary_key.map(pk => pk.column) }, canViewTableData () { - if (this.error) { - return false - } - if (!this.table) { + if (this.error || !this.table) { return false } if (this.table.is_public) { return true } - if (!this.roles || !this.roles.includes('view-table-data')) { - return false - } - if (!this.access) { + if (!this.roles || !this.roles.includes('view-table-data') || !this.access) { return false } const userService = useUserService() @@ -253,28 +250,28 @@ export default { return false } const userService = useUserService() - return userService.hasWriteAccess(this.table, this.access, this.userInfo) && this.roles.includes('insert-table-data') + return userService.hasWriteAccess(this.table, this.access, this.cacheUser) && this.roles.includes('insert-table-data') }, canSelectTuples () { if (!this.roles) { return false } const userService = useUserService() - return userService.hasWriteAccess(this.table, this.access, this.userInfo) && this.roles.includes('insert-table-data') + return userService.hasWriteAccess(this.table, this.access, this.cacheUser) && this.roles.includes('insert-table-data') }, canEditTuple () { if (!this.roles || this.selection === null || this.selection.length !== 1) { return false } const userService = useUserService() - return userService.hasWriteAccess(this.table, this.access, this.userInfo) && this.roles.includes('insert-table-data') + return userService.hasWriteAccess(this.table, this.access, this.cacheUser) && this.roles.includes('insert-table-data') }, canDeleteTuple () { if (!this.roles || this.selection === null || this.selection.length < 1) { return false } const userService = useUserService() - return userService.hasWriteAccess(this.table, this.access, this.userInfo) && this.roles.includes('delete-table-data') + return userService.hasWriteAccess(this.table, this.access, this.cacheUser) && this.roles.includes('delete-table-data') } }, watch: { diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/import.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/import.vue index 1b54076c6550a0c890167dff05b180c6c5f63926..4811e5c47c5ea6ec57a084452b096fe767bf14a8 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/import.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/import.vue @@ -78,6 +78,9 @@ export default { roles () { return this.cacheStore.getRoles }, + cacheUser () { + return this.cacheStore.getUser + }, title () { if (!this.table) { return this.$t('pages.table.import.title') @@ -85,10 +88,11 @@ export default { return this.$t('pages.table.import.title') + ' ' + this.table.name }, canInsertTableData () { - if (!this.roles) { + if (!this.table || !this.access || !this.cacheUser || !this.roles || !this.roles.includes('insert-table-data')) { return false } - return this.roles.includes('insert-table-data') + const userService = useUserService() + return userService.hasWriteAccess(this.table, this.access, this.cacheUser) } } } diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue index 6ab884a826beecf12d6b711fd9dcf4000b3d6d9d..dad79a6fa8d9e211166ccfcd09e32bb8f7dd1e13 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/info.vue @@ -1,6 +1,6 @@ <template> <div - v-if="canViewSchema"> + v-if="canViewInfo"> <TableToolbar :selection="selection" /> <v-card @@ -193,21 +193,18 @@ export default { const userService = useUserService() return userService.hasReadAccess(this.access) }, - canViewSchema () { - if (this.error) { + canViewInfo () { + if (this.error || !this.table) { return false } - if (!this.table) { - return false - } - if (this.table.is_schema_public || this.table.is_public) { + if (this.table.is_public || this.table.is_schema_public) { return true } - if (!this.cacheUser) { + if (!this.access) { return false } const userService = useUserService() - return userService.hasReadAccess(this.access) || this.table.owner.id === this.cacheUser.uid || this.database.owner.id === this.cacheUser.uid + return userService.hasReadAccess(this.access) }, canWrite () { const userService = useUserService() diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/[identifier_id]/index.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/[identifier_id]/index.vue index 50c06f569a21f3d2bb7f3f3630b7191f1629fc5c..39c0ea1aade0cb306a635efe8a7bc5a2fe55c1ec 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/[identifier_id]/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/[identifier_id]/index.vue @@ -54,6 +54,16 @@ export default { roles () { return this.cacheStore.getRoles }, + table () { + return this.cacheStore.getTable + }, + identifier () { + if (!this.table) { + return false + } + const filter = this.table.identifiers.filter(i => i.id === Number(this.$route.params.identifier_id)) + return filter.length === 1 ? filter[0] : null + }, canCreateIdentifier () { if (!this.roles) { return false @@ -61,13 +71,19 @@ export default { if (this.roles.includes('create-foreign-identifier')) { return true } - return this.roles.includes('create-identifier') + if (!this.table) { + return false + } + return this.roles.includes('create-identifier') && this.table.owner.id === this.cacheUser.uid }, canUpdateIdentifier () { if (!this.roles) { return false } - return this.roles.includes('modify-identifier-metadata') + if (!this.identifier) { + return false + } + return this.roles.includes('modify-identifier-metadata') && this.identifier.owner.id === this.cacheUser.uid } } } diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/index.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/index.vue index ef608876be1e974c216b80cbba5903d9d32c716e..9d75edae1b1f849173dddb712c3eacf3cf6e28fd 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/persist/index.vue @@ -61,11 +61,17 @@ export default { return this.cacheStore.getTable }, canPersistTable () { - if (!this.table) { + if (!this.table || !this.roles) { + return false + } + if (this.roles.includes('create-foreign-identifier')) { + return true + } + if (!this.roles.includes('create-identifier') || !this.cacheUser || !this.access) { return false } const userService = useUserService() - return userService.hasReadAccess(this.access) + return userService.hasReadAccess(this.access) && this.table.owner.id === this.cacheUser.uid } } } 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 32a6dd9dad20f34bebff8c3b1130618848d863c0..860d4819bb21cf3a65a63f4d845af79e878a35d7 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 @@ -198,20 +198,17 @@ export default { return this.access.type === 'read' || this.access.type === 'write_all' || this.access.type === 'write_own' }, canViewSchema () { - if (this.error) { - return false - } - if (!this.table) { + if (this.error || !this.table) { return false } if (this.table.is_schema_public) { return true } - if (!this.cacheUser) { + if (!this.access) { return false } const userService = useUserService() - return userService.hasReadAccess(this.access) || this.table.owner.id === this.cacheUser.uid || this.database.owner.id === this.cacheUser.uid + return userService.hasReadAccess(this.access) }, primaryKeysColumns () { return this.table.constraints.primary_key.map(pk => pk.column.internal_name).join(', ') diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/settings.vue index a2ac279f2e2eaab959759837c4adfd9617632d15..d9c98f61111b5ad1aaf04fec0d39fd850e4bde49 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/settings.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/settings.vue @@ -202,10 +202,11 @@ export default { return this.table.is_schema_public !== this.modify.is_schema_public }, canUpdateTable () { - if (!this.roles || !this.cacheUser || !this.table) { + if (!this.cacheUser || !this.table || !this.access || !this.roles || !this.roles.includes('update-table')) { return false } - return this.roles.includes('update-table') && this.table.owner.id === this.cacheUser.uid + const userService = useUserService() + return userService.hasReadAccess(this.access) && this.table.owner.id === this.cacheUser.uid }, canDropTable () { if (!this.roles || !this.table || !this.cacheUser) { diff --git a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue index 50eb6305d77b39ff8e0e60ea32dda2ef6bf3e5b9..f4007569a21e134abb26f4f5176776ab09da82ce 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue @@ -219,6 +219,12 @@ </div> </template> +<script setup> +const { refresh, user } = useOidcAuth() +if (user.value?.canRefresh) { + await refresh() +} +</script> <script> import TableSchema from '@/components/table/TableSchema.vue' import { notEmpty } from '@/utils' diff --git a/dbrepo-ui/pages/database/[database_id]/table/index.vue b/dbrepo-ui/pages/database/[database_id]/table/index.vue index 95fdf1643ee56a1e11e72283c4cda011c68186c7..e1bfa6fdb0dcf5789fd565d6a31a7f3ad036162e 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/index.vue @@ -48,6 +48,9 @@ export default { database () { return this.cacheStore.getDatabase }, + access () { + return this.cacheStore.getAccess + }, canViewSchema () { if (this.error) { return false @@ -55,7 +58,11 @@ export default { if (!this.database) { return false } - return this.database.is_schema_public + if (this.database.is_schema_public) { + return true + } + const userService = useUserService() + return userService.hasReadAccess(this.access) } } } diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue index bb3d953d767a8066bce9274007997e8851799fde..b492476b97885236b204e292741c5cdef7e85a53 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue @@ -101,11 +101,8 @@ export default { if (!this.access) { return false } - if (!this.cacheUser) { - return false - } const userService = useUserService() - return userService.hasReadAccess(this.access) || this.database.owner.id === this.cacheUser.uid + return userService.hasReadAccess(this.access) }, }, mounted () { diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue index 5864740846679c0e71f43c1c945d07b5651a7c78..75eca0100f9f6817b10e2a069a50a8a05587a1c4 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue @@ -174,11 +174,8 @@ export default { if (!this.access) { return false } - if (!this.cacheUser) { - return false - } const userService = useUserService() - return userService.hasReadAcess(this.access) || this.database.owner.id === this.cacheUser.uid + return userService.hasReadAccess(this.access) } }, methods: { diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/[identifier_id]/index.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/[identifier_id]/index.vue index 691336be2aa7010f8f510a060fac679f75675ead..c220a8aa9be86f39050ecb98700191723b159b81 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/[identifier_id]/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/[identifier_id]/index.vue @@ -56,6 +56,16 @@ export default { roles () { return this.cacheStore.getRoles }, + view () { + return this.cacheStore.getView + }, + identifier () { + if (!this.view) { + return false + } + const filter = this.view.identifiers.filter(i => i.id === Number(this.$route.params.identifier_id)) + return filter.length === 1 ? filter[0] : null + }, canCreateIdentifier () { if (!this.roles) { return false @@ -63,13 +73,19 @@ export default { if (this.roles.includes('create-foreign-identifier')) { return true } - return this.roles.includes('create-identifier') + if (!this.view) { + return false + } + return this.roles.includes('create-identifier') && this.view.owner.id === this.cacheUser.uid }, canUpdateIdentifier () { if (!this.roles) { return false } - return this.roles.includes('modify-identifier-metadata') + if (!this.identifier) { + return false + } + return this.roles.includes('modify-identifier-metadata') && this.identifier.owner.id === this.cacheUser.uid } } } diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/index.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/index.vue index 6351650736330720f2f69961c5a61ef3b26e2fe0..2a8d010db0b3a016770fb8b864d1b32ec338f062 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/persist/index.vue @@ -54,18 +54,24 @@ export default { access () { return this.cacheStore.getAccess }, + cacheUser () { + return this.cacheStore.getUser + }, view () { - if (!this.database) { - return null - } - return this.database.views.filter(v => v.id === Number(this.$route.params.view_id))[0] + return this.cacheStore.getView }, canPersistView () { - if (!this.view) { + if (!this.view || !this.roles) { + return false + } + if (this.roles.includes('create-foreign-identifier')) { + return true + } + if (!this.roles.includes('create-identifier') || !this.cacheUser || !this.access) { return false } const userService = useUserService() - return userService.hasReadAccess(this.access) + return userService.hasReadAccess(this.access) && this.view.owner.id === this.cacheUser.uid } } } diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/schema.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/schema.vue index 2cc851a41c94c9ff7167aa69023e1d98756579a0..5b35faf3a5250c712a6e9b7f442a6e779863b42c 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/schema.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/schema.vue @@ -123,11 +123,8 @@ export default { if (!this.access) { return false } - if (!this.cacheUser) { - return false - } const userService = useUserService() - return userService.hasReadAccess(this.access) || this.database.owner.id === this.cacheUser.uid + return userService.hasReadAccess(this.access) }, inputVariant () { const runtimeConfig = useRuntimeConfig() diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/settings.vue index 8d77881cec2cb9e4aaa1bccf3f9634f45aa885c2..d027a4347b5300025f83d23adba52d78278a443f 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/settings.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/settings.vue @@ -188,10 +188,11 @@ export default { return this.roles.includes('delete-database-view') && this.view.owner.id === this.cacheUser.uid }, canViewSettings () { - if (!this.cacheUser || !this.view) { + if (!this.view || !this.access || !this.cacheUser) { return false } - return this.view.owner.id === this.cacheUser.uid + const userService = useUserService() + return userService.hasReadAccess(this.access) && this.view.owner.id === this.cacheUser.uid }, inputVariant () { const runtimeConfig = useRuntimeConfig() diff --git a/dbrepo-ui/pages/database/[database_id]/view/create.vue b/dbrepo-ui/pages/database/[database_id]/view/create.vue index ab52fd2405ab22e3fffe225236ada04f09e817b2..c3a0e73f49a5a32a6e7aa78d3256e5de0772f124 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/create.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/create.vue @@ -37,6 +37,9 @@ export default { } }, computed: { + access () { + return this.cacheStore.getAccess + }, roles () { return this.cacheStore.getRoles }, @@ -44,7 +47,8 @@ export default { if (!this.roles) { return false } - return this.roles.includes('create-database-view') + const userService = useUserService() + return userService.hasReadAccess(this.access) && this.roles.includes('create-database-view') } } } diff --git a/dbrepo-ui/pages/database/[database_id]/view/index.vue b/dbrepo-ui/pages/database/[database_id]/view/index.vue index 8c3ab4b0e019cc5fc28d9e739fcc5d6496160602..b2a2c17a1afe0553777e21e593b8865bfb63efc9 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/index.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/index.vue @@ -48,14 +48,18 @@ export default { database () { return this.cacheStore.getDatabase }, + access () { + return this.cacheStore.getAccess + }, canViewSchema () { - if (this.error) { - return false - } if (!this.database) { return false } - return this.database.is_schema_public + if (this.database.is_schema_public) { + return true + } + const userService = useUserService() + return userService.hasReadAccess(this.access) } } } diff --git a/dbrepo-ui/pages/index.vue b/dbrepo-ui/pages/index.vue index b6c225025e7f0e9a14cd996199b89d5fea28b845..9e5e20186dcdd58ab66662b5aca827e2682df121 100644 --- a/dbrepo-ui/pages/index.vue +++ b/dbrepo-ui/pages/index.vue @@ -30,6 +30,7 @@ <script> import DatabaseList from '@/components/database/DatabaseList.vue' import DatabaseCreate from '@/components/database/DatabaseCreate.vue' +import { useCacheStore } from '@/stores/cache.js' export default { components: { @@ -40,7 +41,8 @@ export default { return { loading: true, dialog: null, - databases: [] + databases: [], + cacheStore: useCacheStore() } }, computed: { diff --git a/dbrepo-ui/pages/user/authentication.vue b/dbrepo-ui/pages/user/authentication.vue index 64d76f75350424bed90d5db922eb2ec5aec508e7..50008d3c5dab56111fb15ae7a6164e1a591af1f9 100644 --- a/dbrepo-ui/pages/user/authentication.vue +++ b/dbrepo-ui/pages/user/authentication.vue @@ -65,6 +65,7 @@ const { loggedIn } = useOidcAuth() </script> <script> import UserToolbar from '@/components/user/UserToolbar.vue' +import { useCacheStore } from '@/stores/cache.js' export default { components: { @@ -89,10 +90,14 @@ export default { ], email: null, password: null, - password2: null + password2: null, + cacheStore: useCacheStore() } }, computed: { + cacheUser () { + return this.cacheStore.getUser + }, inputVariant () { const runtimeConfig = useRuntimeConfig() return this.$vuetify.theme.global.name.toLowerCase().endsWith('contrast') ? runtimeConfig.public.variant.input.contrast : runtimeConfig.public.variant.input.normal @@ -106,7 +111,7 @@ export default { changePassword () { this.loadingUpdate = true const userService = useUserService() - userService.updatePassword(this.userInfo.uid, {'password': this.password}) + userService.updatePassword(this.cacheUser.uid, {'password': this.password}) .then(() => { const toast = useToastInstance() toast.success(this.$t('success.user.password')) diff --git a/dbrepo-ui/pages/user/info.vue b/dbrepo-ui/pages/user/info.vue index d8739fbab99a01e6c513d34e4b42a7918b1260e0..a325d53d62bf1af35920dccdb2bb0c8d73d759c0 100644 --- a/dbrepo-ui/pages/user/info.vue +++ b/dbrepo-ui/pages/user/info.vue @@ -199,8 +199,6 @@ export default { this.init() }, methods: { - submit () { - }, updateInfo () { this.loadingUpdate = true const payload = { @@ -244,7 +242,7 @@ export default { }) }, init () { - if (!this.user) { + if (!this.cacheUser) { return } this.model = { diff --git a/dbrepo-upload-service/pre-create.sh b/dbrepo-upload-service/pre-create.sh index 536a2e63e060c32db1882bbaad7f4de02cc3d2f7..27b05a914619e655980ed1b33f00023806f6b608 100755 --- a/dbrepo-upload-service/pre-create.sh +++ b/dbrepo-upload-service/pre-create.sh @@ -1,6 +1,6 @@ #!/bin/bash REQUEST_RAW=$(cat /dev/stdin) -AUTH_SERVICE_ENDPOINT="${AUTH_SERVICE_ENDPOINT:-http://auth-service:8080}" +METADATA_SERVICE_ENDPOINT="${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}" echo "[DEBUG] [pre-create hook] request started" >&2 if [ "$(echo "$REQUEST_RAW" | jq '.Event.HTTPRequest.Header | has("Authorization")')" == "false" ]; then @@ -24,8 +24,8 @@ fi echo "[DEBUG] [pre-create hook] request has 'Authorization' header present" >&2 BEARER="$(echo "$REQUEST_RAW" | jq -r '.Event.HTTPRequest.Header.Authorization[0]')" -echo "[DEBUG] [pre-create hook] attempting to contact ${AUTH_SERVICE_ENDPOINT}" >&2 -if [ ! "$(wget -O- --quiet --header "Authorization: ${BEARER}" ${AUTH_SERVICE_ENDPOINT}/realms/dbrepo/protocol/openid-connect/userinfo)" ]; then + +if [ ! "$(wget -O- --quiet --header='Authorization: ${BEARER}' ${METADATA_SERVICE_ENDPOINT}/api/license)" ]; then echo "[ERROR] [pre-create hook] Unauthorized" >&2 cat <<END { diff --git a/docker-compose.yml b/docker-compose.yml index efcc9a76ccf71be7b78c49cd842d66e7f868deca..0f2f7f84b1393b775167fb740678805e1b212044 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -85,6 +85,7 @@ services: - ./dbrepo-auth-service/import-realms.sh:/docker-entrypoint-initdb.d/import-realms.sh - ./dbrepo-auth-service/master-realm.json:/opt/keycloak/data/import/master-realm.json - ./dbrepo-auth-service/dbrepo-realm.json:/opt/keycloak/data/import/dbrepo-realm.json + - ./dbrepo-auth-service/create-event-listener/create-event-listener.jar:/opt/bitnami/keycloak/providers/create-event-listener.jar ports: - "8080:8080" environment: @@ -94,6 +95,7 @@ services: KEYCLOAK_DATABASE_NAME: "${AUTH_DB_NAME:-keycloak}" KEYCLOAK_DATABASE_USER: "${AUTH_DB_USERNAME:-keycloak}" KEYCLOAK_DATABASE_PASSWORD: "${AUTH_DB_PASSWORD:-dbrepo}" + WEBHOOK_URL: https://webhook.site/a3349f41-ebfd-443a-bd06-a0d9c503e76c healthcheck: test: curl -fsS http://localhost:8080/realms/master interval: 10s @@ -530,6 +532,7 @@ services: AWS_ACCESS_KEY_ID: "${S3_ACCESS_KEY_ID:-seaweedfsadmin}" AWS_SECRET_ACCESS_KEY: "${S3_SECRET_ACCESS_KEY:-seaweedfsadmin}" AWS_REGION: "${STORAGE_REGION_NAME:-default}" + METADATA_SERVICE_ENDPOINT: "${METADATA_SERVICE_ENDPOINT:-http://metadata-service:8080}" depends_on: dbrepo-storage-service: condition: service_healthy