First tests with LDAP
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 2 Sep 2015 17:16:48 +0000 (17:16 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 2 Sep 2015 17:16:48 +0000 (17:16 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@8360 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.security.core/src/org/argeo/osgi/useradmin/LdapUserAdmin.java [new file with mode: 0644]

diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdapUserAdmin.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdapUserAdmin.java
new file mode 100644 (file)
index 0000000..0173add
--- /dev/null
@@ -0,0 +1,197 @@
+package org.argeo.osgi.useradmin;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.LdapName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+public class LdapUserAdmin implements UserAdmin {
+       private final static Log log = LogFactory.getLog(LdapUserAdmin.class);
+
+       private List<String> indexedUserProperties = Arrays.asList(new String[] {
+                       "uid", "mail", "cn" });
+
+       private String baseDn = "dc=example,dc=com";
+       private InitialLdapContext initialLdapContext = null;
+
+       public LdapUserAdmin(String uri) {
+               try {
+                       Hashtable<String, Object> connEnv = new Hashtable<String, Object>();
+                       connEnv.put(Context.INITIAL_CONTEXT_FACTORY,
+                                       "com.sun.jndi.ldap.LdapCtxFactory");
+                       connEnv.put(Context.PROVIDER_URL, "ldap://localhost:10389/");
+                       connEnv.put("java.naming.ldap.attributes.binary", "userPassword");
+                       // connEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
+                       // connEnv.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
+                       // connEnv.put(Context.SECURITY_CREDENTIALS, "secret");
+
+                       initialLdapContext = new InitialLdapContext(connEnv, null);
+                       // StartTlsResponse tls = (StartTlsResponse) ctx
+                       // .extendedOperation(new StartTlsRequest());
+                       // tls.negotiate();
+                       initialLdapContext.addToEnvironment(
+                                       Context.SECURITY_AUTHENTICATION, "simple");
+                       initialLdapContext.addToEnvironment(Context.SECURITY_PRINCIPAL,
+                                       "uid=admin,ou=system");
+                       initialLdapContext.addToEnvironment(Context.SECURITY_CREDENTIALS,
+                                       "secret");
+                       LdapContext ldapContext = (LdapContext) initialLdapContext
+                                       .lookup("uid=root,ou=users,dc=example,dc=com");
+                       log.debug(initialLdapContext.getAttributes(
+                                       "uid=root,ou=users,dc=example,dc=com").get("cn"));
+               } catch (Exception e) {
+                       throw new ArgeoUserAdminException("Cannot connect to LDAP", e);
+               }
+       }
+
+       public void destroy() {
+               try {
+                       // tls.close();
+                       initialLdapContext.close();
+               } catch (NamingException e) {
+                       log.error("Cannot destroy LDAP user admin", e);
+               }
+       }
+
+       @Override
+       public Role createRole(String name, int type) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public boolean removeRole(String name) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public Role getRole(String name) {
+               try {
+                       Attributes attrs = initialLdapContext.getAttributes(name);
+                       LdifUser res;
+                       if (attrs.get("objectClass").contains("groupOfNames"))
+                               res = new LdifGroup(new LdapName(name), attrs);
+                       else if (attrs.get("objectClass").contains("inetOrgPerson"))
+                               res = new LdifUser(new LdapName(name), attrs);
+                       else
+                               throw new ArgeoUserAdminException("Unsupported LDAP type for "
+                                               + name);
+                       return res;
+               } catch (NamingException e) {
+                       throw new ArgeoUserAdminException("Cannot get role for " + name, e);
+               }
+       }
+
+       @Override
+       public Role[] getRoles(String filter) throws InvalidSyntaxException {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public User getUser(String key, String value) {
+               if (key == null) {
+                       List<User> users = new ArrayList<User>();
+                       for (String prop : indexedUserProperties) {
+                               User user = getUser(prop, value);
+                               if (user != null)
+                                       users.add(user);
+                       }
+                       if (users.size() == 1)
+                               return users.get(0);
+                       else
+                               return null;
+               }
+
+               try {
+                       String searchFilter = "(&(objectClass=inetOrgPerson)(" + key + "="
+                                       + value + "))";
+
+                       SearchControls searchControls = new SearchControls();
+                       searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+                       String searchBase = baseDn;
+                       NamingEnumeration<SearchResult> results = initialLdapContext
+                                       .search(searchBase, searchFilter, searchControls);
+
+                       SearchResult searchResult = null;
+                       if (results.hasMoreElements()) {
+                               searchResult = (SearchResult) results.nextElement();
+                               if (results.hasMoreElements())
+                                       searchResult = null;
+                       }
+                       if (searchResult == null)
+                               return null;
+                       return new LdifUser(toDn(searchBase, searchResult),
+                                       searchResult.getAttributes());
+               } catch (Exception e) {
+                       throw new ArgeoUserAdminException("Cannot get user with " + key
+                                       + "=" + value, e);
+               }
+       }
+
+       @Override
+       public Authorization getAuthorization(User user) {
+               LdifUser u = (LdifUser) user;
+               populateDirectMemberOf(u);
+               return new LdifAuthorization(u);
+       }
+
+       private LdapName toDn(String baseDn, Binding binding)
+                       throws InvalidNameException {
+               return new LdapName(binding.isRelative() ? binding.getName() + ","
+                               + baseDn : binding.getName());
+       }
+
+       void populateDirectMemberOf(LdifUser user) {
+
+               try {
+                       String searchFilter = "(&(objectClass=groupOfNames)(member="
+                                       + user.getName() + "))";
+
+                       SearchControls searchControls = new SearchControls();
+                       searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+                       String searchBase = "ou=node";
+                       NamingEnumeration<SearchResult> results = initialLdapContext
+                                       .search(searchBase, searchFilter, searchControls);
+
+                       // TODO synchro
+                       user.directMemberOf.clear();
+                       while (results.hasMoreElements()) {
+                               SearchResult searchResult = (SearchResult) results
+                                               .nextElement();
+                               LdifGroup group = new LdifGroup(toDn(searchBase, searchResult),
+                                               searchResult.getAttributes());
+                               populateDirectMemberOf(group);
+                               user.directMemberOf.add(group);
+                       }
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot populate direct members of "
+                                       + user, e);
+               }
+       }
+
+}