Преглед изворни кода

SEC-449: Changed role searching to use parent spring ldap template search method.

Luke Taylor пре 18 година
родитељ
комит
223a597208
1 измењених фајлова са 47 додато и 53 уклоњено
  1. 47 53
      core/src/main/java/org/acegisecurity/ldap/SpringSecurityLdapTemplate.java

+ 47 - 53
core/src/main/java/org/acegisecurity/ldap/SpringSecurityLdapTemplate.java

@@ -25,19 +25,28 @@ import org.springframework.ldap.core.ContextSource;
 import org.springframework.ldap.core.DirContextAdapter;
 import org.springframework.ldap.core.ContextMapper;
 import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.AttributesMapperCallbackHandler;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 import java.util.HashSet;
 import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import java.text.MessageFormat;
 
 import javax.naming.NameNotFoundException;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.Context;
+import javax.naming.NameClassPair;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
+import javax.management.AttributeNotFoundException;
 
 
 /**
@@ -51,13 +60,12 @@ import javax.naming.directory.SearchResult;
  */
 public class SpringSecurityLdapTemplate extends org.springframework.ldap.core.LdapTemplate {
     //~ Static fields/initializers =====================================================================================
+    private static final Log logger = LogFactory.getLog(SpringSecurityLdapTemplate.class);
 
     public static final String[] NO_ATTRS = new String[0];
 
     //~ Instance fields ================================================================================================
 
-    private NamingExceptionTranslator exceptionTranslator = new LdapExceptionTranslator();
-
     /** Default search controls */
     private SearchControls searchControls = new SearchControls();
 
@@ -104,20 +112,6 @@ public class SpringSecurityLdapTemplate extends org.springframework.ldap.core.Ld
         return matches.booleanValue();
     }
 
-//    public Object execute(LdapCallback callback) throws DataAccessException {
-//        DirContext ctx = null;
-//
-//        try {
-//            ctx = dirContextFactory.getReadOnlyContext();
-//
-//            return callback.doInDirContext(ctx);
-//        } catch (NamingException exception) {
-//            throw exceptionTranslator.translate("LdapCallback", exception);
-//        } finally {
-//            LdapUtils.closeContext(ctx);
-//        }
-//    }
-
     public boolean nameExists(final String dn) {
         Boolean exists = (Boolean) executeReadOnly(new ContextExecutor() {
                 public Object executeWithContext(DirContext ctx) throws NamingException {
@@ -176,46 +170,54 @@ public class SpringSecurityLdapTemplate extends org.springframework.ldap.core.Ld
      */
     public Set searchForSingleAttributeValues(final String base, final String filter, final Object[] params,
         final String attributeName) {
-        class SingleAttributeSearchCallback implements ContextExecutor {
-            public Object executeWithContext(DirContext ctx)
-                throws NamingException {
-                Set unionOfValues = new HashSet();
 
-                // We're only interested in a single attribute for this method, so we make a copy of
-                // the search controls and override the returningAttributes property
-                SearchControls ctls = new SearchControls();
+        String formattedFilter = MessageFormat.format(filter, params);
 
-                ctls.setSearchScope(searchControls.getSearchScope());
-                ctls.setTimeLimit(searchControls.getTimeLimit());
-                ctls.setDerefLinkFlag(searchControls.getDerefLinkFlag());
-                ctls.setReturningAttributes(new String[] {attributeName});
+        // Returns either a string or list of strings from each match, depending on whether the
+        // specified attribute has one or more values.
+        AttributesMapper roleMapper = new AttributesMapper() {
+            public Object mapFromAttributes(Attributes attributes) throws NamingException {
+                Attribute attribute = attributes.get(attributeName);
 
-                NamingEnumeration matchingEntries = ctx.search(base, filter, params, ctls);
+                if (attribute == null || attribute.size() == 0) {
+                    logger.debug("No attribute value found for '" + attributeName + "'");
 
-                while (matchingEntries.hasMore()) {
-                    SearchResult result = (SearchResult) matchingEntries.next();
-                    Attributes attrs = result.getAttributes();
+                    return null;
+                }
 
-                    // There should only be one attribute in each matching entry.
-                    NamingEnumeration returnedAttributes = attrs.getAll();
+                if (attribute.size() == 1) {
+                    return attribute.get();
+                }
 
-                    while (returnedAttributes.hasMore()) {
-                        Attribute returnedAttribute = (Attribute) returnedAttributes.next();
-                        NamingEnumeration attributeValues = returnedAttribute.getAll();
+                NamingEnumeration ne = attribute.getAll();
+                List values = new ArrayList(attribute.size());
+                while (ne.hasMore()) {
+                    values.add(ne.next());
+                }
+                return values;
+            }
+        };
 
-                        while (attributeValues.hasMore()) {
-                            Object value = attributeValues.next();
+        AttributesMapperCallbackHandler collector = new AttributesMapperCallbackHandler(roleMapper) {
+            public void handleNameClassPair(NameClassPair nameClassPair) {
+                Object roleObject = getObjectFromNameClassPair(nameClassPair);
 
-                            unionOfValues.add(value.toString());
-                        }
-                    }
+                if (roleObject instanceof String) {
+                    getList().add(roleObject);
+                } else if (roleObject instanceof List) {
+                    getList().addAll((List)roleObject);
                 }
-
-                return unionOfValues;
             }
-        }
+        };
+
+        SearchControls ctls = new SearchControls();
+        ctls.setSearchScope(searchControls.getSearchScope());
+        ctls.setReturningAttributes(new String[] {attributeName});
+        ctls.setReturningObjFlag(false);
+
+        search(base, formattedFilter, ctls, collector);
 
-        return (Set) executeReadOnly(new SingleAttributeSearchCallback());
+        return new HashSet(collector.getList());
     }
 
     /**
@@ -283,12 +285,4 @@ public class SpringSecurityLdapTemplate extends org.springframework.ldap.core.Ld
     public void setSearchControls(SearchControls searchControls) {
         this.searchControls = searchControls;
     }
-
-    //~ Inner Classes ==================================================================================================
-
-    private static class LdapExceptionTranslator implements NamingExceptionTranslator {
-        public DataAccessException translate(String task, NamingException e) {
-            return new LdapDataAccessException(task + ";" + e.getMessage(), e);
-        }
-    }
 }