doortts doortts 2017-07-04
LDAP: Make more sophisticated logged in
@28f0a0961f823524b45b92fc9d8295a007bee98f
app/controllers/UserApp.java
--- app/controllers/UserApp.java
+++ app/controllers/UserApp.java
@@ -431,7 +431,8 @@
             forceOAuthLogout();
             return User.anonymous;
         }
-        User created = createUserDelegate(userCredential.name, userCredential.email, null);
+        CandidateUser candidateUser = new CandidateUser(userCredential.name, userCredential.email);
+        User created = createUserDelegate(candidateUser);
 
         if(isUsingEmailVerification() && created.isLocked()){
             flash(Constants.INFO, "user.verification.mail.sent");
@@ -453,18 +454,24 @@
         session().put("pa.url.orig", routes.Application.oAuthLogout().url());
     }
 
-    private static User createUserDelegate(@Nonnull String name, @Nonnull String email, String password) {
-        String loginIdCandidate = email.substring(0, email.indexOf("@"));
+    private static User createUserDelegate(CandidateUser candidateUser) {
+        // . is replaced with - because of BasicAuth parsing case with id
+        String loginIdCandidate = candidateUser.getLoginId();
 
         User user = new User();
-        user.loginId = generateLoginId(user, loginIdCandidate);
-        user.name = name;
-        user.email = email;
 
-        if(StringUtils.isEmpty(password)){
+        if (StringUtils.isBlank(loginIdCandidate) || LdapService.USE_EMAIL_BASE_LOGIN) {
+            loginIdCandidate = candidateUser.getEmail().substring(0, candidateUser.getEmail().indexOf("@"));
+            user.loginId = generateLoginId(user, loginIdCandidate);
+        }
+
+        user.name = candidateUser.getName();
+        user.email = candidateUser.getEmail();
+
+        if(StringUtils.isEmpty(candidateUser.getPassword())){
             user.password = (new SecureRandomNumberGenerator()).nextBytes().toBase64();  // random password because created with OAuth
         } else {
-            user.password = password;
+            user.password = candidateUser.getPassword();
         }
 
         return createNewUser(user);
@@ -1142,7 +1149,13 @@
             play.Logger.error("l: " + ldapUser);
             User localUserFoundByLdapLogin = User.findByEmail(ldapUser.getEmail());
             if (localUserFoundByLdapLogin.isAnonymous()) {
-                User created = createUserDelegate(ldapUser.getDisplayName(), ldapUser.getEmail(), password);
+                CandidateUser candidateUser = new CandidateUser(
+                        ldapUser.getDisplayName(),
+                        ldapUser.getEmail(),
+                        ldapUser.getUserLoginId(),
+                        password
+                );
+                User created = createUserDelegate(candidateUser);
                 if (created.state == UserState.LOCKED) {
                     flash(Constants.INFO, "user.signup.requested");
                     return User.anonymous;
@@ -1153,11 +1166,7 @@
                     User.resetPassword(localUserFoundByLdapLogin.loginId, password);
                 }
 
-                if (StringUtils.isNotBlank(ldapUser.getDepartment())) {
-                    localUserFoundByLdapLogin.name = ldapUser.getDisplayName() + " [" + ldapUser.getDepartment() + "]";
-                } else {
-                    localUserFoundByLdapLogin.name = ldapUser.getDisplayName();
-                }
+                localUserFoundByLdapLogin.name = ldapUser.getDisplayName();
                 localUserFoundByLdapLogin.update();
                 return localUserFoundByLdapLogin;
             }
 
app/models/CandidateUser.java (added)
+++ app/models/CandidateUser.java
@@ -0,0 +1,76 @@
+/**
+ * Yona, 21st Century Project Hosting SW
+ * <p>
+ * Copyright Yona & Yobi Authors & NAVER Corp.
+ * https://yona.io
+ **/
+
+package models;
+
+import org.apache.commons.lang3.StringUtils;
+import play.Play;
+
+// Simple DTO for automatic user creation
+public class CandidateUser {
+    private String name;
+    private String email;
+    private String loginId;
+    private String password;
+
+    public CandidateUser(String name, String email) {
+        this.name = name;
+        this.email = email;
+    }
+
+    public CandidateUser(String name, String email, String loginId, String password) {
+        this.name = name;
+        this.email = email;
+        this.loginId = loginId;
+        this.password = password;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getEmail() {
+        if (StringUtils.isBlank(this.email)) {
+            return "";
+        }
+        return email;
+    }
+
+    public String getLoginId() {
+        return loginId;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public void setLoginId(String loginId) {
+        this.loginId = loginId;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    @Override
+    public String toString() {
+        return "CandidateUser{" +
+                "name='" + name + '\'' +
+                ", email='" + email + '\'' +
+                ", loginId='" + loginId + '\'' +
+                ", password='" + password + '\'' +
+                '}';
+    }
+}
app/models/support/LdapUser.java
--- app/models/support/LdapUser.java
+++ app/models/support/LdapUser.java
@@ -6,6 +6,8 @@
  **/
 package models.support;
 
+import org.apache.commons.lang3.StringUtils;
+
 import javax.naming.NamingException;
 import javax.naming.directory.Attribute;
 
@@ -23,7 +25,11 @@
     }
 
     public String getDisplayName() {
-        return getString(this.displayName);
+        if (StringUtils.isNotBlank(getDepartment())) {
+            return getString(this.displayName) + " [" + getDepartment() + "]";
+        } else {
+            return getString(this.displayName);
+        }
     }
 
     private String getString(Attribute attr) {
app/utils/BasicAuthAction.java
--- app/utils/BasicAuthAction.java
+++ app/utils/BasicAuthAction.java
@@ -33,6 +33,8 @@
 
 import java.io.UnsupportedEncodingException;
 
+import static utils.LdapService.USE_EMAIL_BASE_LOGIN;
+
 public class BasicAuthAction extends Action<Object> {
     private static final String REALM = "Yobi";
 
@@ -88,21 +90,23 @@
     public User authenticate(Request request) throws UnsupportedEncodingException, MalformedCredentialsException {
         String credential = request.getHeader(Http.HeaderNames.AUTHORIZATION);
         User authUser = parseCredentials(credential);
-        
-        if (authUser != null) {
+
+        if (authUser == null) {
+            return User.anonymous;
+        } else {
             String credentialKey = authUser.loginId;
             if (LdapService.useLdap) {
-                // Notice: Email is used for LDAP authentication
-                User targetUser = User.findByLoginId(authUser.loginId);
-                if(!targetUser.isAnonymous()) {
-                    credentialKey = targetUser.email;
+                if (USE_EMAIL_BASE_LOGIN) {
+                    // Notice: Email is used for LDAP authentication
+                    User targetUser = User.findByLoginId(authUser.loginId);
+                    if (!targetUser.isAnonymous()) {
+                        credentialKey = targetUser.email;
+                    }
                 }
-                return  UserApp.authenticateWithLdap(credentialKey, authUser.password);
-            } else {
-                return UserApp.authenticateWithPlainPassword(authUser.loginId, authUser.password);
+                return UserApp.authenticateWithLdap(credentialKey, authUser.password);
             }
-        } else {
-            return User.anonymous;
+
+            return UserApp.authenticateWithPlainPassword(credentialKey, authUser.password);
         }
     }
 
app/utils/LdapService.java
--- app/utils/LdapService.java
+++ app/utils/LdapService.java
@@ -27,6 +27,8 @@
     private static final String LOGIN_PROPERTY = Play.application().configuration().getString("ldap.loginProperty", "sAMAccountName");
     private static final String DISPLAY_NAME_PROPERTY = Play.application().configuration().getString("ldap.displayNameProperty", "displayName");
     private static final String USER_NAME_PROPERTY = Play.application().configuration().getString("ldap.userNameProperty", "CN");
+    public static final boolean USE_EMAIL_BASE_LOGIN = Play.application().configuration().getBoolean("ldap" +
+            ".options.useEmailBaseLogin", false);
     private static final int TIMEOUT = 5000; //ms
 
     public LdapUser authenticate(String username, String password) throws NamingException {
@@ -38,7 +40,7 @@
         env.put("com.sun.jndi.ldap.connect.timeout", ""+(TIMEOUT));
         env.put(Context.PROVIDER_URL, PROTOCOL + "://" + HOST + ":" + PORT);
         env.put(Context.SECURITY_AUTHENTICATION, "simple");
-        play.Logger.error("getProperUsernameGuessing: " + getProperUsernameGuessing(guessedUserIdentity));
+        play.Logger.info("getProperUsernameGuessing: " + getProperUsernameGuessing(guessedUserIdentity));
         env.put(Context.SECURITY_PRINCIPAL, getProperUsernameGuessing(guessedUserIdentity));
         env.put(Context.SECURITY_CREDENTIALS, password);
 
@@ -53,11 +55,16 @@
     }
 
     private String guessedUser(String username) {
+        if(!USE_EMAIL_BASE_LOGIN){
+            return username;
+        }
+
         String guessedUserIdentity = username;
         User user = User.findByLoginId(username);
-        if(!user.isAnonymous()) {
+        if (!user.isAnonymous()) {
             guessedUserIdentity = user.email;
         }
+
         return guessedUserIdentity;
     }
 
@@ -89,7 +96,7 @@
 
         String searchFilter = "(" + filter + "=" + username + ")";
 
-        play.Logger.error("filter: " + searchFilter);
+        play.Logger.info("filter: " + searchFilter);
         SearchControls searchControls = new SearchControls();
         searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
conf/application.conf.default
--- conf/application.conf.default
+++ conf/application.conf.default
@@ -334,6 +334,9 @@
     loginProperty = "sAMAccountName"
     displayNameProperty = "displayName"
     userNameProperty = "CN"
+    option {
+        useEmailBaseLogin = false
+    }
 }
 
 include "social-login.conf"
Add a comment
List