diff --git a/plugins/scm-auth-ldap-plugin/pom.xml b/plugins/scm-auth-ldap-plugin/pom.xml
index 92a3205900..65e4420914 100644
--- a/plugins/scm-auth-ldap-plugin/pom.xml
+++ b/plugins/scm-auth-ldap-plugin/pom.xml
@@ -6,7 +6,7 @@
scm-plugins
sonia.scm.plugins
- 1.0-M6-SNAPSHOT
+ 1.0-M7-SNAPSHOT
sonia.scm.plugins
@@ -30,7 +30,7 @@
sonia.scm
scm-test
- 1.0-M6-SNAPSHOT
+ 1.0-M7-SNAPSHOT
test
diff --git a/plugins/scm-auth-ldap-plugin/src/main/java/sonia/scm/auth/ldap/LDAPAuthenticationHandler.java b/plugins/scm-auth-ldap-plugin/src/main/java/sonia/scm/auth/ldap/LDAPAuthenticationHandler.java
index 028ff45d04..4230946bb2 100644
--- a/plugins/scm-auth-ldap-plugin/src/main/java/sonia/scm/auth/ldap/LDAPAuthenticationHandler.java
+++ b/plugins/scm-auth-ldap-plugin/src/main/java/sonia/scm/auth/ldap/LDAPAuthenticationHandler.java
@@ -29,6 +29,8 @@
*
*/
+
+
package sonia.scm.auth.ldap;
//~--- non-JDK imports --------------------------------------------------------
@@ -51,8 +53,22 @@ import sonia.scm.web.security.AuthenticationResult;
import java.io.IOException;
+import java.text.MessageFormat;
+
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import sonia.scm.user.User;
/**
*
@@ -105,6 +121,90 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
AssertUtil.assertIsNotEmpty(password);
AuthenticationResult result = AuthenticationResult.NOT_FOUND;
+ DirContext context = null;
+
+ try
+ {
+ context = new InitialDirContext(ldapProperties);
+
+ SearchControls searchControls = new SearchControls();
+
+ searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ searchControls.setCountLimit(1);
+ searchControls.setReturningAttributes(new String[] {
+ config.getAttributeNameId(),
+ config.getAttributeNameFullname(), config.getAttributeNameMail() });
+
+ String filter = MessageFormat.format(config.getSearchFilter(), username);
+ String baseDn = config.getUnitPeople() + "," + config.getBaseDn();
+ NamingEnumeration searchResult = context.search(baseDn,
+ filter, searchControls);
+
+ if (searchResult.hasMore())
+ {
+ result = AuthenticationResult.FAILED;
+
+ SearchResult sr = searchResult.next();
+ String userDn = sr.getName() + "," + baseDn;
+ Properties userProperties = new Properties(ldapProperties);
+
+ userProperties.put(Context.SECURITY_PRINCIPAL, userDn);
+ userProperties.put(Context.SECURITY_CREDENTIALS, password);
+
+ DirContext userContext = null;
+
+ try
+ {
+ userContext = new InitialDirContext(userProperties);
+
+ User user = new User();
+ Attributes userAttributes = sr.getAttributes();
+ user.setName((String)userAttributes.get(config.getAttributeNameId()).get());
+ user.setDisplayName((String)userAttributes.get(config.getAttributeNameFullname()).get());
+ user.setMail((String)userAttributes.get(config.getAttributeNameMail()).get());
+ user.setType(TYPE);
+ result = new AuthenticationResult(user);
+ }
+ catch (NamingException ex)
+ {
+ logger.trace(ex.getMessage(), ex);
+ }
+ finally
+ {
+ if (userContext != null)
+ {
+ try
+ {
+ userContext.close();
+ }
+ catch (NamingException ex)
+ {
+ logger.error(ex.getMessage(), ex);
+ }
+ }
+ }
+ }
+
+ searchResult.close();
+ }
+ catch (NamingException ex)
+ {
+ logger.error(ex.getMessage(), ex);
+ }
+ finally
+ {
+ if (context != null)
+ {
+ try
+ {
+ context.close();
+ }
+ catch (NamingException ex)
+ {
+ logger.error(ex.getMessage(), ex);
+ }
+ }
+ }
return result;
}
@@ -138,6 +238,8 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
config = new LDAPConfig();
store.set(config);
}
+
+ buildLdapProperties();
}
/**
@@ -185,14 +287,45 @@ public class LDAPAuthenticationHandler implements AuthenticationHandler
public void setConfig(LDAPConfig config)
{
this.config = config;
+ buildLdapProperties();
}
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ */
+ private void buildLdapProperties()
+ {
+ ldapProperties = new Properties();
+ ldapProperties.put(Context.INITIAL_CONTEXT_FACTORY,
+ "com.sun.jndi.ldap.LdapCtxFactory");
+ ldapProperties.put(Context.PROVIDER_URL, config.getHostUrl());
+ ldapProperties.put(Context.SECURITY_AUTHENTICATION, "simple");
+
+ /*
+ * if( contextSecurityProtocol.equalsIgnoreCase( "ssl" ) )
+ * {
+ * ldapContextProperties.put( Context.SECURITY_PROTOCOL, "ssl" );
+ * ldapContextProperties.put( "java.naming.ldap.factory.socket",
+ * "sonia.net.ssl.SSLSocketFactory" );
+ * }
+ */
+ ldapProperties.put(Context.SECURITY_PRINCIPAL, config.getConnectionDn());
+ ldapProperties.put(Context.SECURITY_CREDENTIALS,
+ config.getConnectionPassword());
+ ldapProperties.put("java.naming.ldap.version", "3");
+ }
//~--- fields ---------------------------------------------------------------
/** Field description */
private LDAPConfig config;
+ /** Field description */
+ private Properties ldapProperties;
+
/** Field description */
private Store store;
}
diff --git a/plugins/scm-auth-ldap-plugin/src/main/java/sonia/scm/auth/ldap/LDAPConfig.java b/plugins/scm-auth-ldap-plugin/src/main/java/sonia/scm/auth/ldap/LDAPConfig.java
index f8ad66d5c6..e2431bed1f 100644
--- a/plugins/scm-auth-ldap-plugin/src/main/java/sonia/scm/auth/ldap/LDAPConfig.java
+++ b/plugins/scm-auth-ldap-plugin/src/main/java/sonia/scm/auth/ldap/LDAPConfig.java
@@ -325,7 +325,7 @@ public class LDAPConfig
/** Field description */
@XmlElement(name = "search-filter")
- private String searchFilter = "objectClass=posixAccount";
+ private String searchFilter = "(&(uid={0})(objectClass=posixAccount))";
/** Field description */
@XmlElement(name = "search-scope")
diff --git a/plugins/scm-auth-ldap-plugin/src/main/resources/META-INF/scm/plugin.xml b/plugins/scm-auth-ldap-plugin/src/main/resources/META-INF/scm/plugin.xml
index c2f77990d1..9b1228a219 100644
--- a/plugins/scm-auth-ldap-plugin/src/main/resources/META-INF/scm/plugin.xml
+++ b/plugins/scm-auth-ldap-plugin/src/main/resources/META-INF/scm/plugin.xml
@@ -6,11 +6,8 @@
${project.artifactId}
${project.version}
${project.name}
- ${project.description}
-
+ SCM-Manager LDAP Plugin
+ Thorsten Ludewig
diff --git a/plugins/scm-auth-ldap-plugin/src/main/resources/sonia/scm/auth/ldap/sonia.ldap.js b/plugins/scm-auth-ldap-plugin/src/main/resources/sonia/scm/auth/ldap/sonia.ldap.js
index 1c78176334..5dc6021193 100644
--- a/plugins/scm-auth-ldap-plugin/src/main/resources/sonia/scm/auth/ldap/sonia.ldap.js
+++ b/plugins/scm-auth-ldap-plugin/src/main/resources/sonia/scm/auth/ldap/sonia.ldap.js
@@ -33,22 +33,104 @@
registerGeneralConfigPanel({
xtype : 'configForm',
- title : 'PAM Authentication',
+ title : 'LDAP Authentication',
items : [{
xtype : 'textfield',
- fieldLabel : 'Service name',
- name : 'service-name',
- allowBlank : false
+ fieldLabel : 'Admin NSRole DN',
+ name : 'admin-nsrole-dn',
+ allowBlank : true
},{
xtype : 'textfield',
fieldLabel : 'Admin Groups',
name : 'admin-groups',
allowBlank : true
- },{
+ }
+ ,{
xtype : 'textfield',
fieldLabel : 'Admin Users',
name : 'admin-users',
allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'Fullname Attribute Name',
+ name : 'attribute-name-fullname',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'ID Attribute Name',
+ name : 'attribute-name-id',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'Mail Attribute Name',
+ name : 'attribute-name-mail',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'Base DN',
+ name : 'base-dn',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'Connection DN',
+ name : 'connection-dn',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ inputType: 'password',
+ fieldLabel : 'Connection Password',
+ name : 'connection-password',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'Host URL',
+ name : 'host-url',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'Search Filter',
+ name : 'search-filter',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'combo',
+ fieldLabel : 'Search Scope',
+ name : 'search-scope',
+ allowBlank : true,
+ valueField: 'scope',
+ displayField: 'scope',
+ typeAhead: false,
+ editable: false,
+ triggerAction: 'all',
+ mode: 'local',
+ store: new Ext.data.SimpleStore({
+ fields: ['scope'],
+ data: [
+ ['object'],
+ ['one'],
+ ['sub']
+ ]
+ })
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'Groups Unit',
+ name : 'unit-groups',
+ allowBlank : true
+ }
+ ,{
+ xtype : 'textfield',
+ fieldLabel : 'Groups People',
+ name : 'unit-people',
+ allowBlank : true
}],
onSubmit: function(values){