Remove dependency to OSGi user admin from API
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / runtime / CmsUserManagerImpl.java
index 6c6001563ba198c6239a8f856451b9bb0ec25c99..64d3fab2583e8ffb7259133f894f00044f23ccb0 100644 (file)
@@ -1,8 +1,8 @@
 package org.argeo.cms.internal.runtime;
 
-import static org.argeo.api.acr.ldap.LdapAttrs.cn;
-import static org.argeo.api.acr.ldap.LdapAttrs.description;
-import static org.argeo.api.acr.ldap.LdapAttrs.owner;
+import static org.argeo.api.acr.ldap.LdapAttr.cn;
+import static org.argeo.api.acr.ldap.LdapAttr.description;
+import static org.argeo.api.acr.ldap.LdapAttr.owner;
 
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
@@ -26,17 +26,18 @@ import javax.security.auth.Subject;
 import javax.xml.namespace.QName;
 
 import org.argeo.api.acr.NamespaceUtils;
-import org.argeo.api.acr.ldap.LdapAttrs;
+import org.argeo.api.acr.ldap.LdapAttr;
 import org.argeo.api.acr.ldap.NamingUtils;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.directory.CmsGroup;
+import org.argeo.api.cms.directory.CmsRole;
 import org.argeo.api.cms.directory.CmsUser;
 import org.argeo.api.cms.directory.CmsUserManager;
 import org.argeo.api.cms.directory.HierarchyUnit;
 import org.argeo.api.cms.directory.UserDirectory;
 import org.argeo.api.cms.transaction.WorkTransaction;
-import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.CurrentUser;
 import org.argeo.cms.auth.UserAdminUtils;
 import org.argeo.cms.directory.ldap.LdapEntry;
 import org.argeo.cms.directory.ldap.SharedSecret;
@@ -69,8 +70,8 @@ public class CmsUserManagerImpl implements CmsUserManager {
 //     private Map<String, String> serviceProperties;
        private WorkTransaction userTransaction;
 
-       private final String[] knownProps = { LdapAttrs.cn.name(), LdapAttrs.sn.name(), LdapAttrs.givenName.name(),
-                       LdapAttrs.uid.name() };
+       private final String[] knownProps = { LdapAttr.cn.name(), LdapAttr.sn.name(), LdapAttr.givenName.name(),
+                       LdapAttr.uid.name() };
 
 //     private Map<UserDirectory, Hashtable<String, Object>> userDirectories = Collections
 //                     .synchronizedMap(new LinkedHashMap<>());
@@ -85,15 +86,19 @@ public class CmsUserManagerImpl implements CmsUserManager {
 
        }
 
-       @Override
-       public String getMyMail() {
-               return getUserMail(CurrentUser.getUsername());
-       }
+//     @Override
+//     public String getMyMail() {
+//             return getUserMail(CurrentUser.getUsername());
+//     }
 
        @Override
-       public Role[] getRoles(String filter) {
+       public CmsRole[] getRoles(String filter) {
                try {
-                       return userAdmin.getRoles(filter);
+                       Role[] roles = userAdmin.getRoles(filter);
+                       CmsRole[] res = new CmsRole[roles.length];
+                       for (int i = 0; i < roles.length; i++)
+                               res[i] = (CmsRole) roles[i];
+                       return res;
                } catch (InvalidSyntaxException e) {
                        throw new IllegalArgumentException("Invalid filter " + filter, e);
                }
@@ -124,7 +129,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
        /** Lists all roles of the given user */
        @Override
        public String[] getUserRoles(String dn) {
-               Authorization currAuth = getUserAdmin().getAuthorization(getUser(dn));
+               Authorization currAuth = getUserAdmin().getAuthorization((User) getUser(dn));
                return currAuth.getRoles();
        }
 
@@ -147,28 +152,12 @@ public class CmsUserManagerImpl implements CmsUserManager {
                return users;
        }
 
-//     @Override
-//     public Set<User> listAccounts(HierarchyUnit hierarchyUnit, boolean deep) {
-//             if(!hierarchyUnit.isFunctional())
-//                     throw new IllegalArgumentException("Hierarchy unit "+hierarchyUnit.getBase()+" is not functional");
-//             UserDirectory directory = (UserDirectory)hierarchyUnit.getDirectory();
-//             Set<User> res = new HashSet<>();
-//             for(HierarchyUnit technicalHu:hierarchyUnit.getDirectHierarchyUnits(false)) {
-//                     if(technicalHu.isFunctional())
-//                             continue;
-//                     for(Role role:directory.getHierarchyUnitRoles(technicalHu, null, false)) {
-//                             if(role)
-//                     }
-//             }
-//             return res;
-//     }
-
        /** Recursively add users to list */
        private void addUsers(Set<CmsUser> users, Group group, String filter) {
-               Role[] roles = group.getMembers();
+               Role[] roles = ((Group) group).getMembers();
                for (Role role : roles) {
                        if (role.getType() == Role.GROUP) {
-                               addUsers(users, (CmsGroup) role, filter);
+                               addUsers(users, (Group) role, filter);
                        } else if (role.getType() == Role.USER) {
                                if (match(role, filter))
                                        users.add((CmsUser) role);
@@ -222,9 +211,9 @@ public class CmsUserManagerImpl implements CmsUserManager {
 
        @Override
        public CmsUser getUserFromLocalId(String localId) {
-               CmsUser user = (CmsUser) getUserAdmin().getUser(LdapAttrs.uid.name(), localId);
+               CmsUser user = (CmsUser) getUserAdmin().getUser(LdapAttr.uid.name(), localId);
                if (user == null)
-                       user = (CmsUser) getUserAdmin().getUser(LdapAttrs.cn.name(), localId);
+                       user = (CmsUser) getUserAdmin().getUser(LdapAttr.cn.name(), localId);
                return user;
        }
 
@@ -240,7 +229,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
        public CmsUser createUser(String username, Map<String, Object> properties, Map<String, Object> credentials) {
                try {
                        userTransaction.begin();
-                       CmsUser user = (CmsUser) userAdmin.createRole(username, Role.USER);
+                       User user = (User) userAdmin.createRole(username, Role.USER);
                        if (properties != null) {
                                for (String key : properties.keySet())
                                        user.getProperties().put(key, properties.get(key));
@@ -250,7 +239,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
                                        user.getCredentials().put(key, credentials.get(key));
                        }
                        userTransaction.commit();
-                       return user;
+                       return (CmsUser) user;
                } catch (Exception e) {
                        try {
                                userTransaction.rollback();
@@ -264,13 +253,33 @@ public class CmsUserManagerImpl implements CmsUserManager {
                }
        }
 
+       @Override
+       public CmsGroup createGroup(String dn) {
+               try {
+                       userTransaction.begin();
+                       CmsGroup group = (CmsGroup) userAdmin.createRole(dn, Role.GROUP);
+                       userTransaction.commit();
+                       return group;
+               } catch (Exception e) {
+                       try {
+                               userTransaction.rollback();
+                       } catch (Exception e1) {
+                               log.error("Could not roll back", e1);
+                       }
+                       if (e instanceof RuntimeException)
+                               throw (RuntimeException) e;
+                       else
+                               throw new RuntimeException("Cannot create group " + dn, e);
+               }
+       }
+
        @Override
        public CmsGroup getOrCreateGroup(HierarchyUnit groups, String commonName) {
+               String dn = LdapAttr.cn.name() + "=" + commonName + "," + groups.getBase();
+               CmsGroup group = (CmsGroup) getUserAdmin().getRole(dn);
+               if (group != null)
+                       return group;
                try {
-                       String dn = LdapAttrs.cn.name() + "=" + commonName + "," + groups.getBase();
-                       CmsGroup group = (CmsGroup) getUserAdmin().getRole(dn);
-                       if (group != null)
-                               return group;
                        userTransaction.begin();
                        group = (CmsGroup) userAdmin.createRole(dn, Role.GROUP);
                        userTransaction.commit();
@@ -290,11 +299,11 @@ public class CmsUserManagerImpl implements CmsUserManager {
 
        @Override
        public CmsGroup getOrCreateSystemRole(HierarchyUnit roles, QName systemRole) {
+               String dn = LdapAttr.cn.name() + "=" + NamespaceUtils.toPrefixedName(systemRole) + "," + roles.getBase();
+               CmsGroup group = (CmsGroup) getUserAdmin().getRole(dn);
+               if (group != null)
+                       return group;
                try {
-                       String dn = LdapAttrs.cn.name() + "=" + NamespaceUtils.toPrefixedName(systemRole) + "," + roles.getBase();
-                       CmsGroup group = (CmsGroup) getUserAdmin().getRole(dn);
-                       if (group != null)
-                               return group;
                        userTransaction.begin();
                        group = (CmsGroup) userAdmin.createRole(dn, Role.GROUP);
                        userTransaction.commit();
@@ -335,7 +344,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
        }
 
        @Override
-       public void addObjectClasses(Role role, Set<String> objectClasses, Map<String, Object> additionalProperties) {
+       public void addObjectClasses(CmsRole role, Set<String> objectClasses, Map<String, Object> additionalProperties) {
                try {
                        userTransaction.begin();
                        LdapEntry.addObjectClasses(role.getProperties(), objectClasses);
@@ -397,10 +406,28 @@ public class CmsUserManagerImpl implements CmsUserManager {
        }
 
        @Override
-       public void addMember(CmsGroup group, Role role) {
+       public void addMember(CmsGroup group, CmsRole role) {
+               try {
+                       userTransaction.begin();
+                       ((Group) group).addMember((Role) role);
+                       userTransaction.commit();
+               } catch (Exception e1) {
+                       try {
+                               if (!userTransaction.isNoTransactionStatus())
+                                       userTransaction.rollback();
+                       } catch (Exception e2) {
+                               if (log.isTraceEnabled())
+                                       log.trace("Cannot rollback transaction", e2);
+                       }
+                       throw new RuntimeException("Cannot add member " + role + " to group " + group, e1);
+               }
+       }
+
+       @Override
+       public void removeMember(CmsGroup group, CmsRole role) {
                try {
                        userTransaction.begin();
-                       group.addMember(role);
+                       ((Group) group).removeMember((Role) role);
                        userTransaction.commit();
                } catch (Exception e1) {
                        try {
@@ -410,7 +437,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
                                if (log.isTraceEnabled())
                                        log.trace("Cannot rollback transaction", e2);
                        }
-                       throw new RuntimeException("Cannot add object classes " + role + " to group " + group, e1);
+                       throw new RuntimeException("Cannot remove member " + role + " from group " + group, e1);
                }
        }
 
@@ -453,9 +480,9 @@ public class CmsUserManagerImpl implements CmsUserManager {
                Dictionary<String, ?> props = DirectoryConf.uriAsProperties(dns.get(baseDn));
                String dn = null;
                if (Role.GROUP == type)
-                       dn = LdapAttrs.cn.name() + "=" + localId + "," + DirectoryConf.groupBase.getValue(props) + "," + baseDn;
+                       dn = LdapAttr.cn.name() + "=" + localId + "," + DirectoryConf.groupBase.getValue(props) + "," + baseDn;
                else if (Role.USER == type)
-                       dn = LdapAttrs.uid.name() + "=" + localId + "," + DirectoryConf.userBase.getValue(props) + "," + baseDn;
+                       dn = LdapAttr.uid.name() + "=" + localId + "," + DirectoryConf.userBase.getValue(props) + "," + baseDn;
                else
                        throw new IllegalStateException("Unknown role type. " + "Cannot deduce dn for " + localId);
                return dn;
@@ -520,7 +547,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
        }
 
        public String addSharedSecret(String email, int hours) {
-               User user = (User) userAdmin.getUser(LdapAttrs.mail.name(), email);
+               User user = (User) userAdmin.getUser(LdapAttr.mail.name(), email);
                try {
                        userTransaction.begin();
                        String uuid = UUID.randomUUID().toString();
@@ -637,7 +664,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
        }
 
        @Override
-       public UserDirectory getDirectory(Role user) {
+       public UserDirectory getDirectory(CmsRole user) {
                String name = user.getName();
                NavigableMap<String, UserDirectory> possible = new TreeMap<>();
                for (UserDirectory userDirectory : userDirectories) {