/* * Copyright (c) 2005-2011 Grameen Foundation USA * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * See also http://www.apache.org/licenses/LICENSE-2.0.html for an * explanation of the license and how it is applied. */ package org.mifos.application.servicefacade; import java.util.Date; import java.util.List; import java.util.Locale; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.mifos.accounts.servicefacade.UserContextFactory; import org.mifos.application.admin.servicefacade.PersonnelServiceFacade; import org.mifos.config.PasswordRules; import org.mifos.config.business.MifosConfigurationManager; import org.mifos.core.MifosRuntimeException; import org.mifos.customers.personnel.business.PersonnelBO; import org.mifos.customers.personnel.business.service.PersonnelService; import org.mifos.customers.personnel.exceptions.PersonnelException; import org.mifos.customers.personnel.persistence.PersonnelDao; import org.mifos.customers.personnel.util.helpers.PersonnelConstants; import org.mifos.dto.domain.ChangePasswordRequest; import org.mifos.dto.domain.LoginDto; import org.mifos.dto.domain.ValueListElement; import org.mifos.framework.exceptions.ApplicationException; import org.mifos.framework.hibernate.helper.HibernateTransactionHelper; import org.mifos.framework.hibernate.helper.HibernateTransactionHelperForStaticHibernateUtil; import org.mifos.security.MifosUser; import org.mifos.security.login.util.helpers.LoginConstants; import org.mifos.security.util.UserContext; import org.mifos.service.BusinessRuleException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.validation.Errors; public class LoginServiceFacadeWebTier implements NewLoginServiceFacade { private final PersonnelService personnelService; private final PersonnelDao personnelDao; private HibernateTransactionHelper transactionHelper = new HibernateTransactionHelperForStaticHibernateUtil(); private static final String COUNTRY_CODE = "Localization.CountryCode"; private static final String LANGUAGE_CODE = "Localization.LanguageCode"; @Autowired public LoginServiceFacadeWebTier(PersonnelService personnelService, PersonnelDao personnelDao) { this.personnelService = personnelService; this.personnelDao = personnelDao; } @Autowired private PersonnelServiceFacade personnelServiceFacade; @Override public LoginDto login(String username, String password) { PersonnelBO user = this.personnelDao.findPersonnelByUsername(username); if (user == null) { throw new UsernameNotFoundException(LoginConstants.KEYINVALIDUSER); } MifosConfigurationManager configMgr = MifosConfigurationManager.getInstance(); List<ValueListElement> localeList = personnelServiceFacade.getDisplayLocaleList(); Locale preferredLocale = new Locale(configMgr.getString(LANGUAGE_CODE), configMgr.getString(COUNTRY_CODE)); String listElement = "[" + preferredLocale.toString() + "]"; Short localeId = user.getPreferredLocale(); for (ValueListElement element : localeList) { if (element.getName().contains(listElement)) { localeId = element.getId().shortValue(); break; } } user.setPreferredLocale(localeId); UserContext userContext = new UserContext(); userContext.setPreferredLocale(preferredLocale); userContext.setLocaleId(localeId); userContext.setId(user.getPersonnelId()); userContext.setName(user.getDisplayName()); userContext.setLevel(user.getLevelEnum()); userContext.setRoles(user.getRoles()); userContext.setLastLogin(user.getLastLogin()); userContext.setPasswordChanged(user.getPasswordChanged()); userContext.setBranchId(user.getOffice().getOfficeId()); userContext.setBranchGlobalNum(user.getOffice().getGlobalOfficeNum()); userContext.setOfficeLevelId(user.getOffice().getLevel().getId()); user.updateDetails(userContext); try { this.transactionHelper.startTransaction(); this.transactionHelper.beginAuditLoggingFor(user); user.login(password); this.personnelDao.save(user); this.transactionHelper.commitTransaction(); boolean isPasswordExpired = new LocalDate(user.getPasswordExpirationDate()).isBefore(new LocalDate()); return new LoginDto(user.getPersonnelId(), user.getOffice().getOfficeId(), user.isPasswordChanged(), isPasswordExpired); } catch (ApplicationException e) { this.transactionHelper.rollbackTransaction(); throw new BusinessRuleException(e.getKey(), e); } catch (Exception e) { this.transactionHelper.rollbackTransaction(); throw new MifosRuntimeException(e); } finally { this.transactionHelper.closeSession(); } } @Override public void changePassword(ChangePasswordRequest changePasswordRequest) { PersonnelBO user = this.personnelDao.findPersonnelByUsername(changePasswordRequest.getUsername()); this.personnelService.changePassword(user, changePasswordRequest.getNewPassword(), true); Date newExpirationDate = null; if (user.getPasswordExpirationDate() != null) { newExpirationDate = new LocalDateTime().plusDays(PasswordRules.getPasswordExpirationDatePrelongation()).toDateTime().toDate(); } personnelService.changePasswordExpirationDate(user, newExpirationDate); } @Override public boolean updatePassword(String username, String oldPassword, String newPassword) { MifosUser appUser = (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); UserContext userContext = new UserContextFactory().create(appUser); PersonnelBO user = this.personnelDao.findPersonnelByUsername(username); boolean passwordIsAlreadyChanged = user.isPasswordChanged(); this.personnelService.changePassword(user, newPassword, true); Date newExpirationDate = null; if (user.getPasswordExpirationDate() != null) { newExpirationDate = new LocalDateTime().plusDays(PasswordRules.getPasswordExpirationDatePrelongation()).toDateTime().toDate(); } personnelService.changePasswordExpirationDate(user, newExpirationDate); return passwordIsAlreadyChanged; } @Override public boolean checkOldPassword(String username, String oldPassword) { try { return this.personnelDao.findPersonnelByUsername(username).isPasswordValid(oldPassword); } catch (PersonnelException e) { return false; } } @Override public void validatePassword(String password, Errors errors) { if (password.length() < PasswordRules.getMinPasswordLength()) { errors.reject(PersonnelConstants.ERROR_PASSWORD_LENGTH, new Integer[]{PasswordRules.getMinPasswordLength()}, "Password should have the minimum length of " + PasswordRules.getMinPasswordLength() + " characters."); } if (PasswordRules.isMustContainDigit() && !password.matches(".*\\d.*")) { errors.reject(PersonnelConstants.ERROR_PASSWORD_DIGIT); } if (PasswordRules.isMustContainSpecial() && StringUtils.isAlphanumeric(password)) { errors.reject(PersonnelConstants.ERROR_PASSWORD_SPECIAL); } if (PasswordRules.isMustContainBothCaseLetters() && !password.matches(".*[a-z]*[A-Z].*")) { //contains at least one upper and lower case letter? errors.reject(PersonnelConstants.ERROR_PASSWORD_BOTH_CASE); } } }