Skip to content

Commit

Permalink
LDAP: Make more sophisticated logged in
Browse files Browse the repository at this point in the history
  • Loading branch information
doortts committed Jul 4, 2017
1 parent e3f9e87 commit 28f0a09
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 29 deletions.
37 changes: 23 additions & 14 deletions app/controllers/UserApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,8 @@ public static User createLocalUserWithOAuth(UserCredential userCredential){
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");
Expand All @@ -453,18 +454,24 @@ private static void forceOAuthLogout() {
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);
Expand Down Expand Up @@ -1142,7 +1149,13 @@ public static User authenticateWithLdap(String loginIdOrEmail, String password)
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;
Expand All @@ -1153,11 +1166,7 @@ public static User authenticateWithLdap(String loginIdOrEmail, String password)
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;
}
Expand Down
76 changes: 76 additions & 0 deletions app/models/CandidateUser.java
Original file line number Diff line number Diff line change
@@ -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 + '\'' +
'}';
}
}
8 changes: 7 additions & 1 deletion app/models/support/LdapUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
**/
package models.support;

import org.apache.commons.lang3.StringUtils;

import javax.naming.NamingException;
import javax.naming.directory.Attribute;

Expand All @@ -23,7 +25,11 @@ public LdapUser(Attribute displayName, Attribute email, Attribute userLoginId, A
}

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) {
Expand Down
26 changes: 15 additions & 11 deletions app/utils/BasicAuthAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -88,21 +90,23 @@ public static User parseCredentials(String credentials) throws MalformedCredenti
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);
}
}

Expand Down
13 changes: 10 additions & 3 deletions app/utils/LdapService.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class LdapService {
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 {
Expand All @@ -38,7 +40,7 @@ public LdapUser authenticate(String username, String password) throws NamingExce
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);

Expand All @@ -53,11 +55,16 @@ public LdapUser authenticate(String username, String password) throws NamingExce
}

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;
}

Expand Down Expand Up @@ -89,7 +96,7 @@ private SearchResult findUser(DirContext ctx, String username, String filter) th

String searchFilter = "(" + filter + "=" + username + ")";

play.Logger.error("filter: " + searchFilter);
play.Logger.info("filter: " + searchFilter);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

Expand Down
3 changes: 3 additions & 0 deletions conf/application.conf.default
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,9 @@ ldap {
loginProperty = "sAMAccountName"
displayNameProperty = "displayName"
userNameProperty = "CN"
option {
useEmailBaseLogin = false
}
}

include "social-login.conf"

0 comments on commit 28f0a09

Please sign in to comment.