mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-03-06 04:10:52 +01:00
move scm-auth-ldap-plugin to its own repository at https://bitbucket.org/tludewig/scm-auth-ldap-plugin
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
|
||||
<modules>
|
||||
<module>scm-activedirectory-auth-plugin</module>
|
||||
<module>scm-auth-ldap-plugin</module>
|
||||
<!-- core plugins -->
|
||||
<module>scm-hg-plugin</module>
|
||||
<module>scm-git-plugin</module>
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>scm-plugins</artifactId>
|
||||
<groupId>sonia.scm.plugins</groupId>
|
||||
<version>1.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>sonia.scm.plugins</groupId>
|
||||
<artifactId>scm-auth-ldap-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.4-SNAPSHOT</version>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>plugin description</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>${servlet.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- test scope -->
|
||||
|
||||
<dependency>
|
||||
<groupId>sonia.scm</groupId>
|
||||
<artifactId>scm-test</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
|
||||
<repository>
|
||||
<id>maven.scm-manager.org</id>
|
||||
<name>scm-manager release repository</name>
|
||||
<url>http://maven.scm-manager.org/nexus/content/groups/public</url>
|
||||
</repository>
|
||||
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
@@ -1,704 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.auth.ldap;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.SCMContextProvider;
|
||||
import sonia.scm.plugin.ext.Extension;
|
||||
import sonia.scm.store.Store;
|
||||
import sonia.scm.store.StoreFactory;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.util.AssertUtil;
|
||||
import sonia.scm.util.Util;
|
||||
import sonia.scm.web.security.AuthenticationHandler;
|
||||
import sonia.scm.web.security.AuthenticationResult;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Thorsten Ludewig
|
||||
*/
|
||||
@Singleton
|
||||
@Extension
|
||||
public class LDAPAuthenticationHandler implements AuthenticationHandler
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
public static final String ATTRIBUTE_GROUP_NAME = "cn";
|
||||
|
||||
/** Field description */
|
||||
public static final String FILTER_GROUP =
|
||||
"(&(objectClass=groupOfUniqueNames)(uniqueMember={0}))";
|
||||
|
||||
/** Field description */
|
||||
public static final String SEARCHTYPE_GROUP = "group";
|
||||
|
||||
/** Field description */
|
||||
public static final String SEARCHTYPE_USER = "user";
|
||||
|
||||
/** Field description */
|
||||
public static final String TYPE = "ldap";
|
||||
|
||||
/** the logger for PAMAuthenticationHandler */
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(LDAPAuthenticationHandler.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param factory
|
||||
*/
|
||||
@Inject
|
||||
public LDAPAuthenticationHandler(StoreFactory factory)
|
||||
{
|
||||
store = factory.getStore(LDAPConfig.class, TYPE);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param username
|
||||
* @param password
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public AuthenticationResult authenticate(HttpServletRequest request,
|
||||
HttpServletResponse response, String username, String password)
|
||||
{
|
||||
AuthenticationResult result = AuthenticationResult.NOT_FOUND;
|
||||
|
||||
if (config.isEnabled())
|
||||
{
|
||||
AssertUtil.assertIsNotEmpty(username);
|
||||
AssertUtil.assertIsNotEmpty(password);
|
||||
result = authenticate(username, password);
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("ldap plugin is disabled");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
@Override
|
||||
public void init(SCMContextProvider context)
|
||||
{
|
||||
config = store.get();
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
config = new LDAPConfig();
|
||||
store.set(config);
|
||||
}
|
||||
|
||||
buildLdapProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
public void storeConfig()
|
||||
{
|
||||
store.set(config);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LDAPConfig getConfig()
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
public void setConfig(LDAPConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
buildLdapProperties();
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param list
|
||||
* @param attribute
|
||||
*/
|
||||
private void appendAttribute(List<String> list, String attribute)
|
||||
{
|
||||
if (Util.isNotEmpty(attribute))
|
||||
{
|
||||
list.add(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private AuthenticationResult authenticate(String username, String password)
|
||||
{
|
||||
AuthenticationResult result = AuthenticationResult.NOT_FOUND;
|
||||
DirContext bindContext = null;
|
||||
|
||||
try
|
||||
{
|
||||
bindContext = createBindContext();
|
||||
|
||||
if (bindContext != null)
|
||||
{
|
||||
SearchResult searchResult = getUserSearchResult(bindContext, username);
|
||||
|
||||
if (searchResult != null)
|
||||
{
|
||||
result = AuthenticationResult.FAILED;
|
||||
|
||||
String userDN = searchResult.getNameInNamespace();
|
||||
|
||||
if (authenticateUser(userDN, password))
|
||||
{
|
||||
Attributes attributes = searchResult.getAttributes();
|
||||
User user = createUser(attributes);
|
||||
Set<String> groups = new HashSet<String>();
|
||||
|
||||
fetchGroups(bindContext, groups, userDN);
|
||||
getGroups(attributes, groups);
|
||||
result = new AuthenticationResult(user, groups);
|
||||
} // password wrong ?
|
||||
} // user not found
|
||||
} // no bind context available
|
||||
}
|
||||
finally
|
||||
{
|
||||
LdapUtil.close(bindContext);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param userDN
|
||||
* @param password
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean authenticateUser(String userDN, String password)
|
||||
{
|
||||
boolean authenticated = false;
|
||||
Hashtable<String, String> userProperties = new Hashtable<String,
|
||||
String>(ldapProperties);
|
||||
|
||||
userProperties.put(Context.SECURITY_PRINCIPAL, userDN);
|
||||
userProperties.put(Context.SECURITY_CREDENTIALS, password);
|
||||
|
||||
DirContext userContext = null;
|
||||
|
||||
try
|
||||
{
|
||||
userContext = new InitialDirContext(userProperties);
|
||||
authenticated = true;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("user {} successfully authenticated", userDN);
|
||||
}
|
||||
}
|
||||
catch (NamingException ex)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("authentication failed for user ".concat(userDN), ex);
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.debug("authentication failed for user {}", userDN);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
LdapUtil.close(userContext);
|
||||
}
|
||||
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
private void buildLdapProperties()
|
||||
{
|
||||
ldapProperties = new Hashtable<String, String>();
|
||||
ldapProperties.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
ldapProperties.put(Context.PROVIDER_URL, config.getHostUrl());
|
||||
ldapProperties.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
ldapProperties.put(Context.SECURITY_PRINCIPAL, config.getConnectionDn());
|
||||
ldapProperties.put(Context.SECURITY_CREDENTIALS,
|
||||
config.getConnectionPassword());
|
||||
ldapProperties.put("java.naming.ldap.version", "3");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private DirContext createBindContext()
|
||||
{
|
||||
DirContext context = null;
|
||||
|
||||
try
|
||||
{
|
||||
context = new InitialDirContext(ldapProperties);
|
||||
}
|
||||
catch (NamingException ex)
|
||||
{
|
||||
logger.error(
|
||||
"could not bind to ldap with dn ".concat(config.getConnectionDn()),
|
||||
ex);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String createGroupSearchBaseDN()
|
||||
{
|
||||
return createSearchBaseDN(SEARCHTYPE_GROUP, config.getUnitGroup());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @param prefix
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String createSearchBaseDN(String type, String prefix)
|
||||
{
|
||||
String dn = null;
|
||||
|
||||
if (Util.isNotEmpty(config.getBaseDn()))
|
||||
{
|
||||
if (Util.isNotEmpty(prefix))
|
||||
{
|
||||
dn = prefix.concat(",").concat(config.getBaseDn());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("no prefix for {} defined, using basedn for search",
|
||||
type);
|
||||
}
|
||||
|
||||
dn = config.getBaseDn();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("saarch base for {} search: {}", type, dn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error("no basedn defined");
|
||||
}
|
||||
|
||||
return dn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param attributes
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private User createUser(Attributes attributes)
|
||||
{
|
||||
User user = new User();
|
||||
|
||||
user.setName(LdapUtil.getAttribute(attributes,
|
||||
config.getAttributeNameId()));
|
||||
user.setDisplayName(LdapUtil.getAttribute(attributes,
|
||||
config.getAttributeNameFullname()));
|
||||
user.setMail(LdapUtil.getAttribute(attributes,
|
||||
config.getAttributeNameMail()));
|
||||
user.setType(TYPE);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String createUserSearchBaseDN()
|
||||
{
|
||||
return createSearchBaseDN(SEARCHTYPE_USER, config.getUnitPeople());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param username
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String createUserSearchFilter(String username)
|
||||
{
|
||||
String filter = null;
|
||||
|
||||
if (Util.isNotEmpty(config.getSearchFilter()))
|
||||
{
|
||||
filter = MessageFormat.format(config.getSearchFilter(), username);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("search-filter for user search: {}", filter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error("search filter not defined");
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
* @param groups
|
||||
* @param userDN
|
||||
*/
|
||||
private void fetchGroups(DirContext context, Set<String> groups,
|
||||
String userDN)
|
||||
{
|
||||
NamingEnumeration<SearchResult> searchResultEnm = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// read group of unique names
|
||||
SearchControls searchControls = new SearchControls();
|
||||
|
||||
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
searchControls.setReturningAttributes(new String[] { "cn" });
|
||||
|
||||
String filter = MessageFormat.format(FILTER_GROUP, userDN);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("using filter {} for group search", filter);
|
||||
}
|
||||
|
||||
String searchDN = createGroupSearchBaseDN();
|
||||
|
||||
searchResultEnm = context.search(searchDN, filter, searchControls);
|
||||
|
||||
while (searchResultEnm.hasMore())
|
||||
{
|
||||
SearchResult searchResult = searchResultEnm.next();
|
||||
Attributes groupAttributes = searchResult.getAttributes();
|
||||
String name = LdapUtil.getAttribute(groupAttributes,
|
||||
ATTRIBUTE_GROUP_NAME);
|
||||
|
||||
if (Util.isNotEmpty(name))
|
||||
{
|
||||
groups.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException ex)
|
||||
{
|
||||
logger.debug("groupOfUniqueNames not found", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LdapUtil.close(searchResultEnm);
|
||||
}
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param attributes
|
||||
* @param groups
|
||||
*
|
||||
*/
|
||||
private void getGroups(Attributes attributes, Set<String> groups)
|
||||
{
|
||||
NamingEnumeration<?> userGroupsEnm = null;
|
||||
|
||||
try
|
||||
{
|
||||
Attribute groupsAttribute =
|
||||
attributes.get(config.getAttributeNameGroup());
|
||||
|
||||
if (groupsAttribute != null)
|
||||
{
|
||||
userGroupsEnm = (NamingEnumeration<?>) groupsAttribute.getAll();
|
||||
|
||||
while (userGroupsEnm.hasMore())
|
||||
{
|
||||
groups.add((String) userGroupsEnm.next());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.info("user has no group attributes assigned");
|
||||
}
|
||||
}
|
||||
catch (NamingException ex)
|
||||
{
|
||||
logger.error("could not read group attribute", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LdapUtil.close(userGroupsEnm);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String[] getReturnAttributes()
|
||||
{
|
||||
List<String> list = new ArrayList<String>();
|
||||
|
||||
appendAttribute(list, config.getAttributeNameId());
|
||||
appendAttribute(list, config.getAttributeNameFullname());
|
||||
appendAttribute(list, config.getAttributeNameMail());
|
||||
appendAttribute(list, config.getAttributeNameMail());
|
||||
|
||||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param bindContext
|
||||
* @param username
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private SearchResult getUserSearchResult(DirContext bindContext,
|
||||
String username)
|
||||
{
|
||||
SearchResult result = null;
|
||||
|
||||
if (bindContext != null)
|
||||
{
|
||||
NamingEnumeration<SearchResult> searchResultEnm = null;
|
||||
|
||||
try
|
||||
{
|
||||
SearchControls searchControls = new SearchControls();
|
||||
int scope = LdapUtil.getSearchScope(config.getSearchScope());
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("using scope {} for user search",
|
||||
LdapUtil.getSearchScope(scope));
|
||||
}
|
||||
|
||||
searchControls.setSearchScope(scope);
|
||||
searchControls.setCountLimit(1);
|
||||
searchControls.setReturningAttributes(getReturnAttributes());
|
||||
|
||||
String filter = createUserSearchFilter(username);
|
||||
|
||||
if (filter != null)
|
||||
{
|
||||
String baseDn = createUserSearchBaseDN();
|
||||
|
||||
if (baseDn != null)
|
||||
{
|
||||
searchResultEnm = bindContext.search(baseDn, filter,
|
||||
searchControls);
|
||||
|
||||
if (searchResultEnm.hasMore())
|
||||
{
|
||||
result = searchResultEnm.next();
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("no user with username {} found", username);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException ex)
|
||||
{
|
||||
logger.error("exception occured during user search", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LdapUtil.close(searchResultEnm);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private LDAPConfig config;
|
||||
|
||||
/** Field description */
|
||||
private Hashtable<String, String> ldapProperties;
|
||||
|
||||
/** Field description */
|
||||
private Store<LDAPConfig> store;
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.auth.ldap;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Thorsten Ludewig
|
||||
*/
|
||||
@XmlRootElement(name = "ldap-config")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class LDAPConfig
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getAttributeNameFullname()
|
||||
{
|
||||
return attributeNameFullname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getAttributeNameGroup()
|
||||
{
|
||||
return attributeNameGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getAttributeNameId()
|
||||
{
|
||||
return attributeNameId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getAttributeNameMail()
|
||||
{
|
||||
return attributeNameMail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getBaseDn()
|
||||
{
|
||||
return baseDn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getConnectionDn()
|
||||
{
|
||||
return connectionDn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getConnectionPassword()
|
||||
{
|
||||
return connectionPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getHostUrl()
|
||||
{
|
||||
return hostUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSearchFilter()
|
||||
{
|
||||
return searchFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSearchScope()
|
||||
{
|
||||
return searchScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUnitGroup()
|
||||
{
|
||||
return unitGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUnitPeople()
|
||||
{
|
||||
return unitPeople;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "attribute-name-fullname")
|
||||
private String attributeNameFullname = "cn";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "attribute-name-group")
|
||||
private String attributeNameGroup = "group";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "attribute-name-id")
|
||||
private String attributeNameId = "uid";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "attribute-name-mail")
|
||||
private String attributeNameMail = "mail";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "base-dn")
|
||||
private String baseDn = "dc=scm-manager,dc=org";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "connection-dn")
|
||||
private String connectionDn = "cn=Directory Manager";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "connection-password")
|
||||
private String connectionPassword = "password";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "host-url")
|
||||
private String hostUrl = "ldap://localhost:389";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "search-filter")
|
||||
private String searchFilter = "(&(uid={0})(objectClass=posixAccount))";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "search-scope")
|
||||
private String searchScope = "one";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "unit-groups")
|
||||
private String unitGroup = "ou=Groups";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "unit-people")
|
||||
private String unitPeople = "ou=People";
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "enabled")
|
||||
private boolean enabled = false;
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.auth.ldap;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Thorsten Ludewig
|
||||
*/
|
||||
@Singleton
|
||||
@Path("config/auth/ldap")
|
||||
public class LDAPConfigResource
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param authenticationHandler
|
||||
*/
|
||||
@Inject
|
||||
public LDAPConfigResource(LDAPAuthenticationHandler authenticationHandler)
|
||||
{
|
||||
this.authenticationHandler = authenticationHandler;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
||||
public LDAPConfig getConfig()
|
||||
{
|
||||
return authenticationHandler.getConfig();
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param uriInfo
|
||||
* @param config
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
||||
public Response setConfig(@Context UriInfo uriInfo, LDAPConfig config)
|
||||
throws IOException
|
||||
{
|
||||
authenticationHandler.setConfig(config);
|
||||
authenticationHandler.storeConfig();
|
||||
|
||||
return Response.created(uriInfo.getRequestUri()).build();
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private LDAPAuthenticationHandler authenticationHandler;
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.auth.ldap;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.util.Util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchControls;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class LdapUtil
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
public static final String SCOPE_OBJECT = "object";
|
||||
|
||||
/** Field description */
|
||||
public static final String SCOPE_ONE = "one";
|
||||
|
||||
/** Field description */
|
||||
public static final String SCOPE_SUB = "sub";
|
||||
|
||||
/** the logger for LdapUtil */
|
||||
private static final Logger logger = LoggerFactory.getLogger(LdapUtil.class);
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public static void close(Context context)
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
context.close();
|
||||
}
|
||||
catch (NamingException ex)
|
||||
{
|
||||
logger.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param enm
|
||||
*/
|
||||
public static void close(NamingEnumeration<?> enm)
|
||||
{
|
||||
if (enm != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
enm.close();
|
||||
}
|
||||
catch (NamingException ex)
|
||||
{
|
||||
logger.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param attributes
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public static String getAttribute(Attributes attributes, String name)
|
||||
{
|
||||
String value = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (Util.isNotEmpty(name))
|
||||
{
|
||||
Attribute attribute = attributes.get(name);
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
value = (String) attribute.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException ex)
|
||||
{
|
||||
logger.warn("could not fetch attribute ".concat(name), ex);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param scopeString
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int getSearchScope(String scopeString)
|
||||
{
|
||||
int scope = SearchControls.SUBTREE_SCOPE;
|
||||
|
||||
if (Util.isNotEmpty(scopeString))
|
||||
{
|
||||
scopeString = scopeString.trim();
|
||||
|
||||
if (SCOPE_SUB.equalsIgnoreCase(scopeString))
|
||||
{
|
||||
scope = SearchControls.SUBTREE_SCOPE;
|
||||
}
|
||||
else if (SCOPE_ONE.equalsIgnoreCase(scopeString))
|
||||
{
|
||||
scope = SearchControls.ONELEVEL_SCOPE;
|
||||
}
|
||||
else if (SCOPE_OBJECT.equalsIgnoreCase(scopeString))
|
||||
{
|
||||
scope = SearchControls.OBJECT_SCOPE;
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("unknown scope {}, using subtree scope", scopeString);
|
||||
}
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("no search scope defined, using subtree scope");
|
||||
}
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param scope
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getSearchScope(int scope)
|
||||
{
|
||||
String scopeString = SCOPE_SUB;
|
||||
|
||||
switch (scope)
|
||||
{
|
||||
case SearchControls.ONELEVEL_SCOPE :
|
||||
scopeString = SCOPE_ONE;
|
||||
|
||||
break;
|
||||
|
||||
case SearchControls.OBJECT_SCOPE :
|
||||
scopeString = SCOPE_OBJECT;
|
||||
}
|
||||
|
||||
return scopeString;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plugin>
|
||||
|
||||
<information>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>${project.artifactId}</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<name>${project.name}</name>
|
||||
<description>SCM-Manager LDAP Plugin</description>
|
||||
<author>Thorsten Ludewig</author>
|
||||
</information>
|
||||
|
||||
<packages>
|
||||
<package>sonia.scm.auth.ldap</package>
|
||||
</packages>
|
||||
|
||||
<resources>
|
||||
<script>/sonia/scm/auth/ldap/sonia.ldap.js</script>
|
||||
</resources>
|
||||
|
||||
</plugin>
|
||||
@@ -1,232 +0,0 @@
|
||||
/* *
|
||||
* Copyright (c) 2010, Sebastian Sdorra
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
Ext.ns("Sonia.ldap");
|
||||
|
||||
Sonia.ldap.ConfigPanel = Ext.extend(Sonia.config.ConfigForm, {
|
||||
|
||||
titleText: 'LDAP Authentication',
|
||||
idAttributeText: 'ID Attribute Name',
|
||||
fullnameAttributeText: 'Fullname Attribute Name',
|
||||
mailAttributeText: 'Mail Attribute Name',
|
||||
groupAttributeText: 'Group Attribute Name',
|
||||
baseDNText: 'Base DN',
|
||||
connectionDNText: 'Connection DN',
|
||||
connectionPasswordText: 'Connection Password',
|
||||
hostURLText: 'Host URL',
|
||||
searchFilterText: 'Search Filter',
|
||||
searchScopeText: 'Search Scope',
|
||||
groupsUnitText: 'Groups Unit',
|
||||
peopleUnitText: 'People Unit',
|
||||
enabledText: 'Enabled',
|
||||
|
||||
// help texts
|
||||
idAttributeHelpText: 'The name of the ldap attribute which contains the username',
|
||||
fullnameAttributeHelpText: 'The name of the ldap attribute which contains the displayname of the user',
|
||||
mailAttributeHelpText: 'The name of the ldap attribute which contains the e-mail address of the user',
|
||||
// TODO improve
|
||||
groupAttributeHelpText: 'The name of the ldap attribute which contains the group names of the user',
|
||||
baseDNHelpText: 'The basedn for example: dc=example,dc=com',
|
||||
connectionDNHelpText: 'The complete dn of the connection user. <strong>Note:<strong> \n\
|
||||
This user needs read an search privileges for the id, mail and fullname attributes.',
|
||||
connectionPasswordHelpText: 'The password for connection user.',
|
||||
hostURLHelpText: 'The url for the ldap server. For example: ldap://localhost:389/',
|
||||
searchFilterHelpText: 'The search filter to find the users. <strong>Note:</strong>\n\
|
||||
{0} will be replaced by the username.',
|
||||
searchScopeHelpText: 'The scope for the user search.',
|
||||
peopleUnitHelpText: 'The relative location of the users. For example: ou=People',
|
||||
groupsUnitHelpText: 'The relative location of the users. For example: ou=Groups',
|
||||
enabledHelpText: 'Enables or disables the ldap authentication',
|
||||
|
||||
initComponent: function(){
|
||||
|
||||
var config = {
|
||||
title : this.titleText,
|
||||
items : [{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.idAttributeText,
|
||||
name : 'attribute-name-id',
|
||||
allowBlank : true,
|
||||
helpText: this.idAttributeHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.fullnameAttributeText,
|
||||
name : 'attribute-name-fullname',
|
||||
allowBlank : true,
|
||||
helpText: this.fullnameAttributeHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.mailAttributeText,
|
||||
name : 'attribute-name-mail',
|
||||
allowBlank : true,
|
||||
helpText: this.mailAttributeHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.groupAttributeText,
|
||||
name : 'attribute-name-group',
|
||||
allowBlank : true,
|
||||
helpText: this.groupAttributeHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.baseDNText,
|
||||
name : 'base-dn',
|
||||
allowBlank : true,
|
||||
helpText: this.baseDNHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.connectionDNText,
|
||||
name : 'connection-dn',
|
||||
allowBlank : true,
|
||||
helpText: this.connectionDNHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
inputType: 'password',
|
||||
fieldLabel : this.connectionPasswordText,
|
||||
name : 'connection-password',
|
||||
allowBlank : true,
|
||||
helpText: this.connectionPasswordHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.hostURLText,
|
||||
name : 'host-url',
|
||||
allowBlank : true,
|
||||
helpText: this.hostURLHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.searchFilterText,
|
||||
name : 'search-filter',
|
||||
allowBlank : true,
|
||||
helpText: this.searchFilterHelpText
|
||||
},{
|
||||
xtype : 'combo',
|
||||
fieldLabel : this.searchScopeText,
|
||||
name : 'search-scope',
|
||||
allowBlank : true,
|
||||
helpText: this.searchScopeHelpText,
|
||||
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 : this.peopleUnitText,
|
||||
name : 'unit-people',
|
||||
allowBlank : true,
|
||||
helpText: this.peopleUnitHelpText
|
||||
},{
|
||||
xtype : 'textfield',
|
||||
fieldLabel : this.groupsUnitText,
|
||||
name : 'unit-groups',
|
||||
allowBlank : true,
|
||||
helpText: this.groupsUnitHelpText
|
||||
},{
|
||||
xtpye: 'checkbox',
|
||||
fieldLabel : this.enabledText,
|
||||
name: 'enabled',
|
||||
helpText: this.enabledHelpText
|
||||
}]
|
||||
}
|
||||
|
||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
||||
Sonia.ldap.ConfigPanel.superclass.initComponent.apply(this, arguments);
|
||||
},
|
||||
|
||||
onSubmit: function(values){
|
||||
this.el.mask(this.submitText);
|
||||
Ext.Ajax.request({
|
||||
url: restUrl + 'config/auth/ldap.json',
|
||||
method: 'POST',
|
||||
jsonData: values,
|
||||
scope: this,
|
||||
disableCaching: true,
|
||||
success: function(response){
|
||||
this.el.unmask();
|
||||
},
|
||||
failure: function(){
|
||||
this.el.unmask();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onLoad: function(el){
|
||||
var tid = setTimeout( function(){el.mask(this.loadingText);}, 100);
|
||||
Ext.Ajax.request({
|
||||
url: restUrl + 'config/auth/ldap.json',
|
||||
method: 'GET',
|
||||
scope: this,
|
||||
disableCaching: true,
|
||||
success: function(response){
|
||||
var obj = Ext.decode(response.responseText);
|
||||
this.load(obj);
|
||||
clearTimeout(tid);
|
||||
el.unmask();
|
||||
},
|
||||
failure: function(){
|
||||
el.unmask();
|
||||
clearTimeout(tid);
|
||||
alert('failure');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// register xtype
|
||||
Ext.reg("ldapConfigPanel", Sonia.ldap.ConfigPanel);
|
||||
|
||||
|
||||
// i18n
|
||||
|
||||
if ( i18n != null && i18n.country == 'de' ){
|
||||
|
||||
Ext.override(Sonia.ldap.ConfigPanel, {
|
||||
|
||||
// TODO
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// regist config panel
|
||||
registerGeneralConfigPanel({
|
||||
id: 'ldapConfigPanel',
|
||||
xtype: 'ldapConfigPanel'
|
||||
});
|
||||
Reference in New Issue
Block a user