org.keycloak.storage.UserStorageManager Maven / Gradle / Ivy
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.storage;
import org.jboss.logging.Logger;
import org.keycloak.common.util.reflections.Types;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.CredentialValidationOutput;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.storage.user.UserCredentialAuthenticationProvider;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.storage.user.UserCredentialValidatorProvider;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.storage.user.UserLookupProvider;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.storage.user.UserQueryProvider;
import org.keycloak.storage.user.UserRegistrationProvider;
import org.keycloak.models.utils.CredentialValidation;
import org.keycloak.storage.federated.UserFederatedStorageProvider;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Bill Burke
* @version $Revision: 1 $
*/
public class UserStorageManager implements UserProvider {
private static final Logger logger = Logger.getLogger(UserStorageManager.class);
protected KeycloakSession session;
public UserStorageManager(KeycloakSession session) {
this.session = session;
}
protected UserProvider localStorage() {
return session.userLocalStorage();
}
protected List getStorageProviders(RealmModel realm) {
return realm.getUserStorageProviders();
}
protected T getFirstStorageProvider(RealmModel realm, Class type) {
for (UserStorageProviderModel model : getStorageProviders(realm)) {
UserStorageProviderFactory factory = (UserStorageProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, model.getProviderId());
if (Types.supports(type, factory, UserStorageProviderFactory.class)) {
return type.cast(getStorageProviderInstance(model, factory));
}
}
return null;
}
private UserStorageProvider getStorageProviderInstance(UserStorageProviderModel model, UserStorageProviderFactory factory) {
UserStorageProvider instance = (UserStorageProvider)session.getAttribute(model.getId());
if (instance != null) return instance;
instance = factory.create(session, model);
session.enlistForClose(instance);
session.setAttribute(model.getId(), instance);
return instance;
}
protected List getStorageProviders(RealmModel realm, Class type) {
List list = new LinkedList<>();
for (UserStorageProviderModel model : getStorageProviders(realm)) {
UserStorageProviderFactory factory = (UserStorageProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, model.getProviderId());
if (Types.supports(type, factory, UserStorageProviderFactory.class)) {
list.add(type.cast(getStorageProviderInstance(model, factory)));
}
}
return list;
}
@Override
public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) {
return localStorage().addUser(realm, id, username.toLowerCase(), addDefaultRoles, addDefaultRequiredActions);
}
@Override
public UserModel addUser(RealmModel realm, String username) {
UserRegistrationProvider registry = getFirstStorageProvider(realm, UserRegistrationProvider.class);
if (registry != null) {
return registry.addUser(realm, username);
}
return localStorage().addUser(realm, username.toLowerCase());
}
public UserStorageProvider getStorageProvider(RealmModel realm, String componentId) {
ComponentModel model = realm.getComponent(componentId);
if (model == null) return null;
UserStorageProviderFactory factory = (UserStorageProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, model.getProviderId());
if (factory == null) {
throw new ModelException("Could not find UserStorageProviderFactory for: " + model.getProviderId());
}
return getStorageProviderInstance(new UserStorageProviderModel(model), factory);
}
@Override
public boolean removeUser(RealmModel realm, UserModel user) {
getFederatedStorage().preRemove(realm, user);
StorageId storageId = new StorageId(user.getId());
if (storageId.getProviderId() == null) {
return localStorage().removeUser(realm, user);
}
UserRegistrationProvider registry = (UserRegistrationProvider)getStorageProvider(realm, storageId.getProviderId());
if (registry == null) {
throw new ModelException("Could not resolve StorageProvider: " + storageId.getProviderId());
}
return registry.removeUser(realm, user);
}
public UserFederatedStorageProvider getFederatedStorage() {
return session.userFederatedStorage();
}
@Override
public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink) {
if (StorageId.isLocalStorage(user)) {
localStorage().addFederatedIdentity(realm, user, socialLink);
} else {
getFederatedStorage().addFederatedIdentity(realm, user, socialLink);
}
}
public void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel) {
if (StorageId.isLocalStorage(federatedUser)) {
localStorage().updateFederatedIdentity(realm, federatedUser, federatedIdentityModel);
} else {
getFederatedStorage().updateFederatedIdentity(realm, federatedUser, federatedIdentityModel);
}
}
@Override
public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
if (StorageId.isLocalStorage(user)) {
return localStorage().removeFederatedIdentity(realm, user, socialProvider);
} else {
return getFederatedStorage().removeFederatedIdentity(realm, user, socialProvider);
}
}
@Override
public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
if (StorageId.isLocalStorage(user)) {
localStorage().addConsent(realm, user, consent);
} else {
getFederatedStorage().addConsent(realm, user, consent);
}
}
@Override
public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientInternalId) {
if (StorageId.isLocalStorage(user)) {
return localStorage().getConsentByClient(realm, user, clientInternalId);
} else {
return getFederatedStorage().getConsentByClient(realm, user, clientInternalId);
}
}
@Override
public List getConsents(RealmModel realm, UserModel user) {
if (StorageId.isLocalStorage(user)) {
return localStorage().getConsents(realm, user);
} else {
return getFederatedStorage().getConsents(realm, user);
}
}
@Override
public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
if (StorageId.isLocalStorage(user)) {
localStorage().updateConsent(realm, user, consent);
} else {
getFederatedStorage().updateConsent(realm, user, consent);
}
}
@Override
public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId) {
if (StorageId.isLocalStorage(user)) {
return localStorage().revokeConsentForClient(realm, user, clientInternalId);
} else {
return getFederatedStorage().revokeConsentForClient(realm, user, clientInternalId);
}
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
StorageId storageId = new StorageId(id);
if (storageId.getProviderId() == null) {
return localStorage().getUserById(id, realm);
}
UserLookupProvider provider = (UserLookupProvider)getStorageProvider(realm, storageId.getProviderId());
return provider.getUserById(id, realm);
}
@Override
public List getGroupMembers(RealmModel realm, GroupModel group) {
return getGroupMembers(realm, group, -1, -1);
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
UserModel user = localStorage().getUserByUsername(username, realm);
if (user != null) return user;
for (UserLookupProvider provider : getStorageProviders(realm, UserLookupProvider.class)) {
user = provider.getUserByUsername(username, realm);
if (user != null) return user;
}
return null;
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
UserModel user = localStorage().getUserByEmail(email, realm);
if (user != null) return user;
for (UserLookupProvider provider : getStorageProviders(realm, UserLookupProvider.class)) {
user = provider.getUserByEmail(email, realm);
if (user != null) return user;
}
return null;
}
@Override
public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
UserModel user = localStorage().getUserByFederatedIdentity(socialLink, realm);
if (user != null) {
return user;
}
String id = getFederatedStorage().getUserByFederatedIdentity(socialLink, realm);
if (id != null) return getUserById(id, realm);
return null;
}
@Override
public UserModel getServiceAccount(ClientModel client) {
return localStorage().getServiceAccount(client);
}
@Override
public List getUsers(RealmModel realm, boolean includeServiceAccounts) {
return getUsers(realm, 0, Integer.MAX_VALUE - 1, includeServiceAccounts);
}
@Override
public List getUsers(RealmModel realm) {
return getUsers(realm, false);
}
@Override
public List getUsers(RealmModel realm, int firstResult, int maxResults) {
return getUsers(realm, firstResult, maxResults, false);
}
@Override
public int getUsersCount(RealmModel realm) {
int size = localStorage().getUsersCount(realm);
for (UserQueryProvider provider : getStorageProviders(realm, UserQueryProvider.class)) {
size += provider.getUsersCount(realm);
}
return size;
}
@FunctionalInterface
interface PaginatedQuery {
List query(Object provider, int first, int max);
}
protected List query(PaginatedQuery pagedQuery, RealmModel realm, int firstResult, int maxResults) {
if (maxResults == 0) return Collections.EMPTY_LIST;
List storageProviders = getStorageProviders(realm, UserQueryProvider.class);
// we can skip rest of method if there are no storage providers
if (storageProviders.isEmpty()) {
return pagedQuery.query(localStorage(), firstResult, maxResults);
}
LinkedList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy