]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.util/src/org/argeo/osgi/useradmin/LdifUserAdmin.java
Introduce system roles
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / osgi / useradmin / LdifUserAdmin.java
index c32bbc53fa9236f3f81211dfb8d6730a63ba746d..0a925e4eb41b3612f531f3ace8534a198065d72d 100644 (file)
@@ -1,7 +1,7 @@
 package org.argeo.osgi.useradmin;
 
-import static org.argeo.naming.LdapAttrs.objectClass;
-import static org.argeo.naming.LdapObjs.inetOrgPerson;
+import static org.argeo.util.naming.LdapAttrs.objectClass;
+import static org.argeo.util.naming.LdapObjs.inetOrgPerson;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -16,6 +16,7 @@ import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
@@ -25,16 +26,20 @@ import javax.naming.NamingEnumeration;
 import javax.naming.directory.Attributes;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.naming.LdifParser;
-import org.argeo.naming.LdifWriter;
+import org.argeo.util.naming.LdapObjs;
+import org.argeo.util.naming.LdifParser;
+import org.argeo.util.naming.LdifWriter;
 import org.osgi.framework.Filter;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
 
 /** A user admin based on a LDIF files. */
 public class LdifUserAdmin extends AbstractUserDirectory {
-       private SortedMap<LdapName, DirectoryUser> users = new TreeMap<LdapName, DirectoryUser>();
-       private SortedMap<LdapName, DirectoryGroup> groups = new TreeMap<LdapName, DirectoryGroup>();
+       private SortedMap<LdapName, DirectoryUser> users = new TreeMap<>();
+       private SortedMap<LdapName, DirectoryGroup> groups = new TreeMap<>();
+
+       private SortedMap<LdapName, LdifHierarchyUnit> hierarchy = new TreeMap<>();
+       private List<HierarchyUnit> rootHierarchyUnits = new ArrayList<>();
 
        public LdifUserAdmin(String uri, String baseDn) {
                this(fromUri(uri, baseDn), false);
@@ -113,6 +118,8 @@ public class LdifUserAdmin extends AbstractUserDirectory {
        public void save(OutputStream out) throws IOException {
                try {
                        LdifWriter ldifWriter = new LdifWriter(out);
+                       for (LdapName name : hierarchy.keySet())
+                               ldifWriter.writeEntry(name, hierarchy.get(name).getAttributes());
                        for (LdapName name : groups.keySet())
                                ldifWriter.writeEntry(name, groups.get(name).getAttributes());
                        for (LdapName name : users.keySet())
@@ -126,6 +133,7 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                try {
                        users.clear();
                        groups.clear();
+                       hierarchy.clear();
 
                        LdifParser ldifParser = new LdifParser();
                        SortedMap<LdapName, Attributes> allEntries = ldifParser.read(in);
@@ -148,14 +156,39 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                                        String objectClass = objectClasses.next().toString();
                                        // System.out.println(" " + objectClass);
                                        if (objectClass.toLowerCase().equals(inetOrgPerson.name().toLowerCase())) {
-                                               users.put(key, new LdifUser(this, key, attributes));
+                                               users.put(key, newUser(key, attributes));
                                                break objectClasses;
                                        } else if (objectClass.toLowerCase().equals(getGroupObjectClass().toLowerCase())) {
-                                               groups.put(key, new LdifGroup(this, key, attributes));
+                                               groups.put(key, newGroup(key, attributes));
+                                               break objectClasses;
+//                                     } else if (objectClass.equalsIgnoreCase(LdapObjs.organization.name())) {
+//                                             // we only consider organizations which are not groups
+//                                             hierarchy.put(key, new LdifHierarchyUnit(this, key, HierarchyUnit.ORGANIZATION, attributes));
+//                                             break objectClasses;
+                                       } else if (objectClass.equalsIgnoreCase(LdapObjs.organizationalUnit.name())) {
+//                                             String name = key.getRdn(key.size() - 1).toString();
+//                                             if (getUserBase().equalsIgnoreCase(name) || getGroupBase().equalsIgnoreCase(name))
+//                                                     break objectClasses; // skip
+                                               // TODO skip if it does not contain groups or users
+                                               hierarchy.put(key, new LdifHierarchyUnit(this, key, attributes));
                                                break objectClasses;
                                        }
                                }
                        }
+
+                       // link hierarchy
+                       hierachyUnits: for (LdapName dn : hierarchy.keySet()) {
+                               LdifHierarchyUnit unit = hierarchy.get(dn);
+                               LdapName parentDn = (LdapName) dn.getPrefix(dn.size() - 1);
+                               LdifHierarchyUnit parent = hierarchy.get(parentDn);
+                               if (parent == null) {
+                                       rootHierarchyUnits.add(unit);
+                                       unit.parent = null;
+                                       continue hierachyUnits;
+                               }
+                               parent.children.add(unit);
+                               unit.parent = parent;
+                       }
                } catch (Exception e) {
                        throw new UserDirectoryException("Cannot load user admin service from LDIF", e);
                }
@@ -168,6 +201,10 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                groups = null;
        }
 
+       /*
+        * USER ADMIN
+        */
+
        @Override
        protected DirectoryUser daoGetRole(LdapName key) throws NameNotFoundException {
                if (groups.containsKey(key))
@@ -182,21 +219,35 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                return users.containsKey(dn) || groups.containsKey(dn);
        }
 
-       protected List<DirectoryUser> doGetRoles(Filter f) {
+       @Override
+       protected List<DirectoryUser> doGetRoles(LdapName searchBase, Filter f, boolean deep) {
+               Objects.requireNonNull(searchBase);
                ArrayList<DirectoryUser> res = new ArrayList<DirectoryUser>();
-               if (f == null) {
+               if (f == null && deep && getBaseDn().equals(searchBase)) {
                        res.addAll(users.values());
                        res.addAll(groups.values());
                } else {
-                       for (DirectoryUser user : users.values()) {
-                               if (f.match(user.getProperties()))
+                       filterRoles(users, searchBase, f, deep, res);
+                       filterRoles(groups, searchBase, f, deep, res);
+               }
+               return res;
+       }
+
+       private void filterRoles(SortedMap<LdapName, ? extends DirectoryUser> map, LdapName searchBase, Filter f,
+                       boolean deep, List<DirectoryUser> res) {
+               // TODO reduce map with search base ?
+               roles: for (DirectoryUser user : map.values()) {
+                       LdapName dn = user.getDn();
+                       if (dn.startsWith(searchBase)) {
+                               if (!deep && dn.size() != (searchBase.size() + 1))
+                                       continue roles;
+                               if (f == null)
+                                       res.add(user);
+                               else if (f.match(user.getProperties()))
                                        res.add(user);
                        }
-                       for (DirectoryUser group : groups.values())
-                               if (f.match(group.getProperties()))
-                                       res.add(group);
                }
-               return res;
+
        }
 
        @Override
@@ -257,4 +308,49 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                init();
        }
 
+       /*
+        * HIERARCHY
+        */
+
+//     @Override
+//     public int getHierarchyChildCount() {
+//             return rootHierarchyUnits.size();
+//     }
+//
+//     @Override
+//     public HierarchyUnit getHierarchyChild(int i) {
+//             return rootHierarchyUnits.get(i);
+//     }
+
+       @Override
+       public HierarchyUnit getHierarchyUnit(String path) {
+               LdapName dn = pathToName(path);
+               return hierarchy.get(dn);
+       }
+
+       @Override
+       public Iterable<HierarchyUnit> getDirectHierarchyUnits(boolean functionalOnly) {
+               if (functionalOnly) {
+                       List<HierarchyUnit> res = new ArrayList<>();
+                       for (HierarchyUnit hu : rootHierarchyUnits) {
+                               if (hu.isFunctional())
+                                       res.add(hu);
+                       }
+                       return res;
+
+               } else {
+                       return rootHierarchyUnits;
+               }
+       }
+
+       @Override
+       public HierarchyUnit getHierarchyUnit(Role role) {
+               LdapName dn = LdapNameUtils.toLdapName(role.getName());
+               LdapName huDn = LdapNameUtils.getParent(dn);
+               HierarchyUnit hierarchyUnit = hierarchy.get(huDn);
+               if (hierarchyUnit == null)
+                       throw new IllegalStateException("No hierarchy unit found for " + role);
+               return hierarchyUnit;
+       }
+
 }