Package org.projectforge.user

Source Code of org.projectforge.user.LoginDefaultHandler

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.user;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.PredicateUtils;
import org.projectforge.registry.Registry;
import org.projectforge.web.UserFilter;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.orm.hibernate3.HibernateTemplate;

public class LoginDefaultHandler implements LoginHandler
{
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LoginDefaultHandler.class);

  private UserDao userDao;

  /**
   * Only needed if the data-base needs an update first (may-be the PFUserDO can't be read because of unmatching tables).
   */
  private DataSource dataSource;

  private HibernateTemplate hibernateTemplate;

  /**
   * @see org.projectforge.user.LoginHandler#initialize(org.projectforge.registry.Registry)
   */
  @Override
  public void initialize()
  {
    final Registry registry = Registry.instance();
    userDao = registry.getDao(UserDao.class);
    dataSource = registry.getDataSource();
    hibernateTemplate = registry.getHibernateTemplate();
  }

  /**
   * @see org.projectforge.user.LoginHandler#checkLogin(java.lang.String, java.lang.String, boolean)
   */
  @Override
  public LoginResult checkLogin(final String username, final String password)
  {
    final LoginResult loginResult = new LoginResult();
    PFUserDO user = null;
    if (UserFilter.isUpdateRequiredFirst() == true) {
      // Only administrator login is allowed. The login is checked without Hibernate because the data-base schema may be out-dated thus
      // Hibernate isn't functioning.
      try {
        final PFUserDO resUser = getUserWithJdbc(username, password);
        if (resUser == null || resUser.getUsername() == null) {
          log.info("Admin login for maintenance (data-base update) failed for user '" + username + "' (user/password not found).");
          return loginResult.setLoginResultStatus(LoginResultStatus.FAILED);
        }
        if (isAdminUser(resUser) == false) {
          return loginResult.setLoginResultStatus(LoginResultStatus.ADMIN_LOGIN_REQUIRED);
        }
        userDao.getUserGroupCache().internalSetAdminUser(resUser); // User is now marked as admin user.
        return loginResult.setLoginResultStatus(LoginResultStatus.SUCCESS).setUser(resUser);
      } catch (final Exception ex) {
        log.error(ex.getMessage(), ex);
      }
    } else {
      user = userDao.authenticateUser(username, password);
    }
    if (user != null) {
      log.info("User with valid username/password: " + username + "/****");
      if (user.hasSystemAccess() == false) {
        log.info("User has no system access (is deleted/deactivated): " + user.getDisplayUsername());
        return loginResult.setLoginResultStatus(LoginResultStatus.LOGIN_EXPIRED);
      } else {
        return loginResult.setLoginResultStatus(LoginResultStatus.SUCCESS).setUser(user);
      }
    } else {
      log.info("User login failed: " + username + "/****");
      return loginResult.setLoginResultStatus(LoginResultStatus.FAILED);
    }
  }

  /**
   * Only administrator login is allowed. The login is checked without Hibernate because the data-base schema may be out-dated thus
   * Hibernate isn't functioning.
   * @param jdbc
   * @param username
   * @param password
   * @return
   * @throws SQLException
   */
  private PFUserDO getUserWithJdbc(final String username, final String password) throws SQLException
  {
    final JdbcTemplate jdbc = new JdbcTemplate(dataSource);
    String sql = "select pk, firstname, lastname, password, password_salt from t_pf_user where username=? and deleted=false and deactivated=false and restricted_user=false";
    PFUserDO user = null;
    try {
      user = loadUser(jdbc, sql, username, true);
    } catch (final Exception ex) {
      log.warn("This SQLException is only OK if you've a ProjectForge installation 5.2 or minor!");
      sql = "select pk, firstname, lastname, password from t_pf_user where username=? and deleted=false and deactivated=false and restricted_user=false";
      user = loadUser(jdbc, sql, username, false);
    }
    if (user == null) {
      return null;
    }
    final PasswordCheckResult passwordCheckResult = userDao.checkPassword(user, password);
    if (passwordCheckResult.isOK() == false) {
      log.warn("Login for admin user '" + username + "' in maintenance mode failed, wrong password.");
      return null;
    }
    return user;
  }

  /**
   * @param user
   * @param rs
   * @param username
   * @param withSaltString false before ProjectForge version 5.3.
   * @throws SQLException
   */
  @SuppressWarnings({ "unchecked", "rawtypes"})
  private PFUserDO loadUser(final JdbcTemplate jdbc, final String sql, final String username, final boolean withSaltString)
      throws SQLException
      {
    final PFUserDO user = (PFUserDO)jdbc.query(sql, new Object[] { username}, new ResultSetExtractor() {
      @Override
      public Object extractData(final ResultSet rs) throws SQLException, DataAccessException
      {
        if (rs.next() == true) {
          final PFUserDO user = new PFUserDO();
          user.setUsername(username);
          final String password = rs.getString("password");
          final int pk = rs.getInt("pk");
          final String firstname = rs.getString("firstname");
          final String lastname = rs.getString("lastname");
          if (withSaltString == true) {
            final String saltString = rs.getString("password_salt");
            user.setPasswordSalt(saltString);
          }
          user.setId(pk);
          user.setUsername(username).setFirstname(firstname).setLastname(lastname).setPassword(password);
          return user;
        }
        return null;
      }
    });
    return user;
      }

  public boolean isAdminUser(final PFUserDO user)
  {
    final JdbcTemplate jdbc = new JdbcTemplate(dataSource);
    String sql = "select pk from t_group where name=?";
    final int adminGroupId = jdbc.queryForInt(sql, new Object[] { ProjectForgeGroup.ADMIN_GROUP.getKey()});
    sql = "select count(*) from t_group_user where group_id=? and user_id=?";
    final int count = jdbc.queryForInt(sql, new Object[] { adminGroupId, user.getId()});
    if (count != 1) {
      log.info("Admin login for maintenance (data-base update) failed for user '"
          + user.getUsername()
          + "' (user not member of admin group).");
      return false;
    }
    return true;
  }

  /**
   * @see org.projectforge.user.LoginHandler#checkStayLoggedIn(org.projectforge.user.PFUserDO)
   */
  @Override
  public boolean checkStayLoggedIn(final PFUserDO user)
  {
    final PFUserDO dbUser = userDao.getUserGroupCache().getUser(user.getId());
    if (dbUser != null && dbUser.hasSystemAccess() == true) {
      return true;
    }
    log.warn("User is deleted/deactivated, stay-logged-in denied for the given user: " + user);
    return false;
  }

  /**
   * The assigned users are fetched.
   * @see org.projectforge.user.LoginHandler#getAllGroups()
   */
  @SuppressWarnings("unchecked")
  @Override
  public List<GroupDO> getAllGroups()
  {
    try {
      List<GroupDO> list = hibernateTemplate.find("from GroupDO t");
      if (list != null) {
        list = (List<GroupDO>) selectUnique(list);
      }
      return list;
    } catch (final Exception ex) {
      log.fatal(
          "******* Exception while getting groups from data-base (OK only in case of migration from older versions): " + ex.getMessage(),
          ex);
      return new ArrayList<GroupDO>();
    }
  }

  /**
   * @see org.projectforge.user.LoginHandler#getAllUsers()
   */
  @SuppressWarnings("unchecked")
  @Override
  public List<PFUserDO> getAllUsers()
  {
    try {
      return hibernateTemplate.find("from PFUserDO t");
    } catch (final Exception ex) {
      log.fatal("******* Exception while getting users from data-base (OK only in case of migration from older versions): "
          + ex.getMessage(), ex);
      return new ArrayList<PFUserDO>();
    }
  }

  /**
   * Do nothing.
   * @see org.projectforge.user.LoginHandler#afterUserGroupCacheRefresh(java.util.List, java.util.List)
   */
  @Override
  public void afterUserGroupCacheRefresh(final Collection<PFUserDO> users, final Collection<GroupDO> groups)
  {
  }

  protected List< ? > selectUnique(final List< ? > list)
  {
    final List< ? > result = (List< ? >) CollectionUtils.select(list, PredicateUtils.uniquePredicate());
    return result;
  }

  /**
   * This login handler doesn't support an external user management system.
   * @return false.
   * @see org.projectforge.user.LoginHandler#hasExternalUsermanagementSystem()
   */
  @Override
  public boolean hasExternalUsermanagementSystem()
  {
    return false;
  }

  /**
   * Do nothing.
   * @see org.projectforge.user.LoginHandler#passwordChanged(org.projectforge.user.PFUserDO, java.lang.String)
   */
  @Override
  public void passwordChanged(final PFUserDO user, final String newPassword)
  {
    // Do nothing.
  }

  /**
   * @see org.projectforge.user.LoginHandler#isPasswordChangeSupported(org.projectforge.user.PFUserDO)
   * @return always true.
   */
  @Override
  public boolean isPasswordChangeSupported(final PFUserDO user)
  {
    return true;
  }
}
TOP

Related Classes of org.projectforge.user.LoginDefaultHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.