1 package com.atlassian.user.impl.ldap.search.page;
2
3 import com.atlassian.user.EntityException;
4 import com.atlassian.user.impl.RepositoryException;
5 import com.atlassian.user.impl.ldap.properties.LdapSearchProperties;
6 import com.atlassian.user.impl.ldap.repository.LdapContextFactory;
7 import com.atlassian.user.impl.ldap.search.LDAPPagerInfo;
8 import com.atlassian.user.util.LDAPUtils;
9 import com.atlassian.util.profiling.UtilTimerStack;
10 import org.apache.log4j.Logger;
11
12 import javax.naming.NamingEnumeration;
13 import javax.naming.NamingException;
14 import javax.naming.directory.*;
15 import java.util.List;
16
17 public class LDAPMembershipToUsernamePager extends LDAPSingleStringPager
18 {
19 private static final Logger log = Logger.getLogger(LDAPMembershipToUsernamePager.class);
20
21 public LDAPMembershipToUsernamePager(LdapSearchProperties searchProperties, LdapContextFactory repository, LDAPPagerInfo info)
22 {
23 super(searchProperties, repository, info);
24 }
25
26 protected List<String> preloadSearchResult(SearchResult result, List<String> prefetched) throws EntityException
27 {
28 DirContext ctx = null;
29 try
30 {
31 Attributes entityAttributes = result.getAttributes();
32 String attributeToFind = returningAttributes[0];
33 Attribute attr = entityAttributes.get(attributeToFind);
34
35 if (attr != null)
36 {
37 NamingEnumeration interiorList = attr.getAll();
38 ctx = repository.getLDAPContext();
39 while (interiorList.hasMoreElements())
40 addIfFoundUser(prefetched, (String) interiorList.nextElement(), ctx);
41 }
42 }
43 catch (Throwable t)
44 {
45 log.error("Error converting search result: " + result + " into list of members as usernames.", t);
46 }
47 finally
48 {
49 closeContext(ctx);
50 }
51
52 return prefetched;
53 }
54
55
56
57
58
59
60
61 private void addIfFoundUser(List<String> prefetched, String dn, DirContext ctx)
62 {
63 try
64 {
65 String username = findByDN(dn, ctx);
66 if (username != null)
67 prefetched.add(username);
68 }
69 catch (RepositoryException e)
70 {
71 log.error("Error resolving dn [ " + dn + " ] to a username", e);
72 }
73 }
74
75
76
77
78 private String findByDN(String dn, DirContext ctx) throws RepositoryException
79 {
80 String usernameAttribure = searchProperties.getUsernameAttribute();
81 SearchControls ctls = LDAPUtils.createSearchControls(
82 new String[]{usernameAttribure}, true, searchProperties.getTimeLimitMillis());
83
84 try
85 {
86 if (UtilTimerStack.isActive())
87 UtilTimerStack.push(this.getClass().getName() + "_search_JNDI_RAW_" + searchProperties.getUserFilter());
88
89 NamingEnumeration<SearchResult> userSearchEnum = ctx.search(dn, searchProperties.getUserFilter(), ctls);
90 if (userSearchEnum.hasMoreElements())
91 {
92 SearchResult sr = userSearchEnum.next();
93 if (sr != null && sr.getAttributes() != null && sr.getAttributes().get(usernameAttribure) != null)
94 {
95 String username = (String) sr.getAttributes().get(usernameAttribure).get();
96 if (log.isDebugEnabled())
97 log.debug("LDAPMembershipToUse.findByDN [ " + dn + " ] username [ " + username + " ]");
98 return username;
99 }
100 }
101 return null;
102 }
103
104 catch (NamingException e)
105 {
106 throw new RepositoryException(e);
107 }
108 finally
109 {
110 if (UtilTimerStack.isActive())
111 UtilTimerStack.pop(this.getClass().getName() + "_search_JNDI_RAW_" + searchProperties.getUserFilter());
112 }
113
114 }
115
116 private void closeContext(DirContext ctx)
117 {
118 try
119 {
120 if (ctx != null)
121 ctx.close();
122 }
123 catch (NamingException e)
124 {
125 log.warn("Exception closing context", e);
126 }
127 }
128 }