mongo fed
This commit is contained in:
parent
8967ca4066
commit
110f6ad549
14 changed files with 779 additions and 741 deletions
|
@ -1,218 +0,0 @@
|
|||
/*
|
||||
* 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.jpa;
|
||||
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.credential.UserCredentialStore;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserCredentialAttributeEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class JpaFederatedUserCredentialStore implements UserCredentialStore {
|
||||
|
||||
private final KeycloakSession session;
|
||||
protected final EntityManager em;
|
||||
|
||||
public JpaFederatedUserCredentialStore(KeycloakSession session, EntityManager em) {
|
||||
this.session = session;
|
||||
this.em = em;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) {
|
||||
FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, cred.getId());
|
||||
if (entity == null) return;
|
||||
entity.setAlgorithm(cred.getAlgorithm());
|
||||
entity.setCounter(cred.getCounter());
|
||||
entity.setCreatedDate(cred.getCreatedDate());
|
||||
entity.setDevice(cred.getDevice());
|
||||
entity.setDigits(cred.getDigits());
|
||||
entity.setHashIterations(cred.getHashIterations());
|
||||
entity.setPeriod(cred.getPeriod());
|
||||
entity.setSalt(cred.getSalt());
|
||||
entity.setType(cred.getType());
|
||||
entity.setValue(cred.getValue());
|
||||
if (entity.getCredentialAttributes().isEmpty() && (cred.getConfig() == null || cred.getConfig().isEmpty())) {
|
||||
|
||||
} else {
|
||||
MultivaluedHashMap<String, String> attrs = cred.getConfig();
|
||||
MultivaluedHashMap<String, String> config = cred.getConfig();
|
||||
if (config == null) config = new MultivaluedHashMap<>();
|
||||
|
||||
Iterator<FederatedUserCredentialAttributeEntity> it = entity.getCredentialAttributes().iterator();
|
||||
while (it.hasNext()) {
|
||||
FederatedUserCredentialAttributeEntity attr = it.next();
|
||||
List<String> values = config.getList(attr.getName());
|
||||
if (values == null || !values.contains(attr.getValue())) {
|
||||
em.remove(attr);
|
||||
it.remove();
|
||||
} else {
|
||||
attrs.add(attr.getName(), attr.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
for (String key : config.keySet()) {
|
||||
List<String> values = config.getList(key);
|
||||
List<String> attrValues = attrs.getList(key);
|
||||
for (String val : values) {
|
||||
if (attrValues == null || !attrValues.contains(val)) {
|
||||
FederatedUserCredentialAttributeEntity attr = new FederatedUserCredentialAttributeEntity();
|
||||
attr.setId(KeycloakModelUtils.generateId());
|
||||
attr.setValue(val);
|
||||
attr.setName(key);
|
||||
attr.setCredential(entity);
|
||||
em.persist(attr);
|
||||
entity.getCredentialAttributes().add(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) {
|
||||
FederatedUserCredentialEntity entity = new FederatedUserCredentialEntity();
|
||||
String id = cred.getId() == null ? KeycloakModelUtils.generateId() : cred.getId();
|
||||
entity.setId(id);
|
||||
entity.setAlgorithm(cred.getAlgorithm());
|
||||
entity.setCounter(cred.getCounter());
|
||||
entity.setCreatedDate(cred.getCreatedDate());
|
||||
entity.setDevice(cred.getDevice());
|
||||
entity.setDigits(cred.getDigits());
|
||||
entity.setHashIterations(cred.getHashIterations());
|
||||
entity.setPeriod(cred.getPeriod());
|
||||
entity.setSalt(cred.getSalt());
|
||||
entity.setType(cred.getType());
|
||||
entity.setValue(cred.getValue());
|
||||
entity.setUserId(user.getId());
|
||||
entity.setRealmId(realm.getId());
|
||||
entity.setStorageProviderId(StorageId.resolveProviderId(user));
|
||||
em.persist(entity);
|
||||
MultivaluedHashMap<String, String> config = cred.getConfig();
|
||||
if (config != null || !config.isEmpty()) {
|
||||
|
||||
for (String key : config.keySet()) {
|
||||
List<String> values = config.getList(key);
|
||||
for (String val : values) {
|
||||
FederatedUserCredentialAttributeEntity attr = new FederatedUserCredentialAttributeEntity();
|
||||
attr.setId(KeycloakModelUtils.generateId());
|
||||
attr.setValue(val);
|
||||
attr.setName(key);
|
||||
attr.setCredential(entity);
|
||||
em.persist(attr);
|
||||
entity.getCredentialAttributes().add(attr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return toModel(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) {
|
||||
FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, id);
|
||||
if (entity == null) return false;
|
||||
em.remove(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) {
|
||||
FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, id);
|
||||
if (entity == null) return null;
|
||||
CredentialModel model = toModel(entity);
|
||||
return model;
|
||||
}
|
||||
|
||||
protected CredentialModel toModel(FederatedUserCredentialEntity entity) {
|
||||
CredentialModel model = new CredentialModel();
|
||||
model.setId(entity.getId());
|
||||
model.setType(entity.getType());
|
||||
model.setValue(entity.getValue());
|
||||
model.setAlgorithm(entity.getAlgorithm());
|
||||
model.setSalt(entity.getSalt());
|
||||
model.setPeriod(entity.getPeriod());
|
||||
model.setCounter(entity.getCounter());
|
||||
model.setCreatedDate(entity.getCreatedDate());
|
||||
model.setDevice(entity.getDevice());
|
||||
model.setDigits(entity.getDigits());
|
||||
MultivaluedHashMap<String, String> config = new MultivaluedHashMap<>();
|
||||
model.setConfig(config);
|
||||
for (FederatedUserCredentialAttributeEntity attr : entity.getCredentialAttributes()) {
|
||||
config.add(attr.getName(), attr.getValue());
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CredentialModel> getStoredCredentials(RealmModel realm, UserModel user) {
|
||||
TypedQuery<FederatedUserCredentialEntity> query = em.createNamedQuery("federatedUserCredentialByUser", FederatedUserCredentialEntity.class)
|
||||
.setParameter("userId", user.getId());
|
||||
List<FederatedUserCredentialEntity> results = query.getResultList();
|
||||
List<CredentialModel> rtn = new LinkedList<>();
|
||||
for (FederatedUserCredentialEntity entity : results) {
|
||||
rtn.add(toModel(entity));
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) {
|
||||
TypedQuery<FederatedUserCredentialEntity> query = em.createNamedQuery("federatedUserCredentialByUserAndType", FederatedUserCredentialEntity.class)
|
||||
.setParameter("type", type)
|
||||
.setParameter("userId", user.getId());
|
||||
List<FederatedUserCredentialEntity> results = query.getResultList();
|
||||
List<CredentialModel> rtn = new LinkedList<>();
|
||||
for (FederatedUserCredentialEntity entity : results) {
|
||||
rtn.add(toModel(entity));
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) {
|
||||
TypedQuery<FederatedUserCredentialEntity> query = em.createNamedQuery("federatedUserCredentialByNameAndType", FederatedUserCredentialEntity.class)
|
||||
.setParameter("type", type)
|
||||
.setParameter("device", name)
|
||||
.setParameter("userId", user.getId());
|
||||
List<FederatedUserCredentialEntity> results = query.getResultList();
|
||||
if (results.isEmpty()) return null;
|
||||
return toModel(results.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
|
@ -30,18 +30,14 @@ import org.keycloak.models.ProtocolMapperModel;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserCredentialValueModel;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.FederatedCredentials;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.federated.UserAttributeFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserBrokerLinkFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserConsentFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserCredentialsFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||
import org.keycloak.storage.federated.UserGroupMembershipFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserRequiredActionsFederatedStorage;
|
||||
|
@ -77,7 +73,6 @@ public class JpaUserFederatedStorageProvider implements
|
|||
UserAttributeFederatedStorage,
|
||||
UserBrokerLinkFederatedStorage,
|
||||
UserConsentFederatedStorage,
|
||||
UserCredentialsFederatedStorage,
|
||||
UserGroupMembershipFederatedStorage,
|
||||
UserRequiredActionsFederatedStorage,
|
||||
UserRoleMappingsFederatedStorage,
|
||||
|
@ -427,76 +422,6 @@ public class JpaUserFederatedStorageProvider implements
|
|||
|
||||
|
||||
|
||||
@Override
|
||||
public List<UserCredentialValueModel> getCredentials(RealmModel realm, UserModel user) {
|
||||
TypedQuery<FederatedUserCredentialEntity> query = em.createNamedQuery("federatedUserCredentialByUser", FederatedUserCredentialEntity.class)
|
||||
.setParameter("userId", user.getId());
|
||||
List<FederatedUserCredentialEntity> results = query.getResultList();
|
||||
List<UserCredentialValueModel> list = new LinkedList<>();
|
||||
for (FederatedUserCredentialEntity credEntity : results) {
|
||||
UserCredentialValueModel credModel = new UserCredentialValueModel();
|
||||
credModel.setId(credEntity.getId());
|
||||
credModel.setType(credEntity.getType());
|
||||
credModel.setDevice(credEntity.getDevice());
|
||||
credModel.setValue(credEntity.getValue());
|
||||
credModel.setCreatedDate(credEntity.getCreatedDate());
|
||||
credModel.setSalt(credEntity.getSalt());
|
||||
credModel.setHashIterations(credEntity.getHashIterations());
|
||||
credModel.setCounter(credEntity.getCounter());
|
||||
credModel.setAlgorithm(credEntity.getAlgorithm());
|
||||
credModel.setDigits(credEntity.getDigits());
|
||||
credModel.setPeriod(credEntity.getPeriod());
|
||||
|
||||
list.add(credModel);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCredential(RealmModel realm, UserModel user, UserCredentialModel cred) {
|
||||
createIndex(realm, user);
|
||||
FederatedCredentials.updateCredential(session, this, realm, user, cred);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCredential(RealmModel realm, UserModel user, UserCredentialValueModel cred) {
|
||||
createIndex(realm, user);
|
||||
FederatedUserCredentialEntity entity = null;
|
||||
if (cred.getId() != null) entity = em.find(FederatedUserCredentialEntity.class, cred.getId());
|
||||
boolean newEntity = false;
|
||||
if (entity == null) {
|
||||
entity = new FederatedUserCredentialEntity();
|
||||
entity.setId(KeycloakModelUtils.generateId());
|
||||
newEntity = true;
|
||||
}
|
||||
entity.setUserId(user.getId());
|
||||
entity.setRealmId(realm.getId());
|
||||
entity.setStorageProviderId(StorageId.resolveProviderId(user));
|
||||
entity.setAlgorithm(cred.getAlgorithm());
|
||||
entity.setCounter(cred.getCounter());
|
||||
Long createdDate = cred.getCreatedDate();
|
||||
if (createdDate == null) createdDate = System.currentTimeMillis();
|
||||
entity.setCreatedDate(createdDate);
|
||||
entity.setDevice(cred.getDevice());
|
||||
entity.setDigits(cred.getDigits());
|
||||
entity.setHashIterations(cred.getHashIterations());
|
||||
entity.setPeriod(cred.getPeriod());
|
||||
entity.setSalt(cred.getSalt());
|
||||
entity.setType(cred.getType());
|
||||
entity.setValue(cred.getValue());
|
||||
if (newEntity) {
|
||||
em.persist(entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCredential(RealmModel realm, UserModel user, UserCredentialValueModel cred) {
|
||||
FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, cred.getId());
|
||||
em.remove(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<GroupModel> getGroups(RealmModel realm, UserModel user) {
|
||||
Set<GroupModel> set = new HashSet<>();
|
||||
|
@ -638,36 +563,6 @@ public class JpaUserFederatedStorageProvider implements
|
|||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeCredential(RealmModel realm, String id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CredentialModel getCredentialById(String id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CredentialModel> getCredentials(RealmModel realm) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CredentialModel> getUserCredentials(RealmModel realm, UserModel user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CredentialModel> getCredentialsByType(RealmModel realm, UserModel user, String type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CredentialModel getCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) {
|
||||
FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, cred.getId());
|
||||
|
@ -686,7 +581,7 @@ public class JpaUserFederatedStorageProvider implements
|
|||
if (entity.getCredentialAttributes().isEmpty() && (cred.getConfig() == null || cred.getConfig().isEmpty())) {
|
||||
|
||||
} else {
|
||||
MultivaluedHashMap<String, String> attrs = cred.getConfig();
|
||||
MultivaluedHashMap<String, String> attrs = new MultivaluedHashMap<>();
|
||||
MultivaluedHashMap<String, String> config = cred.getConfig();
|
||||
if (config == null) config = new MultivaluedHashMap<>();
|
||||
|
||||
|
|
|
@ -65,22 +65,23 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
|||
"org.keycloak.models.mongo.keycloak.entities.MongoMigrationModelEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoOnlineUserSessionEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoOfflineUserSessionEntity",
|
||||
"org.keycloak.models.entities.IdentityProviderEntity",
|
||||
"org.keycloak.models.entities.ClientIdentityProviderMappingEntity",
|
||||
"org.keycloak.models.entities.RequiredCredentialEntity",
|
||||
"org.keycloak.models.entities.CredentialEntity",
|
||||
"org.keycloak.models.entities.FederatedIdentityEntity",
|
||||
"org.keycloak.models.entities.UserFederationProviderEntity",
|
||||
"org.keycloak.models.entities.UserFederationMapperEntity",
|
||||
"org.keycloak.models.entities.ProtocolMapperEntity",
|
||||
"org.keycloak.models.entities.IdentityProviderMapperEntity",
|
||||
"org.keycloak.models.entities.AuthenticationExecutionEntity",
|
||||
"org.keycloak.models.entities.AuthenticationFlowEntity",
|
||||
"org.keycloak.models.entities.AuthenticatorConfigEntity",
|
||||
"org.keycloak.models.entities.RequiredActionProviderEntity",
|
||||
"org.keycloak.models.entities.PersistentUserSessionEntity",
|
||||
"org.keycloak.models.entities.PersistentClientSessionEntity",
|
||||
"org.keycloak.models.entities.ComponentEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.IdentityProviderEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.ClientIdentityProviderMappingEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.CredentialEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.FederatedIdentityEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.UserFederationProviderEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.UserFederationMapperEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.ProtocolMapperEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.IdentityProviderMapperEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.AuthenticationExecutionEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.AuthenticationFlowEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.AuthenticatorConfigEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.RequiredActionProviderEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.PersistentUserSessionEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.PersistentClientSessionEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.ComponentEntity",
|
||||
"org.keycloak.storage.mongo.entity.FederatedUser",
|
||||
"org.keycloak.authorization.mongo.entities.PolicyEntity",
|
||||
"org.keycloak.authorization.mongo.entities.ResourceEntity",
|
||||
"org.keycloak.authorization.mongo.entities.ResourceServerEntity",
|
||||
|
|
|
@ -0,0 +1,571 @@
|
|||
/*
|
||||
* 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.mongo;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.QueryBuilder;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.connections.mongo.api.MongoStore;
|
||||
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.credential.UserCredentialStore;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.mongo.keycloak.entities.CredentialEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.FederatedIdentityEntity;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.federated.UserAttributeFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserBrokerLinkFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserConsentFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||
import org.keycloak.storage.federated.UserGroupMembershipFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserRequiredActionsFederatedStorage;
|
||||
import org.keycloak.storage.federated.UserRoleMappingsFederatedStorage;
|
||||
import org.keycloak.storage.mongo.entity.FederatedUser;
|
||||
|
||||
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.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class MongoUserFederatedStorageProvider implements
|
||||
UserFederatedStorageProvider,
|
||||
UserAttributeFederatedStorage,
|
||||
UserBrokerLinkFederatedStorage,
|
||||
UserConsentFederatedStorage,
|
||||
UserGroupMembershipFederatedStorage,
|
||||
UserRequiredActionsFederatedStorage,
|
||||
UserRoleMappingsFederatedStorage,
|
||||
UserCredentialStore {
|
||||
|
||||
private final MongoStoreInvocationContext invocationContext;
|
||||
private final KeycloakSession session;
|
||||
|
||||
public MongoUserFederatedStorageProvider(KeycloakSession session, MongoStoreInvocationContext invocationContext) {
|
||||
this.session = session;
|
||||
this.invocationContext = invocationContext;
|
||||
}
|
||||
|
||||
protected MongoStore getMongoStore() {
|
||||
return invocationContext.getMongoStore();
|
||||
}
|
||||
|
||||
|
||||
protected FederatedUser addUserEntity(RealmModel realm, String id) {
|
||||
FederatedUser userEntity = new FederatedUser();
|
||||
userEntity.setId(id);
|
||||
userEntity.setStorageId(StorageId.providerId(id));
|
||||
userEntity.setRealmId(realm.getId());
|
||||
|
||||
getMongoStore().insertEntity(userEntity, invocationContext);
|
||||
return userEntity;
|
||||
}
|
||||
|
||||
protected FederatedUser getUserById(String id) {
|
||||
return getMongoStore().loadEntity(FederatedUser.class, id, invocationContext);
|
||||
}
|
||||
|
||||
protected FederatedUser findOrCreate(RealmModel realm, String id) {
|
||||
FederatedUser user = getUserById(id);
|
||||
if (user != null) return user;
|
||||
return addUserEntity(realm, id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null) return false;
|
||||
CredentialEntity ce = getCredentialEntity(id, userEntity);
|
||||
if (ce != null) return getMongoStore().pullItemFromList(userEntity, "credentials", ce, invocationContext);
|
||||
return false;
|
||||
}
|
||||
|
||||
private CredentialEntity getCredentialEntity(String id, FederatedUser userEntity) {
|
||||
CredentialEntity ce = null;
|
||||
if (userEntity.getCredentials() != null) {
|
||||
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
|
||||
if (credentialEntity.getId().equals(id)) {
|
||||
ce = credentialEntity;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return ce;
|
||||
}
|
||||
|
||||
protected CredentialModel toModel(CredentialEntity entity) {
|
||||
CredentialModel model = new CredentialModel();
|
||||
model.setId(entity.getId());
|
||||
model.setHashIterations(entity.getHashIterations());
|
||||
model.setType(entity.getType());
|
||||
model.setValue(entity.getValue());
|
||||
model.setAlgorithm(entity.getAlgorithm());
|
||||
model.setSalt(entity.getSalt());
|
||||
model.setPeriod(entity.getPeriod());
|
||||
model.setCounter(entity.getCounter());
|
||||
model.setCreatedDate(entity.getCreatedDate());
|
||||
model.setDevice(entity.getDevice());
|
||||
model.setDigits(entity.getDigits());
|
||||
MultivaluedHashMap<String, String> config = new MultivaluedHashMap<>();
|
||||
model.setConfig(config);
|
||||
if (entity.getConfig() != null) {
|
||||
config.putAll(entity.getConfig());
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) {
|
||||
FederatedUser userEntity = getUserById(id);
|
||||
if (userEntity != null && userEntity.getCredentials() != null) {
|
||||
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
|
||||
if (credentialEntity.getId().equals(id)) {
|
||||
return toModel(credentialEntity);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CredentialModel> getStoredCredentials(RealmModel realm, UserModel user) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity != null && userEntity.getCredentials() != null) {
|
||||
List<CredentialModel> list = new LinkedList<>();
|
||||
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
|
||||
list.add(toModel(credentialEntity));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity != null && userEntity.getCredentials() != null) {
|
||||
List<CredentialModel> list = new LinkedList<>();
|
||||
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
|
||||
if (type.equals(credentialEntity.getType())) list.add(toModel(credentialEntity));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity != null && userEntity.getCredentials() != null) {
|
||||
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
|
||||
if (credentialEntity.getDevice().equals(name) && type.equals(credentialEntity.getType())) {
|
||||
return toModel(credentialEntity);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getStoredUsers(RealmModel realm, int first, int max) {
|
||||
QueryBuilder queryBuilder = new QueryBuilder()
|
||||
.and("realmId").is(realm.getId());
|
||||
|
||||
DBObject query = queryBuilder.get();
|
||||
List<FederatedUser> users = getMongoStore().loadEntities(FederatedUser.class, query, null, first, max, invocationContext);
|
||||
List<String> ids = new LinkedList<>();
|
||||
for (FederatedUser user : users) ids.add(user.getId());
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm, UserFederationProviderModel link) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm, GroupModel group) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm, RoleModel role) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm, ClientModel client) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(ProtocolMapperModel protocolMapper) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm, UserModel user) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm, ComponentModel model) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSingleAttribute(RealmModel realm, UserModel user, String name, String value) {
|
||||
FederatedUser userEntity = findOrCreate(realm, user.getId());
|
||||
if (userEntity.getAttributes() == null) {
|
||||
userEntity.setAttributes(new HashMap<>());
|
||||
}
|
||||
|
||||
List<String> attrValues = new LinkedList<>();
|
||||
attrValues.add(value);
|
||||
userEntity.getAttributes().put(name, attrValues);
|
||||
getMongoStore().updateEntity(userEntity, invocationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(RealmModel realm, UserModel user, String name, List<String> values) {
|
||||
FederatedUser userEntity = findOrCreate(realm, user.getId());
|
||||
if (userEntity.getAttributes() == null) {
|
||||
userEntity.setAttributes(new HashMap<>());
|
||||
}
|
||||
|
||||
userEntity.getAttributes().put(name, values);
|
||||
getMongoStore().updateEntity(userEntity, invocationContext);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(RealmModel realm, UserModel user, String name) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null || userEntity.getAttributes() == null) return;
|
||||
|
||||
userEntity.getAttributes().remove(name);
|
||||
getMongoStore().updateEntity(userEntity, invocationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultivaluedHashMap<String, String> getAttributes(RealmModel realm, UserModel user) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null || userEntity.getAttributes() == null) return new MultivaluedHashMap<>();
|
||||
MultivaluedHashMap<String, String> result = new MultivaluedHashMap<>();
|
||||
result.putAll(userEntity.getAttributes());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUsersByUserAttribute(RealmModel realm, String name, String value) {
|
||||
QueryBuilder queryBuilder = new QueryBuilder()
|
||||
.and("realmId").is(realm.getId());
|
||||
queryBuilder.and("attributes." + name).is(value);
|
||||
|
||||
List<FederatedUser> users = getMongoStore().loadEntities(FederatedUser.class, queryBuilder.get(), invocationContext);
|
||||
List<String> ids = new LinkedList<>();
|
||||
for (FederatedUser user : users) ids.add(user.getId());
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("federatedIdentities.identityProvider").is(socialLink.getIdentityProvider())
|
||||
.and("federatedIdentities.userId").is(socialLink.getUserId())
|
||||
.and("realmId").is(realm.getId())
|
||||
.get();
|
||||
FederatedUser userEntity = getMongoStore().loadSingleEntity(FederatedUser.class, query, invocationContext);
|
||||
return userEntity != null ? userEntity.getId() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink) {
|
||||
FederatedUser userEntity = findOrCreate(realm, user.getId());
|
||||
FederatedIdentityEntity federatedIdentityEntity = new FederatedIdentityEntity();
|
||||
federatedIdentityEntity.setIdentityProvider(socialLink.getIdentityProvider());
|
||||
federatedIdentityEntity.setUserId(socialLink.getUserId());
|
||||
federatedIdentityEntity.setUserName(socialLink.getUserName().toLowerCase());
|
||||
federatedIdentityEntity.setToken(socialLink.getToken());
|
||||
|
||||
getMongoStore().pushItemToList(userEntity, "federatedIdentities", federatedIdentityEntity, true, invocationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null) return false;
|
||||
|
||||
FederatedIdentityEntity federatedIdentityEntity = findFederatedIdentityLink(userEntity, socialProvider);
|
||||
if (federatedIdentityEntity == null) {
|
||||
return false;
|
||||
}
|
||||
return getMongoStore().pullItemFromList(userEntity, "federatedIdentities", federatedIdentityEntity, invocationContext); }
|
||||
|
||||
private FederatedIdentityEntity findFederatedIdentityLink(FederatedUser userEntity, String identityProvider) {
|
||||
List<FederatedIdentityEntity> linkEntities = userEntity.getFederatedIdentities();
|
||||
if (linkEntities == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (FederatedIdentityEntity federatedIdentityEntity : linkEntities) {
|
||||
if (federatedIdentityEntity.getIdentityProvider().equals(identityProvider)) {
|
||||
return federatedIdentityEntity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel) {
|
||||
FederatedUser userEntity = getUserById(federatedUser.getId());
|
||||
if (userEntity == null) return;
|
||||
FederatedIdentityEntity federatedIdentityEntity = findFederatedIdentityLink(userEntity, federatedIdentityModel.getIdentityProvider());
|
||||
if (federatedIdentityEntity == null) return;
|
||||
//pushItemToList updates the whole federatedIdentities array in Mongo so we just need to remove this object from the Java
|
||||
//List and pushItemToList will handle the DB update.
|
||||
userEntity.getFederatedIdentities().remove(federatedIdentityEntity);
|
||||
federatedIdentityEntity.setToken(federatedIdentityModel.getToken());
|
||||
getMongoStore().pushItemToList(userEntity, "federatedIdentities", federatedIdentityEntity, true, invocationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null) return Collections.EMPTY_SET;
|
||||
List<FederatedIdentityEntity> linkEntities = userEntity.getFederatedIdentities();
|
||||
|
||||
if (linkEntities == null) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
Set<FederatedIdentityModel> result = new HashSet<FederatedIdentityModel>();
|
||||
for (FederatedIdentityEntity federatedIdentityEntity : linkEntities) {
|
||||
FederatedIdentityModel model = new FederatedIdentityModel(federatedIdentityEntity.getIdentityProvider(),
|
||||
federatedIdentityEntity.getUserId(), federatedIdentityEntity.getUserName(), federatedIdentityEntity.getToken());
|
||||
result.add(model);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null) return null;
|
||||
FederatedIdentityEntity federatedIdentityEntity = findFederatedIdentityLink(userEntity, socialProvider);
|
||||
|
||||
return federatedIdentityEntity != null ? new FederatedIdentityModel(federatedIdentityEntity.getIdentityProvider(), federatedIdentityEntity.getUserId(),
|
||||
federatedIdentityEntity.getUserName(), federatedIdentityEntity.getToken()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
|
||||
session.userLocalStorage().addConsent(realm, user, consent);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientInternalId) {
|
||||
return session.userLocalStorage().getConsentByClient(realm, user, clientInternalId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserConsentModel> getConsents(RealmModel realm, UserModel user) {
|
||||
return session.userLocalStorage().getConsents(realm, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
|
||||
session.userLocalStorage().updateConsent(realm, user, consent);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId) {
|
||||
return session.userLocalStorage().revokeConsentForClient(realm, user, clientInternalId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null) return;
|
||||
CredentialEntity entity = getCredentialEntity(cred.getId(), userEntity);
|
||||
if (entity == null) return;
|
||||
toEntity(cred, entity);
|
||||
userEntity.getCredentials().remove(entity);
|
||||
|
||||
getMongoStore().pushItemToList(userEntity, "credentials", entity, true, invocationContext);
|
||||
}
|
||||
|
||||
private void toEntity(CredentialModel cred, CredentialEntity entity) {
|
||||
entity.setAlgorithm(cred.getAlgorithm());
|
||||
entity.setCounter(cred.getCounter());
|
||||
entity.setCreatedDate(cred.getCreatedDate());
|
||||
entity.setDevice(cred.getDevice());
|
||||
entity.setDigits(cred.getDigits());
|
||||
entity.setHashIterations(cred.getHashIterations());
|
||||
entity.setPeriod(cred.getPeriod());
|
||||
entity.setSalt(cred.getSalt());
|
||||
entity.setType(cred.getType());
|
||||
entity.setValue(cred.getValue());
|
||||
|
||||
if (cred.getConfig() == null) entity.setConfig(null);
|
||||
else {
|
||||
MultivaluedHashMap<String, String> newConfig = new MultivaluedHashMap<>();
|
||||
newConfig.putAll(cred.getConfig());
|
||||
entity.setConfig(newConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) {
|
||||
FederatedUser userEntity = findOrCreate(realm, user.getId());
|
||||
CredentialEntity entity = new CredentialEntity();
|
||||
entity.setId(KeycloakModelUtils.generateId());
|
||||
toEntity(cred, entity);
|
||||
getMongoStore().pushItemToList(userEntity, "credentials", entity, true, invocationContext);
|
||||
cred.setId(entity.getId());
|
||||
return cred;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<GroupModel> getGroups(RealmModel realm, UserModel user) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null || userEntity.getGroupIds() == null || userEntity.getGroupIds().isEmpty()) return Collections.EMPTY_SET;
|
||||
Set<GroupModel> groups = new HashSet<>();
|
||||
for (String groupId : userEntity.getGroupIds()) {
|
||||
GroupModel group = session.realms().getGroupById(groupId, realm);
|
||||
if (group != null) groups.add(group);
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joinGroup(RealmModel realm, UserModel user, GroupModel group) {
|
||||
FederatedUser userEntity = findOrCreate(realm, user.getId());
|
||||
getMongoStore().pushItemToList(userEntity, "groupIds", group.getId(), true, invocationContext);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leaveGroup(RealmModel realm, UserModel user, GroupModel group) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null || group == null) return;
|
||||
getMongoStore().pullItemFromList(userEntity, "groupIds", group.getId(), invocationContext);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max) {
|
||||
QueryBuilder queryBuilder = new QueryBuilder()
|
||||
.and("realmId").is(realm.getId());
|
||||
queryBuilder.and("groupIds").is(group.getId());
|
||||
|
||||
List<FederatedUser> users = getMongoStore().loadEntities(FederatedUser.class, queryBuilder.get(), null, firstResult, max, invocationContext);
|
||||
List<String> ids = new LinkedList<>();
|
||||
for (FederatedUser user : users) ids.add(user.getId());
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRequiredActions(RealmModel realm, UserModel user) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null || userEntity.getRequiredActions() == null || userEntity.getRequiredActions().isEmpty()) return Collections.EMPTY_SET;
|
||||
Set<String> set = new HashSet<>();
|
||||
set.addAll(userEntity.getRequiredActions());
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredAction(RealmModel realm, UserModel user, String action) {
|
||||
FederatedUser userEntity = findOrCreate(realm, user.getId());
|
||||
getMongoStore().pushItemToList(userEntity, "requiredActions", action, true, invocationContext);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRequiredAction(RealmModel realm, UserModel user, String action) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null || userEntity.getRequiredActions() == null || userEntity.getRequiredActions().isEmpty()) return;
|
||||
getMongoStore().pullItemFromList(userEntity, "requiredActions", action, invocationContext);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantRole(RealmModel realm, UserModel user, RoleModel role) {
|
||||
FederatedUser userEntity = findOrCreate(realm, user.getId());
|
||||
getMongoStore().pushItemToList(userEntity, "roleIds", role.getId(), true, invocationContext);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRoleMappings(RealmModel realm, UserModel user) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null || userEntity.getRoleIds() == null || userEntity.getRoleIds().isEmpty()) return Collections.EMPTY_SET;
|
||||
Set<RoleModel> roles = new HashSet<>();
|
||||
for (String roleId : userEntity.getRoleIds()) {
|
||||
RoleModel role = realm.getRoleById(roleId);
|
||||
if (role != null) roles.add(role);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRoleMapping(RealmModel realm, UserModel user, RoleModel role) {
|
||||
FederatedUser userEntity = getUserById(user.getId());
|
||||
if (userEntity == null || userEntity.getRoleIds() == null || userEntity.getRoleIds().isEmpty()) return;
|
||||
getMongoStore().pullItemFromList(userEntity, "roleIds", role.getId(), invocationContext);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.mongo;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.connections.mongo.MongoConnectionProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||
import org.keycloak.storage.federated.UserFederatedStorageProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class MongoUserFederatedStorageProviderFactory implements UserFederatedStorageProviderFactory {
|
||||
@Override
|
||||
public UserFederatedStorageProvider create(KeycloakSession session) {
|
||||
MongoConnectionProvider connection = session.getProvider(MongoConnectionProvider.class);
|
||||
return new MongoUserFederatedStorageProvider(session, connection.getInvocationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "mongo";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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.mongo.entity;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.QueryBuilder;
|
||||
import org.keycloak.connections.mongo.api.MongoCollection;
|
||||
import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
|
||||
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||
import org.keycloak.models.mongo.keycloak.entities.AbstractIdentifiableEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.CredentialEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.FederatedIdentityEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity;
|
||||
import org.keycloak.models.mongo.keycloak.entities.UserConsentEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@MongoCollection(collectionName = "federatedusers")
|
||||
public class FederatedUser extends AbstractIdentifiableEntity implements MongoIdentifiableEntity {
|
||||
protected String realmId;
|
||||
protected String storageId;
|
||||
|
||||
private Map<String, List<String>> attributes;
|
||||
private List<String> roleIds;
|
||||
private List<String> groupIds;
|
||||
private List<String> requiredActions;
|
||||
private List<CredentialEntity> credentials;
|
||||
private List<FederatedIdentityEntity> federatedIdentities;
|
||||
|
||||
public String getRealmId() {
|
||||
return realmId;
|
||||
}
|
||||
|
||||
public void setRealmId(String realmId) {
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
||||
public String getStorageId() {
|
||||
return storageId;
|
||||
}
|
||||
|
||||
public void setStorageId(String storageId) {
|
||||
this.storageId = storageId;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, List<String>> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public List<String> getRoleIds() {
|
||||
return roleIds;
|
||||
}
|
||||
|
||||
public void setRoleIds(List<String> roleIds) {
|
||||
this.roleIds = roleIds;
|
||||
}
|
||||
|
||||
public List<String> getGroupIds() {
|
||||
return groupIds;
|
||||
}
|
||||
|
||||
public void setGroupIds(List<String> groupIds) {
|
||||
this.groupIds = groupIds;
|
||||
}
|
||||
|
||||
public List<String> getRequiredActions() {
|
||||
return requiredActions;
|
||||
}
|
||||
|
||||
public void setRequiredActions(List<String> requiredActions) {
|
||||
this.requiredActions = requiredActions;
|
||||
}
|
||||
|
||||
public List<CredentialEntity> getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
public void setCredentials(List<CredentialEntity> credentials) {
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
public List<FederatedIdentityEntity> getFederatedIdentities() {
|
||||
return federatedIdentities;
|
||||
}
|
||||
|
||||
public void setFederatedIdentities(List<FederatedIdentityEntity> federatedIdentities) {
|
||||
this.federatedIdentities = federatedIdentities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRemove(MongoStoreInvocationContext context) {
|
||||
// Remove all consents of this user
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("userId").is(getId())
|
||||
.get();
|
||||
|
||||
context.getMongoStore().removeEntities(MongoUserConsentEntity.class, query, true, context);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.keycloak.storage.mongo.MongoUserFederatedStorageProviderFactory
|
|
@ -1,166 +0,0 @@
|
|||
/*
|
||||
* 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.models.utils;
|
||||
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.hash.PasswordHashManager;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.JWSInputException;
|
||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.OTPPolicy;
|
||||
import org.keycloak.models.PasswordPolicy;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserCredentialValueModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.representations.PasswordToken;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class FederatedCredentialValidation {
|
||||
|
||||
private static int hashIterations(RealmModel realm) {
|
||||
PasswordPolicy policy = realm.getPasswordPolicy();
|
||||
if (policy != null) {
|
||||
return policy.getHashIterations();
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Will update password if hash iteration policy has changed
|
||||
*
|
||||
* @param realm
|
||||
* @param user
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
public static boolean validPassword(KeycloakSession session, RealmModel realm, UserModel user, String password, UserCredentialValueModel fedCred) {
|
||||
return validateHashedCredential(session, realm, user, password, fedCred);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static boolean validateHashedCredential(KeycloakSession session, RealmModel realm, UserModel user, String unhashedCredValue, UserCredentialValueModel credential) {
|
||||
if (unhashedCredValue == null || unhashedCredValue.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean validated = PasswordHashManager.verify(session, realm, unhashedCredValue, credential);
|
||||
|
||||
if (validated) {
|
||||
int iterations = hashIterations(realm);
|
||||
if (iterations > -1 && iterations != credential.getHashIterations()) {
|
||||
|
||||
UserCredentialValueModel newCred = PasswordHashManager.encode(session, realm, unhashedCredValue);
|
||||
session.userFederatedStorage().updateCredential(realm, user, newCred);
|
||||
}
|
||||
|
||||
}
|
||||
return validated;
|
||||
}
|
||||
|
||||
public static boolean validPasswordToken(RealmModel realm, UserModel user, String encodedPasswordToken) {
|
||||
try {
|
||||
JWSInput jws = new JWSInput(encodedPasswordToken);
|
||||
if (!RSAProvider.verify(jws, realm.getPublicKey())) {
|
||||
return false;
|
||||
}
|
||||
PasswordToken passwordToken = jws.readJsonContent(PasswordToken.class);
|
||||
if (!passwordToken.getRealm().equals(realm.getName())) {
|
||||
return false;
|
||||
}
|
||||
if (!passwordToken.getUser().equals(user.getId())) {
|
||||
return false;
|
||||
}
|
||||
if (Time.currentTime() - passwordToken.getTimestamp() > realm.getAccessCodeLifespanUserAction()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (JWSInputException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean validHOTP(KeycloakSession session, RealmModel realm, UserModel user, String otp, List<UserCredentialValueModel> fedCreds) {
|
||||
UserCredentialValueModel passwordCred = null;
|
||||
OTPPolicy policy = realm.getOTPPolicy();
|
||||
HmacOTP validator = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow());
|
||||
for (UserCredentialValueModel cred : fedCreds) {
|
||||
if (cred.getType().equals(UserCredentialModel.HOTP)) {
|
||||
int counter = validator.validateHOTP(otp, cred.getValue(), cred.getCounter());
|
||||
if (counter < 0) return false;
|
||||
cred.setCounter(counter);
|
||||
session.userFederatedStorage().updateCredential(realm, user, cred);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static boolean validTOTP(RealmModel realm, UserModel user, String otp, List<UserCredentialValueModel> fedCreds) {
|
||||
UserCredentialValueModel passwordCred = null;
|
||||
OTPPolicy policy = realm.getOTPPolicy();
|
||||
TimeBasedOTP validator = new TimeBasedOTP(policy.getAlgorithm(), policy.getDigits(), policy.getPeriod(), policy.getLookAheadWindow());
|
||||
for (UserCredentialValueModel cred : fedCreds) {
|
||||
if (validator.validateTOTP(otp, cred.getValue().getBytes())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
public static boolean validSecret(RealmModel realm, UserModel user, String secret, UserCredentialValueModel cred) {
|
||||
return cred.getValue().equals(secret);
|
||||
|
||||
}
|
||||
|
||||
public static boolean validCredential(KeycloakSession session, RealmModel realm, UserModel user, UserCredentialModel credential, List<UserCredentialValueModel> fedCreds) {
|
||||
if (credential.getType().equals(UserCredentialModel.PASSWORD)) {
|
||||
if (!validPassword(session, realm, user, credential.getValue(), fedCreds.get(0))) {
|
||||
return false;
|
||||
}
|
||||
} else if (credential.getType().equals(UserCredentialModel.PASSWORD_TOKEN)) {
|
||||
if (!validPasswordToken(realm, user, credential.getValue())) {
|
||||
return false;
|
||||
}
|
||||
} else if (credential.getType().equals(UserCredentialModel.TOTP)) {
|
||||
if (!validTOTP(realm, user, credential.getValue(), fedCreds)) {
|
||||
return false;
|
||||
}
|
||||
} else if (credential.getType().equals(UserCredentialModel.HOTP)) {
|
||||
if (!validHOTP(session, realm, user, credential.getValue(), fedCreds)) {
|
||||
return false;
|
||||
}
|
||||
} else if (credential.getType().equals(UserCredentialModel.SECRET)) {
|
||||
if (!validSecret(realm, user, credential.getValue(), fedCreds.get(0))) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
* 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.models.utils;
|
||||
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.hash.PasswordHashManager;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.OTPPolicy;
|
||||
import org.keycloak.models.PasswordPolicy;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserCredentialValueModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class FederatedCredentials {
|
||||
public static void updateCredential(KeycloakSession session, UserFederatedStorageProvider provider, RealmModel realm, UserModel user, UserCredentialModel cred) {
|
||||
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
|
||||
updatePasswordCredential(session, provider,realm, user, cred);
|
||||
} else if (UserCredentialModel.isOtp(cred.getType())) {
|
||||
updateOtpCredential(session, provider, realm, user, cred);
|
||||
} else {
|
||||
UserCredentialValueModel fedCred = getCredentialByType(provider, realm, user, cred.getType());
|
||||
if (fedCred == null) {
|
||||
fedCred.setCreatedDate(Time.toMillis(Time.currentTime()));
|
||||
fedCred.setType(cred.getType());
|
||||
fedCred.setDevice(cred.getDevice());
|
||||
fedCred.setValue(cred.getValue());
|
||||
|
||||
} else {
|
||||
fedCred.setValue(cred.getValue());
|
||||
}
|
||||
provider.updateCredential(realm, user, fedCred);
|
||||
}
|
||||
}
|
||||
|
||||
public static UserCredentialValueModel getCredentialByType(UserFederatedStorageProvider provider, RealmModel realm, UserModel user, String type) {
|
||||
List<UserCredentialValueModel> creds = provider.getCredentials(realm, user);
|
||||
for (UserCredentialValueModel cred : creds) {
|
||||
if (cred.getType().equals(type)) return cred;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static LinkedList<UserCredentialValueModel> getCredentialsByType(UserFederatedStorageProvider provider, RealmModel realm, UserModel user, String type) {
|
||||
List<UserCredentialValueModel> creds = provider.getCredentials(realm, user);
|
||||
LinkedList<UserCredentialValueModel> newCreds = new LinkedList<>();
|
||||
for (UserCredentialValueModel cred : creds) {
|
||||
if (cred.getType().equals(type)) newCreds.add(cred);
|
||||
}
|
||||
return newCreds;
|
||||
}
|
||||
|
||||
public static void updatePasswordCredential(KeycloakSession session, UserFederatedStorageProvider provider, RealmModel realm, UserModel user, UserCredentialModel cred) {
|
||||
UserCredentialValueModel fedCred = getCredentialByType(provider, realm, user, cred.getType());
|
||||
if (fedCred == null) {
|
||||
UserCredentialValueModel newCred = PasswordHashManager.encode(session, realm, cred.getValue());
|
||||
newCred.setCreatedDate(Time.toMillis(Time.currentTime()));
|
||||
newCred.setType(cred.getType());
|
||||
newCred.setDevice(cred.getDevice());
|
||||
provider.updateCredential(realm, user, newCred);
|
||||
} else {
|
||||
int expiredPasswordsPolicyValue = -1;
|
||||
PasswordPolicy policy = realm.getPasswordPolicy();
|
||||
if(policy != null) {
|
||||
expiredPasswordsPolicyValue = policy.getExpiredPasswords();
|
||||
}
|
||||
|
||||
if (expiredPasswordsPolicyValue != -1) {
|
||||
fedCred.setType(UserCredentialModel.PASSWORD_HISTORY);
|
||||
|
||||
LinkedList<UserCredentialValueModel> credentialEntities = getCredentialsByType(provider, realm, user, UserCredentialModel.PASSWORD_HISTORY);
|
||||
if (credentialEntities.size() > expiredPasswordsPolicyValue - 1) {
|
||||
Collections.sort(credentialEntities, new Comparator<UserCredentialValueModel>() {
|
||||
@Override
|
||||
public int compare(UserCredentialValueModel o1, UserCredentialValueModel o2) {
|
||||
if (o1.getCreatedDate().equals(o2.getCreatedDate())) return 0;
|
||||
return o1.getCreatedDate() < o2.getCreatedDate() ? -1 : 1;
|
||||
}
|
||||
});
|
||||
while (credentialEntities.size() > expiredPasswordsPolicyValue - 1) {
|
||||
UserCredentialValueModel model = credentialEntities.removeFirst();
|
||||
provider.removeCredential(realm, user, model);
|
||||
}
|
||||
|
||||
}
|
||||
provider.updateCredential(realm, user, fedCred);
|
||||
fedCred = PasswordHashManager.encode(session, realm, cred.getValue());
|
||||
fedCred.setCreatedDate(Time.toMillis(Time.currentTime()));
|
||||
fedCred.setType(cred.getType());
|
||||
fedCred.setDevice(cred.getDevice());
|
||||
provider.updateCredential(realm, user, fedCred);
|
||||
} else {
|
||||
// clear password history as it is not required anymore
|
||||
for (UserCredentialValueModel model : getCredentialsByType(provider, realm, user, UserCredentialModel.PASSWORD_HISTORY)) {
|
||||
provider.removeCredential(realm, user, model);
|
||||
}
|
||||
UserCredentialValueModel newCred = PasswordHashManager.encode(session, realm, cred.getValue());
|
||||
newCred.setCreatedDate(Time.toMillis(Time.currentTime()));
|
||||
newCred.setType(cred.getType());
|
||||
newCred.setDevice(cred.getDevice());
|
||||
newCred.setId(fedCred.getId());
|
||||
provider.updateCredential(realm, user, newCred);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void updateOtpCredential(KeycloakSession session, UserFederatedStorageProvider provider, RealmModel realm, UserModel user, UserCredentialModel cred) {
|
||||
LinkedList<UserCredentialValueModel> credentialEntities = getCredentialsByType(provider, realm, user, UserCredentialModel.PASSWORD_HISTORY);
|
||||
|
||||
if (credentialEntities.isEmpty()) {
|
||||
UserCredentialValueModel fedCred = new UserCredentialValueModel();
|
||||
fedCred.setCreatedDate(Time.toMillis(Time.currentTime()));
|
||||
fedCred.setType(cred.getType());
|
||||
fedCred.setDevice(cred.getDevice());
|
||||
fedCred.setValue(cred.getValue());
|
||||
OTPPolicy otpPolicy = realm.getOTPPolicy();
|
||||
fedCred.setAlgorithm(otpPolicy.getAlgorithm());
|
||||
fedCred.setDigits(otpPolicy.getDigits());
|
||||
fedCred.setCounter(otpPolicy.getInitialCounter());
|
||||
fedCred.setPeriod(otpPolicy.getPeriod());
|
||||
provider.updateCredential(realm, user, fedCred);
|
||||
} else {
|
||||
OTPPolicy policy = realm.getOTPPolicy();
|
||||
if (cred.getDevice() == null) {
|
||||
for (UserCredentialValueModel model : credentialEntities) provider.removeCredential(realm, user, model);
|
||||
UserCredentialValueModel fedCred = new UserCredentialValueModel();
|
||||
fedCred.setCreatedDate(Time.toMillis(Time.currentTime()));
|
||||
fedCred.setType(cred.getType());
|
||||
fedCred.setDevice(cred.getDevice());
|
||||
fedCred.setDigits(policy.getDigits());
|
||||
fedCred.setCounter(policy.getInitialCounter());
|
||||
fedCred.setAlgorithm(policy.getAlgorithm());
|
||||
fedCred.setValue(cred.getValue());
|
||||
fedCred.setPeriod(policy.getPeriod());
|
||||
provider.updateCredential(realm, user, fedCred);
|
||||
} else {
|
||||
UserCredentialValueModel fedCred = new UserCredentialValueModel();
|
||||
for (UserCredentialValueModel model : credentialEntities) {
|
||||
if (cred.getDevice().equals(model.getDevice())) {
|
||||
fedCred = model;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fedCred.setCreatedDate(Time.toMillis(Time.currentTime()));
|
||||
fedCred.setType(cred.getType());
|
||||
fedCred.setDevice(cred.getDevice());
|
||||
fedCred.setDigits(policy.getDigits());
|
||||
fedCred.setCounter(policy.getInitialCounter());
|
||||
fedCred.setAlgorithm(policy.getAlgorithm());
|
||||
fedCred.setValue(cred.getValue());
|
||||
fedCred.setPeriod(policy.getPeriod());
|
||||
provider.updateCredential(realm, user, fedCred);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -63,6 +63,9 @@ public class StorageId implements Serializable {
|
|||
public static String externalId(String keycloakId) {
|
||||
return new StorageId(keycloakId).getExternalId();
|
||||
}
|
||||
public static String providerId(String keycloakId) {
|
||||
return new StorageId(keycloakId).getProviderId();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* 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.federated;
|
||||
|
||||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserCredentialValueModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface UserCredentialsFederatedStorage {
|
||||
// deprecated
|
||||
void updateCredential(RealmModel realm, UserModel user, UserCredentialModel cred);
|
||||
void updateCredential(RealmModel realm, UserModel user, UserCredentialValueModel cred);
|
||||
void removeCredential(RealmModel realm, UserModel user, UserCredentialValueModel cred);
|
||||
List<UserCredentialValueModel> getCredentials(RealmModel realm, UserModel user);
|
||||
|
||||
// new
|
||||
void updateCredential(RealmModel realm, UserModel user, CredentialModel cred);
|
||||
CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred);
|
||||
boolean removeCredential(RealmModel realm, String id);
|
||||
CredentialModel getCredentialById(String id);
|
||||
List<CredentialModel> getCredentials(RealmModel realm);
|
||||
List<CredentialModel> getUserCredentials(RealmModel realm, UserModel user);
|
||||
List<CredentialModel> getCredentialsByType(RealmModel realm, UserModel user, String type);
|
||||
CredentialModel getCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type);
|
||||
|
||||
}
|
|
@ -37,7 +37,6 @@ public interface UserFederatedStorageProvider extends Provider,
|
|||
UserAttributeFederatedStorage,
|
||||
UserBrokerLinkFederatedStorage,
|
||||
UserConsentFederatedStorage,
|
||||
UserCredentialsFederatedStorage,
|
||||
UserGroupMembershipFederatedStorage,
|
||||
UserRequiredActionsFederatedStorage,
|
||||
UserRoleMappingsFederatedStorage {
|
||||
|
|
|
@ -459,6 +459,7 @@
|
|||
<systemPropertyVariables>
|
||||
<keycloak.realm.provider>mongo</keycloak.realm.provider>
|
||||
<keycloak.user.provider>mongo</keycloak.user.provider>
|
||||
<keycloak.userFederatedStorage.provider>mongo</keycloak.userFederatedStorage.provider>
|
||||
<keycloak.userSessionPersister.provider>mongo</keycloak.userSessionPersister.provider>
|
||||
<keycloak.eventsStore.provider>mongo</keycloak.eventsStore.provider>
|
||||
<keycloak.authorization.provider>mongo</keycloak.authorization.provider>
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
"provider": "${keycloak.user.provider:jpa}"
|
||||
},
|
||||
|
||||
"userFederatedStorage": {
|
||||
"provider": "${keycloak.userFederatedStorage.provider:jpa}"
|
||||
},
|
||||
|
||||
"userSessionPersister": {
|
||||
"provider": "${keycloak.userSessionPersister.provider:jpa}"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue