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 Permissionermission">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 }