/** * Abiquo community edition * cloud management application for hybrid clouds * Copyright (C) 2008-2010 - Abiquo Holdings S.L. * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC * LICENSE as published by the Free Software Foundation under * version 3 of the License * * This software 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 * LESSER GENERAL PUBLIC LICENSE v.3 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package com.abiquo.abiserver.business.authentication; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import org.apache.commons.lang.StringUtils; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.abiquo.abiserver.abicloudws.AbiCloudConstants; import com.abiquo.abiserver.business.hibernate.pojohb.user.UserHB; import com.abiquo.abiserver.config.AbiConfig; import com.abiquo.abiserver.config.AbiConfigManager; import com.abiquo.abiserver.persistence.hibernate.HibernateUtil; import com.abiquo.abiserver.pojo.authentication.Login; import com.abiquo.abiserver.pojo.authentication.LoginResult; import com.abiquo.abiserver.pojo.authentication.UserSession; import com.abiquo.abiserver.pojo.result.BasicResult; import com.abiquo.abiserver.pojo.result.DataResult; import com.abiquo.util.ErrorManager; import com.abiquo.util.resources.ResourceManager; /** * This Authentication Manager provides authentication services, with a Data Base backend. * * @author Oliver * @deprecated From now on we should log in (authenticat) against the API! * {@link AuthenticationManagerApi} */ @Deprecated public class AuthenticationManagerDB implements IAuthenticationManager { private static final Logger logger = LoggerFactory.getLogger(AuthenticationManagerDB.class); private final AbiConfig abiConfig = AbiConfigManager.getInstance().getAbiConfig(); private static final ResourceManager resourceManger = new ResourceManager(AuthenticationManagerDB.class); private final ErrorManager errorManager = ErrorManager .getInstance(AbiCloudConstants.ERROR_PREFIX); @Override @SuppressWarnings("unchecked") public DataResult<LoginResult> doLogin(final Login login) { DataResult<LoginResult> dataResult = new DataResult<LoginResult>(); Session session = null; Transaction transaction = null; try { session = HibernateUtil.getSession(); transaction = session.beginTransaction(); // Get the user from the appropiate source UserHB userHB = null; if (StringUtils.isBlank(login.getAuthToken())) { userHB = getUser(login, session); } else { userHB = getUserUsingToken(login, session); } if (userHB != null) { // User exists. Check if it is active if (userHB.getActive() == 1) { // User exists in database and is active. // Looking for all existing active sessions of this user, ordered by when were // created ArrayList<UserSession> oldUserSessions = (ArrayList<UserSession>) session.createCriteria(UserSession.class) .add(Restrictions.eq("user", login.getUser())) .addOrder(Order.desc("key")).list(); Date currentTime = new Date(); // We erase old expired sessions for (UserSession existingSession : oldUserSessions) { if (currentTime.after(existingSession.getExpireDate())) { session.delete(existingSession); } } // Creating the user session UserSession userSession = new UserSession(); userSession.setUser(userHB.getUser()); userSession.setKey(String.valueOf(Calendar.getInstance().getTimeInMillis())); userSession.setLocale(login.getLocale()); userSession.setUserIdDb(userHB.getIdUser()); userSession.setEnterpriseName(userHB.getEnterpriseHB().getName()); int sessionTimeout = abiConfig.getSessionTimeout(); long expireMilis = new Date().getTime() + sessionTimeout * 60 * 1000; Date expireDate = new Date(expireMilis); userSession.setExpireDate(expireDate); // Saving in Data Base the created User Session session.save(userSession); // Generating the login result, with the user who has logged in and his session LoginResult loginResult = new LoginResult(); loginResult.setSession(userSession); loginResult.setUser(userHB.toPojo()); // Generating the DataResult dataResult.setSuccess(true); dataResult.setMessage(AuthenticationManagerDB.resourceManger .getMessage("doLogin.success")); dataResult.setData(loginResult); } else { // User is not active. Generating the DataResult errorManager.reportError(resourceManger, dataResult, "doLogin.userInActive"); } } else { // User not exists in database or bad credentials. Generating the DataResult errorManager.reportError(resourceManger, dataResult, "doLogin.passwordUserIncorrect"); dataResult.setResultCode(BasicResult.USER_INVALID); } transaction.commit(); } catch (Exception e) { if (transaction != null && transaction.isActive()) { transaction.rollback(); } errorManager.reportError(resourceManger, dataResult, "doLogin.exception", e); } return dataResult; } @Override public BasicResult doLogout(final UserSession userSession) { BasicResult basicResult = new BasicResult(); Session session = null; Transaction transaction = null; try { session = HibernateUtil.getSession(); transaction = session.beginTransaction(); // Deleting the user session UserSession previousSession = (UserSession) session.createCriteria(UserSession.class) .add(Restrictions.eq("user", userSession.getUser())) .add(Restrictions.eq("key", userSession.getKey())).uniqueResult(); if (previousSession != null) { session.delete(previousSession.getClass().getSimpleName(), previousSession); } basicResult.setSuccess(true); basicResult.setMessage(AuthenticationManagerDB.resourceManger .getMessage("doLogout.success")); transaction.commit(); } catch (Exception e) { if (transaction != null && transaction.isActive()) { transaction.rollback(); } errorManager.reportError(resourceManger, basicResult, "doLogout", e); } return basicResult; } @Override public BasicResult checkSession(final UserSession userSession) { BasicResult checkSessionResult = new BasicResult(); Session session = null; Transaction transaction = null; UserSession sessionToCheck = null; try { session = HibernateUtil.getSession(); transaction = session.beginTransaction(); sessionToCheck = (UserSession) HibernateUtil.getSession().createCriteria(UserSession.class) .add(Restrictions.eq("user", userSession.getUser())) .add(Restrictions.eq("key", userSession.getKey())).uniqueResult(); if (sessionToCheck == null) { // The session does not exist, so is not valid checkSessionResult.setResultCode(BasicResult.SESSION_INVALID); logger.trace("Invalod session. Please login again"); } else { // Checking if the session has expired Date currentDate = new Date(); if (currentDate.before(sessionToCheck.getExpireDate())) { // The session is valid updating the expire Date int sessionTimeout = abiConfig.getSessionTimeout(); long expireMilis = new Date().getTime() + sessionTimeout * 60 * 1000; Date expireDate = new Date(expireMilis); sessionToCheck.setExpireDate(expireDate); session.update(sessionToCheck); checkSessionResult.setSuccess(true); checkSessionResult.setMessage(AuthenticationManagerDB.resourceManger .getMessage("checkSession.success")); } else { // The session has time out. Deleting the session from Data Base session.delete(sessionToCheck); checkSessionResult.setResultCode(BasicResult.SESSION_TIMEOUT); logger.trace("Session expired. Please login again"); } } transaction.commit(); } catch (Exception e) { if (transaction != null && transaction.isActive()) { transaction.rollback(); } logger.trace("Unexpected error while checking the user session", e); } return checkSessionResult; } @Override public boolean isLoggedIn(final String username) { List<UserSession> sessions = findAllSessions(username); return sessions != null && !sessions.isEmpty(); } @SuppressWarnings("unchecked") @Override public List<UserSession> findAllSessions(final String username) { Session session = null; Transaction transaction = null; List<UserSession> sessions = null; try { session = HibernateUtil.getSession(); transaction = session.beginTransaction(); sessions = session.createCriteria(UserSession.class).add(Restrictions.eq("user", username)) .list(); transaction.commit(); } catch (Exception ex) { if (transaction != null && transaction.isActive()) { transaction.rollback(); } BasicResult checkSessionResult = new BasicResult(); checkSessionResult.setSuccess(false); errorManager.reportError(resourceManger, checkSessionResult, "checkSession.exception", ex); } return sessions; } /** * gets a user from DB given the credentials. * * @param login The user credentials. * @param session The Hibernate session. * @return The user. */ private UserHB getUser(final Login login, final Session session) { // Checking if a user exists for the given credentials (remeber to check that the user String customQuery = "SELECT * FROM user WHERE user= :user AND password= :password"; Query query = session.createSQLQuery(customQuery).addEntity(UserHB.class); query.setString("user", login.getUser()); query.setString("password", login.getPassword()); return (UserHB) query.uniqueResult(); } /** * Gets the user from DB using the authentication Token information. * * @param login The object with the token information. * @param session The Hibernate session. * @return The user. */ private UserHB getUserUsingToken(final Login login, final Session session) throws Exception { // Get token data String[] token = TokenUtils.getTokenFields(login.getAuthToken()); String tokenUser = TokenUtils.getTokenUser(token); long tokenExpiration = TokenUtils.getTokenExpiration(token); String tokenSignature = TokenUtils.getTokenSignature(token); // Check token expiration if (TokenUtils.isTokenExpired(tokenExpiration)) { throw new Exception("Authentication token has expired."); } // Get the token user from db String customQuery = "SELECT * FROM user WHERE user= :user"; Query query = session.createSQLQuery(customQuery).addEntity(UserHB.class); query.setString("user", tokenUser); UserHB userHB = (UserHB) query.uniqueResult(); if (userHB != null) { // Validate credentials with the token String signature = TokenUtils.makeTokenSignature(tokenExpiration, userHB.getUser(), userHB.getPassword()); if (!signature.equals(tokenSignature)) { return null; } } return userHB; } }