use of org.keycloak.userprofile.UserProfileProvider in project keycloak by keycloak.
the class UserProfileTest method testCreateAndUpdateUser.
private static void testCreateAndUpdateUser(KeycloakSession session) throws IOException {
UserProfileProvider provider = getDynamicUserProfileProvider(session);
UPConfig config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class);
UPAttribute attribute = new UPAttribute();
attribute.setName("address");
UPAttributePermissions permissions = new UPAttributePermissions();
permissions.setEdit(new HashSet<>(Arrays.asList("admin", "user")));
attribute.setPermissions(permissions);
config.addAttribute(attribute);
attribute = new UPAttribute();
attribute.setName("business.address");
permissions = new UPAttributePermissions();
permissions.setEdit(new HashSet<>(Arrays.asList("admin", "user")));
attribute.setPermissions(permissions);
config.addAttribute(attribute);
provider.setConfiguration(JsonSerialization.writeValueAsString(config));
Map<String, Object> attributes = new HashMap<>();
String userName = org.keycloak.models.utils.KeycloakModelUtils.generateId();
attributes.put(UserModel.USERNAME, userName);
attributes.put(UserModel.FIRST_NAME, "Joe");
attributes.put(UserModel.LAST_NAME, "Doe");
attributes.put("address", "fixed-address");
UserProfile profile = provider.create(UserProfileContext.ACCOUNT, attributes);
UserModel user = profile.create();
assertEquals(userName, user.getUsername());
assertEquals("fixed-address", user.getFirstAttribute("address"));
attributes.put(UserModel.FIRST_NAME, "Alice");
attributes.put(UserModel.LAST_NAME, "In Chains");
attributes.put(UserModel.EMAIL, "alice@keycloak.org");
profile = provider.create(UserProfileContext.ACCOUNT, attributes, user);
Set<String> attributesUpdated = new HashSet<>();
Map<String, String> attributesUpdatedOldValues = new HashMap<>();
attributesUpdatedOldValues.put(UserModel.FIRST_NAME, "Joe");
attributesUpdatedOldValues.put(UserModel.LAST_NAME, "Doe");
profile.update((attributeName, userModel, oldValue) -> {
assertTrue(attributesUpdated.add(attributeName));
assertEquals(attributesUpdatedOldValues.get(attributeName), getSingleValue(oldValue));
assertEquals(attributes.get(attributeName), userModel.getFirstAttribute(attributeName));
});
assertThat(attributesUpdated, containsInAnyOrder(UserModel.FIRST_NAME, UserModel.LAST_NAME, UserModel.EMAIL));
configureAuthenticationSession(session);
attributes.put("business.address", "fixed-business-address");
profile = provider.create(UserProfileContext.ACCOUNT, attributes, user);
attributesUpdated.clear();
profile.update((attributeName, userModel, oldValue) -> assertTrue(attributesUpdated.add(attributeName)));
assertThat(attributesUpdated, containsInAnyOrder("business.address"));
assertEquals("fixed-business-address", user.getFirstAttribute("business.address"));
}
use of org.keycloak.userprofile.UserProfileProvider in project keycloak by keycloak.
the class UserProfileTest method failValidationWhenEmptyAttributes.
private static void failValidationWhenEmptyAttributes(KeycloakSession session) {
Map<String, Object> attributes = new HashMap<>();
UserProfileProvider provider = session.getProvider(UserProfileProvider.class);
provider.setConfiguration(null);
UserProfile profile;
try {
profile = provider.create(UserProfileContext.UPDATE_PROFILE, attributes);
profile.validate();
Assert.fail("Should fail validation");
} catch (ValidationException ve) {
// username is mandatory
assertTrue(ve.isAttributeOnError(UserModel.USERNAME));
}
RealmModel realm = session.getContext().getRealm();
try {
attributes.clear();
attributes.put(UserModel.EMAIL, "profile-user@keycloak.org");
profile = provider.create(UserProfileContext.UPDATE_PROFILE, attributes);
profile.validate();
Assert.fail("Should fail validation");
} catch (ValidationException ve) {
// username is mandatory
assertTrue(ve.isAttributeOnError(UserModel.USERNAME));
}
try {
realm.setRegistrationEmailAsUsername(true);
attributes.clear();
attributes.put(UserModel.FIRST_NAME, "Joe");
attributes.put(UserModel.LAST_NAME, "Doe");
attributes.put(UserModel.EMAIL, "profile-user@keycloak.org");
profile = provider.create(UserProfileContext.UPDATE_PROFILE, attributes);
profile.validate();
} catch (ValidationException ve) {
Assert.fail("Should be OK email as username");
} finally {
// we should probably avoid this kind of logic and make the test reset the realm to original state
realm.setRegistrationEmailAsUsername(false);
}
attributes.clear();
attributes.put(UserModel.USERNAME, "profile-user");
attributes.put(UserModel.FIRST_NAME, "Joe");
attributes.put(UserModel.LAST_NAME, "Doe");
provider.create(UserProfileContext.UPDATE_PROFILE, attributes).validate();
}
use of org.keycloak.userprofile.UserProfileProvider in project keycloak by keycloak.
the class UserProfileTest method testGetProfileAttributeGroups.
private static void testGetProfileAttributeGroups(KeycloakSession session) {
RealmModel realm = session.getContext().getRealm();
UserModel user = session.users().addUser(realm, org.keycloak.models.utils.KeycloakModelUtils.generateId());
UserProfileProvider provider = getDynamicUserProfileProvider(session);
String configuration = "{\n" + " \"attributes\": [\n" + " {\n" + " \"name\": \"address\",\n" + " \"group\": \"companyaddress\"\n" + " },\n" + " {\n" + " \"name\": \"second\",\n" + " \"group\": \"groupwithanno" + "\"\n" + " }\n" + " ],\n" + " \"groups\": [\n" + " {\n" + " \"name\": \"companyaddress\",\n" + " \"displayHeader\": \"header\",\n" + " \"displayDescription\": \"description\"\n" + " },\n" + " {\n" + " \"name\": \"groupwithanno\",\n" + " \"annotations\": {\n" + " \"anno1\": \"value1\",\n" + " \"anno2\": \"value2\"\n" + " }\n" + " }\n" + " ]\n" + "}\n";
provider.setConfiguration(configuration);
UserProfile profile = provider.create(UserProfileContext.ACCOUNT, user);
Attributes attributes = profile.getAttributes();
assertThat(attributes.nameSet(), containsInAnyOrder(UserModel.USERNAME, UserModel.EMAIL, UserModel.FIRST_NAME, UserModel.LAST_NAME, "address", "second"));
AttributeGroupMetadata companyAddressGroup = attributes.getMetadata("address").getAttributeGroupMetadata();
assertEquals("companyaddress", companyAddressGroup.getName());
assertEquals("header", companyAddressGroup.getDisplayHeader());
assertEquals("description", companyAddressGroup.getDisplayDescription());
assertNull(companyAddressGroup.getAnnotations());
AttributeGroupMetadata groupwithannoGroup = attributes.getMetadata("second").getAttributeGroupMetadata();
assertEquals("groupwithanno", groupwithannoGroup.getName());
assertNull(groupwithannoGroup.getDisplayHeader());
assertNull(groupwithannoGroup.getDisplayDescription());
Map<String, Object> annotations = groupwithannoGroup.getAnnotations();
assertEquals(2, annotations.size());
assertEquals("value1", annotations.get("anno1"));
assertEquals("value2", annotations.get("anno2"));
}
use of org.keycloak.userprofile.UserProfileProvider in project keycloak by keycloak.
the class IdpReviewProfileAuthenticator method requiresUpdateProfilePage.
protected boolean requiresUpdateProfilePage(AuthenticationFlowContext context, SerializedBrokeredIdentityContext userCtx, BrokeredIdentityContext brokerContext) {
String enforceUpdateProfile = context.getAuthenticationSession().getAuthNote(ENFORCE_UPDATE_PROFILE);
if (Boolean.parseBoolean(enforceUpdateProfile)) {
return true;
}
String updateProfileFirstLogin;
AuthenticatorConfigModel authenticatorConfig = context.getAuthenticatorConfig();
if (authenticatorConfig == null || !authenticatorConfig.getConfig().containsKey(IdpReviewProfileAuthenticatorFactory.UPDATE_PROFILE_ON_FIRST_LOGIN)) {
updateProfileFirstLogin = IdentityProviderRepresentation.UPFLM_MISSING;
} else {
updateProfileFirstLogin = authenticatorConfig.getConfig().get(IdpReviewProfileAuthenticatorFactory.UPDATE_PROFILE_ON_FIRST_LOGIN);
}
if (IdentityProviderRepresentation.UPFLM_MISSING.equals(updateProfileFirstLogin)) {
try {
UserProfileProvider profileProvider = context.getSession().getProvider(UserProfileProvider.class);
profileProvider.create(UserProfileContext.IDP_REVIEW, userCtx.getAttributes()).validate();
return false;
} catch (ValidationException pve) {
return true;
}
} else {
return IdentityProviderRepresentation.UPFLM_ON.equals(updateProfileFirstLogin);
}
}
use of org.keycloak.userprofile.UserProfileProvider in project keycloak by keycloak.
the class RepresentationToModel method updateRealm.
public static void updateRealm(RealmRepresentation rep, RealmModel realm, KeycloakSession session) {
if (rep.getRealm() != null) {
renameRealm(realm, rep.getRealm());
}
if (!Boolean.parseBoolean(rep.getAttributesOrEmpty().get("userProfileEnabled"))) {
UserProfileProvider provider = session.getProvider(UserProfileProvider.class);
provider.setConfiguration(null);
}
// Import attributes first, so the stuff saved directly on representation (displayName, bruteForce etc) has bigger priority
if (rep.getAttributes() != null) {
Set<String> attrsToRemove = new HashSet<>(realm.getAttributes().keySet());
attrsToRemove.removeAll(rep.getAttributes().keySet());
for (Map.Entry<String, String> entry : rep.getAttributes().entrySet()) {
realm.setAttribute(entry.getKey(), entry.getValue());
}
for (String attr : attrsToRemove) {
realm.removeAttribute(attr);
}
}
if (rep.getDisplayName() != null)
realm.setDisplayName(rep.getDisplayName());
if (rep.getDisplayNameHtml() != null)
realm.setDisplayNameHtml(rep.getDisplayNameHtml());
if (rep.isEnabled() != null)
realm.setEnabled(rep.isEnabled());
if (rep.isUserManagedAccessAllowed() != null)
realm.setUserManagedAccessAllowed(rep.isUserManagedAccessAllowed());
if (rep.isBruteForceProtected() != null)
realm.setBruteForceProtected(rep.isBruteForceProtected());
if (rep.isPermanentLockout() != null)
realm.setPermanentLockout(rep.isPermanentLockout());
if (rep.getMaxFailureWaitSeconds() != null)
realm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
if (rep.getMinimumQuickLoginWaitSeconds() != null)
realm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
if (rep.getWaitIncrementSeconds() != null)
realm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
if (rep.getQuickLoginCheckMilliSeconds() != null)
realm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
if (rep.getMaxDeltaTimeSeconds() != null)
realm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
if (rep.getFailureFactor() != null)
realm.setFailureFactor(rep.getFailureFactor());
if (rep.isRegistrationAllowed() != null)
realm.setRegistrationAllowed(rep.isRegistrationAllowed());
if (rep.isRegistrationEmailAsUsername() != null)
realm.setRegistrationEmailAsUsername(rep.isRegistrationEmailAsUsername());
if (rep.isRememberMe() != null)
realm.setRememberMe(rep.isRememberMe());
if (rep.isVerifyEmail() != null)
realm.setVerifyEmail(rep.isVerifyEmail());
if (rep.isLoginWithEmailAllowed() != null)
realm.setLoginWithEmailAllowed(rep.isLoginWithEmailAllowed());
if (rep.isDuplicateEmailsAllowed() != null)
realm.setDuplicateEmailsAllowed(rep.isDuplicateEmailsAllowed());
if (rep.isResetPasswordAllowed() != null)
realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
if (rep.isEditUsernameAllowed() != null)
realm.setEditUsernameAllowed(rep.isEditUsernameAllowed());
if (rep.getSslRequired() != null)
realm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase()));
if (rep.getAccessCodeLifespan() != null)
realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
if (rep.getAccessCodeLifespanUserAction() != null)
realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
if (rep.getAccessCodeLifespanLogin() != null)
realm.setAccessCodeLifespanLogin(rep.getAccessCodeLifespanLogin());
if (rep.getActionTokenGeneratedByAdminLifespan() != null)
realm.setActionTokenGeneratedByAdminLifespan(rep.getActionTokenGeneratedByAdminLifespan());
if (rep.getActionTokenGeneratedByUserLifespan() != null)
realm.setActionTokenGeneratedByUserLifespan(rep.getActionTokenGeneratedByUserLifespan());
OAuth2DeviceConfig deviceConfig = realm.getOAuth2DeviceConfig();
deviceConfig.setOAuth2DeviceCodeLifespan(rep.getOAuth2DeviceCodeLifespan());
deviceConfig.setOAuth2DevicePollingInterval(rep.getOAuth2DevicePollingInterval());
if (rep.getNotBefore() != null)
realm.setNotBefore(rep.getNotBefore());
if (rep.getDefaultSignatureAlgorithm() != null)
realm.setDefaultSignatureAlgorithm(rep.getDefaultSignatureAlgorithm());
if (rep.getRevokeRefreshToken() != null)
realm.setRevokeRefreshToken(rep.getRevokeRefreshToken());
if (rep.getRefreshTokenMaxReuse() != null)
realm.setRefreshTokenMaxReuse(rep.getRefreshTokenMaxReuse());
if (rep.getAccessTokenLifespan() != null)
realm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
if (rep.getAccessTokenLifespanForImplicitFlow() != null)
realm.setAccessTokenLifespanForImplicitFlow(rep.getAccessTokenLifespanForImplicitFlow());
if (rep.getSsoSessionIdleTimeout() != null)
realm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
if (rep.getSsoSessionMaxLifespan() != null)
realm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
if (rep.getSsoSessionIdleTimeoutRememberMe() != null)
realm.setSsoSessionIdleTimeoutRememberMe(rep.getSsoSessionIdleTimeoutRememberMe());
if (rep.getSsoSessionMaxLifespanRememberMe() != null)
realm.setSsoSessionMaxLifespanRememberMe(rep.getSsoSessionMaxLifespanRememberMe());
if (rep.getOfflineSessionIdleTimeout() != null)
realm.setOfflineSessionIdleTimeout(rep.getOfflineSessionIdleTimeout());
// KEYCLOAK-7688 Offline Session Max for Offline Token
if (rep.getOfflineSessionMaxLifespanEnabled() != null)
realm.setOfflineSessionMaxLifespanEnabled(rep.getOfflineSessionMaxLifespanEnabled());
if (rep.getOfflineSessionMaxLifespan() != null)
realm.setOfflineSessionMaxLifespan(rep.getOfflineSessionMaxLifespan());
if (rep.getClientSessionIdleTimeout() != null)
realm.setClientSessionIdleTimeout(rep.getClientSessionIdleTimeout());
if (rep.getClientSessionMaxLifespan() != null)
realm.setClientSessionMaxLifespan(rep.getClientSessionMaxLifespan());
if (rep.getClientOfflineSessionIdleTimeout() != null)
realm.setClientOfflineSessionIdleTimeout(rep.getClientOfflineSessionIdleTimeout());
if (rep.getClientOfflineSessionMaxLifespan() != null)
realm.setClientOfflineSessionMaxLifespan(rep.getClientOfflineSessionMaxLifespan());
if (rep.getRequiredCredentials() != null) {
realm.updateRequiredCredentials(rep.getRequiredCredentials());
}
if (rep.getLoginTheme() != null)
realm.setLoginTheme(rep.getLoginTheme());
if (rep.getAccountTheme() != null)
realm.setAccountTheme(rep.getAccountTheme());
if (rep.getAdminTheme() != null)
realm.setAdminTheme(rep.getAdminTheme());
if (rep.getEmailTheme() != null)
realm.setEmailTheme(rep.getEmailTheme());
if (rep.isEventsEnabled() != null)
realm.setEventsEnabled(rep.isEventsEnabled());
if (rep.getEventsExpiration() != null)
realm.setEventsExpiration(rep.getEventsExpiration());
if (rep.getEventsListeners() != null)
realm.setEventsListeners(new HashSet<>(rep.getEventsListeners()));
if (rep.getEnabledEventTypes() != null)
realm.setEnabledEventTypes(new HashSet<>(rep.getEnabledEventTypes()));
if (rep.isAdminEventsEnabled() != null)
realm.setAdminEventsEnabled(rep.isAdminEventsEnabled());
if (rep.isAdminEventsDetailsEnabled() != null)
realm.setAdminEventsDetailsEnabled(rep.isAdminEventsDetailsEnabled());
if (rep.getPasswordPolicy() != null)
realm.setPasswordPolicy(PasswordPolicy.parse(session, rep.getPasswordPolicy()));
if (rep.getOtpPolicyType() != null)
realm.setOTPPolicy(toPolicy(rep));
WebAuthnPolicy webAuthnPolicy = getWebAuthnPolicyTwoFactor(rep);
realm.setWebAuthnPolicy(webAuthnPolicy);
webAuthnPolicy = getWebAuthnPolicyPasswordless(rep);
realm.setWebAuthnPolicyPasswordless(webAuthnPolicy);
updateCibaSettings(rep, realm);
updateParSettings(rep, realm);
session.clientPolicy().updateRealmModelFromRepresentation(realm, rep);
if (rep.getSmtpServer() != null) {
Map<String, String> config = new HashMap(rep.getSmtpServer());
if (rep.getSmtpServer().containsKey("password") && ComponentRepresentation.SECRET_VALUE.equals(rep.getSmtpServer().get("password"))) {
String passwordValue = realm.getSmtpConfig() != null ? realm.getSmtpConfig().get("password") : null;
config.put("password", passwordValue);
}
realm.setSmtpConfig(config);
}
if (rep.getBrowserSecurityHeaders() != null) {
realm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders());
}
if (rep.isInternationalizationEnabled() != null) {
realm.setInternationalizationEnabled(rep.isInternationalizationEnabled());
}
if (rep.getSupportedLocales() != null) {
realm.setSupportedLocales(new HashSet<String>(rep.getSupportedLocales()));
}
if (rep.getDefaultLocale() != null) {
realm.setDefaultLocale(rep.getDefaultLocale());
}
if (rep.getBrowserFlow() != null) {
realm.setBrowserFlow(realm.getFlowByAlias(rep.getBrowserFlow()));
}
if (rep.getRegistrationFlow() != null) {
realm.setRegistrationFlow(realm.getFlowByAlias(rep.getRegistrationFlow()));
}
if (rep.getDirectGrantFlow() != null) {
realm.setDirectGrantFlow(realm.getFlowByAlias(rep.getDirectGrantFlow()));
}
if (rep.getResetCredentialsFlow() != null) {
realm.setResetCredentialsFlow(realm.getFlowByAlias(rep.getResetCredentialsFlow()));
}
if (rep.getClientAuthenticationFlow() != null) {
realm.setClientAuthenticationFlow(realm.getFlowByAlias(rep.getClientAuthenticationFlow()));
}
if (rep.getDockerAuthenticationFlow() != null) {
realm.setDockerAuthenticationFlow(realm.getFlowByAlias(rep.getDockerAuthenticationFlow()));
}
}
Aggregations