diff --git a/jans-keycloak-integration/pom.xml b/jans-keycloak-integration/pom.xml index 22c49f0ce6c..1502fc74538 100644 --- a/jans-keycloak-integration/pom.xml +++ b/jans-keycloak-integration/pom.xml @@ -58,7 +58,7 @@ authenticator - storage-spi + job-scheduler spi diff --git a/jans-keycloak-integration/storage-spi/.gitignore b/jans-keycloak-integration/storage-spi/.gitignore deleted file mode 100644 index c53194b720c..00000000000 --- a/jans-keycloak-integration/storage-spi/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Eclipse -.project -jans-config-api-access*.log -.classpath -.settings/ -bin/ - -# IntelliJ -.idea -*.ipr -*.iml -*.iws - -# NetBeans -nb-configuration.xml - -# Visual Studio Code -.vscode - -# OSX -.DS_Store - -# Vim -*.swp -*.swo - -# patch -*.orig -*.rej - -# Maven -target/ -pom.xml.tag -pom.xml.releaseBackup -pom.xml.versionsBackup -release.properties diff --git a/jans-keycloak-integration/storage-spi/pom.xml b/jans-keycloak-integration/storage-spi/pom.xml deleted file mode 100644 index 5add606ecf0..00000000000 --- a/jans-keycloak-integration/storage-spi/pom.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - 4.0.0 - kc-jans-storage-plugin - kc-jans-storage-plugin - jar - - - io.jans - jans-kc-parent - 1.1.3-SNAPSHOT - - - - - - - io.jans - jans-scim-model - - - - - jakarta.ws.rs - jakarta.ws.rs-api - - - jakarta.servlet - jakarta.servlet-api - - - - - org.keycloak - keycloak-core - - - org.keycloak - keycloak-server-spi - - - org.keycloak - keycloak-model-legacy - - - - - org.apache.commons - commons-collections4 - - - org.apache.commons - commons-lang3 - - - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-base - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - - - - - - io.swagger.core.v3 - swagger-core-jakarta - - - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - - org.apache.maven.plugins - maven-compiler-plugin - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - diff --git a/jans-keycloak-integration/storage-spi/src/assembly/dependencies.xml b/jans-keycloak-integration/storage-spi/src/assembly/dependencies.xml deleted file mode 100644 index 392faa3826e..00000000000 --- a/jans-keycloak-integration/storage-spi/src/assembly/dependencies.xml +++ /dev/null @@ -1,17 +0,0 @@ - - deps - - zip - - false - - - target/deps/ - . - - *.jar - - - - \ No newline at end of file diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/config/PluginConfiguration.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/config/PluginConfiguration.java deleted file mode 100644 index 77950fe6c11..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/config/PluginConfiguration.java +++ /dev/null @@ -1,84 +0,0 @@ -package io.jans.kc.spi.storage.config; - -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; -import org.keycloak.Config; - -public class PluginConfiguration { - - private static final String AUTH_TOKEN_ENDPOINT_KEY = "auth-token-endpoint"; - private static final String SCIM_USER_ENDPOINT_KEY = "scim-user-endpoint"; - private static final String SCIM_USER_SEARCH_ENDPOINT_KEY = "scim-user-search-endpoint"; - private static final String SCIM_OAUTH_SCOPES_KEY = "scim-oauth-scopes"; - private static final String SCIM_CLIENT_ID_KEY = "scim-client-id"; - private static final String SCIM_CLIENT_SECRET = "scim-client-secret"; - - private String authTokenEndpoint; - private String scimUserEndpoint; - private String scimUserSearchEndpoint; - private List scimOauthScopes; - private String scimClientId; - private String scimClientSecret; - - private PluginConfiguration() { - - } - - public static PluginConfiguration fromKeycloakConfiguration(Config.Scope config) { - - PluginConfiguration ret = new PluginConfiguration(); - ret.authTokenEndpoint = config.get(AUTH_TOKEN_ENDPOINT_KEY); - ret.scimUserEndpoint = config.get(SCIM_USER_ENDPOINT_KEY); - ret.scimUserSearchEndpoint = config.get(SCIM_USER_SEARCH_ENDPOINT_KEY); - ret.scimOauthScopes = new ArrayList<>(); - String tmpscopes = config.get(SCIM_OAUTH_SCOPES_KEY); - if(tmpscopes != null) { - ret.scimOauthScopes = Arrays.asList(tmpscopes.split(",")); - } - ret.scimClientId = config.get(SCIM_CLIENT_ID_KEY); - ret.scimClientSecret = config.get(SCIM_CLIENT_SECRET); - return ret; - } - - public String getAuthTokenEndpoint() { - - return authTokenEndpoint; - } - - public String getScimUserEndpoint() { - - return scimUserEndpoint; - } - - - public String getScimUserSearchEndpoint() { - - return scimUserSearchEndpoint; - } - - public List getScimOauthScopes() { - - return scimOauthScopes; - } - - public String getScimClientId() { - - return scimClientId; - } - - public String getScimClientSecret() { - - return scimClientSecret; - } - - public boolean isValid() { - - return authTokenEndpoint != null - && scimUserEndpoint != null - && scimUserSearchEndpoint != null - && scimOauthScopes != null - && scimClientId != null - && scimClientSecret != null; - } -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/exception/JansConfigurationException.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/exception/JansConfigurationException.java deleted file mode 100644 index e4461547a96..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/exception/JansConfigurationException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.kc.spi.storage.exception; - -public class JansConfigurationException extends RuntimeException { - - - public JansConfigurationException() { - } - - public JansConfigurationException(String message) { - super(message); - } - - public JansConfigurationException(Throwable cause) { - super(cause); - } - - public JansConfigurationException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/CredentialAuthenticatingService.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/CredentialAuthenticatingService.java deleted file mode 100644 index 14fc98309c3..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/CredentialAuthenticatingService.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.jans.kc.spi.storage.service; - -import io.jans.kc.spi.storage.util.Constants; -import io.jans.kc.spi.storage.util.JansUtil; - -import jakarta.ws.rs.core.MediaType; - -import org.apache.commons.lang.StringUtils; - -import org.jboss.logging.Logger; - -public class CredentialAuthenticatingService { - - private static Logger log = Logger.getLogger(CredentialAuthenticatingService.class); - - private JansUtil jansUtil; - - public CredentialAuthenticatingService(JansUtil jansUtil) { - this.jansUtil = jansUtil; - } - - public boolean authenticateUser(final String username, final String password) { - log.debugv("CredentialAuthenticatingService::authenticateUser() - username:{0}, password:{1} ", username, - password); - boolean isValid = false; - try { - - String token = jansUtil.requestUserToken(jansUtil.getTokenEndpoint(), username, password, null, - Constants.RESOURCE_OWNER_PASSWORD_CREDENTIALS, null, MediaType.APPLICATION_FORM_URLENCODED); - - log.debugv("CredentialAuthenticatingService::authenticateUser() - Final token token - {0}", token); - - if (StringUtils.isNotBlank(token)) { - isValid = true; - } - } catch (Exception ex) { - log.debug("CredentialAuthenticatingService::authenticateUser() - Error while authenticating", ex); - } - return isValid; - } - -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/RemoteUserStorageProvider.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/RemoteUserStorageProvider.java deleted file mode 100644 index 3a70142e225..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/RemoteUserStorageProvider.java +++ /dev/null @@ -1,179 +0,0 @@ -package io.jans.kc.spi.storage.service; - -import io.jans.kc.spi.storage.config.PluginConfiguration; -import io.jans.kc.spi.storage.util.JansUtil; -import io.jans.scim.model.scim2.user.UserResource; - -import org.keycloak.component.ComponentModel; -import org.keycloak.credential.CredentialInput; -import org.keycloak.credential.CredentialInputValidator; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.credential.PasswordCredentialModel; -import org.keycloak.storage.StorageId; -import org.keycloak.storage.UserStorageProvider; -import org.keycloak.storage.user.UserLookupProvider; - -import org.jboss.logging.Logger; - - -public class RemoteUserStorageProvider implements CredentialInputValidator, UserLookupProvider, UserStorageProvider { - - private static Logger log = Logger.getLogger(RemoteUserStorageProvider.class); - - private KeycloakSession session; - private ComponentModel model; - private UsersApiLegacyService usersService; - private CredentialAuthenticatingService credentialAuthenticatingService; - - public RemoteUserStorageProvider(KeycloakSession session, ComponentModel model, PluginConfiguration pluginConfiguration) { - log.debugv("RemoteUserStorageProvider() - session:{0}, model:{1}", session, model); - JansUtil jansUtil = new JansUtil(pluginConfiguration); - this.session = session; - this.model = model; - this.usersService = new UsersApiLegacyService(session, model,new ScimService(jansUtil)); - this.credentialAuthenticatingService = new CredentialAuthenticatingService(jansUtil); - } - - @Override - public boolean supportsCredentialType(String credentialType) { - log.debugv("RemoteUserStorageProvider::supportsCredentialType() - credentialType:{0}", credentialType); - return PasswordCredentialModel.TYPE.equals(credentialType); - } - - @Override - public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) { - log.debugv("RemoteUserStorageProvider::isConfiguredFor() - realm:{0}, user:{1}, credentialType:{2} ", realm, user, - credentialType); - return user.credentialManager().isConfiguredFor(credentialType); - } - - @Override - public boolean isValid(RealmModel realm, UserModel user, CredentialInput credentialInput) { - log.debugv( - "RemoteUserStorageProvider::isValid() - realm:{0}, user:{1}, credentialInput:{2}, user.getUsername():{2}, credentialInput.getChallengeResponse():{}", - realm, user, credentialInput, user.getUsername(), credentialInput.getChallengeResponse()); - - boolean valid = credentialAuthenticatingService.authenticateUser(user.getUsername(), - credentialInput.getChallengeResponse()); - - log.debugv("RemoteUserStorageProvider::isValid() - valid:{0}", valid); - - return valid; - - } - - /** - * Get user based on id - */ - public UserModel getUserById(RealmModel paramRealmModel, String id) { - log.debugv("RemoteUserStorageProvider::getUserById() - paramRealmModel:{0}, id:{1}", paramRealmModel, id); - - UserModel userModel = null; - try { - UserResource user = usersService.getUserById(StorageId.externalId(id)); - log.debugv("RemoteUserStorageProvider::getUserById() - user fetched based on id:{0} is user:{1}", id, user); - if (user != null) { - userModel = createUserModel(paramRealmModel, user); - log.debugv(" RemoteUserStorageProvider::getUserById() - userModel:{0}", userModel); - - if (userModel != null) { - log.debugv( - "RemoteUserStorageProvider::getUserById() - Final userModel fetched with id:{0}, userModel:{1}, userModel.getAttributes(:{2})", - id, userModel, userModel.getAttributes()); - } - } - - log.debugv( - "RemoteUserStorageProvider::getUserById() - User fetched with id:{0} from external service is:{1}", - id, user); - - } catch (Exception ex) { - log.errorv(ex, - "RemoteUserStorageProvider::getUserById() - Error fetching user id:{0} from external service", - id); - - } - - return userModel; - } - - /** - * Get user based on name - */ - public UserModel getUserByUsername(RealmModel paramRealmModel, String name) { - log.debugv("RemoteUserStorageProvider::getUserByUsername() - paramRealmModel:{0}, name:{1}", paramRealmModel, - name); - - UserModel userModel = null; - try { - UserResource user = usersService.getUserByName(name); - log.debugv( - "RemoteUserStorageProvider::getUserByUsername() - User fetched with name:{0} from external service is:{1}", - name, user); - - if (user != null) { - userModel = createUserModel(paramRealmModel, user); - log.debugv("RemoteUserStorageProvider::getUserByUsername() - userModel:{0}", userModel); - } - if (userModel != null) { - log.debugv( - "RemoteUserStorageProvider::getUserByUsername() - Final User fetched with name:{0}, userModel:{1}, userModel.getAttributes():{2}", - name, userModel, userModel.getAttributes()); - } - - } catch (Exception ex) { - log.errorv(ex, - "\n RemoteUserStorageProvider::getUserByUsername() - Error fetching user name:{0}", - name); - - } - return userModel; - } - - public UserModel getUserByEmail(RealmModel paramRealmModel, String email) { - log.debugv("RemoteUserStorageProvider::getUserByEmail() - paramRealmModel:{0}, email:{1}", paramRealmModel, - email); - - UserModel userModel = null; - try { - UserResource user = usersService.getUserByEmail(email); - log.debugv( - "RemoteUserStorageProvider::getUserByEmail() - User fetched with email:{0} from external service is:{1}", - email, user); - - if (user != null) { - userModel = createUserModel(paramRealmModel, user); - log.debugv("RemoteUserStorageProvider::getUserByEmail() - userModel:{0}", userModel); - } - - if (userModel != null) { - log.debugv( - "RemoteUserStorageProvider::getUserByEmail() - Final User fetched with email:{0}, userModel:{1}, userModel.getAttributes(:{2})", - email, userModel, userModel.getAttributes()); - } - - } catch (Exception ex) { - log.errorv(ex, - "RemoteUserStorageProvider::getUserByEmail() - Error fetching user email:{0}", - email); - - } - return userModel; - } - - public void close() { - log.debug("RemoteUserStorageProvider::close()"); - - } - - private UserModel createUserModel(RealmModel realm, UserResource user) { - log.debugv("RemoteUserStorageProvider::createUserModel() - realm:{0} , user:{1}", realm, user); - - UserModel userModel = new UserAdapter(session, realm, model, user); - log.debugv("Final RemoteUserStorageProvider::createUserModel() - userModel:{0}", userModel); - - return userModel; - } -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/RemoteUserStorageProviderFactory.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/RemoteUserStorageProviderFactory.java deleted file mode 100644 index 77a1c8fbeae..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/RemoteUserStorageProviderFactory.java +++ /dev/null @@ -1,57 +0,0 @@ -package io.jans.kc.spi.storage.service; - -import io.jans.kc.spi.storage.config.PluginConfiguration; -import io.jans.kc.spi.storage.util.Constants; - -import org.jboss.logging.Logger; - -import org.keycloak.Config; -import org.keycloak.component.ComponentModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.storage.UserStorageProviderFactory; - - - - -public class RemoteUserStorageProviderFactory implements UserStorageProviderFactory { - - private static Logger log = Logger.getLogger(RemoteUserStorageProviderFactory.class); - - public static final String PROVIDER_NAME = "jans-keycloak-storage-api"; - private PluginConfiguration pluginConfiguration; - - @Override - public RemoteUserStorageProvider create(KeycloakSession session, ComponentModel model) { - log.debugv("RemoteUserStorageProviderFactory::create() - session:{}, model:{}", session, model); - return new RemoteUserStorageProvider(session, model,pluginConfiguration); - } - - @Override - public String getId() { - - return Constants.PROVIDER_ID; - } - - @Override - public String getHelpText() { - return "Janssen User Storage Provider"; - } - - @Override - public void init(Config.Scope config) { - - this.pluginConfiguration = PluginConfiguration.fromKeycloakConfiguration(config); - } - - @Override - public void postInit(KeycloakSessionFactory factory) { - log.debug("RemoteUserStorageProviderFactory::postInit()"); - } - - @Override - public void close() { - log.debug("RemoteUserStorageProviderFactory::close() - Exit"); - } - -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/ScimService.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/ScimService.java deleted file mode 100644 index 13002f1de2f..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/ScimService.java +++ /dev/null @@ -1,187 +0,0 @@ -package io.jans.kc.spi.storage.service; - -import com.fasterxml.jackson.databind.JsonNode; - -import io.jans.kc.spi.storage.util.JansUtil; -import io.jans.scim.model.scim2.SearchRequest; -import io.jans.scim.model.scim2.user.UserResource; - -import org.apache.http.client.HttpClient; -import org.apache.http.impl.client.HttpClientBuilder; - -import org.jboss.logging.Logger; - -import org.keycloak.broker.provider.util.SimpleHttp; -import org.keycloak.util.JsonSerialization; - - -public class ScimService { - - private static Logger log = Logger.getLogger(ScimService.class); - - private JansUtil jansUtil; - - public ScimService(JansUtil jansUtil) { - this.jansUtil = jansUtil; - } - - private String getScimUserEndpoint() { - String scimUserEndpoint = jansUtil.getScimUserEndpoint(); - log.debugv("ScimService::getScimUserEndpoint() - scimUserEndpoint:{0}", scimUserEndpoint); - return scimUserEndpoint; - } - - private String getScimUserSearchEndpoint() { - String scimUserSearchEndpoint = jansUtil.getScimUserSearchEndpoint(); - log.debugv("ScimService::getScimUserSearchEndpoint() - scimUserSearchEndpoint:{0}", scimUserSearchEndpoint); - return scimUserSearchEndpoint; - } - - private String requestAccessToken() { - log.debug("ScimService::requestAccessToken()"); - String token = null; - - try { - token = jansUtil.requestScimAccessToken(); - log.debugv("ScimService::requestAccessToken() - token:{}", token); - } catch (Exception ex) { - log.errorv(ex,"ScimService::requestAccessToken() - Error while generating access token for SCIM"); - throw new RuntimeException( - "ScimService::requestAccessToken() - Error while generating access token for SCIM endpoint",ex); - } - return token; - } - - public UserResource getUserById(String inum) { - log.infov(" ScimService::getUserById() - inum:{0}", inum); - try { - return getData(getScimUserEndpoint() + "/" + inum, this.requestAccessToken()); - } catch (Exception ex) { - log.errorv(ex, - "ScimService::getUserById() - Error fetching user based on inum:{0} from external service", - inum); - } - return null; - } - - public UserResource getUserByName(String username) { - log.infov("ScimService::getUserByName() - username:{0}", username); - try { - - String filter = "userName eq \"" + username + "\""; - return postData(this.getScimUserSearchEndpoint(), this.requestAccessToken(), filter); - } catch (Exception ex) { - log.errorv(ex, - "ScimService::getUserByName() - Error fetching user based on username:{0} from external service", - username); - } - return null; - } - - public UserResource getUserByEmail(String email) { - log.debugv(" ScimService::getUserByEmail() - email:{}", email); - try { - - String filter = "emails[value eq \"" + email + "\"]"; - log.debugv(" ScimService::getUserByEmail() - filter:{}", filter); - return postData(this.getScimUserSearchEndpoint(), this.requestAccessToken(), filter); - } catch (Exception ex) { - log.errorv(ex, - " ScimService::getUserByEmail() - Error fetching user based on email:{0}", - email); - - } - return null; - } - - public UserResource postData(String uri, String accessToken, String filter) { - UserResource user = null; - log.debugv("ScimService::postData() - uri:{0}, accessToken:{1}, filter:{2}", uri, accessToken, filter); - try { - HttpClient client = HttpClientBuilder.create().build(); - - SearchRequest searchRequest = createSearchRequest(filter); - log.debugv("ScimService::postData() - client:{0}, searchRequest:{1}, accessToken:{2}", client, searchRequest.toString(), - accessToken); - - JsonNode jsonNode = SimpleHttp.doPost(uri, client).auth(accessToken).json(searchRequest).asJson(); - - log.debugv("\n\n ScimService::postData() - jsonNode:{0}", jsonNode); - - user = getUserResourceFromList(jsonNode); - - log.debugv("ScimService::postData() - user:{0}", user); - - } catch (Exception ex) { - log.errorv(ex,"ScimService::postData() - Error while fetching data"); - } - return user; - } - - public UserResource getData(String uri, String accessToken) { - UserResource user = null; - log.debugv("ScimService::getData() - uri:{0}, accessToken:{1}", uri, accessToken); - try { - HttpClient client = HttpClientBuilder.create().build(); - - JsonNode jsonNode = SimpleHttp.doGet(uri, client).auth(accessToken).asJson(); - - log.debugv("\n\n ScimService::getData() - jsonNode:{0}", jsonNode); - - user = getUserResource(jsonNode); - - log.debugv("ScimService::getData() - user:{}", user); - - } catch (Exception ex) { - log.errorv(ex,"\n\n ScimService::getData() - Error while fetching data"); - } - return user; - } - - private SearchRequest createSearchRequest(String filter) { - log.debugv("ScimService::createSearchRequest() - createSearchRequest() - filter:{0}", filter); - SearchRequest searchRequest = new SearchRequest(); - searchRequest.setFilter(filter); - - log.debugv(" ScimService::createSearchRequest() - searchRequest:{0}", searchRequest); - - return searchRequest; - } - - private UserResource getUserResourceFromList(JsonNode jsonNode) { - log.debugv(" \n\n ScimService::getUserResourceFromList() - jsonNode:{0}", jsonNode); - - UserResource user = null; - try { - if (jsonNode != null) { - if (jsonNode.get("Resources") != null) { - JsonNode value = jsonNode.get("Resources").get(0); - log.debugv("*** ScimService::getUserResourceFromList() - value:{0}, value.getClass():{1}", value, - value.getClass()); - user = JsonSerialization.readValue(JsonSerialization.writeValueAsBytes(value), UserResource.class); - log.debugv(" ScimService::getUserResourceFromList() - user:{0}, user.getClass():{1}", user, - user.getClass()); - } - } - } catch (Exception ex) { - log.errorv(ex,"\n\n ScimService::getUserResourceFromList() - Error while fetching data"); - } - return user; - } - - private UserResource getUserResource(JsonNode jsonNode) { - log.debugv("ScimService::getUserResource() - jsonNode:{0}", jsonNode); - - UserResource user = null; - try { - if (jsonNode != null) { - user = JsonSerialization.readValue(JsonSerialization.writeValueAsBytes(jsonNode), UserResource.class); - log.debugv(" ScimService::getUserResource() - user:{0}, user.getClass():{1}", user, user.getClass()); - } - } catch (Exception ex) { - log.errorv(ex,"\n\n ScimService::getUserResource() - Error while fetching data is ex:{}"); - } - return user; - } - -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/UserAdapter.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/UserAdapter.java deleted file mode 100644 index 8e52331fb93..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/UserAdapter.java +++ /dev/null @@ -1,141 +0,0 @@ -package io.jans.kc.spi.storage.service; - -import io.jans.kc.spi.storage.util.JansDataUtil; -import io.jans.scim.model.scim2.user.UserResource; -import io.jans.scim.model.scim2.util.DateUtil; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Stream; - -import org.apache.commons.lang3.StringUtils; -import org.keycloak.common.util.MultivaluedHashMap; -import org.keycloak.component.ComponentModel; -import org.keycloak.credential.LegacyUserCredentialManager; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.SubjectCredentialManager; -import org.keycloak.models.UserModel; -import org.keycloak.storage.StorageId; -import org.keycloak.storage.adapter.AbstractUserAdapter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class UserAdapter extends AbstractUserAdapter { - private static Logger logger = LoggerFactory.getLogger(UserAdapter.class); - private final UserResource user; - - public UserAdapter(KeycloakSession session, RealmModel realm, ComponentModel model, UserResource user) { - - super(session, realm, model); - logger.debug( - " UserAdapter() - model:{}, user:{}, storageProviderModel:{}, storageProviderModel.getId():{}, user.getId():{}", - model, user, storageProviderModel, storageProviderModel.getId(), user.getId()); - this.storageId = new StorageId(storageProviderModel.getId(), user.getId()); - this.user = user; - - logger.debug("UserAdapter() - All User Resource field():{}", printUserResourceField()); - } - - @Override - public String getUsername() { - return user.getUserName(); - } - - @Override - public String getFirstName() { - return user.getDisplayName(); - } - - @Override - public String getLastName() { - return user.getNickName(); - } - - @Override - public String getEmail() { - return ((user.getEmails() != null && user.getEmails().get(0) != null) ? user.getEmails().get(0).getValue() - : null); - } - - @Override - public SubjectCredentialManager credentialManager() { - return new LegacyUserCredentialManager(session, realm, this); - } - - public Map getCustomAttributes() { - printUserCustomAttributes(); - return user.getCustomAttributes(); - } - - @Override - public boolean isEnabled() { - boolean enabled = false; - if (user != null) { - enabled = user.getActive(); - } - return enabled; - } - - @Override - public Long getCreatedTimestamp() { - Long createdDate = null; - if (user.getMeta().getCreated() != null) { - String created = user.getMeta().getCreated(); - if (created != null && StringUtils.isNotBlank(created)) { - createdDate = DateUtil.ISOToMillis(created); - } - } - return createdDate; - } - - @Override - public Map> getAttributes() { - MultivaluedHashMap attributes = new MultivaluedHashMap<>(); - attributes.add(UserModel.USERNAME, getUsername()); - attributes.add(UserModel.EMAIL, getEmail()); - attributes.add(UserModel.FIRST_NAME, getFirstName()); - attributes.add(UserModel.LAST_NAME, getLastName()); - return attributes; - } - - @Override - public Stream getAttributeStream(String name) { - if (name.equals(UserModel.USERNAME)) { - return Stream.of(getUsername()); - } - return Stream.empty(); - } - - @Override - protected Set getRoleMappingsInternal() { - return Set.of(); - } - - private void printUserCustomAttributes() { - logger.info(" UserAdapter::printUserCustomAttributes() - user:{}", user); - if (user == null || user.getCustomAttributes() == null || user.getCustomAttributes().isEmpty()) { - return; - } - - user.getCustomAttributes().keySet().stream() - .forEach(key -> logger.info("key:{} , value:{}", key, user.getCustomAttributes().get(key))); - - } - - private Map printUserResourceField() { - logger.info(" UserAdapter::printUserResourceField() - user:{}", user); - Map propertyTypeMap = null; - if (user == null) { - return propertyTypeMap; - } - - propertyTypeMap = JansDataUtil.getFieldTypeMap(user.getClass()); - logger.info("UserAdapter::printUserResourceField() - all fields of user:{}", propertyTypeMap); - return propertyTypeMap; - } - -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/UsersApiLegacyService.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/UsersApiLegacyService.java deleted file mode 100644 index 4bb8d75b2a6..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/service/UsersApiLegacyService.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.jans.kc.spi.storage.service; - -import io.jans.scim.model.scim2.user.UserResource; - -import java.util.Properties; - -import org.jboss.logging.Logger; - -import org.keycloak.component.ComponentModel; -import org.keycloak.models.KeycloakSession; - -public class UsersApiLegacyService { - - private static Logger log = Logger.getLogger(UsersApiLegacyService.class); - - private ScimService scimService; - protected Properties jansProperties = new Properties(); - - public UsersApiLegacyService(KeycloakSession session, ComponentModel model, ScimService scimService) { - - log.debugv(" UsersApiLegacyService() - session:{0}, model:{1}", session, model); - this.scimService = scimService; - } - - public UserResource getUserById(String inum) { - log.debugv("UsersApiLegacyService::getUserById() - inum:{0}", inum); - try { - return scimService.getUserById(inum); - } catch (Exception ex) { - log.errorv(ex, - "UsersApiLegacyService::getUserById() - Error fetching user based on inum:{0} from external service", - inum); - - } - return null; - } - - public UserResource getUserByName(String username) { - log.debugv(" UsersApiLegacyService::getUserByName() - username:{0}", username); - try { - - return scimService.getUserByName(username); - } catch (Exception ex) { - log.errorv(ex, - "UsersApiLegacyService::getUserByName() - Error fetching user based on username:{0} from external service", - username); - - } - return null; - } - - public UserResource getUserByEmail(String email) { - log.infov(" UsersApiLegacyService::getUserByEmail() - email:{0}", email); - try { - - return scimService.getUserByEmail(email); - } catch (Exception ex) { - log.errorv( - " UsersApiLegacyService::getUserByEmail() - Error fetching user based on email:{0}", - email); - - } - return null; - } - -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/Constants.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/Constants.java deleted file mode 100644 index 4740e3c734f..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/Constants.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.kc.spi.storage.util; - -public class Constants { - - private Constants() {} - - public static final String PROVIDER_ID = "kc-jans-storage"; - public static final String JANS_CONFIG_PROP_PATH = "jans.config.prop.path"; - public static final String KEYCLOAK_USER = "/keycloak-user"; - public static final String BASE_URL = "https://localhost"; - - public static final String SCOPE_TYPE_OPENID = "openid"; - public static final String UTF8_STRING_ENCODING = "UTF-8"; - public static final String CLIENT_SECRET_BASIC = "client_secret_basic"; - public static final String CLIENT_CREDENTIALS = "client_credentials"; - public static final String RESOURCE_OWNER_PASSWORD_CREDENTIALS = "password"; - - //properties - public static final String KEYCLOAK_SERVER_URL = "keycloak.server.url"; - public static final String AUTH_TOKEN_ENDPOINT = "auth.token.endpoint"; - public static final String SCIM_USER_ENDPOINT = "scim.user.endpoint"; - public static final String SCIM_USER_SEARCH_ENDPOINT = "scim.user.search.endpoint"; - public static final String SCIM_OAUTH_SCOPE = "scim.oauth.scope"; - public static final String KEYCLOAK_SCIM_CLIENT_ID = "keycloak.scim.client.id"; - public static final String KEYCLOAK_SCIM_CLIENT_PASSWORD = "keycloak.scim.client.password"; - - -} \ No newline at end of file diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/JansDataUtil.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/JansDataUtil.java deleted file mode 100644 index 179dd9bebdd..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/JansDataUtil.java +++ /dev/null @@ -1,107 +0,0 @@ -package io.jans.kc.spi.storage.util; - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.jboss.logging.Logger; - -public class JansDataUtil { - - private static final Logger log = Logger.getLogger(JansDataUtil.class); - - public static Object invokeMethod(Class clazz, String methodName, Class... parameterTypes) - throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - log.debugv("JansDataUtil::invokeMethod() - Invoke clazz:{0} on methodName:{1} with name:{2} ", clazz, methodName, - parameterTypes); - Object obj = null; - if (clazz == null || methodName == null || parameterTypes == null) { - return obj; - } - Method m = clazz.getDeclaredMethod(methodName, parameterTypes); - obj = m.invoke(null, parameterTypes); - - log.debugv("JansDataUtil::invokeMethod() - methodName:{0} returned obj:{1} ", methodName, obj); - return obj; - } - - public Object invokeReflectionGetter(Object obj, String variableName) { - log.debugv("JansDataUtil::invokeMethod() - Invoke obj:{0}, variableName:{1}", obj, variableName); - try { - if (obj == null) { - return obj; - } - PropertyDescriptor pd = new PropertyDescriptor(variableName, obj.getClass()); - Method getter = pd.getReadMethod(); - log.debugv("JansDataUtil::invokeMethod() - Invoke getter:{0}", getter); - if (getter != null) { - return getter.invoke(obj); - } else { - log.errorv( - "JansDataUtil::invokeReflectionGetter() - Getter Method not found for class:{0} property:{1}", - obj.getClass().getName(), variableName); - } - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException - | IntrospectionException e) { - log.errorv(e,"JansDataUtil::invokeReflectionGetter() - Getter Method ERROR for class: {0} property: {1}", - obj.getClass().getName(), variableName); - } - return obj; - } - - public static List getAllFields(Class type) { - log.debugv("JansDataUtil::getAllFields() - type:{0} ", type); - List allFields = new ArrayList<>(); - if (type == null) { - return allFields; - } - getAllFields(allFields, type); - log.debugv("JansDataUtil::getAllFields() - Fields:{0} of type:{1} ", allFields, type); - return allFields; - } - - public static List getAllFields(List fields, Class type) { - log.debugv("JansDataUtil::getAllFields() - fields:{0} , type:{1} ", fields, type); - if (fields == null || type == null) { - return fields; - } - fields.addAll(Arrays.asList(type.getDeclaredFields())); - - if (type.getSuperclass() != null) { - getAllFields(fields, type.getSuperclass()); - } - log.debugv("JansDataUtil::getAllFields() - Final fields:{0} of type:{1} ", fields, type); - return fields; - } - - public static Map getFieldTypeMap(Class clazz) { - log.debugv("JansDataUtil::getFieldTypeMap() - clazz:{0} ", clazz); - Map propertyTypeMap = new HashMap<>(); - - if (clazz == null) { - return propertyTypeMap; - } - - List fields = getAllFields(clazz); - log.debugv("JansDataUtil::getFieldTypeMap() - all-fields:{0} ", fields); - - for (Field field : fields) { - log.debugv( - "JansDataUtil::getFieldTypeMap() - field:{0} , field.getAnnotatedType():{1}, field.getAnnotations():{2} , field.getType().getAnnotations():{3}, field.getType().getCanonicalName():{4} , field.getType().getClass():{5} , field.getType().getClasses():{6} , field.getType().getComponentType():{7}", - field, field.getAnnotatedType(), field.getAnnotations(), field.getType().getAnnotations(), - field.getType().getCanonicalName(), field.getType().getClass(), field.getType().getClasses(), - field.getType().getComponentType()); - propertyTypeMap.put(field.getName(), field.getType().getSimpleName()); - } - log.debugv("JansDataUtil::getFieldTypeMap() - Final propertyTypeMap{0} ", propertyTypeMap); - return propertyTypeMap; - } - -} diff --git a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/JansUtil.java b/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/JansUtil.java deleted file mode 100644 index ff33cf8f614..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/java/io/jans/kc/spi/storage/util/JansUtil.java +++ /dev/null @@ -1,266 +0,0 @@ -package io.jans.kc.spi.storage.util; - -import com.fasterxml.jackson.databind.JsonNode; - -import io.jans.kc.spi.storage.config.PluginConfiguration; - -import jakarta.ws.rs.core.MediaType; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.stream.*; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.client.HttpClient; -import org.apache.http.impl.client.HttpClientBuilder; - -import org.jboss.logging.Logger; - -import org.keycloak.broker.provider.util.SimpleHttp; - -public class JansUtil { - - private static Logger log = Logger.getLogger(JansUtil.class); - private PluginConfiguration pluginConfiguration; - - public JansUtil(PluginConfiguration pluginConfiguration) { - - this.pluginConfiguration = pluginConfiguration; - if (this.pluginConfiguration == null || !this.pluginConfiguration.isValid()) { - throw new RuntimeException("Plugin configuration missing or invalid"); - } - } - - public String getTokenEndpoint() { - log.debugv("JansUtil::getTokenEndpoint() - {0}", - pluginConfiguration.getAuthTokenEndpoint()); - - return pluginConfiguration.getAuthTokenEndpoint(); - } - - public String getScimUserEndpoint() { - log.debugv("JansUtil::getScimUserEndpoint() - {0}", - pluginConfiguration.getScimUserEndpoint()); - - return pluginConfiguration.getScimUserEndpoint(); - } - - public String getScimUserSearchEndpoint() { - log.debugv( - "JansUtil::getScimUserSearchEndpoint() - {0}", - pluginConfiguration.getScimUserSearchEndpoint()); - return pluginConfiguration.getScimUserSearchEndpoint(); - } - - public String getScimClientId() { - log.debugv("JansUtil::getScimClientId() - {0}", - pluginConfiguration.getScimClientId()); - return pluginConfiguration.getScimClientId(); - } - - public String getScimClientSecret() { - log.debugv("JansUtil::getClientPassword() - {0}", - pluginConfiguration.getScimClientSecret()); - return pluginConfiguration.getScimClientSecret(); - } - - public List getScimOauthScopes() { - log.debugv("JansUtil::getScimOauthScope() - {0}", - pluginConfiguration.getScimOauthScopes()); - return pluginConfiguration.getScimOauthScopes(); - } - - public String requestScimAccessToken() throws IOException { - log.debug("JansUtil::requestScimAccessToken() "); - List scopes = getScimOauthScopes(); - String token = requestAccessToken(getScimClientId(), scopes); - log.debugv("JansUtil::requestScimAccessToken() - token:{0} ", token); - return token; - } - - public String requestAccessToken(final String clientId, final List scope) throws IOException { - log.debugv("JansUtil::requestAccessToken() - Request for AccessToken - clientId:{0}, scope:{1} ", clientId, - scope); - - String tokenUrl = getTokenEndpoint(); - String token = getAccessToken(tokenUrl, clientId, scope); - log.debugv("JansUtil::requestAccessToken() - oAuth AccessToken response - token:{0}", token); - - return token; - } - - public String getAccessToken(final String tokenUrl, final String clientId, final List scopes) - throws IOException { - log.debugv("JansUtil::getAccessToken() - Access Token Request - tokenUrl:{0}, clientId:{1}, scopes:{2}", tokenUrl, - clientId, scopes); - - // Get clientSecret - String clientSecret = getScimClientSecret(); - log.debugv("JansUtil::getAccessToken() - Access Token Request - clientId:{0}, clientSecret:{1}", clientId, - clientSecret); - - // distinct scopes - Set scopesSet = new HashSet<>(scopes); - StringBuilder scope = new StringBuilder(Constants.SCOPE_TYPE_OPENID); - for (String s : scopesSet) { - scope.append(" ").append(s); - } - - log.debugv("JansUtil::getAccessToken() - Scope required - {0}", scope); - - String token = requestAccessToken(tokenUrl, clientId, clientSecret, scope.toString(), - Constants.CLIENT_CREDENTIALS, Constants.CLIENT_SECRET_BASIC, MediaType.APPLICATION_FORM_URLENCODED); - log.debugv("JansUtil::getAccessToken() - Final token token - {0}", token); - return token; - } - - public String requestAccessToken(final String tokenUrl, final String clientId, final String clientSecret, - final String scope, String grantType, String authenticationMethod, String mediaType) throws IOException { - log.debugv( - "JansUtil::requestAccessToken() - Request for Access Token - tokenUrl:{0}, clientId:{1}, clientSecret:{2}, scope:{3}, grantType:{4}, authenticationMethod:{5}, mediaType:{6}", - tokenUrl, clientId, clientSecret, scope, grantType, authenticationMethod, mediaType); - String token = null; - try { - - log.debugv("JansUtil::requestAccessToken() - this.getEncodedCredentials():{0}", - this.getEncodedCredentials(clientId, clientSecret)); - HttpClient client = HttpClientBuilder.create().build(); - JsonNode jsonNode = SimpleHttp.doPost(tokenUrl, client) - .header("Authorization", "Basic " + this.getEncodedCredentials(clientId, clientSecret)) - .header("Content-Type", mediaType).param("grant_type", "client_credentials") - .param("username", clientId + ":" + clientSecret).param("scope", scope).param("client_id", clientId) - .param("client_secret", clientSecret).param("authorization_method", "client_secret_basic").asJson(); - log.debugv("JansUtil::requestAccessToken() - POST Request for Access Token - jsonNode:{0} ", jsonNode); - - token = this.getToken(jsonNode); - - log.debugv("\n JansUtil::requestAccessToken() - After Post request for Access Token - token:{0} ", token); - - } catch (Exception ex) { - log.error("JansUtil::requestAccessToken() - Post error is ",ex); - } - return token; - } - - public String requestUserToken(final String tokenUrl, final String username, final String password, - final String scope, String grantType, String authenticationMethod, String mediaType) throws IOException { - log.debugv( - "JansUtil::requestUserToken() - Request for Access Token - tokenUrl:{0}, username:{1}, password:{2}, scope:{3}, grantType:{4}, authenticationMethod:{5}, mediaType:{6}", - tokenUrl, username, password, scope, grantType, authenticationMethod, mediaType); - String token = null; - try { - String clientId = this.getScimClientId(); - String clientSecret = this.getScimClientSecret(); - - log.debugv( - " JansUtil::requestUserToken() - clientId:{0} , clientSecret:{1}, this.getEncodedCredentials():{2}", - clientId, clientSecret, this.getEncodedCredentials(clientId, clientSecret)); - HttpClient client = HttpClientBuilder.create().build(); - JsonNode jsonNode = SimpleHttp.doPost(tokenUrl, client) - .header("Authorization", "Basic " + this.getEncodedCredentials(clientId, clientSecret)) - .header("Content-Type", mediaType).param("grant_type", grantType).param("username", username) - .param("password", password).asJson(); - - log.debugv("JansUtil::requestUserToken() - After invoking post request for user token - jsonNode:{0}", - jsonNode); - - token = this.getToken(jsonNode); - - log.debugv("\n JansUtil::requestUserToken() -POST Request for Access Token - token:{0} ", token); - - } catch (Exception ex) { - log.errorv("\n JansUtil::requestUserToken() - Error getting user token", ex); - } - return token; - } - - private boolean validateTokenScope(JsonNode jsonNode, String scope) { - - log.debugv("JansUtil::validateTokenScope() - jsonNode:{0}, scope:{1}", jsonNode, scope); - boolean validScope = false; - try { - - List scopeList = Stream.of(scope.split(" ", -1)).collect(Collectors.toList()); - - if (jsonNode != null && jsonNode.get("scope") != null) { - JsonNode value = jsonNode.get("scope"); - log.debugv("JansUtil::validateTokenScope() - value:{0}", value); - - if (value != null) { - String responseScope = value.toString(); - log.debugv( - "JansUtil::validateTokenScope() - scope:{0}, responseScope:{1}, responseScope.contains(scope):{2}", - scope, responseScope, responseScope.contains(scope)); - if (scopeList.contains(responseScope)) { - validScope = true; - } - } - - } - log.debugv("JansUtil::validateTokenScope() - validScope:{0}", validScope); - - } catch (Exception ex) { - log.error("JansUtil::validateTokenScope() - Error while validating token scope from response is ", - ex); - } - return validScope; - - } - - private String getToken(JsonNode jsonNode) { - log.debugv("JansUtil::getToken() - jsonNode:{0}", jsonNode); - - String token = null; - try { - - if (jsonNode != null && jsonNode.get("access_token") != null) { - JsonNode value = jsonNode.get("access_token"); - log.debugv("JansUtil::getToken() - value:{0}", value); - - if (value != null) { - token = value.asText(); - } - log.debugv("getToken() - token:{0}", token); - } - } catch (Exception ex) { - log.errorv("Error while getting token from response", ex); - } - return token; - } - - private boolean hasCredentials(String authUsername, String authPassword) { - return (StringUtils.isNotBlank(authUsername) && StringUtils.isNotBlank(authPassword)); - } - - /** - * Returns the client credentials (URL encoded). - * - * @return The client credentials. - */ - private String getCredentials(String authUsername, String authPassword) throws UnsupportedEncodingException { - log.debugv("getCredentials() - authUsername:{0}, authPassword:{1}", authUsername, authPassword); - return URLEncoder.encode(authUsername, Constants.UTF8_STRING_ENCODING) + ":" - + URLEncoder.encode(authPassword, Constants.UTF8_STRING_ENCODING); - } - - private String getEncodedCredentials(String authUsername, String authPassword) { - log.debugv("getEncodedCredentials() - authUsername:{0}, authPassword:{1}", authUsername, authPassword); - try { - if (hasCredentials(authUsername, authPassword)) { - return Base64.encodeBase64String(getBytes(getCredentials(authUsername, authPassword))); - } - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - - return null; - } - - private static byte[] getBytes(String str) { - return str.getBytes(StandardCharsets.UTF_8); - } - -} diff --git a/jans-keycloak-integration/storage-spi/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory b/jans-keycloak-integration/storage-spi/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory deleted file mode 100644 index 2691b848dd3..00000000000 --- a/jans-keycloak-integration/storage-spi/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory +++ /dev/null @@ -1 +0,0 @@ -io.jans.kc.spi.storage.service.RemoteUserStorageProviderFactory \ No newline at end of file