1   package com.atlassian.user.impl.ldap;
2   
3   import com.atlassian.user.Entity;
4   import com.atlassian.user.EntityException;
5   import com.atlassian.user.User;
6   import com.atlassian.user.impl.ReadOnlyUserManager;
7   import com.atlassian.user.impl.RepositoryException;
8   import com.atlassian.user.impl.ldap.properties.LdapSearchProperties;
9   import com.atlassian.user.impl.ldap.repository.LdapContextFactory;
10  import com.atlassian.user.impl.ldap.search.DefaultLDAPUserAdaptor;
11  import com.atlassian.user.impl.ldap.search.LDAPPagerInfo;
12  import com.atlassian.user.impl.ldap.search.LDAPUserAdaptor;
13  import com.atlassian.user.impl.ldap.search.LdapFilterFactory;
14  import com.atlassian.user.impl.ldap.search.page.LDAPEntityPager;
15  import com.atlassian.user.impl.ldap.search.page.LDAPSingleStringPager;
16  import com.atlassian.user.repository.RepositoryIdentifier;
17  import com.atlassian.user.search.page.Pager;
18  import com.atlassian.util.profiling.UtilTimerStack;
19  import net.sf.ldaptemplate.support.filter.EqualsFilter;
20  import org.apache.log4j.Logger;
21  
22  import javax.naming.Context;
23  import java.net.Inet4Address;
24  import java.net.URI;
25  import java.net.URISyntaxException;
26  import java.net.UnknownHostException;
27  
28  public class LDAPUserManagerReadOnly extends ReadOnlyUserManager
29  {
30      protected final Logger log = Logger.getLogger(this.getClass());
31  
32      private final RepositoryIdentifier repositoryIdentifier;
33      private final LdapContextFactory repository;
34      private final LdapSearchProperties searchProperties;
35      private final LDAPUserAdaptor userAdaptor;
36  
37      public LDAPUserManagerReadOnly(RepositoryIdentifier repositoryIdentifier, LdapContextFactory repository,
38          LdapSearchProperties searchProperties, LdapFilterFactory filterFactory)
39      {
40          this.repositoryIdentifier = repositoryIdentifier;
41          this.repository = repository;
42          this.searchProperties = searchProperties;
43          userAdaptor = new DefaultLDAPUserAdaptor(repository, searchProperties, filterFactory);
44      }
45  
46      /**
47       * @return all users in the configured repository
48       * @throws RepositoryException
49       */
50      public Pager<User> getUsers() throws EntityException
51      {
52          profilePush(this.getClass().getName() + "_getUsers");
53  
54          LDAPPagerInfo info = userAdaptor.search(null);
55          Pager<User> pager = new LDAPEntityPager<User>(searchProperties, repository, new DefaultLDAPUserFactory(searchProperties), info);
56  
57          profilePop(this.getClass().getName() + "_getUsers");
58  
59          return pager;
60      }
61  
62      public Pager<String> getUserNames() throws EntityException
63      {
64          LDAPPagerInfo info = userAdaptor.search(null, new String[]{searchProperties.getUsernameAttribute()});
65          return new LDAPSingleStringPager(searchProperties, repository, info);
66      }
67  
68      public User getUser(String username) throws EntityException
69      {
70          profilePush(this.getClass().getName() + "_getUser(" + username + ")");
71  
72          User user = null;
73  
74          try
75          {
76              LDAPPagerInfo info =
77                  userAdaptor.search(new EqualsFilter(searchProperties.getUsernameAttribute(), username));
78  
79              Pager pager = new LDAPEntityPager<User>(searchProperties, repository, new DefaultLDAPUserFactory(searchProperties), info);
80  
81              if (pager.getCurrentPage().size() > 0)
82                  user = (User) pager.getCurrentPage().get(0);
83          }
84          catch (EntityException e)
85          {
86              String host = "<unknown>";
87              String ipAddress = "<unknown>";
88              try
89              {
90                  String urlString = (String) repository.getJNDIEnv().get(Context.PROVIDER_URL);
91                  URI uri = new URI(urlString);
92                  host = uri.getHost();
93                  ipAddress = Inet4Address.getByName(host).getHostAddress();
94              }
95              catch (URISyntaxException use)
96              {
97                  log.debug("Error while retrieving LDAP server info", use);
98              }
99              catch (UnknownHostException uhe)
100             {
101                 log.debug("Error while retrieving LDAP server info", uhe);
102             }
103             log.error("Error retrieving user: '" + username + "' from LDAP server " + host + "[" + ipAddress + "]", e);
104         }
105 
106         profilePop(this.getClass().getName() + "_getUser(" + username + ")");
107 
108         return user;
109     }
110 
111     /**
112      * @return the {@link com.atlassian.user.repository.RepositoryIdentifier} which is managed by this instance.
113      */
114     public RepositoryIdentifier getIdentifier()
115     {
116         return repositoryIdentifier;
117     }
118 
119     public RepositoryIdentifier getRepository(Entity entity) throws EntityException
120     {
121         if (!LDAPValidator.validateLDAPEntity(entity))
122             return null;
123 
124         if (getUser(entity.getName()) == null) // not handled by this manager
125             return null;
126 
127         return repositoryIdentifier;
128 
129     }
130 
131     private void profilePush(String key)
132     {
133         if (UtilTimerStack.isActive())
134             UtilTimerStack.push(key);
135     }
136 
137     private void profilePop(String key)
138     {
139         if (UtilTimerStack.isActive())
140             UtilTimerStack.pop(key);
141     }
142 }