Add Authorization, with chained groups
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 24 Aug 2015 19:23:42 +0000 (19:23 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 24 Aug 2015 19:23:42 +0000 (19:23 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@8337 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.security.core/ext/test/org/argeo/osgi/useradmin/BasicTestConstants.java
org.argeo.security.core/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java
org.argeo.security.core/ext/test/org/argeo/osgi/useradmin/basic.ldif
org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifAuthorization.java [new file with mode: 0644]
org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifGroup.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUser.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java

index f608cce8625dbd8309b0365867f41e5b2814c821..56c9b92cd7a23291c0689982b987ed9bcea6e8ad 100644 (file)
@@ -2,5 +2,7 @@ package org.argeo.osgi.useradmin;
 
 interface BasicTestConstants {
        final static String ROOT_USER_DN = "uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org";
+       final static String DEMO_USER_DN = "uid=demo,ou=People,dc=demo,dc=example,dc=org";
        final static String ADMIN_GROUP_DN = "cn=admin,ou=Roles,dc=demo,dc=example,dc=org";
+       final static String EDITOR_GROUP_DN = "cn=editor,ou=Roles,dc=demo,dc=example,dc=org";
 }
index 75a58d0d3450aae234c13784f0d5a4aa50cda7c8..c2d5b31f0d7b260f13e14c43e030392a0183fa98 100644 (file)
@@ -1,7 +1,11 @@
 package org.argeo.osgi.useradmin;
 
+import java.util.Arrays;
+import java.util.List;
+
 import junit.framework.TestCase;
 
+import org.osgi.service.useradmin.Authorization;
 import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
@@ -13,10 +17,27 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants {
                                .getResourceAsStream("basic.ldif"));
                User rootUser = (User) userAdmin.getRole(ROOT_USER_DN);
                assertNotNull(rootUser);
+               User demoUser = (User) userAdmin.getRole(DEMO_USER_DN);
+               assertNotNull(demoUser);
+
                Group adminGroup = (Group) userAdmin.getRole(ADMIN_GROUP_DN);
                assertNotNull(adminGroup);
                Role[] members = adminGroup.getMembers();
                assertEquals(1, members.length);
-               assertEquals(rootUser.getName(), members[0].getName());
+               assertEquals(rootUser, members[0]);
+
+               Group editorGroup = (Group) userAdmin.getRole(EDITOR_GROUP_DN);
+               assertNotNull(editorGroup);
+               members = editorGroup.getMembers();
+               assertEquals(2, members.length);
+               assertEquals(adminGroup, members[0]);
+               assertEquals(demoUser, members[1]);
+
+               Authorization rootAuth = userAdmin.getAuthorization(rootUser);
+               List<String> rootRoles = Arrays.asList(rootAuth.getRoles());
+               assertEquals(3, rootRoles.size());
+               assertTrue(rootRoles.contains(ROOT_USER_DN));
+               assertTrue(rootRoles.contains(ADMIN_GROUP_DN));
+               assertTrue(rootRoles.contains(EDITOR_GROUP_DN));
        }
 }
index 380311f4d83aad2508d33b9213c8404f9e68dbe6..56c7499b29c7dfd9a2397c95912149fb969bd44e 100644 (file)
@@ -44,4 +44,12 @@ dn: cn=admin,ou=Roles,dc=demo,dc=example,dc=org
 objectClass: groupOfNames
 objectClass: top
 cn: admin
-member: uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org
\ No newline at end of file
+member: uid=root+cn=Super Admin,ou=People,dc=demo,dc=example,dc=org
+
+dn: cn=editor,ou=Roles,dc=demo,dc=example,dc=org
+objectClass: groupOfNames
+objectClass: top
+cn: admin
+member: cn=admin,ou=Roles,dc=demo,dc=example,dc=org
+member: uid=demo,ou=People,dc=demo,dc=example,dc=org
+
diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifAuthorization.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifAuthorization.java
new file mode 100644 (file)
index 0000000..4ae2434
--- /dev/null
@@ -0,0 +1,54 @@
+package org.argeo.osgi.useradmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Role;
+
+public class LdifAuthorization implements Authorization {
+       private final LdifUser user;
+
+       public LdifAuthorization(LdifUser user) {
+               this.user = user;
+       }
+
+       @Override
+       public String getName() {
+               return user.getName();
+       }
+
+       @Override
+       public boolean hasRole(String name) {
+               for (Role role : getAllRoles()) {
+                       if (role.getName().equals(name))
+                               return true;
+               }
+               return false;
+       }
+
+       @Override
+       public String[] getRoles() {
+               List<Role> allRoles = getAllRoles();
+               String[] res = new String[allRoles.size() + 1];
+               res[0] = user.getName();
+               for (int i = 0; i < allRoles.size(); i++)
+                       res[i + 1] = allRoles.get(i).getName();
+               return res;
+       }
+
+       List<Role> getAllRoles() {
+               List<Role> allRoles = new ArrayList<Role>();
+               collectRoles(user, allRoles);
+               return allRoles;
+       }
+
+       private void collectRoles(LdifUser user, List<Role> allRoles) {
+               for (LdifGroup group : user.directMemberOf) {
+                       // TODO check for loops
+                       allRoles.add(group);
+                       collectRoles(group, allRoles);
+               }
+       }
+
+}
index c2c666700710c994aa6af93c080c066854ba2cca..845094820c84e897df2844ce31e83ed8e20d7eac 100644 (file)
@@ -12,6 +12,8 @@ import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
 
 public class LdifGroup extends LdifUser implements Group {
+       // optimisation
+       List<Role> directMembers = null;
 
        public LdifGroup(LdapName dn, Attributes attributes) {
                super(dn, attributes);
@@ -34,17 +36,55 @@ public class LdifGroup extends LdifUser implements Group {
 
        @Override
        public Role[] getMembers() {
+               if (directMembers != null)
+                       return directMembers.toArray(new Role[directMembers.size()]);
+               else
+                       throw new ArgeoUserAdminException("Members have not been loaded.");
+
+               // Attribute memberAttribute = getAttributes().get("member");
+               // if (memberAttribute == null)
+               // return new Role[0];
+               // try {
+               // List<Role> roles = new ArrayList<Role>();
+               // NamingEnumeration values = memberAttribute.getAll();
+               // while (values.hasMore()) {
+               // LdapName dn = new LdapName(values.next().toString());
+               // roles.add(new LdifUser(dn, null));
+               // }
+               // return roles.toArray(new Role[roles.size()]);
+               // } catch (Exception e) {
+               // throw new ArgeoUserAdminException("Cannot get members", e);
+               // }
+       }
+
+       void loadMembers(LdifUserAdmin userAdmin) {
+               directMembers = new ArrayList<Role>();
+               for (LdapName ldapName : getMemberNames()) {
+                       LdifUser role;
+                       if (userAdmin.groups.containsKey(ldapName))
+                               role = userAdmin.groups.get(ldapName);
+                       else if (userAdmin.users.containsKey(ldapName))
+                               role = userAdmin.users.get(ldapName);
+                       else
+                               throw new ArgeoUserAdminException("No roel found for "
+                                               + ldapName);
+                       role.directMemberOf.add(this);
+                       directMembers.add(role);
+               }
+       }
+
+       List<LdapName> getMemberNames() {
                Attribute memberAttribute = getAttributes().get("member");
                if (memberAttribute == null)
-                       return new Role[0];
+                       return new ArrayList<LdapName>();
                try {
-                       List<Role> roles = new ArrayList<Role>();
+                       List<LdapName> roles = new ArrayList<LdapName>();
                        NamingEnumeration values = memberAttribute.getAll();
                        while (values.hasMore()) {
                                LdapName dn = new LdapName(values.next().toString());
-                               roles.add(new LdifUser(dn, null));
+                               roles.add(dn);
                        }
-                       return roles.toArray(new Role[roles.size()]);
+                       return roles;
                } catch (Exception e) {
                        throw new ArgeoUserAdminException("Cannot get members", e);
                }
@@ -59,5 +99,4 @@ public class LdifGroup extends LdifUser implements Group {
        public int getType() {
                return GROUP;
        }
-
 }
index 1de18c5b42be9a9468e64e7c2784751e094b7377..379ac23ab2ca6349203655b318b4166efc8e620d 100644 (file)
@@ -1,17 +1,20 @@
 package org.argeo.osgi.useradmin;
 
+import java.util.ArrayList;
 import java.util.Dictionary;
-import java.util.Hashtable;
+import java.util.List;
 
 import javax.naming.directory.Attributes;
 import javax.naming.ldap.LdapName;
 
 import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdmin;
 
 class LdifUser implements User {
+       // optimisation
+       List<LdifGroup> directMemberOf = new ArrayList<LdifGroup>();
+
        private final LdapName dn;
-       private final Attributes attributes;
+       private Attributes attributes;
 
        LdifUser(LdapName dn, Attributes attributes) {
                this.dn = dn;
@@ -56,4 +59,25 @@ class LdifUser implements User {
                return attributes;
        }
 
+       @Override
+       public int hashCode() {
+               return dn.hashCode();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj instanceof LdifUser) {
+                       LdifUser that = (LdifUser) obj;
+                       return this.dn.equals(that.dn);
+               }
+               return false;
+       }
+
+       @Override
+       public String toString() {
+               return dn.toString();
+       }
+
 }
index 5796b46c4e0e19cb7c22b94c3dc5e7362289affd..440e93d9d1f3fc9fcb3b28049ec69609a795376a 100644 (file)
@@ -16,7 +16,8 @@ import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
 
 public class LdifUserAdmin implements UserAdmin {
-       private SortedMap<LdapName, Role> roles = new TreeMap<LdapName, Role>();
+       SortedMap<LdapName, LdifUser> users = new TreeMap<LdapName, LdifUser>();
+       SortedMap<LdapName, LdifGroup> groups = new TreeMap<LdapName, LdifGroup>();
 
        public LdifUserAdmin(InputStream in) {
                try {
@@ -29,14 +30,19 @@ public class LdifUserAdmin implements UserAdmin {
                                objectClasses: while (objectClasses.hasMore()) {
                                        String objectClass = objectClasses.next().toString();
                                        if (objectClass.equals("inetOrgPerson")) {
-                                               roles.put(key, new LdifUser(key, attributes));
+                                               users.put(key, new LdifUser(key, attributes));
                                                break objectClasses;
                                        } else if (objectClass.equals("groupOfNames")) {
-                                               roles.put(key, new LdifGroup(key, attributes));
+                                               groups.put(key, new LdifGroup(key, attributes));
                                                break objectClasses;
                                        }
                                }
                        }
+
+                       // optimise
+                       for (LdifGroup group : groups.values()) {
+                               group.loadMembers(this);
+                       }
                } catch (Exception e) {
                        throw new ArgeoUserAdminException(
                                        "Cannot initialise user admin service from LDIF", e);
@@ -54,15 +60,16 @@ public class LdifUserAdmin implements UserAdmin {
                                        + name, e);
                }
 
-               if (!roles.containsKey(key))
-                       return null;
-               return roles.get(key);
+               if (groups.containsKey(key))
+                       return groups.get(key);
+               if (users.containsKey(key))
+                       return users.get(key);
+               return null;
        }
 
        @Override
        public Authorization getAuthorization(User user) {
-               // TODO Auto-generated method stub
-               return null;
+               return new LdifAuthorization((LdifUser) user);
        }
 
        @Override