/** * Yona, 21st Century Project Hosting SW *

* Copyright Yona & Yobi Authors & NAVER Corp. * https://yona.io **/ package models; import com.avaje.ebean.Ebean; import com.avaje.ebean.ExpressionList; import com.feth.play.module.pa.user.AuthUser; import com.feth.play.module.pa.user.AuthUserIdentity; import com.feth.play.module.pa.user.EmailIdentity; import com.feth.play.module.pa.user.NameIdentity; import play.data.validation.Constraints; import play.db.ebean.Model; import javax.persistence.*; import java.util.*; @Entity public class UserCredential extends Model { private static final long serialVersionUID = 1L; @Id public Long id; @OneToOne public User user; public String loginId; @Constraints.Email // if you make this unique, keep in mind that users *must* merge/link their // accounts then on signup with additional providers // @Column(unique = true) public String email; public String name; public boolean active; public boolean emailValidated; @OneToMany(cascade = CascadeType.ALL) public List linkedAccounts; public static final Finder find = new Finder( Long.class, UserCredential.class); public static boolean existsByAuthUserIdentity( final AuthUserIdentity identity) { final ExpressionList exp = getAuthUserFind(identity); return exp.findRowCount() > 0; } private static ExpressionList getAuthUserFind( final AuthUserIdentity identity) { return find.where().eq("active", true) .eq("linkedAccounts.providerUserId", identity.getId()) .eq("linkedAccounts.providerKey", identity.getProvider()); } public static UserCredential findByAuthUserIdentity(final AuthUserIdentity identity) { if (identity == null) { return null; } return getAuthUserFind(identity).findUnique(); } public void merge(final UserCredential otherUser) { for (final LinkedAccount acc : otherUser.linkedAccounts) { this.linkedAccounts.add(LinkedAccount.create(acc)); } // do all other merging stuff here - like resources, etc. // deactivate the merged user that got added to this one otherUser.active = false; Ebean.save(Arrays.asList(new UserCredential[] { otherUser, this })); } public static UserCredential create(final AuthUser authUser) { final UserCredential userCredential = new UserCredential(); userCredential.active = true; userCredential.linkedAccounts = Collections.singletonList(LinkedAccount .create(authUser)); if (authUser instanceof EmailIdentity) { final EmailIdentity identity = (EmailIdentity) authUser; // Remember, even when getting them from FB & Co., emails should be // verified within the application as a security breach there might // break your security as well! userCredential.email = identity.getEmail(); userCredential.emailValidated = true; } if (authUser instanceof NameIdentity) { final NameIdentity identity = (NameIdentity) authUser; final String name = identity.getName(); if (name != null) { userCredential.name = name; } } userCredential.save(); return userCredential; } public static void merge(final AuthUser oldUser, final AuthUser newUser) { UserCredential.findByAuthUserIdentity(oldUser).merge( UserCredential.findByAuthUserIdentity(newUser)); } public Set getProviders() { final Set providerKeys = new HashSet( linkedAccounts.size()); for (final LinkedAccount acc : linkedAccounts) { providerKeys.add(acc.providerKey); } return providerKeys; } public static void addLinkedAccount(final AuthUser oldUser, final AuthUser newUser) { final UserCredential u = UserCredential.findByAuthUserIdentity(oldUser); u.linkedAccounts.add(LinkedAccount.create(newUser)); u.save(); } public static UserCredential findByEmail(final String email) { return getEmailUserFind(email).findUnique(); } private static ExpressionList getEmailUserFind(final String email) { return find.where().eq("active", true).eq("email", email); } public LinkedAccount getAccountByProvider(final String providerKey) { return LinkedAccount.findByProviderKey(this, providerKey); } public static List findByUserId(Long id){ return find.where().eq("user.id", id).findList(); } @Override public String toString() { return "UserCredential{" + "id=" + id + ", user=" + user + ", loginId='" + loginId + '\'' + ", email='" + email + '\'' + ", name='" + name + '\'' + ", active=" + active + ", emailValidated=" + emailValidated + ", linkedAccounts=" + linkedAccounts + '}'; } }