diff --git a/README.md b/README.md index 53b5764..40bbc99 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # Keycloak GraphDB User Replicator [![Build docker](https://github.com/datagov-cz/keycloak-graphdb-user-replicator/actions/workflows/build-docker.yml/badge.svg)](https://github.com/datagov-cz/keycloak-graphdb-user-replicator/actions/workflows/build-docker.yml) -Ensures user data are replicated into a GraphDB instance for the purpose of data provenance display. Another feature is -creating GraphDB users corresponding to Keycloak users so that applications authenticated via Keycloak can access -protected GraphDB repositories. +Replicates basic user data from Keycloak into a GraphDB repository for the purpose of data provenance display. +Another (optional) feature is creating GraphDB users corresponding to Keycloak users so that applications authenticated +via Keycloak can access protected GraphDB repositories. ## Compatibility -This service provider is compatible with Keycloak 18 and later. Previous versions were powered by JBoss and had a different +This service provider is compatible with Keycloak 18 and later. Previous Keycloak versions were powered by JBoss and had a different directory structure as well as means of deploying service providers. Since version 18, Keycloak is powered by Quarkus. This service provider is also compatible with GraphDB 10 and later. Previous GraphDB versions used RDF4J 3, GraphDB 10 uses @@ -22,12 +22,12 @@ from Keycloak and handles selected user-related ones. More specifically, the fol * User profile or email update 1. When a user account is created, corresponding user metadata are generated into the configured GraphDB repository. These metadata -consist of user classification and first and last name property values. In addition, a new user is created in the GraphDB user database -so that Keycloak authenticated users can access protected GraphDB repositories. The GraphDB users are without password, so they can be used +consist of user classification and first and last name property values. In addition, a new user account can be created in the GraphDB user database +so that Keycloak authenticated users can access protected GraphDB repositories. Such user accounts are without password, so they can be used only via Keycloak. 2. When a user account is updated, corresponding user metadata are updated in the configured GraphDB repository. If the user's email -has changed, a new matching user account is created in the GraphDB user database as well. +has changed, a new matching user account is created in the GraphDB user database as well (if this feature is eanbled). Note that due to the nature of the Keycloak events received by the SPI, it is not possible to update or remove GraphDB users. The original user email is not available in the event, so the corresponding GraphDB user cannot be found and disposed of. However, since @@ -58,14 +58,12 @@ The following configuration parameters can (and in some cases must) be provided | `REPOSITORY_PASSWORD` | no | - | Password to authenticate with when replicating user metadata into the triple store repository and into the GraphDB user database. | | `DB_SERVER_CONTEXT` | no | - | Identifier of named graph into which user account metadata will be saved. | | `NAMESPACE` | no | `http://onto.fel.cvut.cz/ontologies/uzivatel/` | Namespace for generating user identifiers. | +| `ADD_ACCOUNTS` | no | `true` | Allows disabling replication of user accounts to GraphDB's user database for deployments where such a functionality is not required. | -Note that the GraphDB user (identifier by `repositoryUsername` and `repositoryPassword`) has to be an admin, -so that it can add new users into the user database. +Note that the GraphDB user (identifier by `REPOSITORY_USERNAME` and `REPOSITORY_PASSWORD`) has to be an admin, +so that it can add new users into the user database (if this feature is enabled). ## License Licensed under LGPL v3.0. - -Tento repozitář je udržován v rámci projektu OPZ č. CZ.03.4.74/0.0/0.0/15_025/0013983. -![Evropská unie - Evropský sociální fond - Operační program Zaměstnanost](https://data.gov.cz/images/ozp_logo_cz.jpg) diff --git a/src/main/java/cz/cvut/kbss/keycloak/provider/Configuration.java b/src/main/java/cz/cvut/kbss/keycloak/provider/Configuration.java index f1e8140..3f5a601 100644 --- a/src/main/java/cz/cvut/kbss/keycloak/provider/Configuration.java +++ b/src/main/java/cz/cvut/kbss/keycloak/provider/Configuration.java @@ -19,6 +19,8 @@ public class Configuration { private final String graphDBServerUrl; + private final boolean addAccounts; + Configuration(Config.Scope scope) { final String components = getProperty("COMPONENTS"); if (isNullOrEmpty(getProperty("DB_SERVER_URL")) @@ -44,23 +46,29 @@ public class Configuration { } this.repositoryUsername = getProperty("REPOSITORY_USERNAME"); this.repositoryPassword = getProperty("REPOSITORY_PASSWORD"); + this.addAccounts = getBooleanProperty("ADD_ACCOUNTS", true); KodiUserAccount.setNamespace(getProperty("NAMESPACE")); KodiUserAccount.setContext(getProperty("DB_SERVER_CONTEXT")); } - private boolean isNullOrEmpty(final String nullOrEmpty) { + private static boolean isNullOrEmpty(final String nullOrEmpty) { return Objects.isNull(nullOrEmpty) || nullOrEmpty.isEmpty(); } - private String getProperty(String key) { + private static String getProperty(String key) { return System.getenv(key); } - private Map parseComponents(String components) { + private static Map parseComponents(String components) { final String componentsDecoded = new String(Base64.getDecoder().decode(components)); return new Yaml().load(componentsDecoded); } + private static boolean getBooleanProperty(String key, boolean defaultValue) { + final String value = getProperty(key); + return isNullOrEmpty(value) ? defaultValue : Boolean.parseBoolean(value); + } + public String getRealmId() { return realmId; } @@ -80,4 +88,8 @@ public String getRepositoryPassword() { public String getGraphDBServerUrl() { return graphDBServerUrl; } + + public boolean shouldAddAccounts() { + return addAccounts; + } } diff --git a/src/main/java/cz/cvut/kbss/keycloak/provider/DataReplicationProvider.java b/src/main/java/cz/cvut/kbss/keycloak/provider/DataReplicationProvider.java index bd7207c..b8d520e 100644 --- a/src/main/java/cz/cvut/kbss/keycloak/provider/DataReplicationProvider.java +++ b/src/main/java/cz/cvut/kbss/keycloak/provider/DataReplicationProvider.java @@ -69,8 +69,10 @@ private void newUser(KodiUserAccount userAccount) { } private void addGraphDBUser(KodiUserAccount userAccount) { - LOG.info("Adding user account to GraphDB use database."); - graphDBUserDao.addUser(userAccount); + if (keycloakAdapter.shouldAddAccounts()) { + LOG.info("Adding user account to GraphDB user database."); + graphDBUserDao.addUser(userAccount); + } } private void updateUser(KodiUserAccount userAccount) { diff --git a/src/main/java/cz/cvut/kbss/keycloak/provider/KeycloakAdapter.java b/src/main/java/cz/cvut/kbss/keycloak/provider/KeycloakAdapter.java index 635bfc8..a016992 100644 --- a/src/main/java/cz/cvut/kbss/keycloak/provider/KeycloakAdapter.java +++ b/src/main/java/cz/cvut/kbss/keycloak/provider/KeycloakAdapter.java @@ -28,4 +28,8 @@ public KodiUserAccount getUser(String userId, String realmId) { final UserModel userModel = userProvider.getUserById(realmProvider.getRealm(realmId), userId); return userModel != null ? new KodiUserAccount(userModel) : null; } + + public boolean shouldAddAccounts() { + return configuration.shouldAddAccounts(); + } }