View Javadoc
1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.services.authentication;
20  
21  import org.apache.log4j.Logger;
22  import org.itracker.model.Permission;
23  import org.itracker.model.PermissionType;
24  import org.itracker.model.User;
25  import org.itracker.UserException;
26  import org.itracker.services.exceptions.AuthenticatorException;
27  import org.itracker.PasswordException;
28  import org.itracker.model.util.UserUtilities;
29  
30  import org.springframework.dao.DataAccessException;
31  
32  import java.util.ArrayList;
33  import java.util.HashMap;
34  import java.util.List;
35  import java.util.Map;
36  
37  
38  /**
39   * This class provides a default authentication scheme for ITracker.  It uses passwords
40   * in the user table provided by ITracker to authenticate users.  This authenticator
41   * allows any user to self register if self registration is available in the system.
42   */
43  public class DefaultAuthenticator extends AbstractPluggableAuthenticator {
44  
45      private static final Logger logger = Logger.getLogger(DefaultAuthenticator.class);
46  
47      /**
48       * Checks the login of a user against the user profile provided in ITracker.  This is
49       * the default authentication scheme provided by ITracker.
50       *
51       * @param login          the login the user/client provided
52       * @param authentication the user's authentication information, if known
53       * @param authType       the type of authentication information being provided
54       * @param reqSource      the source of the request (eg web, api)
55       * @return a User if the login is successful
56       * @throws AuthenticatorException an exception if the login is unsuccessful, or an error occurs
57       */
58      public User checkLogin(final String login, final Object authentication, final int authType, final int reqSource) throws AuthenticatorException {
59          if (logger.isDebugEnabled()) {
60              logger.debug("Checking login for " + login + " using DefaultAuthenticator");
61          }
62  
63          if (login != null && authentication != null && !login.equals("")) {
64              User user;
65              try {
66                  user = getUserService().getUserByLogin(login);
67              } catch (DataAccessException e) {
68                  logger.error("checkLogin: failed to get user by login: " + login, e);
69                  throw new AuthenticatorException(AuthenticatorException.UNKNOWN_USER, e.getMessage());
70              }
71  
72              if (user.getStatus() != UserUtilities.STATUS_ACTIVE) {
73                  AuthenticatorExceptionticatorException.html#AuthenticatorException">AuthenticatorException e = new AuthenticatorException(AuthenticatorException.INACTIVE_ACCOUNT);
74                  logger.info("checkLogin: user is inactive, user: " + user, e);
75                  throw e;
76              }
77  
78              String userPassword;
79              try {
80                  userPassword = getUserService().getUserPasswordByLogin(login);
81              } catch (DataAccessException e) {
82                  AuthenticatorExceptionicatorException.html#AuthenticatorException">AuthenticatorException ex = new AuthenticatorException(e.getMessage(), authType);
83                  logger.info("checkLogin: user is inactive, user: " + user, ex);
84                  throw e;
85              }
86              if (userPassword == null || userPassword.equals("")) {
87                  AuthenticatorExceptionticatorException.html#AuthenticatorException">AuthenticatorException e = new AuthenticatorException(AuthenticatorException.INVALID_PASSWORD);
88                  logger.info("checkLogin: user has no password, user: " + user, e);
89                  throw e;
90              }
91  
92              try {
93                  if (!userPassword.endsWith("=")) {
94                      logger.info("checkLogin: User " + login + " has old style password.  Converting to SHA1 hash.");
95                      try {
96                          user.setPassword(UserUtilities.encryptPassword(userPassword));
97                          getUserService().updateUser(user);
98                      } catch (UserException ue) {
99                          logger.error("checkLogin: User password conversion failed for user " + user, ue);
100                         throw new AuthenticatorException(AuthenticatorException.SYSTEM_ERROR);
101                     }
102                 }
103 
104                 if (authType == AUTH_TYPE_PASSWORD_PLAIN) {
105                     if (!userPassword.equals(UserUtilities.encryptPassword((String) authentication))) {
106                         throw new AuthenticatorException(AuthenticatorException.INVALID_PASSWORD);
107                     }
108                 } else if (authType == AUTH_TYPE_PASSWORD_ENC) {
109                     if (!userPassword.equals(authentication)) {
110                         throw new AuthenticatorException(AuthenticatorException.INVALID_PASSWORD);
111                     }
112                 } else {
113                     logger.info("checkLogin: invalid authenticator type: " + authType);
114                     throw new AuthenticatorException(AuthenticatorException.INVALID_AUTHENTICATION_TYPE);
115                 }
116             } catch (ClassCastException cce) {
117                 logger.error("checkLogin: Authenticator was of wrong type.", cce);
118                 throw new AuthenticatorException(AuthenticatorException.SYSTEM_ERROR);
119             } catch (PasswordException pe) {
120                 throw new AuthenticatorException(AuthenticatorException.SYSTEM_ERROR);
121             } catch (AuthenticatorException ae) {
122                 if (logger.isDebugEnabled()) {
123                     logger.debug("checkLogin: failed to authenticate " + login, ae);
124                 }
125                 throw ae;
126             }
127 
128             return user;
129         }
130 
131         logger.info("checkLogin: no login was supplied: " + login + ", type: " + authType + ", source: " + reqSource);
132         throw new AuthenticatorException(AuthenticatorException.INVALID_DATA);
133     }
134 
135     /**
136      * The DefaultAuthenticator returns a list of user permissions from the database.
137      *
138      * @param user      a User object that contains the user to retrieve permissions for
139      * @param reqSource the source of the request (eg web, api)
140      * @return an array of PermissionModels
141      * @throws AuthenticatorException an error occurs
142      */
143     public List<Permission> getUserPermissions(User user, int reqSource) throws AuthenticatorException {
144         if (user == null || user.getId() == null) {
145             throw new AuthenticatorException(AuthenticatorException.INVALID_DATA);
146         }
147 
148         List<Permission> permissionList;
149         try {
150             permissionList = getUserService().getUserPermissionsLocal(user);
151         } catch (DataAccessException e) {
152             throw new AuthenticatorException(e.getMessage(), reqSource);
153         }
154 
155         if (user.isSuperUser()) {
156             List<Permission> augmentedPermissions = new ArrayList<Permission>();
157 
158             // Super user has access to all projects (represented by the "null" project). 
159             Permission permission = new Permission(PermissionType.USER_ADMIN, user, null);
160             augmentedPermissions.add(permission);
161             augmentedPermissions.addAll(permissionList);
162             return augmentedPermissions;
163 
164         } else {
165             return permissionList;
166         }
167 
168     }
169 
170 
171 
172     /**
173      * Returns the list of users for a given project. User permissions can be specified.
174      *
175      * @param projectId       - The Project to search for users
176      * @param permissionTypes - User rights to filter
177      * @param requireAll      - Require all permissions
178      * @param activeOnly      - Filter users who are active (Possible user status: DELETED, ACTIVE, LOCKED)
179      * @param reqSource       - not used. TODO: Tagged for removal
180      * @return List of users for the project with filters applied.
181      */
182     @Override
183     public List<User> getUsersWithProjectPermission(Integer projectId, PermissionType[] permissionTypes, boolean requireAll, boolean activeOnly, int reqSource) throws AuthenticatorException {
184 
185         List<User> users;
186 
187         try {
188             Map<Integer, User> userMap = new HashMap<Integer, User>();
189 
190             if (requireAll) {
191 
192                 List<User> explicitUsers = getUserService().findUsersForProjectByPermissionTypeList(projectId, permissionTypes);
193 
194                 for (User user : explicitUsers) {
195                     userMap.put(user.getId(), user);
196                 }
197             } else {
198 
199                 for (int i = 0; i < permissionTypes.length; i++) {
200                     List<User> explicitUsers = getUserService().getUsersWithPermissionLocal(projectId, permissionTypes[i]);
201 
202                     for (User user : explicitUsers) {
203                         userMap.put(user.getId(), user);
204                     }
205 
206                 }
207 
208             }
209 
210             List<User> superUsers = getUserService().getSuperUsers();
211             for (User superUser : superUsers) {
212                 userMap.put(superUser.getId(), superUser);
213             }
214 
215             users = new ArrayList<User>();
216             for (User user : userMap.values()) {
217                 if (activeOnly) {
218                     if (user.getStatus() == UserUtilities.STATUS_ACTIVE) {
219                         users.add(user);
220                     }
221                 } else {
222                     users.add(user);
223                 }
224             }
225 
226         } catch (Exception e) {
227             logger.error("Error retreiving users with permissions.", e);
228             throw new AuthenticatorException();
229         }
230 
231         return users;
232     }
233     @Override
234     @Deprecated
235     public List<User> getUsersWithProjectPermission(Integer projectId,
236                                                     int[] permissionTypes,
237                                                     boolean requireAll,
238                                                     boolean activeOnly,
239                                                     int reqSource)
240             throws AuthenticatorException {
241 
242         return getUsersWithProjectPermission(projectId,
243                 PermissionType.valueOf(permissionTypes),
244                 requireAll,
245                 activeOnly,
246                 reqSource);
247 
248     }
249 
250     /**
251      * The DefaultAuthenticator always allows self registered users.
252      *
253      * @param user           a User object that contains the data the user submitted
254      * @param authentication the user's authentication information, if known
255      * @param authType       the type of authentication information being provided
256      * @param reqSource      the source of the request (eg web, api)
257      * @return true
258      */
259     public boolean allowRegistration(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
260         return true;
261     }
262 
263 
264     /**
265      * The DefaultAuthenticator always allows new user profiles.
266      *
267      * @param user           a User object that contains the data the user submitted
268      * @param authentication the user's authentication information, if known
269      * @param authType       the type of authentication information being provided
270      * @return true
271      * @throws AuthenticatorException an exception if an error occurs
272      */
273     public boolean allowProfileCreation(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
274         return true;
275     }
276 
277     /**
278      * The DefaultAuthenticator always allows profile updates.
279      *
280      * @param user           a User object that contains the data the user submitted
281      * @param authentication the user's authentication information, if known
282      * @param authType       the type of authentication information being provided
283      * @param reqSource      the source of the request (eg web, api)
284      * @return true
285      * @throws AuthenticatorException an exception if an error occurs
286      */
287     public boolean allowProfileUpdates(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
288         return true;
289     }
290 
291     /**
292      * The DefaultAuthenticator always allows password updates.
293      *
294      * @param user           a User object that contains the data the user submitted
295      * @param authentication the user's authentication information, if known
296      * @param authType       the type of authentication information being provided
297      * @param reqSource      the source of the request (eg web, api)
298      * @return true
299      * @throws AuthenticatorException an exception if an error occurs
300      */
301     public boolean allowPasswordUpdates(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
302         return true;
303     }
304 
305     /**
306      * The DefaultAuthenticator always allows permission updates.
307      *
308      * @param user           a User object that contains the data the user submitted
309      * @param authentication the user's authentication information, if known
310      * @param authType       the type of authentication information being provided
311      * @param reqSource      the source of the request (eg web, api)
312      * @return true
313      * @throws AuthenticatorException an exception if an error occurs
314      */
315     public boolean allowPermissionUpdates(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
316         return true;
317     }
318 
319     /**
320      * The DefaultAuthenticator always allows preferences updates.
321      *
322      * @param user           a User object that contains the data the user submitted
323      * @param authentication the user's authentication information, if known
324      * @param authType       the type of authentication information being provided
325      * @param reqSource      the source of the request (eg web, api)
326      * @return true
327      * @throws AuthenticatorException an exception if an error occurs
328      */
329     public boolean allowPreferenceUpdates(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
330         return true;
331     }
332 
333     /**
334      * The DefaultAuthenticator does not make any changes to a newly created profile.
335      *
336      * @param user           a User object that contains the newly created profile
337      * @param authentication the user's authentication information, if known
338      * @param authType       the type of authentication information being provided
339      * @param reqSource      the source of the request (eg web, api)
340      * @return boolean indicating whther changes to the user were made
341      * @throws AuthenticatorException an error occurs
342      */
343     public boolean createProfile(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
344         return false;
345     }
346 
347     /**
348      * The DefaultAuthenticator does not make any changes to an updated profile.
349      *
350      * @param user           a User object that contains the updated profile
351      * @param updateType     the type of information that is being updated
352      * @param authentication the user's authentication information, if known
353      * @param authType       the type of authentication information being provided
354      * @param reqSource      the source of the request (eg web, api)
355      * @return boolean indicating whther changes to the user were made
356      * @throws AuthenticatorException an exception if the login is unsuccessful, or an error occurs
357      */
358     public boolean updateProfile(User user, int updateType, Object authentication, int authType, int reqSource) throws AuthenticatorException {
359         return false;
360     }
361 
362 }