1   /*
2    * Created by IntelliJ IDEA.
3    * User: Administrator
4    * Date: 28/02/2002
5    * Time: 11:30:29
6    * To change template for new class use
7    * Code Style | Class Templates options (Tools | IDE Options).
8    */
9   package com.atlassian.core.user;
10  
11  import com.atlassian.core.util.RandomGenerator;
12  import com.opensymphony.user.*;
13  import org.apache.commons.lang.StringUtils;
14  import org.apache.log4j.Logger;
15  
16  import java.util.*;
17  
18  /**
19   * A utility class for operating on users.
20   *
21   * @see com.atlassian.core.user.GroupUtils
22   */
23  public class UserUtils
24  {
25      private static final Logger log = Logger.getLogger(UserUtils.class);
26  
27      /**
28       * Retrieves and returns the user by given username. If such user does not
29       * exist throws {@link EntityNotFoundException}.
30       *
31       * @param username usename to lookup
32       * @return user looked up by the given username
33       * @throws EntityNotFoundException if user with given username not found
34       */
35      public static User getUser(String username) throws EntityNotFoundException
36      {
37          return username == null ? null : UserManager.getInstance().getUser(username);
38      }
39  
40      /**
41       * Checks if a user with given username exists. Returns true if such user
42       * exists, false otherwise.
43       *
44       * @param username username to look up
45       * @return true if user found, false otherwise
46       */
47      public static boolean existsUser(String username)
48      {
49          try
50          {
51              // we don't care what it returns
52              // its contract is that it returns user if found,
53              // throws exception otherwise, never returns null
54              getUser(username);
55              return true;
56          }
57          catch (EntityNotFoundException e)
58          {
59              return false;
60          }
61      }
62  
63      public static Collection getAllUsers()
64      {
65          return UserManager.getInstance().getUsers();
66      }
67  
68      /**
69       * Return the <b>first</b> user found that matches thie email address.  There may be many users with the
70       * same email address, and this method should not be used to return a single user.
71       * <p/>
72       * The email address is matched case <b>insensitive</b>.  This loops through all users, and so is a
73       * O(N) operation.
74       *
75       * @param email user email
76       * @return The first user that matches the email address
77       * @throws EntityNotFoundException if no user is found.
78       */
79      public static User getUserByEmail(String email) throws EntityNotFoundException
80      {
81          // Trim down the email address to remove any whitespace etc.
82          String emailAddress = StringUtils.trimToNull(email);
83          if (emailAddress != null)
84          {
85              for (Iterator iterator = getAllUsers().iterator(); iterator.hasNext();)
86              {
87                  User user = (User) iterator.next();
88  
89                  if (emailAddress.equalsIgnoreCase(user.getEmail()))
90                  {
91                      return user;
92                  }
93              }
94          }
95  
96          throw new EntityNotFoundException("Could not find user with email: " + email);
97      }
98  
99      /**
100      * Finds the users by the given e-mail address. E-mail address look-up is
101      * done case insensitively. Leading or trailing spaces in the given e-mail
102      * address are trimmed before look up.
103      *
104      * @param email e-mail address
105      * @return always returns a list of users found (even if empty)
106      */
107     public static List getUsersByEmail(String email)
108     {
109         List users = new ArrayList();
110         String emailAddress = StringUtils.trimToNull(email);
111         if (emailAddress != null)
112         {
113             for (Iterator iterator = getAllUsers().iterator(); iterator.hasNext();)
114             {
115                 User user = (User) iterator.next();
116 
117                 if (emailAddress.equalsIgnoreCase(user.getEmail()))
118                 {
119                     users.add(user);
120                 }
121             }
122         }
123         return users;
124     }
125 
126     /**
127      * Get a list of users in a set of groups (either Group objects or String group names)
128      *
129      * @param groups collection of groups (either Group objects or String group names)
130      * @return a collection of {@link User} objects
131      */
132     public static Collection getUsers(Collection groups)
133     {
134         if (groups == null || groups.isEmpty())
135         {
136             return Collections.EMPTY_SET;
137         }
138 
139         Set usernames = new HashSet();
140 
141         for (Iterator iterator = groups.iterator(); iterator.hasNext();)
142         {
143             Object o = iterator.next();
144             if (o == null)
145             {
146                 return UserUtils.getAllUsers();
147             }
148             else
149             {
150                 Group group;
151                 if (o instanceof Group)
152                 {
153                     group = (Group) o;
154                 }
155                 else
156                 {
157                     group = GroupUtils.getGroup((String) o);
158                 }
159                 if (group != null)
160                 {
161                     usernames.addAll(group.getUsers());
162                 }
163             }
164         }
165 
166         List users = new ArrayList();
167 
168         for (Iterator iterator = usernames.iterator(); iterator.hasNext();)
169         {
170             String username = (String) iterator.next();
171             try
172             {
173                 users.add(getUser(username));
174             }
175             catch (EntityNotFoundException e)
176             {
177                 log.error("Could not find user " + username + " but user was returned as in groups " + groups);
178             }
179         }
180 
181         Collections.sort(users, new BestNameComparator());
182 
183         return users;
184     }
185 
186     /**
187      * This method is used when a user is created automatically, or by another user
188      * (for example an administrator). Should not be used for users signing themselves
189      * up.
190      * <p/>
191      * This method will also generate an automatic random password for the user.
192      *
193      * @param username username
194      * @param email    user's e-mail address
195      * @return newly created user
196      * @throws DuplicateEntityException if user already exists
197      * @throws ImmutableException       if setting the user's password fails
198      */
199     public static User createUser(String username, String email) throws DuplicateEntityException, ImmutableException
200     {
201         return createUser(username, RandomGenerator.randomPassword(), email, null);
202     }
203 
204     /**
205      * This method is used when a user is created automatically, or by another user
206      * (for example an administrator). Should not be used for users signing themselves
207      * up.
208      * <p/>
209      * This method will also generate an automatic random password for the user.
210      *
211      * @param username username
212      * @param email    e-mail address
213      * @param fullname user's full name
214      * @return newly created user
215      * @throws DuplicateEntityException if user already exists
216      * @throws ImmutableException       if setting the user's password fails
217      */
218     public static User createUser(String username, String email, String fullname)
219             throws DuplicateEntityException, ImmutableException
220     {
221         return createUser(username, RandomGenerator.randomPassword(), email, fullname);
222     }
223 
224     /**
225      * Generic method which actually creates users, and fires the given event.
226      *
227      * @param username username
228      * @param password password
229      * @param email    e-mail address
230      * @param fullname user's full name
231      * @return newly created user
232      * @throws DuplicateEntityException if user already exists
233      * @throws ImmutableException       if setting the user's password fails
234      */
235     public static User createUser(String username, String password, String email, String fullname)
236             throws DuplicateEntityException, ImmutableException
237     {
238         return createUser(username, password, email, fullname, null);
239     }
240 
241     /**
242      * Creates a new user with given attributes and associates the user with
243      * given collection of groups.
244      *
245      * @param username username
246      * @param password passwod
247      * @param email    e-mail address
248      * @param fullname user's full name
249      * @param groups   group names (String objects) the user will belong to
250      * @return newly created user
251      * @throws DuplicateEntityException if user already exists
252      * @throws ImmutableException       if setting the user's password fails
253      */
254     public static User createUser(String username, String password, String email, String fullname, Collection groups)
255             throws DuplicateEntityException, ImmutableException
256     {
257         log.debug("UserUtils.createUser");
258         try
259         {
260             UserManager.getInstance().getUser(username.toLowerCase());
261             throw new DuplicateEntityException("The user " + username + " already exists.");
262         }
263         catch (EntityNotFoundException ex)
264         {
265             User user = UserManager.getInstance().createUser(username.toLowerCase());
266             user.setEmail(email);
267             user.setPassword(password);
268 
269             if (fullname == null)
270             {
271                 fullname = username;
272             }
273 
274             user.setFullName(fullname);
275 
276             if (groups != null)
277             {
278                 for (Iterator iterator = groups.iterator(); iterator.hasNext();)
279                 {
280                     String groupname = (String) iterator.next();
281                     user.addToGroup(GroupUtils.getGroup(groupname));
282                 }
283             }
284             return user;
285         }
286     }
287 
288     /**
289      * Removes the given user.
290      * A {@link ImmutableException} is thrown if given user cannot be removed.
291      *
292      * @param user user to remove
293      * @throws Exception if user cannot be removed
294      */
295     public static void removeUser(User user) throws Exception
296     {
297         user.remove();
298     }
299 
300     /**
301      * For a user, create a new password, and dispatch an 'forgot password' event
302      *
303      * @param user The user whose password needs to be reset.
304      * @return new password
305      * @throws ImmutableException if password cannot be changed
306      */
307     public static String resetPassword(User user) throws ImmutableException
308     {
309         String newPassword = RandomGenerator.randomPassword();
310         user.setPassword(newPassword);
311         return newPassword;
312     }
313 
314     /**
315      * Changes the password for a given user.
316      *
317      * @param user     user to change password for
318      * @param password new password
319      * @throws ImmutableException if password cannot be changed
320      */
321     public static void changePassword(User user, String password) throws ImmutableException
322     {
323         user.setPassword(password);
324     }
325 
326 }