Skip to content

Commit

Permalink
refactoring add UserProfileAttributes
Browse files Browse the repository at this point in the history
  • Loading branch information
bs-matil authored and pedroigor committed Oct 5, 2020
1 parent 695db3e commit c71ce8c
Show file tree
Hide file tree
Showing 18 changed files with 79 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@

package org.keycloak.userprofile;

import java.util.List;
import java.util.Map;

/**
* Abstraction, which allows to update the user in various contexts (Required action of already existing user, or first identity provider
* login when user doesn't yet exists in Keycloak DB)
Expand All @@ -30,16 +27,6 @@ public interface UserProfile {

String getId();

Map<String, List<String>> getAttributes();

String getFirstAttribute(String key);

List<String> getAttribute(String key);

void setSingleAttribute(String key, String value);

void setAttribute(String key, List<String> value);

void removeAttribute(String attr);
UserProfileAttributes getAttributes();

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,38 @@
* limitations under the License.
*/

package org.keycloak.userprofile.profile;

import org.keycloak.userprofile.UserProfile;
package org.keycloak.userprofile;

import java.util.Collections;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.List;

/**
* @author <a href="mailto:markus.till@bosch.io">Markus Till</a>
*/
public abstract class AbstractUserProfile implements UserProfile {


/*
The user attributes handling is different in each user representation so we have to use the setAttributes and getAttributes from the original object
*/

@Override
public abstract Map<String, List<String>> getAttributes();
//TODO: extend immutable map and list
//TODO: create a immutable copy of all items on create
public class UserProfileAttributes extends HashMap<String, List<String>> {

@Override
public abstract void setAttribute(String key, List<String> value);
public UserProfileAttributes(Map<String, List<String>> attribtues){
this.putAll(attribtues);
}

/*
The user id is different in each user representation
*/
@Override
public abstract String getId();
public void setAttribute(String key, List<String> value){
this.put(key,value);
}

@Override
public void setSingleAttribute(String key, String value) {
this.setAttribute(key, Collections.singletonList(value));
}

@Override
public String getFirstAttribute(String key) {
return this.getAttributes() == null ? null : this.getAttributes().get(key) == null ? null : this.getAttributes().get(key).isEmpty()? null : this.getAttributes().get(key).get(0);
return this.get(key) == null ? null : this.get(key).isEmpty()? null : this.get(key).get(0);
}

@Override
public List<String> getAttribute(String key) {
return getAttributes().get(key);
return this.get(key);
}

@Override
public void removeAttribute(String attr) {
getAttributes().remove(attr);
this.remove(attr);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,4 @@
public interface UserProfileProvider extends Provider {

UserProfileValidationResult validate(UserProfileContext updateContext, UserProfile updatedProfile);

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import org.keycloak.userprofile.LegacyUserProfileProviderFactory;
import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.profile.DefaultUserProfileContext;
import org.keycloak.userprofile.profile.representations.AttributeUserProfile;
import org.keycloak.userprofile.profile.AttributeUserProfile;
import org.keycloak.userprofile.utils.UserUpdateHelper;
import org.keycloak.userprofile.validation.UserProfileValidationResult;

Expand Down Expand Up @@ -108,7 +108,7 @@ protected void actionImpl(AuthenticationFlowContext context, SerializedBrokeredI
AttributeUserProfile updatedProfile = AttributeFormDataProcessor.toUserProfile(formData);

String oldEmail = userCtx.getEmail();
String newEmail = updatedProfile.getFirstAttribute(UserModel.EMAIL);
String newEmail = updatedProfile.getAttributes().getFirstAttribute(UserModel.EMAIL);

UserProfileValidationResult result = profileProvider.validate(DefaultUserProfileContext.forIdpReview(userCtx), updatedProfile);
List<FormMessage> errors = Validation.getFormErrorsFromValidation(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import org.keycloak.userprofile.LegacyUserProfileProviderFactory;
import org.keycloak.userprofile.UserProfile;
import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.profile.representations.AttributeUserProfile;
import org.keycloak.userprofile.profile.AttributeUserProfile;
import org.keycloak.userprofile.utils.UserUpdateHelper;
import org.keycloak.userprofile.profile.DefaultUserProfileContext;
import org.keycloak.userprofile.validation.UserProfileValidationResult;
Expand Down Expand Up @@ -76,7 +76,7 @@ public void validate(org.keycloak.authentication.ValidationContext context) {

if (errors.size() > 0) {
if (result.hasFailureOfErrorType(Messages.EMAIL_EXISTS, Messages.INVALID_EMAIL))
context.getEvent().detail(Details.EMAIL, updatedProfile.getFirstAttribute(UserModel.EMAIL));
context.getEvent().detail(Details.EMAIL, updatedProfile.getAttributes().getFirstAttribute(UserModel.EMAIL));

if (result.hasFailureOfErrorType(Messages.EMAIL_EXISTS)) {
context.error(Errors.EMAIL_IN_USE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import org.keycloak.userprofile.LegacyUserProfileProviderFactory;
import org.keycloak.userprofile.UserProfile;
import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.profile.representations.AttributeUserProfile;
import org.keycloak.userprofile.profile.AttributeUserProfile;
import org.keycloak.userprofile.utils.UserUpdateHelper;
import org.keycloak.userprofile.profile.DefaultUserProfileContext;
import org.keycloak.userprofile.validation.UserProfileValidationResult;
Expand Down Expand Up @@ -72,8 +72,8 @@ public void validate(ValidationContext context) {
context.getEvent().detail(Details.REGISTER_METHOD, "form");

UserProfile newProfile = AttributeFormDataProcessor.toUserProfile(context.getHttpRequest().getDecodedFormParameters());
String email = newProfile.getFirstAttribute(UserModel.EMAIL);
String username = newProfile.getFirstAttribute(UserModel.USERNAME);
String email = newProfile.getAttributes().getFirstAttribute(UserModel.EMAIL);
String username = newProfile.getAttributes().getFirstAttribute(UserModel.USERNAME);
context.getEvent().detail(Details.EMAIL, email);
context.getEvent().detail(Details.USERNAME, username);

Expand Down Expand Up @@ -114,8 +114,8 @@ public void buildPage(FormContext context, LoginFormsProvider form) {
public void success(FormContext context) {
AttributeUserProfile updatedProfile = AttributeFormDataProcessor.toUserProfile(context.getHttpRequest().getDecodedFormParameters());

String email = updatedProfile.getFirstAttribute(UserModel.EMAIL);
String username = updatedProfile.getFirstAttribute(UserModel.USERNAME);
String email = updatedProfile.getAttributes().getFirstAttribute(UserModel.EMAIL);
String username = updatedProfile.getAttributes().getFirstAttribute(UserModel.USERNAME);
if (context.getRealm().isRegistrationEmailAsUsername()) {
username = email;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import org.keycloak.services.validation.Validation;
import org.keycloak.userprofile.LegacyUserProfileProviderFactory;
import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.profile.representations.AttributeUserProfile;
import org.keycloak.userprofile.profile.AttributeUserProfile;
import org.keycloak.userprofile.utils.UserUpdateHelper;
import org.keycloak.userprofile.profile.DefaultUserProfileContext;
import org.keycloak.userprofile.validation.UserProfileValidationResult;
Expand Down Expand Up @@ -75,7 +75,7 @@ public void processAction(RequiredActionContext context) {
AttributeUserProfile updatedProfile = AttributeFormDataProcessor.toUserProfile(formData);

String oldEmail = user.getEmail();
String newEmail = updatedProfile.getFirstAttribute(UserModel.EMAIL);
String newEmail = updatedProfile.getAttributes().getFirstAttribute(UserModel.EMAIL);

UserProfileProvider userProfile = context.getSession().getProvider(UserProfileProvider.class, LegacyUserProfileProviderFactory.PROVIDER_ID);
UserProfileValidationResult result = userProfile.validate(DefaultUserProfileContext.forUpdateProfile(user),updatedProfile);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import org.keycloak.models.Constants;
import org.keycloak.models.UserModel;
import org.keycloak.userprofile.profile.representations.AttributeUserProfile;
import org.keycloak.userprofile.profile.AttributeUserProfile;

import javax.ws.rs.core.MultivaluedMap;
import java.util.ArrayList;
Expand Down Expand Up @@ -68,7 +68,7 @@ public static AttributeUserProfile toUserProfile(MultivaluedMap<String, String>

private static void copyAttribute(String key, MultivaluedMap<String, String> formData, AttributeUserProfile rep) {
if (formData.getFirst(key) != null)
rep.setSingleAttribute(key, formData.getFirst(key));
rep.getAttributes().setSingleAttribute(key, formData.getFirst(key));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
import org.keycloak.storage.ReadOnlyException;
import org.keycloak.userprofile.LegacyUserProfileProviderFactory;
import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.profile.representations.AttributeUserProfile;
import org.keycloak.userprofile.profile.AttributeUserProfile;
import org.keycloak.userprofile.utils.UserUpdateHelper;
import org.keycloak.userprofile.profile.DefaultUserProfileContext;
import org.keycloak.userprofile.validation.UserProfileValidationResult;
Expand Down Expand Up @@ -362,7 +362,7 @@ public Response processAccountUpdate(final MultivaluedMap<String, String> formDa
UserModel user = auth.getUser();
AttributeUserProfile updatedProfile = AttributeFormDataProcessor.toUserProfile(formData);
String oldEmail = user.getEmail();
String newEmail = updatedProfile.getFirstAttribute(UserModel.EMAIL);
String newEmail = updatedProfile.getAttributes().getFirstAttribute(UserModel.EMAIL);

event.event(EventType.UPDATE_PROFILE).client(auth.getClient()).user(auth.getUser());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,41 @@
* limitations under the License.
*/

package org.keycloak.userprofile.profile.representations;
package org.keycloak.userprofile.profile;

import org.keycloak.userprofile.profile.AbstractUserProfile;
import org.keycloak.userprofile.UserProfile;
import org.keycloak.userprofile.UserProfileAttributes;

import javax.ws.rs.NotSupportedException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author <a href="mailto:markus.till@bosch.io">Markus Till</a>
*/
public class AttributeUserProfile extends AbstractUserProfile {
private final Map<String, List<String>> attributes;
public class AttributeUserProfile implements UserProfile {

private final UserProfileAttributes attributes;


public AttributeUserProfile(Map<String, List<String>> attributes) {
this.attributes = attributes;
this.attributes = new UserProfileAttributes(attributes);
}

@Override
public Map<String, List<String>> getAttributes() {
public UserProfileAttributes getAttributes() {
return this.attributes;
}

@Override
public void setAttribute(String key, List<String> value) {
this.getAttributes().put(key, value);
}

/*
The user id is different in each user representation
*/

@Override
public String getId() {
throw new NotSupportedException("No ID support");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.userprofile.UserProfile;
import org.keycloak.userprofile.UserProfileAttributes;
import org.keycloak.userprofile.UserProfileContext;
import org.keycloak.userprofile.profile.representations.IdpUserProfile;
import org.keycloak.userprofile.profile.representations.UserModelUserProfile;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import org.keycloak.models.UserModel;
import org.keycloak.representations.account.UserRepresentation;
import org.keycloak.userprofile.UserProfileAttributes;
import org.keycloak.userprofile.profile.AttributeUserProfile;

import java.util.Collections;
import java.util.HashMap;
Expand All @@ -35,7 +37,7 @@ public AccountUserRepresentationUserProfile(UserRepresentation user) {
super(flattenUserRepresentation(user));
}

private static Map<String, List<String>> flattenUserRepresentation(UserRepresentation user) {
private static UserProfileAttributes flattenUserRepresentation(UserRepresentation user) {
Map<String, List<String>> attrs = new HashMap<>();

if (user.getAttributes() != null) attrs.putAll(user.getAttributes());
Expand All @@ -57,7 +59,7 @@ private static Map<String, List<String>> flattenUserRepresentation(UserRepresent
attrs.put(UserModel.FIRST_NAME, Collections.singletonList(user.getFirstName()));


return attrs;
return (UserProfileAttributes)attrs;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,18 @@
package org.keycloak.userprofile.profile.representations;

import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext;
import org.keycloak.userprofile.profile.AbstractUserProfile;
import org.keycloak.userprofile.profile.AttributeUserProfile;

import java.util.List;
import java.util.Map;

/**
* @author <a href="mailto:markus.till@bosch.io">Markus Till</a>
*/
public class IdpUserProfile extends AbstractUserProfile {
public class IdpUserProfile extends AttributeUserProfile {

private final SerializedBrokeredIdentityContext user;

public IdpUserProfile(SerializedBrokeredIdentityContext user) {
super(user.getAttributes());
this.user = user;
}

Expand All @@ -39,15 +38,4 @@ public String getId() {
return user.getId();
}


@Override
public Map<String, List<String>> getAttributes() {
return user.getAttributes();
}

@Override
public void setAttribute(String key, List<String> value) {
user.setAttribute(key, value);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,24 @@
package org.keycloak.userprofile.profile.representations;

import org.keycloak.models.UserModel;
import org.keycloak.userprofile.profile.AbstractUserProfile;

import java.util.List;
import java.util.Map;
import org.keycloak.userprofile.profile.AttributeUserProfile;

/**
* @author <a href="mailto:markus.till@bosch.io">Markus Till</a>
*/
public class UserModelUserProfile extends AbstractUserProfile {
public class UserModelUserProfile extends AttributeUserProfile {

private final UserModel user;

public UserModelUserProfile(UserModel user) {
super(user.getAttributes());
this.user = user;
}

private final UserModel user;

@Override
public String getId() {
return user.getId();
}

@Override
public Map<String, List<String>> getAttributes() {
return user.getAttributes();
}

@Override
public void setAttribute(String key, List<String> value) {
user.setAttribute(key, value);
}

@Override
public void removeAttribute(String attr) {
// Due to the fact that the user attribute list is a copy and not a reference in the user adapter we have to access the remove function directly
user.removeAttribute(attr);
}
}
Loading

0 comments on commit c71ce8c

Please sign in to comment.