javascalaplayframeworkplayframework-2.3securesocial

SecureSocial : Extending BasicProfile adding attributes in Securesocial 3.0-M4, play 2.4


I'm building a website with play framework 2.4 in which the user will be the most important entity.

I would like to use securesocial (3.0-M4) module with a username/password or email/password registration strategy, but I can't find the best way to extend BasicProfile class to add more attributes than those already implemented in the default class (ex: fisrtname, lastname, email, etc...)

I would like to add attributes such as : - gender - dateOfBirth - ...

If someone knows the best way to proceed, I would be very pleased ! :D

I walked through the entire doc a thousand of times and almost through the entire web. I think the next step for me is to hang myself :P


Solution

  • As far as I understand, BasicProfile denotes the minimum information that is common to all Auth providers. While this may not be 100% true, I feel this was the assumption behind the BasicProfile. There is currently an issue open on GitHub to change this and also a PR that supposedly fixes it (I never tried it to be honest).

    In my opinion your best bet at the moment would be to use a decorator/adapter/wrapper pattern and write methods that convert back and forth between your user and BasicProfile. Assuming your are using Java, PlayFramework and Ebeans, you could do something like below (modify it to suit your needs):

    public class UserProfile extends Model{
    
    
        //Fields from BasicProfile
        public String providerId;
        public String firstName;
        public String lastName;
        public String fullName;
        public String email;
        public String avatarUrl;
    
        String gender;
        Date dateOfBirth;
        //Define other custom fields
    
        //Your custom PasswordInfo model
        public PasswordInfo passwordInfo;
    
        public UserProfile(BasicProfile basicProfile) {
    
            this.providerId = basicProfile.providerId();
            // this.authUserId = Long.valueOf(profile.);
            if (basicProfile.firstName().isDefined())
                firstName = basicProfile.firstName().get();
    
            if (basicProfile.lastName().isDefined())
                lastName = basicProfile.lastName().get();
            if (basicProfile.fullName().isDefined())
                fullName = basicProfile.fullName().get();
            if (basicProfile.email().isDefined())
                email = basicProfile.email().get();
            if (basicProfile.avatarUrl().isDefined())
                avatarUrl = basicProfile.avatarUrl().get();
            if (basicProfile.passwordInfo().isDefined()) {
                String hasher = basicProfile.passwordInfo().get().hasher();
                String password = basicProfile.passwordInfo().get().password();
                String salt = basicProfile.passwordInfo().get().salt().isDefined() ? basicProfile.passwordInfo().get().salt().get()
                        : null;
                //Your own custom PasswordInfo model (not securesocial)
                passwordInfo = new PasswordInfo(hasher, password, salt, this);
    
            }
    
        }
    
    
        public BasicProfile getSecureSocialBasicProfile() {
            BasicProfile basicProfile = null;
    
            final scala.Option<securesocial.core.PasswordInfo> info = scala.Option.apply(
                    new securesocial.core.PasswordInfo(passwordInfo.hasher, passwordInfo.password, scala.Option.apply(passwordInfo.salt)));
    
            basicProfile = new BasicProfile(providerId, id.toString(), scala.Option.apply(firstName),
                    scala.Option.apply(lastName), scala.Option.apply(fullName), scala.Option.apply(email),
                    scala.Option.apply(avatarUrl), AuthenticationMethod.UserPassword(), scala.Option.empty(),
                    scala.Option.empty(), info);
            return basicProfile;
    
        }
    
        .....
        .....
    
    }
    

    With the above model and methods to convert back and forth, you can easily add your properties/attributes to the user profile. Hope that helps.