DefaultAuthenticator.java

  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. package org.itracker.services.authentication;

  19. import org.apache.log4j.Logger;
  20. import org.itracker.model.Permission;
  21. import org.itracker.model.PermissionType;
  22. import org.itracker.model.User;
  23. import org.itracker.UserException;
  24. import org.itracker.services.exceptions.AuthenticatorException;
  25. import org.itracker.PasswordException;
  26. import org.itracker.model.util.UserUtilities;

  27. import org.springframework.dao.DataAccessException;

  28. import java.util.ArrayList;
  29. import java.util.HashMap;
  30. import java.util.List;
  31. import java.util.Map;


  32. /**
  33.  * This class provides a default authentication scheme for ITracker.  It uses passwords
  34.  * in the user table provided by ITracker to authenticate users.  This authenticator
  35.  * allows any user to self register if self registration is available in the system.
  36.  */
  37. public class DefaultAuthenticator extends AbstractPluggableAuthenticator {

  38.     private static final Logger logger = Logger.getLogger(DefaultAuthenticator.class);

  39.     /**
  40.      * Checks the login of a user against the user profile provided in ITracker.  This is
  41.      * the default authentication scheme provided by ITracker.
  42.      *
  43.      * @param login          the login the user/client provided
  44.      * @param authentication the user's authentication information, if known
  45.      * @param authType       the type of authentication information being provided
  46.      * @param reqSource      the source of the request (eg web, api)
  47.      * @return a User if the login is successful
  48.      * @throws AuthenticatorException an exception if the login is unsuccessful, or an error occurs
  49.      */
  50.     public User checkLogin(final String login, final Object authentication, final int authType, final int reqSource) throws AuthenticatorException {
  51.         if (logger.isDebugEnabled()) {
  52.             logger.debug("Checking login for " + login + " using DefaultAuthenticator");
  53.         }

  54.         if (login != null && authentication != null && !login.equals("")) {
  55.             User user;
  56.             try {
  57.                 user = getUserService().getUserByLogin(login);
  58.             } catch (DataAccessException e) {
  59.                 logger.error("checkLogin: failed to get user by login: " + login, e);
  60.                 throw new AuthenticatorException(AuthenticatorException.UNKNOWN_USER, e.getMessage());
  61.             }

  62.             if (user.getStatus() != UserUtilities.STATUS_ACTIVE) {
  63.                 AuthenticatorException e = new AuthenticatorException(AuthenticatorException.INACTIVE_ACCOUNT);
  64.                 logger.info("checkLogin: user is inactive, user: " + user, e);
  65.                 throw e;
  66.             }

  67.             String userPassword;
  68.             try {
  69.                 userPassword = getUserService().getUserPasswordByLogin(login);
  70.             } catch (DataAccessException e) {
  71.                 AuthenticatorException ex = new AuthenticatorException(e.getMessage(), authType);
  72.                 logger.info("checkLogin: user is inactive, user: " + user, ex);
  73.                 throw e;
  74.             }
  75.             if (userPassword == null || userPassword.equals("")) {
  76.                 AuthenticatorException e = new AuthenticatorException(AuthenticatorException.INVALID_PASSWORD);
  77.                 logger.info("checkLogin: user has no password, user: " + user, e);
  78.                 throw e;
  79.             }

  80.             try {
  81.                 if (!userPassword.endsWith("=")) {
  82.                     logger.info("checkLogin: User " + login + " has old style password.  Converting to SHA1 hash.");
  83.                     try {
  84.                         user.setPassword(UserUtilities.encryptPassword(userPassword));
  85.                         getUserService().updateUser(user);
  86.                     } catch (UserException ue) {
  87.                         logger.error("checkLogin: User password conversion failed for user " + user, ue);
  88.                         throw new AuthenticatorException(AuthenticatorException.SYSTEM_ERROR);
  89.                     }
  90.                 }

  91.                 if (authType == AUTH_TYPE_PASSWORD_PLAIN) {
  92.                     if (!userPassword.equals(UserUtilities.encryptPassword((String) authentication))) {
  93.                         throw new AuthenticatorException(AuthenticatorException.INVALID_PASSWORD);
  94.                     }
  95.                 } else if (authType == AUTH_TYPE_PASSWORD_ENC) {
  96.                     if (!userPassword.equals(authentication)) {
  97.                         throw new AuthenticatorException(AuthenticatorException.INVALID_PASSWORD);
  98.                     }
  99.                 } else {
  100.                     logger.info("checkLogin: invalid authenticator type: " + authType);
  101.                     throw new AuthenticatorException(AuthenticatorException.INVALID_AUTHENTICATION_TYPE);
  102.                 }
  103.             } catch (ClassCastException cce) {
  104.                 logger.error("checkLogin: Authenticator was of wrong type.", cce);
  105.                 throw new AuthenticatorException(AuthenticatorException.SYSTEM_ERROR);
  106.             } catch (PasswordException pe) {
  107.                 throw new AuthenticatorException(AuthenticatorException.SYSTEM_ERROR);
  108.             } catch (AuthenticatorException ae) {
  109.                 if (logger.isDebugEnabled()) {
  110.                     logger.debug("checkLogin: failed to authenticate " + login, ae);
  111.                 }
  112.                 throw ae;
  113.             }

  114.             return user;
  115.         }

  116.         logger.info("checkLogin: no login was supplied: " + login + ", type: " + authType + ", source: " + reqSource);
  117.         throw new AuthenticatorException(AuthenticatorException.INVALID_DATA);
  118.     }

  119.     /**
  120.      * The DefaultAuthenticator returns a list of user permissions from the database.
  121.      *
  122.      * @param user      a User object that contains the user to retrieve permissions for
  123.      * @param reqSource the source of the request (eg web, api)
  124.      * @return an array of PermissionModels
  125.      * @throws AuthenticatorException an error occurs
  126.      */
  127.     public List<Permission> getUserPermissions(User user, int reqSource) throws AuthenticatorException {
  128.         if (user == null || user.getId() == null) {
  129.             throw new AuthenticatorException(AuthenticatorException.INVALID_DATA);
  130.         }

  131.         List<Permission> permissionList;
  132.         try {
  133.             permissionList = getUserService().getUserPermissionsLocal(user);
  134.         } catch (DataAccessException e) {
  135.             throw new AuthenticatorException(e.getMessage(), reqSource);
  136.         }

  137.         if (user.isSuperUser()) {
  138.             List<Permission> augmentedPermissions = new ArrayList<Permission>();

  139.             // Super user has access to all projects (represented by the "null" project).
  140.             Permission permission = new Permission(PermissionType.USER_ADMIN, user, null);
  141.             augmentedPermissions.add(permission);
  142.             augmentedPermissions.addAll(permissionList);
  143.             return augmentedPermissions;

  144.         } else {
  145.             return permissionList;
  146.         }

  147.     }



  148.     /**
  149.      * Returns the list of users for a given project. User permissions can be specified.
  150.      *
  151.      * @param projectId       - The Project to search for users
  152.      * @param permissionTypes - User rights to filter
  153.      * @param requireAll      - Require all permissions
  154.      * @param activeOnly      - Filter users who are active (Possible user status: DELETED, ACTIVE, LOCKED)
  155.      * @param reqSource       - not used. TODO: Tagged for removal
  156.      * @return List of users for the project with filters applied.
  157.      */
  158.     @Override
  159.     public List<User> getUsersWithProjectPermission(Integer projectId, PermissionType[] permissionTypes, boolean requireAll, boolean activeOnly, int reqSource) throws AuthenticatorException {

  160.         List<User> users;

  161.         try {
  162.             Map<Integer, User> userMap = new HashMap<Integer, User>();

  163.             if (requireAll) {

  164.                 List<User> explicitUsers = getUserService().findUsersForProjectByPermissionTypeList(projectId, permissionTypes);

  165.                 for (User user : explicitUsers) {
  166.                     userMap.put(user.getId(), user);
  167.                 }
  168.             } else {

  169.                 for (int i = 0; i < permissionTypes.length; i++) {
  170.                     List<User> explicitUsers = getUserService().getUsersWithPermissionLocal(projectId, permissionTypes[i]);

  171.                     for (User user : explicitUsers) {
  172.                         userMap.put(user.getId(), user);
  173.                     }

  174.                 }

  175.             }

  176.             List<User> superUsers = getUserService().getSuperUsers();
  177.             for (User superUser : superUsers) {
  178.                 userMap.put(superUser.getId(), superUser);
  179.             }

  180.             users = new ArrayList<User>();
  181.             for (User user : userMap.values()) {
  182.                 if (activeOnly) {
  183.                     if (user.getStatus() == UserUtilities.STATUS_ACTIVE) {
  184.                         users.add(user);
  185.                     }
  186.                 } else {
  187.                     users.add(user);
  188.                 }
  189.             }

  190.         } catch (Exception e) {
  191.             logger.error("Error retreiving users with permissions.", e);
  192.             throw new AuthenticatorException();
  193.         }

  194.         return users;
  195.     }
  196.     @Override
  197.     @Deprecated
  198.     public List<User> getUsersWithProjectPermission(Integer projectId,
  199.                                                     int[] permissionTypes,
  200.                                                     boolean requireAll,
  201.                                                     boolean activeOnly,
  202.                                                     int reqSource)
  203.             throws AuthenticatorException {

  204.         return getUsersWithProjectPermission(projectId,
  205.                 PermissionType.valueOf(permissionTypes),
  206.                 requireAll,
  207.                 activeOnly,
  208.                 reqSource);

  209.     }

  210.     /**
  211.      * The DefaultAuthenticator always allows self registered users.
  212.      *
  213.      * @param user           a User object that contains the data the user submitted
  214.      * @param authentication the user's authentication information, if known
  215.      * @param authType       the type of authentication information being provided
  216.      * @param reqSource      the source of the request (eg web, api)
  217.      * @return true
  218.      */
  219.     public boolean allowRegistration(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
  220.         return true;
  221.     }


  222.     /**
  223.      * The DefaultAuthenticator always allows new user profiles.
  224.      *
  225.      * @param user           a User object that contains the data the user submitted
  226.      * @param authentication the user's authentication information, if known
  227.      * @param authType       the type of authentication information being provided
  228.      * @return true
  229.      * @throws AuthenticatorException an exception if an error occurs
  230.      */
  231.     public boolean allowProfileCreation(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
  232.         return true;
  233.     }

  234.     /**
  235.      * The DefaultAuthenticator always allows profile updates.
  236.      *
  237.      * @param user           a User object that contains the data the user submitted
  238.      * @param authentication the user's authentication information, if known
  239.      * @param authType       the type of authentication information being provided
  240.      * @param reqSource      the source of the request (eg web, api)
  241.      * @return true
  242.      * @throws AuthenticatorException an exception if an error occurs
  243.      */
  244.     public boolean allowProfileUpdates(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
  245.         return true;
  246.     }

  247.     /**
  248.      * The DefaultAuthenticator always allows password updates.
  249.      *
  250.      * @param user           a User object that contains the data the user submitted
  251.      * @param authentication the user's authentication information, if known
  252.      * @param authType       the type of authentication information being provided
  253.      * @param reqSource      the source of the request (eg web, api)
  254.      * @return true
  255.      * @throws AuthenticatorException an exception if an error occurs
  256.      */
  257.     public boolean allowPasswordUpdates(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
  258.         return true;
  259.     }

  260.     /**
  261.      * The DefaultAuthenticator always allows permission updates.
  262.      *
  263.      * @param user           a User object that contains the data the user submitted
  264.      * @param authentication the user's authentication information, if known
  265.      * @param authType       the type of authentication information being provided
  266.      * @param reqSource      the source of the request (eg web, api)
  267.      * @return true
  268.      * @throws AuthenticatorException an exception if an error occurs
  269.      */
  270.     public boolean allowPermissionUpdates(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
  271.         return true;
  272.     }

  273.     /**
  274.      * The DefaultAuthenticator always allows preferences updates.
  275.      *
  276.      * @param user           a User object that contains the data the user submitted
  277.      * @param authentication the user's authentication information, if known
  278.      * @param authType       the type of authentication information being provided
  279.      * @param reqSource      the source of the request (eg web, api)
  280.      * @return true
  281.      * @throws AuthenticatorException an exception if an error occurs
  282.      */
  283.     public boolean allowPreferenceUpdates(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
  284.         return true;
  285.     }

  286.     /**
  287.      * The DefaultAuthenticator does not make any changes to a newly created profile.
  288.      *
  289.      * @param user           a User object that contains the newly created profile
  290.      * @param authentication the user's authentication information, if known
  291.      * @param authType       the type of authentication information being provided
  292.      * @param reqSource      the source of the request (eg web, api)
  293.      * @return boolean indicating whther changes to the user were made
  294.      * @throws AuthenticatorException an error occurs
  295.      */
  296.     public boolean createProfile(User user, Object authentication, int authType, int reqSource) throws AuthenticatorException {
  297.         return false;
  298.     }

  299.     /**
  300.      * The DefaultAuthenticator does not make any changes to an updated profile.
  301.      *
  302.      * @param user           a User object that contains the updated profile
  303.      * @param updateType     the type of information that is being updated
  304.      * @param authentication the user's authentication information, if known
  305.      * @param authType       the type of authentication information being provided
  306.      * @param reqSource      the source of the request (eg web, api)
  307.      * @return boolean indicating whther changes to the user were made
  308.      * @throws AuthenticatorException an exception if the login is unsuccessful, or an error occurs
  309.      */
  310.     public boolean updateProfile(User user, int updateType, Object authentication, int authType, int reqSource) throws AuthenticatorException {
  311.         return false;
  312.     }

  313. }