use of org.keycloak.models.cache.UserCache in project keycloak by keycloak.
the class BackwardsCompatibilityUserStorage method updateCredential.
@Override
public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) {
if (!(input instanceof UserCredentialModel))
return false;
if (input.getType().equals(UserCredentialModel.PASSWORD)) {
// Compatibility with 4.8.3 - Using "legacy" type PasswordUserCredentialModel
if (!(input instanceof PasswordUserCredentialModel)) {
log.warn("Input is not PasswordUserCredentialModel");
return false;
}
PasswordUserCredentialModel userCredentialModel = (PasswordUserCredentialModel) input;
// Those are not supposed to be set when calling this method in Keycloak 4.8.3 for password credential
assertNull(userCredentialModel.getDevice());
assertNull(userCredentialModel.getAlgorithm());
PasswordPolicy policy = session.getContext().getRealm().getPasswordPolicy();
PasswordHashProvider hashProvider = getHashProvider(policy);
CredentialModel newPassword = new CredentialModel();
newPassword.setType(CredentialModel.PASSWORD);
long createdDate = Time.currentTimeMillis();
newPassword.setCreatedDate(createdDate);
// Compatibility with 4.8.3 - Using "legacy" signature of the method on hashProvider
hashProvider.encode(userCredentialModel.getValue(), policy.getHashIterations(), newPassword);
// Test expected values of credentialModel
assertEquals(newPassword.getAlgorithm(), policy.getHashAlgorithm());
assertNotNull(newPassword.getValue());
assertNotNull(newPassword.getSalt());
users.get(translateUserName(user.getUsername())).hashedPassword = newPassword;
UserCache userCache = session.userCache();
if (userCache != null) {
userCache.evict(realm, user);
}
return true;
} else if (isOTPType(input.getType())) {
UserCredentialModel otpCredential = (UserCredentialModel) input;
// Those are not supposed to be set when calling this method in Keycloak 4.8.3 for password credential
assertNull(otpCredential.getDevice());
assertNull(otpCredential.getAlgorithm());
OTPPolicy otpPolicy = session.getContext().getRealm().getOTPPolicy();
CredentialModel newOTP = new CredentialModel();
newOTP.setType(input.getType());
long createdDate = Time.currentTimeMillis();
newOTP.setCreatedDate(createdDate);
newOTP.setValue(otpCredential.getValue());
newOTP.setCounter(otpPolicy.getInitialCounter());
newOTP.setDigits(otpPolicy.getDigits());
newOTP.setAlgorithm(otpPolicy.getAlgorithm());
newOTP.setPeriod(otpPolicy.getPeriod());
users.get(translateUserName(user.getUsername())).otp = newOTP;
return true;
} else {
log.infof("Attempt to update unsupported credential of type: %s", input.getType());
return false;
}
}
use of org.keycloak.models.cache.UserCache in project keycloak by keycloak.
the class LDAPStorageProvider method checkDNChanged.
private void checkDNChanged(RealmModel realm, UserModel local, LDAPObject ldapObject) {
String dnFromDB = local.getFirstAttribute(LDAPConstants.LDAP_ENTRY_DN);
String ldapDn = ldapObject.getDn().toString();
if (!ldapDn.equals(dnFromDB)) {
logger.debugf("Updated LDAP DN of user '%s' to '%s'", local.getUsername(), ldapDn);
local.setSingleAttribute(LDAPConstants.LDAP_ENTRY_DN, ldapDn);
UserCache userCache = session.userCache();
if (userCache != null) {
userCache.evict(realm, local);
}
}
}
use of org.keycloak.models.cache.UserCache in project keycloak by keycloak.
the class PasswordCredentialProvider method createCredential.
@Override
public CredentialModel createCredential(RealmModel realm, UserModel user, PasswordCredentialModel credentialModel) {
PasswordPolicy policy = realm.getPasswordPolicy();
int expiredPasswordsPolicyValue = policy.getExpiredPasswords();
// 1) create new or reset existing password
CredentialModel createdCredential;
CredentialModel oldPassword = getPassword(realm, user);
if (credentialModel.getCreatedDate() == null) {
credentialModel.setCreatedDate(Time.currentTimeMillis());
}
if (oldPassword == null) {
// no password exists --> create new
createdCredential = getCredentialStore().createCredential(realm, user, credentialModel);
} else {
// password exists --> update existing
credentialModel.setId(oldPassword.getId());
getCredentialStore().updateCredential(realm, user, credentialModel);
createdCredential = credentialModel;
// 2) add a password history item based on the old password
if (expiredPasswordsPolicyValue > 1) {
oldPassword.setId(null);
oldPassword.setType(PasswordCredentialModel.PASSWORD_HISTORY);
getCredentialStore().createCredential(realm, user, oldPassword);
}
}
// 3) remove old password history items
final int passwordHistoryListMaxSize = Math.max(0, expiredPasswordsPolicyValue - 1);
getCredentialStore().getStoredCredentialsByTypeStream(realm, user, PasswordCredentialModel.PASSWORD_HISTORY).sorted(CredentialModel.comparingByStartDateDesc()).skip(passwordHistoryListMaxSize).collect(Collectors.toList()).forEach(p -> getCredentialStore().removeStoredCredential(realm, user, p.getId()));
UserCache userCache = session.userCache();
if (userCache != null) {
userCache.evict(realm, user);
}
return createdCredential;
}
use of org.keycloak.models.cache.UserCache in project keycloak by keycloak.
the class RealmAdminResource method updateRealm.
/**
* Update the top-level information of the realm
*
* Any user, roles or client information in the representation
* will be ignored. This will only update top-level attributes of the realm.
*
* @param rep
* @return
*/
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public Response updateRealm(final RealmRepresentation rep) {
auth.realm().requireManageRealm();
logger.debug("updating realm: " + realm.getName());
if (Config.getAdminRealm().equals(realm.getName()) && (rep.getRealm() != null && !rep.getRealm().equals(Config.getAdminRealm()))) {
return ErrorResponse.error("Can't rename master realm", Status.BAD_REQUEST);
}
ReservedCharValidator.validate(rep.getRealm());
ReservedCharValidator.validateLocales(rep.getSupportedLocales());
try {
if (!Constants.GENERATE.equals(rep.getPublicKey()) && (rep.getPrivateKey() != null && rep.getPublicKey() != null)) {
try {
KeyPairVerifier.verify(rep.getPrivateKey(), rep.getPublicKey());
} catch (VerificationException e) {
return ErrorResponse.error(e.getMessage(), Status.BAD_REQUEST);
}
}
if (!Constants.GENERATE.equals(rep.getPublicKey()) && (rep.getCertificate() != null)) {
try {
X509Certificate cert = PemUtils.decodeCertificate(rep.getCertificate());
if (cert == null) {
return ErrorResponse.error("Failed to decode certificate", Status.BAD_REQUEST);
}
} catch (Exception e) {
return ErrorResponse.error("Failed to decode certificate", Status.BAD_REQUEST);
}
}
boolean wasDuplicateEmailsAllowed = realm.isDuplicateEmailsAllowed();
RepresentationToModel.updateRealm(rep, realm, session);
// Refresh periodic sync tasks for configured federationProviders
UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
realm.getUserStorageProvidersStream().forEachOrdered(fedProvider -> usersSyncManager.notifyToRefreshPeriodicSync(session, realm, fedProvider, false));
// This populates the map in DefaultKeycloakContext to be used when treating the event
session.getContext().getUri();
adminEvent.operation(OperationType.UPDATE).representation(StripSecretsUtils.strip(rep)).success();
if (rep.isDuplicateEmailsAllowed() != null && rep.isDuplicateEmailsAllowed() != wasDuplicateEmailsAllowed) {
UserCache cache = session.getProvider(UserCache.class);
if (cache != null)
cache.clear();
}
return Response.noContent().build();
} catch (ModelDuplicateException e) {
return ErrorResponse.exists("Realm with same name exists");
} catch (ModelException e) {
return ErrorResponse.error(e.getMessage(), Status.BAD_REQUEST);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return ErrorResponse.error("Failed to update realm", Response.Status.INTERNAL_SERVER_ERROR);
}
}
use of org.keycloak.models.cache.UserCache in project keycloak by keycloak.
the class LDAPSyncTest method test09MembershipUsingDifferentAttributes.
// KEYCLOAK-14696
@Test
public void test09MembershipUsingDifferentAttributes() throws Exception {
final Map<String, String> previousConf = testingClient.server().fetch(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// Remove all users from model
session.userLocalStorage().getUsersStream(ctx.getRealm(), true).peek(user -> System.out.println("trying to delete user: " + user.getUsername())).collect(Collectors.toList()).forEach(user -> {
UserCache userCache = session.userCache();
if (userCache != null) {
userCache.evict(ctx.getRealm(), user);
}
session.userLocalStorage().removeUser(ctx.getRealm(), user);
});
Map<String, String> orig = new HashMap<>();
orig.put(LDAPConstants.RDN_LDAP_ATTRIBUTE, ctx.getLdapModel().getConfig().getFirst(LDAPConstants.RDN_LDAP_ATTRIBUTE));
orig.put(LDAPConstants.USERS_DN, ctx.getLdapModel().getConfig().getFirst(LDAPConstants.USERS_DN));
orig.put(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, ctx.getLdapModel().getConfig().getFirst(LDAPConstants.USERNAME_LDAP_ATTRIBUTE));
// create an OU and this test will work below it, set RDN to CN and username to uid/samaccountname
LDAPTestUtils.addLdapOU(ctx.getLdapProvider(), "KC14696");
ctx.getLdapModel().getConfig().putSingle(LDAPConstants.USERS_DN, "ou=KC14696," + orig.get(LDAPConstants.USERS_DN));
ctx.getLdapModel().getConfig().putSingle(LDAPConstants.RDN_LDAP_ATTRIBUTE, LDAPConstants.CN);
ctx.getLdapModel().getConfig().putSingle(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, ctx.getLdapProvider().getLdapIdentityStore().getConfig().isActiveDirectory() ? LDAPConstants.SAM_ACCOUNT_NAME : LDAPConstants.UID);
ctx.getRealm().updateComponent(ctx.getLdapModel());
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "username");
mapperModel.getConfig().putSingle(UserAttributeLDAPStorageMapper.LDAP_ATTRIBUTE, ctx.getLdapProvider().getLdapIdentityStore().getConfig().isActiveDirectory() ? LDAPConstants.SAM_ACCOUNT_NAME : LDAPConstants.UID);
ctx.getRealm().updateComponent(mapperModel);
LDAPTestUtils.addUserAttributeMapper(appRealm, LDAPTestUtils.getLdapProviderModel(appRealm), "cnMapper", "firstName", LDAPConstants.CN);
return orig;
}, Map.class);
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// create a user8 inside the usersDn
LDAPObject user8 = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), ctx.getRealm(), "user8", "User8FN", "User8LN", "user8@email.org", "user8street", "126");
// create a sample ou inside usersDn
LDAPTestUtils.addLdapOU(ctx.getLdapProvider(), "sample-org");
// create a user below the sample org with the same common-name but different username
String usersDn = ctx.getLdapModel().get(LDAPConstants.USERS_DN);
ctx.getLdapModel().getConfig().putSingle(LDAPConstants.USERS_DN, "ou=sample-org," + usersDn);
ctx.getRealm().updateComponent(ctx.getLdapModel());
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), ctx.getRealm(), "user8bis", "User8FN", "User8LN", "user8bis@email.org", "user8street", "126");
// get back to parent usersDn
ctx.getLdapModel().getConfig().putSingle(LDAPConstants.USERS_DN, usersDn);
ctx.getRealm().updateComponent(ctx.getLdapModel());
// create a group with user8 as a member
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
LDAPObject user8Group = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "user8group", descriptionAttrName, "user8group - description");
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", user8Group, user8);
});
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
SynchronizationResult syncResult = new UserStorageSyncManager().syncAllUsers(sessionFactory, "test", ctx.getLdapModel());
Assert.assertEquals(2, syncResult.getAdded());
});
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
GroupModel user8Group = KeycloakModelUtils.findGroupByPath(appRealm, "/user8group");
Assert.assertNotNull(user8Group);
UserModel user8 = session.users().getUserByUsername(appRealm, "user8");
Assert.assertNotNull(user8);
UserModel user8Bis = session.users().getUserByUsername(appRealm, "user8bis");
Assert.assertNotNull(user8Bis);
Assert.assertTrue("User user8 contains the group", user8.getGroupsStream().collect(Collectors.toSet()).contains(user8Group));
Assert.assertFalse("User user8bis does not contain the group", user8Bis.getGroupsStream().collect(Collectors.toSet()).contains(user8Group));
List<String> members = session.users().getGroupMembersStream(appRealm, user8Group).map(u -> u.getUsername()).collect(Collectors.toList());
Assert.assertEquals("Group contains only user8", members, Collections.singletonList("user8"));
});
// revert changes
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
session.users().removeImportedUsers(appRealm, ldapModelId);
LDAPTestUtils.removeLDAPUserByUsername(ctx.getLdapProvider(), appRealm, ctx.getLdapProvider().getLdapIdentityStore().getConfig(), "user8");
LDAPTestUtils.removeLDAPUserByUsername(ctx.getLdapProvider(), appRealm, ctx.getLdapProvider().getLdapIdentityStore().getConfig(), "user8bis");
LDAPObject ou = new LDAPObject();
ou.setDn(LDAPDn.fromString("ou=sample-org,ou=KC14696," + previousConf.get(LDAPConstants.USERS_DN)));
ctx.getLdapProvider().getLdapIdentityStore().remove(ou);
ou.setDn(LDAPDn.fromString("ou=KC14696," + previousConf.get(LDAPConstants.USERS_DN)));
ctx.getLdapProvider().getLdapIdentityStore().remove(ou);
for (Map.Entry<String, String> e : previousConf.entrySet()) {
if (e.getValue() == null) {
ctx.getLdapModel().getConfig().remove(e.getKey());
} else {
ctx.getLdapModel().getConfig().putSingle(e.getKey(), e.getValue());
}
}
ctx.getRealm().updateComponent(ctx.getLdapModel());
ComponentModel cnMapper = LDAPTestUtils.getSubcomponentByName(ctx.getRealm(), ctx.getLdapModel(), "cnMapper");
ctx.getRealm().removeComponent(cnMapper);
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "username");
mapperModel.getConfig().putSingle(UserAttributeLDAPStorageMapper.LDAP_ATTRIBUTE, ctx.getLdapProvider().getLdapIdentityStore().getConfig().getUsernameLdapAttribute());
ctx.getRealm().updateComponent(mapperModel);
});
}
Aggregations