View Javadoc
1   package com.atlassian.refapp.sal.user;
2   
3   import com.atlassian.plugin.spring.scanner.annotation.export.ExportAsService;
4   import com.atlassian.sal.api.user.UserKey;
5   import com.atlassian.sal.api.user.UserProfile;
6   import com.atlassian.sal.api.user.UserResolutionException;
7   import com.atlassian.seraph.auth.AuthenticationContext;
8   import com.atlassian.user.EntityException;
9   import com.atlassian.user.Group;
10  import com.atlassian.user.GroupManager;
11  import com.atlassian.user.User;
12  import com.atlassian.user.UserManager;
13  import com.atlassian.user.search.page.Pager;
14  import com.atlassian.user.security.authentication.Authenticator;
15  import com.google.common.collect.Lists;
16  import org.apache.log4j.Logger;
17  
18  import javax.annotation.Nullable;
19  import javax.inject.Inject;
20  import javax.inject.Named;
21  import javax.servlet.http.HttpServletRequest;
22  import java.security.Principal;
23  import java.util.Collections;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import static org.apache.commons.lang.StringUtils.isBlank;
28  import static org.apache.commons.lang.StringUtils.startsWith;
29  
30  /**
31   * Pretends the 'someUser' is logged in and is an admin
32   */
33  @ExportAsService
34  @Named("salUserManager")
35  public class RefImplUserManager implements com.atlassian.sal.api.user.UserManager {
36      private final Logger log = Logger.getLogger(getClass());
37  
38      private final AuthenticationContext authenticationContext;
39      private final GroupManager groupManager;
40      private final UserManager userManager;
41      private final Authenticator authenticator;
42  
43      @Inject
44      public RefImplUserManager(final AuthenticationContext authenticationContext, final UserManager userManager,
45                                final GroupManager groupManager, final Authenticator authenticator) {
46          this.authenticationContext = assertNotNull(authenticationContext, "authenticationContext");
47          this.userManager = assertNotNull(userManager, "userManager");
48          this.groupManager = assertNotNull(groupManager, "groupManager");
49          this.authenticator = assertNotNull(authenticator, "authenticator");
50      }
51  
52      public String getRemoteUsername() {
53          final Principal user = authenticationContext.getUser();
54          if (user == null)
55              return null;
56          return user.getName();
57      }
58  
59      @Override
60      public UserProfile getRemoteUser() {
61          final Principal reqUser = authenticationContext.getUser();
62          if (reqUser == null)
63              return null;
64  
65          return getUserProfile(reqUser.getName());
66      }
67  
68      @Nullable
69      @Override
70      public UserKey getRemoteUserKey() {
71          final Principal reqUser = authenticationContext.getUser();
72          if (reqUser == null)
73              return null;
74  
75          return new UserKey(reqUser.getName());
76      }
77  
78      public String getRemoteUsername(final HttpServletRequest request) {
79          return request.getRemoteUser();
80      }
81  
82      @Override
83      public UserProfile getRemoteUser(HttpServletRequest request) {
84          return getUserProfile(request.getRemoteUser());
85      }
86  
87      @Nullable
88      @Override
89      public UserKey getRemoteUserKey(HttpServletRequest request) {
90          final String username = request.getRemoteUser();
91          return (username != null) ? new UserKey(username) : null;
92      }
93  
94      public UserProfile getUserProfile(String username) {
95          final User user;
96          try {
97              user = userManager.getUser(username);
98              if (user == null) {
99                  return null;
100             }
101             return new RefimplUserProfile(user);
102         } catch (EntityException e) {
103             return null;
104         }
105     }
106 
107     @Nullable
108     @Override
109     public UserProfile getUserProfile(@Nullable UserKey userKey) {
110         if (userKey == null) {
111             return null;
112         }
113         return getUserProfile(userKey.getStringValue());
114     }
115 
116     public boolean isSystemAdmin(final String username) {
117         return isUserInGroup(username, "system_administrators");
118     }
119 
120     @Override
121     public boolean isSystemAdmin(UserKey userKey) {
122         if (userKey != null) {
123             return isSystemAdmin(userKey.getStringValue());
124         }
125         return false;
126     }
127 
128     public boolean isAdmin(final String username) {
129         return isSystemAdmin(username) || isUserInGroup(username, "administrators");
130     }
131 
132     @Override
133     public boolean isAdmin(UserKey userKey) {
134         if (userKey != null) {
135             return isAdmin(userKey.getStringValue());
136         }
137         return false;
138     }
139 
140     public boolean authenticate(final String username, final String password) {
141         try {
142             final boolean authenticated = authenticator.authenticate(username, password);
143             if (!authenticated) {
144                 log.info("Cannot authenticate user '" + username + "' as they used an incorrect password");
145             }
146             return authenticated;
147         } catch (final EntityException e) {
148             log.info("Cannot authenticate user '" + username + "' as they do not exist.");
149             return false;
150         }
151     }
152 
153     public boolean isUserInGroup(final String username, final String group) {
154         try {
155             final User user = userManager.getUser(username);
156             final Group adminGroup = groupManager.getGroup(group);
157             if ((user == null) || (adminGroup == null)) {
158                 return false;
159             }
160             return groupManager.hasMembership(adminGroup, user);
161         } catch (final EntityException e) {
162             return false;
163         }
164     }
165 
166     @Override
167     public boolean isUserInGroup(UserKey userKey, String groupName) {
168         if (userKey != null) {
169             return isUserInGroup(userKey.getStringValue(), groupName);
170         }
171         return false;
172     }
173 
174     public Principal resolve(final String username) throws UserResolutionException {
175         try {
176             if (userManager.getUser(username) == null) {
177                 return null;
178             }
179         } catch (final EntityException e) {
180             throw new UserResolutionException("Exception resolving user  '" + username + "'.", e);
181         }
182         return new Principal() {
183             public String getName() {
184                 return username;
185             }
186         };
187     }
188 
189     @Override
190     public Iterable<String> findGroupNamesByPrefix(String prefix, int startIndex, int maxResults) {
191         List<String> groupNames = Lists.newArrayList();
192         try {
193             Pager allGroups = groupManager.getGroups();
194 
195             allGroups.skipTo(startIndex);
196 
197             for (Iterator iterator = allGroups.iterator(); iterator.hasNext(); ) {
198                 if (groupNames.size() >= maxResults) {
199                     break;
200                 }
201 
202                 Group group = (Group) iterator.next();
203                 if ((isBlank(prefix) || startsWith(group.getName(), prefix))) {
204                     groupNames.add(group.getName());
205                 }
206             }
207         } catch (EntityException e) {
208             return Collections.emptyList();
209         }
210 
211         return groupNames;
212     }
213 
214     /**
215      * Check that {@code reference} is not {@code null}. If it is, throw a
216      * {@code IllegalArgumentException}.
217      *
218      * @param reference    reference to check is {@code null} or not
219      * @param errorMessage com.atlassian.refapp.sal.message passed to the {@code IllegalArgumentException} constructor
220      *                     to give more context when debugging
221      * @return {@code reference} so it may be used
222      * @throws IllegalArgumentException if {@code reference} is {@code null}
223      */
224     private static <T> T assertNotNull(final T reference, final Object errorMessage) {
225         if (reference == null) {
226             throw new IllegalArgumentException(String.valueOf(errorMessage));
227         }
228         return reference;
229     }
230 }