Lazy loading of attributes
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 29 Jun 2022 07:50:12 +0000 (09:50 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 29 Jun 2022 07:50:12 +0000 (09:50 +0200)
org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java
org.argeo.util/src/org/argeo/osgi/useradmin/DirectoryUserAdmin.java
org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java
org.argeo.util/src/org/argeo/osgi/useradmin/OsUserDirectory.java
org.argeo.util/src/org/argeo/util/directory/ldap/DefaultLdapEntry.java
org.argeo.util/src/org/argeo/util/directory/ldap/LdapConnection.java
org.argeo.util/src/org/argeo/util/directory/ldap/LdapDao.java
org.argeo.util/src/org/argeo/util/directory/ldap/LdapDirectoryDao.java
org.argeo.util/src/org/argeo/util/directory/ldap/LdifDao.java

index f6832ad35af4cfc86bad5c3ab6c9ad5ec3880fd5..0cf5b68391003ed5d5420755186234c6ee88c65b 100644 (file)
@@ -26,7 +26,6 @@ import javax.security.auth.spi.LoginModule;
 
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.internal.osgi.NodeUserAdmin;
 import org.argeo.cms.internal.runtime.CmsContextImpl;
 import org.argeo.cms.security.CryptoKeyring;
 import org.argeo.osgi.useradmin.AuthenticatingUser;
@@ -237,6 +236,8 @@ public class UserAdminLoginModule implements LoginModule {
                                        throw new LoginException("Kerberos login " + authenticatingUser.getName()
                                                        + " is inconsistent with user admin login " + authenticatedUser.getName());
                        }
+                       if (log.isTraceEnabled())
+                               log.trace("Retrieve authorization for " + authenticatingUser + "... ");
                        authorization = Subject.doAs(subject, new PrivilegedAction<Authorization>() {
 
                                @Override
index ac076167e02bb2983a266db60716eb942b5b467d..e6e3f983b1a8a9a16e4db38d9a618efb2789737e 100644 (file)
@@ -23,7 +23,6 @@ import javax.naming.directory.BasicAttributes;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 import javax.security.auth.Subject;
-import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.kerberos.KerberosTicket;
 
 import org.argeo.util.CurrentSubject;
index 11de4ed5697c511eacbfb0db76cf39c36c28bbfe..a40de1c8360139d98625e936f68b4a88c99decbb 100644 (file)
@@ -1,7 +1,5 @@
 package org.argeo.osgi.useradmin;
 
-import java.util.Dictionary;
-
 import javax.naming.directory.Attributes;
 import javax.naming.ldap.LdapName;
 
@@ -24,8 +22,4 @@ class LdifUser extends DefaultLdapEntry implements DirectoryUser {
                return USER;
        }
 
-       @Override
-       public Dictionary<String, Object> getCredentials() {
-               return credentials;
-       }
 }
index c052fee1b1da12bc4193a208c4d21123fc4d0e21..466563a4d1a17bdad5a0ef2651bd944cae05b7dc 100644 (file)
@@ -95,5 +95,13 @@ public class OsUserDirectory extends AbstractLdapDirectoryDao {
                
        }
 
+       @Override
+       public Attributes doGetAttributes(LdapName name) {
+               try {
+                       return doGetEntry(name).getAttributes();
+               } catch (NameNotFoundException e) {
+                       throw new IllegalStateException(name + " doe not exist in " + getDirectory().getBaseDn(), e);
+               }
+       }
        
 }
index 4212c5f5576fa1cfec836695ac7f03bf9dcd5140..8db662393e5ee1fb702664465a2692616ef17e68 100644 (file)
@@ -35,8 +35,8 @@ public class DefaultLdapEntry implements LdapEntry {
        private Attributes publishedAttributes;
 
        // Temporarily expose the fields
-       protected final AttributeDictionary properties;
-       protected final AttributeDictionary credentials;
+       protected AttributeDictionary properties;
+       protected AttributeDictionary credentials;
 
        protected DefaultLdapEntry(AbstractLdapDirectory directory, LdapName dn, Attributes attributes) {
                Objects.requireNonNull(directory);
@@ -44,8 +44,8 @@ public class DefaultLdapEntry implements LdapEntry {
                this.directory = directory;
                this.dn = dn;
                this.publishedAttributes = attributes;
-               properties = new AttributeDictionary(false);
-               credentials = new AttributeDictionary(true);
+//             properties = new AttributeDictionary(false);
+//             credentials = new AttributeDictionary(true);
        }
 
        @Override
@@ -54,6 +54,9 @@ public class DefaultLdapEntry implements LdapEntry {
        }
 
        public synchronized Attributes getAttributes() {
+               // lazy loading
+               if (publishedAttributes == null)
+                       publishedAttributes = getDirectory().getDirectoryDao().doGetAttributes(dn);
                return isEditing() ? getModifiedAttributes() : publishedAttributes;
        }
 
@@ -103,15 +106,23 @@ public class DefaultLdapEntry implements LdapEntry {
        public synchronized void publishAttributes(Attributes modifiedAttributes) {
                publishedAttributes = modifiedAttributes;
        }
-       
+
        /*
         * PROPERTIES
         */
        @Override
        public Dictionary<String, Object> getProperties() {
+               if (properties == null)
+                       properties = new AttributeDictionary(false);
                return properties;
        }
 
+       public Dictionary<String, Object> getCredentials() {
+               if (credentials == null)
+                       credentials = new AttributeDictionary(false);
+               return credentials;
+       }
+
        /*
         * CREDENTIALS
         */
index f7838381d3884a872661ea8b61b408042da63bef..748efe35087867c086aae4d7706b0d216aaf5b5c 100644 (file)
@@ -99,6 +99,20 @@ public class LdapConnection {
                }
        }
 
+       public synchronized boolean entryExists(LdapName name) throws NamingException {
+               String[] noAttrOID = new String[] { "1.1" };
+               try {
+                       getLdapContext().getAttributes(name, noAttrOID);
+                       return true;
+               } catch (CommunicationException e) {
+                       reconnect();
+                       getLdapContext().getAttributes(name, noAttrOID);
+                       return true;
+               } catch (NameNotFoundException e) {
+                       return false;
+               }
+       }
+
        public synchronized void prepareChanges(WorkingCopy<?, ?, LdapName> wc) throws NamingException {
                // make sure connection will work
                reconnect();
@@ -121,13 +135,13 @@ public class LdapConnection {
 
        }
 
-       protected boolean entryExists(LdapName dn) throws NamingException {
-               try {
-                       return getAttributes(dn).size() != 0;
-               } catch (NameNotFoundException e) {
-                       return false;
-               }
-       }
+//     protected boolean entryExists(LdapName dn) throws NamingException {
+//             try {
+//                     return getAttributes(dn).size() != 0;
+//             } catch (NameNotFoundException e) {
+//                     return false;
+//             }
+//     }
 
        public synchronized void commitChanges(LdapEntryWorkingCopy wc) throws NamingException {
                // delete
index c33b50f65fb9a1a781bb62de4535b63b25198c63..e15c005bef38771bedd3a84d7692d8c4e336113c 100644 (file)
@@ -68,29 +68,34 @@ public class LdapDao extends AbstractLdapDirectoryDao {
        @Override
        public Boolean entryExists(LdapName dn) {
                try {
-                       return doGetEntry(dn) != null;
+                       return ldapConnection.entryExists(dn);
                } catch (NameNotFoundException e) {
                        return false;
+               } catch (NamingException e) {
+                       throw new IllegalStateException("Cannot check " + dn, e);
                }
        }
 
        @Override
        public LdapEntry doGetEntry(LdapName name) throws NameNotFoundException {
-               try {
-                       Attributes attrs = ldapConnection.getAttributes(name);
-                       if (attrs.size() == 0)
-                               return null;
+               if (!entryExists(name))
+                       throw new NameNotFoundException(name + " was not found in " + getDirectory().getBaseDn());
+//             try {
+//                     Attributes attrs = ldapConnection.getAttributes(name);
+//                     if (attrs.size() == 0)
+//                             return null;
+
 //                     int roleType = roleType(name);
                        LdapEntry res;
                        Rdn technicalRdn = LdapNameUtils.getParentRdn(name);
                        if (getDirectory().getGroupBaseRdn().equals(technicalRdn))
-                               res = newGroup(name, attrs);
+                               res = newGroup(name, null);
                        else if (getDirectory().getSystemRoleBaseRdn().equals(technicalRdn))
-                               res = newGroup(name, attrs);
+                               res = newGroup(name, null);
                        else if (getDirectory().getUserBaseRdn().equals(technicalRdn))
-                               res = newUser(name, attrs);
+                               res = newUser(name, null);
                        else
-                               res = new DefaultLdapEntry(getDirectory(), name, attrs);
+                               res = new DefaultLdapEntry(getDirectory(), name, null);
 //                     if (isGroup(name))
 //                             res = newGroup(name, attrs);
 //                     else
@@ -98,11 +103,9 @@ public class LdapDao extends AbstractLdapDirectoryDao {
 //                     else
 //                             throw new IllegalArgumentException("Unsupported LDAP type for " + name);
                        return res;
-               } catch (NameNotFoundException e) {
-                       throw e;
-               } catch (NamingException e) {
-                       return null;
-               }
+//             } catch (NameNotFoundException e) {
+//                     throw e;
+//             }
        }
 
 //     protected boolean isGroup(LdapName dn) {
@@ -117,6 +120,16 @@ public class LdapDao extends AbstractLdapDirectoryDao {
 //                                     "Cannot find role type, " + technicalRdn + " is not a technical RDN for " + dn);
 //     }
 
+       @Override
+       public Attributes doGetAttributes(LdapName name) {
+               try {
+                       Attributes attrs = ldapConnection.getAttributes(name);
+                       return attrs;
+               } catch (NamingException e) {
+                       throw new IllegalStateException("Cannot get attributes for " + name);
+               }
+       }
+
        @Override
        public List<LdapEntry> doGetEntries(LdapName searchBase, String f, boolean deep) {
                ArrayList<LdapEntry> res = new ArrayList<>();
index 2739932767419d1d5825d658209cbe4e1be0ceda..81a86fd05f48a8412422e81755d8859725d7c058 100644 (file)
@@ -14,6 +14,8 @@ public interface LdapDirectoryDao extends WorkingCopyProcessor<LdapEntryWorkingC
 
        LdapEntry doGetEntry(LdapName name) throws NameNotFoundException;
 
+       Attributes doGetAttributes(LdapName name);
+
        List<LdapEntry> doGetEntries(LdapName searchBase, String filter, boolean deep);
 
        List<LdapName> getDirectGroups(LdapName dn);
index 740a4762468405e762bba24ad8b61e3b01a1d4ef..7387d9e0f9cd52f735ec94625fa296380431d259 100644 (file)
@@ -12,9 +12,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Dictionary;
 import java.util.HashSet;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.NavigableMap;
 import java.util.Objects;
@@ -28,7 +26,6 @@ import javax.naming.NamingException;
 import javax.naming.directory.Attributes;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.util.directory.DirectoryConf;
 import org.argeo.util.directory.HierarchyUnit;
 import org.argeo.util.naming.LdapObjs;
 import org.osgi.framework.Filter;
@@ -86,12 +83,12 @@ public class LdifDao extends AbstractLdapDirectoryDao {
 //             return scopedUserAdmin;
 //     }
 
-       private static Dictionary<String, Object> fromUri(String uri, String baseDn) {
-               Hashtable<String, Object> res = new Hashtable<String, Object>();
-               res.put(DirectoryConf.uri.name(), uri);
-               res.put(DirectoryConf.baseDn.name(), baseDn);
-               return res;
-       }
+//     private static Dictionary<String, Object> fromUri(String uri, String baseDn) {
+//             Hashtable<String, Object> res = new Hashtable<String, Object>();
+//             res.put(DirectoryConf.uri.name(), uri);
+//             res.put(DirectoryConf.baseDn.name(), baseDn);
+//             return res;
+//     }
 
        public void init() {
 
@@ -227,6 +224,15 @@ public class LdifDao extends AbstractLdapDirectoryDao {
                throw new NameNotFoundException(key + " not persisted");
        }
 
+       @Override
+       public Attributes doGetAttributes(LdapName name) {
+               try {
+                       return doGetEntry(name).getAttributes();
+               } catch (NameNotFoundException e) {
+                       throw new IllegalStateException(name + " doe not exist in " + getDirectory().getBaseDn(), e);
+               }
+       }
+
        @Override
        public Boolean entryExists(LdapName dn) {
                return entries.containsKey(dn);// || groups.containsKey(dn);