View Javadoc

1   package com.atlassian.user.impl.ldap.adaptor;
2   
3   import com.atlassian.user.EntityException;
4   import com.atlassian.user.Group;
5   import com.atlassian.user.User;
6   import com.atlassian.user.impl.RepositoryException;
7   import com.atlassian.user.impl.ldap.LDAPGroupFactory;
8   import com.atlassian.user.impl.ldap.LDAPUserFactory;
9   import com.atlassian.user.impl.ldap.properties.LdapSearchProperties;
10  import com.atlassian.user.impl.ldap.properties.LdapMembershipProperties;
11  import com.atlassian.user.impl.ldap.repository.LdapContextFactory;
12  import com.atlassian.user.impl.ldap.search.DefaultLDAPUserAdaptor;
13  import com.atlassian.user.impl.ldap.search.LDAPPagerInfo;
14  import com.atlassian.user.impl.ldap.search.LDAPUserAdaptor;
15  import com.atlassian.user.impl.ldap.search.LdapFilterFactory;
16  import com.atlassian.user.impl.ldap.search.page.LDAPListOfGroupsPager;
17  import com.atlassian.user.impl.ldap.search.page.LDAPSingleStringPager;
18  import com.atlassian.user.search.page.Pager;
19  import net.sf.ldaptemplate.support.filter.EqualsFilter;
20  import net.sf.ldaptemplate.support.filter.Filter;
21  
22  import javax.naming.NamingEnumeration;
23  import javax.naming.NamingException;
24  import javax.naming.directory.Attribute;
25  import javax.naming.directory.Attributes;
26  import javax.naming.directory.SearchResult;
27  
28  /**
29   * Dynamic groups, in 'LDAP speak', express their membership via user entries (you need
30   * to examine the user entry to discover what groups the user belongs to).
31   *
32   * The role of this class is locate dynamic groups via a getGroupEntries and call the appropriate factory
33   * to construct Groups from the LDAP getGroupEntries results.
34   */
35  public class LDAPDynamicGroupAdaptor extends AbstractLDAPGroupAdaptor
36  {
37      private final LdapMembershipProperties membershipProperties;
38      private final LDAPUserAdaptor userAdaptor;
39  
40      /** @deprecated userFactory no longer required */
41      @SuppressWarnings({"UnusedDeclaration"})
42      public LDAPDynamicGroupAdaptor(LdapContextFactory repo, LdapSearchProperties searchProperties,
43          LDAPGroupFactory groupFactory, LdapFilterFactory filterFactory, LDAPUserFactory userFactory,
44          LdapMembershipProperties membershipProperties)
45      {
46          super(repo, searchProperties, groupFactory, filterFactory);
47          this.membershipProperties = membershipProperties;
48          this.userAdaptor = new DefaultLDAPUserAdaptor(repository, searchProperties, filterFactory);
49      }
50  
51      public LDAPDynamicGroupAdaptor(LdapContextFactory repo, LdapSearchProperties searchProperties,
52          LDAPGroupFactory groupFactory, LdapFilterFactory filterFactory,
53          LdapMembershipProperties membershipProperties)
54      {
55          super(repo, searchProperties, groupFactory, filterFactory);
56          this.membershipProperties = membershipProperties;
57          this.userAdaptor = new DefaultLDAPUserAdaptor(repository, searchProperties, filterFactory);
58      }
59  
60      public Pager<Group> getGroups(User user) throws EntityException
61      {
62          LDAPPagerInfo answer =
63              getGroupEntriesViaMembership(user.getName(), new String[]{membershipProperties.getMembershipAttribute()});
64          return new LDAPListOfGroupsPager(repository, groupFactory, answer);
65      }
66  
67      private String getGroupsForUserSearchString(NamingEnumeration enume) throws RepositoryException
68      {
69          String query = null;
70  
71          while (enume.hasMoreElements())
72          {
73              SearchResult result = (SearchResult) enume.nextElement();
74              Attributes attrs = result.getAttributes();
75              Attribute membershipAttribute = attrs.get(membershipProperties.getMembershipAttribute());
76  
77              if (membershipAttribute != null)
78              {
79                  try
80                  {
81                      NamingEnumeration groupList = membershipAttribute.getAll();
82  
83                      while (groupList.hasMoreElements())
84                      {
85                          String groupDN = (String) groupList.nextElement();
86  
87                          if (query == null)
88                              query = "(" + groupDN.split(",")[0] + ")";
89                          else
90                              query = "(|" + query + "(" + groupDN.split(",")[0] + "))";
91                      }
92                  }
93                  catch (NamingException e)
94                  {
95                      throw new RepositoryException(e);
96                  }
97              }
98          }
99  
100         return query;
101     }
102 
103     // TODO: Prior to genericising, findMembers on the StaticGroupAdaptor returned a list of Strings, while
104     //       the dynamic group adapter method returned a list of Group entities. Since the static adaptor is
105     //       the one most likely to be being used, I've reverted to that behaviour.
106     public Pager<String> findMembers(Group group) throws EntityException
107     {
108         return findMemberNames(group);
109 //        LDAPPagerInfo ldapPagerInfo = findMembershipEntries(group, null);
110 //        return new LDAPEntityPager(repository, userFactory, ldapPagerInfo);
111     }
112 
113     private LDAPPagerInfo findMembershipEntries(Group group, String[] attributesToReturn) throws EntityException
114     {
115         Filter searchFilter = new EqualsFilter(membershipProperties.getMembershipAttribute(), getGroupDN(group));
116 
117         LDAPPagerInfo ldapPagerInfo = null;
118 
119         try
120         {
121             if (attributesToReturn == null)
122                 ldapPagerInfo = userAdaptor.search(searchFilter);
123             else
124                 ldapPagerInfo = userAdaptor.search(searchFilter, attributesToReturn);
125         }
126         catch (EntityException e)
127         {
128             log.fatal("Could not find users in group [" + group.getName() + "] ", e);
129         }
130         return ldapPagerInfo;
131     }
132 
133     public Pager<String> findMemberNames(Group group) throws EntityException
134     {
135         LDAPPagerInfo ldapPagerInfo =
136             findMembershipEntries(group, new String[]{searchProperties.getUsernameAttribute()});
137         return new LDAPSingleStringPager(repository, ldapPagerInfo);
138     }
139 
140     public boolean hasStaticGroups()
141     {
142         return false;
143     }
144 
145     public boolean hasMembership(Group group, User user) throws EntityException
146     {
147         LDAPPagerInfo wrapper =
148             userAdaptor.getUserAttributes(user.getName(), new String[]{membershipProperties.getMembershipAttribute()});
149         NamingEnumeration enume = wrapper.getNamingEnumeration();
150 
151         return getGroupsForUserSearchString(enume).indexOf(group.getName()) != -1;
152     }
153 
154     public LDAPPagerInfo getGroupEntriesViaMembership(User user) throws EntityException
155     {
156         return getGroupEntriesViaMembership(user.getName());
157     }
158 
159     public LDAPPagerInfo getGroupEntriesViaMembership(String username) throws EntityException
160     {
161         return getGroupEntriesViaMembership(username, null);
162     }
163 
164     public LDAPPagerInfo getGroupEntriesViaMembership(String username, String[] attributesToReturn)
165         throws EntityException
166     {
167         if (attributesToReturn == null)
168             attributesToReturn =
169                 new String[]{searchProperties.getGroupnameAttribute(), membershipProperties.getMembershipAttribute()};
170 
171         return userAdaptor.getUserAttributes(username, attributesToReturn);
172     }
173 }