package auth;
import auth.models.Token;
import auth.models.User;
import auth.types.RoleType;
import com.avaje.ebean.Ebean;
import exceptions.PoseidonException;
import models.CoordinateFormat;
import models.UserPreferenceModel;
import org.slf4j.LoggerFactory;
import play.mvc.Http;
import service.PoseidonPropertyService;
import service.PoseidonService;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.*;
import java.util.Date;
import java.util.List;
import java.util.Properties;
public class LDAPAuthenticator extends Authenticator {
public static final String NAMING_EXCEPTION_MESSAGE = "En feil oppstod ved innlogging, vennligst prøv igjen senere";
private static org.slf4j.Logger log = LoggerFactory.getLogger(LDAPAuthenticator.class);
@Override
public Token authenticate(Authentication anAuthentication) {
if (GrantType.LDAP != anAuthentication.getGrantType()) {
return null;
}
LDAPAuthentication authentication = (LDAPAuthentication) anAuthentication;
String username = authentication.getUsername();
String fullName = validatePasswordAndGetName(username, authentication.getPassword());
if (fullName.length() > 0) {
User user = User.findByUsername(username);
if (user == null) {
user = new User();
user.username = username;
user.name = fullName;
user.isActive = true;
user.role = RoleType.READWRITE;
user.createdBy = user.username;
user.created = new Date(PoseidonService.getNow().toDate().getTime());
user.preferences = new UserPreferenceModel();
user.preferences.coordinateFormat = CoordinateFormat.DEGREES_MINUTES_SECONDS;
user.preferences.showGrid = true;
Ebean.save(user);
}
List<String> invoicingUsers = PoseidonPropertyService.getStringListProperty("invoicing.usernames");
if ( invoicingUsers.contains(username)){
user.role = RoleType.INVOICING;
Ebean.update(user);
}
Token token = new Token(user, GrantType.LDAP);
Ebean.save(token);
return token;
} else {
return null;
}
}
private String validatePasswordAndGetName(String username, String password) {
String result = "";
String url = PoseidonPropertyService.getProperty("ldap.serverurl");
String baseDN = PoseidonPropertyService.getProperty("ldap.basedn");
String ou = PoseidonPropertyService.getProperty("ldap.ou");
String principalName = "uid=" + username.trim() + "," + ou + baseDN;
log.debug("Logging in " + principalName);
String domainName = PoseidonPropertyService.getProperty("ldap.domain");
String socketFactory = PoseidonPropertyService.getProperty("ldap.factory.socket");
if (domainName == null || "".equals(domainName)) {
int delim = principalName.indexOf('@');
domainName = principalName.substring(delim + 1);
}
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.PROVIDER_URL, url);
props.put(Context.SECURITY_PRINCIPAL, principalName);
props.put(Context.SECURITY_CREDENTIALS, password);
if (url.toUpperCase().startsWith("LDAPS://")) {
props.put(Context.SECURITY_PROTOCOL, "ssl");
// props.put(Context.SECURITY_AUTHENTICATION, "simple");
props.put("java.naming.ldap.factory.socket", socketFactory);
}
try {
DirContext context = new InitialDirContext(props);
// just need to get the context to verify credentials
Attributes attributes = context.getAttributes(principalName);
result = (String) attributes.get("cn").get(); // common name
log.debug( principalName + " logged in with real name" + result);
} catch (NamingException e) {
throw new PoseidonException(Http.Status.INTERNAL_SERVER_ERROR, NAMING_EXCEPTION_MESSAGE,e);
}
return result;
}
/**
* Create "DC=sub,DC=mydomain,DC=com" string
*
* @param domainName sub.mydomain.com
* @return
*/
private static String toDC(String domainName) {
StringBuilder buf = new StringBuilder();
for (String token : domainName.split("\\.")) {
if (token.length() == 0) continue;
if (buf.length() > 0) buf.append(",");
buf.append("DC=").append(token);
}
return buf.toString();
}
}