]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.security.core/src/org/argeo/osgi/useradmin/LdapUserAdmin.java
- Improve transaction support
[lgpl/argeo-commons.git] / org.argeo.security.core / src / org / argeo / osgi / useradmin / LdapUserAdmin.java
index dcb639d9643f51718a56ceb0c5172c304cfec2f2..0cb435f073e39e25b24efde6a49ac696badd0c85 100644 (file)
@@ -11,21 +11,27 @@ import javax.naming.InvalidNameException;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
 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 javax.transaction.xa.XAException;
+import javax.transaction.xa.Xid;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
+import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
 
-public class LdapUserAdmin extends AbstractLdapUserAdmin {
+public class LdapUserAdmin extends AbstractUserDirectory {
        private final static Log log = LogFactory.getLog(LdapUserAdmin.class);
 
        private String baseDn = "dc=example,dc=com";
@@ -58,7 +64,7 @@ public class LdapUserAdmin extends AbstractLdapUserAdmin {
                        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);
+                       throw new UserDirectoryException("Cannot connect to LDAP", e);
                }
        }
 
@@ -72,39 +78,36 @@ public class LdapUserAdmin extends AbstractLdapUserAdmin {
        }
 
        @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;
+       protected Boolean daoHasRole(LdapName dn) {
+               return daoGetRole(dn) != null;
        }
 
        @Override
-       public Role getRole(String name) {
+       protected DirectoryUser daoGetRole(LdapName name) {
                try {
                        Attributes attrs = initialLdapContext.getAttributes(name);
+                       if (attrs.size() == 0)
+                               return null;
                        LdifUser res;
                        if (attrs.get("objectClass").contains("groupOfNames"))
-                               res = new LdifGroup(new LdapName(name), attrs);
+                               res = new LdifGroup(this, name, attrs);
                        else if (attrs.get("objectClass").contains("inetOrgPerson"))
-                               res = new LdifUser(new LdapName(name), attrs);
+                               res = new LdifUser(this, name, attrs);
                        else
-                               throw new ArgeoUserAdminException("Unsupported LDAP type for "
+                               throw new UserDirectoryException("Unsupported LDAP type for "
                                                + name);
                        return res;
                } catch (NamingException e) {
-                       throw new ArgeoUserAdminException("Cannot get role for " + name, e);
+                       throw new UserDirectoryException("Cannot get role for " + name, e);
                }
        }
 
        @Override
-       public Role[] getRoles(String filter) throws InvalidSyntaxException {
+       protected List<DirectoryUser> doGetRoles(Filter f) {
+               // TODO Auto-generated method stub
                try {
-                       String searchFilter = filter;
+                       String searchFilter = f != null ? f.toString()
+                                       : "(|(objectClass=inetOrgPerson)(objectClass=groupOfNames))";
                        SearchControls searchControls = new SearchControls();
                        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
@@ -112,26 +115,58 @@ public class LdapUserAdmin extends AbstractLdapUserAdmin {
                        NamingEnumeration<SearchResult> results = initialLdapContext
                                        .search(searchBase, searchFilter, searchControls);
 
-                       ArrayList<Role> res = new ArrayList<Role>();
+                       ArrayList<DirectoryUser> res = new ArrayList<DirectoryUser>();
                        while (results.hasMoreElements()) {
                                SearchResult searchResult = results.next();
                                Attributes attrs = searchResult.getAttributes();
-                               String name = searchResult.getName();
                                LdifUser role;
                                if (attrs.get("objectClass").contains("groupOfNames"))
-                                       role = new LdifGroup(new LdapName(name), attrs);
+                                       role = new LdifGroup(this, toDn(searchBase, searchResult),
+                                                       attrs);
                                else if (attrs.get("objectClass").contains("inetOrgPerson"))
-                                       role = new LdifUser(new LdapName(name), attrs);
+                                       role = new LdifUser(this, toDn(searchBase, searchResult),
+                                                       attrs);
                                else
-                                       throw new ArgeoUserAdminException(
-                                                       "Unsupported LDAP type for " + name);
+                                       throw new UserDirectoryException(
+                                                       "Unsupported LDAP type for "
+                                                                       + searchResult.getName());
                                res.add(role);
                        }
-                       return res.toArray(new Role[res.size()]);
+                       return res;
                } catch (Exception e) {
-                       throw new ArgeoUserAdminException("Cannot get roles for filter "
-                                       + filter, e);
+                       throw new UserDirectoryException(
+                                       "Cannot get roles for filter " + f, e);
+               }
+       }
+
+       @Override
+       protected void doGetUser(String key, String value,
+                       List<DirectoryUser> collectedUsers) {
+               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)
+                               collectedUsers.add(new LdifUser(this, toDn(searchBase,
+                                               searchResult), searchResult.getAttributes()));
+               } catch (Exception e) {
+                       throw new UserDirectoryException("Cannot get user with " + key
+                                       + "=" + value, e);
                }
+
        }
 
        @Override
@@ -168,29 +203,52 @@ public class LdapUserAdmin extends AbstractLdapUserAdmin {
                        }
                        if (searchResult == null)
                                return null;
-                       return new LdifUser(toDn(searchBase, searchResult),
+                       return new LdifUser(this, toDn(searchBase, searchResult),
                                        searchResult.getAttributes());
                } catch (Exception e) {
-                       throw new ArgeoUserAdminException("Cannot get user with " + key
+                       throw new UserDirectoryException("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) {
+       // 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);
+       // }
+       // }
 
+       @Override
+       protected List<DirectoryGroup> getDirectGroups(User user) {
+               List<DirectoryGroup> directGroups = new ArrayList<DirectoryGroup>();
                try {
                        String searchFilter = "(&(objectClass=groupOfNames)(member="
                                        + user.getName() + "))";
@@ -198,24 +256,88 @@ public class LdapUserAdmin extends AbstractLdapUserAdmin {
                        SearchControls searchControls = new SearchControls();
                        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 
-                       String searchBase = "ou=node";
+                       String searchBase = getGroupsSearchBase();
                        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);
+                               LdifGroup group = new LdifGroup(this, toDn(searchBase,
+                                               searchResult), searchResult.getAttributes());
+                               directGroups.add(group);
                        }
+                       return directGroups;
                } catch (Exception e) {
                        throw new ArgeoException("Cannot populate direct members of "
                                        + user, e);
                }
        }
 
+       protected String getGroupsSearchBase() {
+               // TODO configure group search base
+               return baseDn;
+       }
+
+       @Override
+       protected void prepare(WorkingCopy wc) {
+               try {
+                       initialLdapContext.reconnect(initialLdapContext
+                                       .getConnectControls());
+                       // delete
+                       for (LdapName dn : wc.getDeletedUsers().keySet()) {
+                               if (!entryExists(dn))
+                                       throw new UserDirectoryException("User to delete no found "
+                                                       + dn);
+                       }
+                       // add
+                       for (LdapName dn : wc.getNewUsers().keySet()) {
+                               if (!entryExists(dn))
+                                       throw new UserDirectoryException("User to create found "
+                                                       + dn);
+                       }
+                       // modify
+                       for (LdapName dn : wc.getModifiedUsers().keySet()) {
+                               if (!entryExists(dn))
+                                       throw new UserDirectoryException("User to modify no found "
+                                                       + dn);
+                       }
+               } catch (NamingException e) {
+                       throw new UserDirectoryException("Cannot prepare LDAP", e);
+               }
+       }
+
+       private boolean entryExists(LdapName dn) throws NamingException {
+               return initialLdapContext.getAttributes(dn).size() != 0;
+       }
+
+       @Override
+       protected void commit(WorkingCopy wc) {
+               try {
+                       // delete
+                       for (LdapName dn : wc.getDeletedUsers().keySet()) {
+                               initialLdapContext.destroySubcontext(dn);
+                       }
+                       // add
+                       for (LdapName dn : wc.getNewUsers().keySet()) {
+                               DirectoryUser user = wc.getNewUsers().get(dn);
+                               initialLdapContext.createSubcontext(dn, user.getAttributes());
+                       }
+                       // modify
+                       for (LdapName dn : wc.getModifiedUsers().keySet()) {
+                               Attributes modifiedAttrs = wc.getModifiedUsers().get(dn);
+                               initialLdapContext.modifyAttributes(dn,
+                                               DirContext.REPLACE_ATTRIBUTE, modifiedAttrs);
+                       }
+               } catch (NamingException e) {
+                       throw new UserDirectoryException("Cannot commit LDAP", e);
+               }
+       }
+
+       @Override
+       protected void rollback(WorkingCopy wc) {
+               // TODO Auto-generated method stub
+               super.rollback(wc);
+       }
+
 }