fixed update of account role mapping

This commit is contained in:
2018-11-25 15:14:39 +01:00
parent ac39be3848
commit 9b8284a2cf
2 changed files with 671 additions and 671 deletions

View File

@ -1,300 +1,300 @@
package de.muehlencord.shared.account.web.presentation; package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.account.control.AccountControl; import de.muehlencord.shared.account.business.account.control.AccountControl;
import de.muehlencord.shared.account.business.application.control.ApplicationRoleControl; import de.muehlencord.shared.account.business.application.control.ApplicationRoleControl;
import de.muehlencord.shared.account.business.account.entity.AccountEntity; import de.muehlencord.shared.account.business.account.entity.AccountEntity;
import de.muehlencord.shared.account.business.account.entity.AccountException; import de.muehlencord.shared.account.business.account.entity.AccountException;
import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity; import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity;
import de.muehlencord.shared.account.business.account.entity.AccountStatus; import de.muehlencord.shared.account.business.account.entity.AccountStatus;
import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.jeeutil.FacesUtil; import de.muehlencord.shared.jeeutil.FacesUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.faces.component.UIInput; import javax.faces.component.UIInput;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped; import javax.faces.view.ViewScoped;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.primefaces.event.SelectEvent; import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent; import org.primefaces.event.UnselectEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* *
* @author jomu * @author jomu
*/ */
@ViewScoped @ViewScoped
@Named("accountView") @Named("accountView")
public class AccountView implements Serializable { public class AccountView implements Serializable {
private static final long serialVersionUID = -8050582392249849438L; private static final long serialVersionUID = -8050582392249849438L;
private static final Logger LOGGER = LoggerFactory.getLogger(AccountView.class); private static final Logger LOGGER = LoggerFactory.getLogger(AccountView.class);
@Inject @Inject
private ApplicationView applicationView; private ApplicationView applicationView;
@EJB @EJB
private AccountControl accountService; private AccountControl accountService;
@EJB @EJB
private ApplicationRoleControl appliationRoleService; private ApplicationRoleControl appliationRoleService;
/** /**
* boolean flag to determine wether disabled accounts should be shown * boolean flag to determine wether disabled accounts should be shown
* accounts are not deleted but disabled and can be activated in case * accounts are not deleted but disabled and can be activated in case
*/ */
private boolean showDisabledAccounts = false; private boolean showDisabledAccounts = false;
// cached accounts // cached accounts
private List<AccountEntity> accountList = null; private List<AccountEntity> accountList = null;
// cached application roles // cached application roles
private List<ApplicationRoleEntity> applicationRoles = null; private List<ApplicationRoleEntity> applicationRoles = null;
// account currently on edit // account currently on edit
private AccountEntity currentAccount; private AccountEntity currentAccount;
private List<ApplicationRoleEntity> currentAccountRoles = null; private List<ApplicationRoleEntity> currentAccountRoles = null;
private AccountLoginEntity currentAccountLogin; private AccountLoginEntity currentAccountLogin;
private String password = null; private String password = null;
private String repeatPassword = null; private String repeatPassword = null;
public List<AccountEntity> getAccounts() { public List<AccountEntity> getAccounts() {
if (accountList == null) { if (accountList == null) {
accountList = accountService.getAccounts(showDisabledAccounts); accountList = accountService.getAccounts(showDisabledAccounts);
} }
return accountList; return accountList;
} }
public List<ApplicationRoleEntity> getAllApplicationRoles() { public List<ApplicationRoleEntity> getAllApplicationRoles() {
if (applicationRoles == null) { if (applicationRoles == null) {
ApplicationEntity application = applicationView.getCurrentApplication(); ApplicationEntity application = applicationView.getCurrentApplication();
applicationRoles = appliationRoleService.getAllRoles(application); applicationRoles = appliationRoleService.getAllRoles(application);
} }
return applicationRoles; return applicationRoles;
} }
public void selectAccount(SelectEvent event) { public void selectAccount(SelectEvent event) {
// nothing to do, currentAccountRoles are loaded before dialog is shown // nothing to do, currentAccountRoles are loaded before dialog is shown
} }
public void unselectAccount(UnselectEvent event) { public void unselectAccount(UnselectEvent event) {
applicationRoles = null; applicationRoles = null;
currentAccountRoles = null; currentAccountRoles = null;
} }
public boolean getAccountSelected() { public boolean getAccountSelected() {
return currentAccount != null; return currentAccount != null;
} }
public void newAccount() { public void newAccount() {
currentAccount = new AccountEntity(); currentAccount = new AccountEntity();
currentAccount.setStatus("NEW"); // TODO add status enum currentAccount.setStatus("NEW"); // TODO add status enum
currentAccountRoles = new ArrayList<>(); currentAccountRoles = new ArrayList<>();
} }
public void editAccount() { public void editAccount() {
// function called by webpage // function called by webpage
if (currentAccount == null) { if (currentAccount == null) {
currentAccountRoles = null; currentAccountRoles = null;
} else { } else {
currentAccount = accountService.getAccountEntity(currentAccount.getUsername(), true); currentAccount = accountService.getAccountEntity(currentAccount.getUsername(), true);
this.currentAccountRoles = new ArrayList<>(); this.currentAccountRoles = new ArrayList<>();
if (currentAccount.getApplicationRoleList() != null) { if (currentAccount.getApplicationRoleList() != null) {
currentAccountRoles.addAll(currentAccount.getApplicationRoleList()); currentAccountRoles.addAll(currentAccount.getApplicationRoleList());
} }
} }
} }
public void cancelEditAccount() { public void cancelEditAccount() {
currentAccount = null; currentAccount = null;
currentAccountRoles = null; currentAccountRoles = null;
} }
public void saveEditAccount() { public void saveEditAccount() {
String username = currentAccount.getUsername(); String username = currentAccount.getUsername();
AccountEntity existingEntity = accountService.getAccountEntity(username, true); AccountEntity existingEntity = accountService.getAccountEntity(username, true);
// check if it is a new user (createdBy == null) but a user with same name already exists // check if it is a new user (createdBy == null) but a user with same name already exists
if ((currentAccount.getCreatedBy() == null) && (existingEntity != null)) { if ((currentAccount.getCreatedBy() == null) && (existingEntity != null)) {
FacesUtil.addErrorMessage("editDialogMessaegs", "Create new account failed", "Account with username " + username + " already exists"); FacesUtil.addErrorMessage("editDialogMessaegs", "Create new account failed", "Account with username " + username + " already exists");
} else { } else {
accountService.saveAccount(currentAccount, currentAccountRoles); accountService.saveAccount(currentAccount, applicationView.getCurrentApplication(), currentAccountRoles);
// force accounts to be loaded from database again // force accounts to be loaded from database again
accountList = null; accountList = null;
} }
} }
public void deleteAccount() { public void deleteAccount() {
try { try {
accountService.deleteAccount(currentAccount); accountService.deleteAccount(currentAccount);
accountList.remove(currentAccount); accountList.remove(currentAccount);
FacesUtil.addGlobalInfoMessage("Info", "Account " + currentAccount.getUsername() + " deleted"); FacesUtil.addGlobalInfoMessage("Info", "Account " + currentAccount.getUsername() + " deleted");
currentAccount = null; currentAccount = null;
currentAccountRoles = null; currentAccountRoles = null;
} catch (AccountException ex) { } catch (AccountException ex) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex); LOGGER.debug(ex.toString(), ex);
} else { } else {
LOGGER.error(ex.toString()); LOGGER.error(ex.toString());
} }
FacesUtil.addGlobalErrorMessage("Error deleting account", ex.getMessage()); FacesUtil.addGlobalErrorMessage("Error deleting account", ex.getMessage());
} }
} }
public void showDisabledAccountsChange() { public void showDisabledAccountsChange() {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("show diabled accounts changed to {}", showDisabledAccounts); LOGGER.debug("show diabled accounts changed to {}", showDisabledAccounts);
} }
this.accountList = null; this.accountList = null;
} }
public List<String> getStatusList() { public List<String> getStatusList() {
return AccountStatus.getAllStatusNames(); return AccountStatus.getAllStatusNames();
} }
/* **** account login methods **** */ /* **** account login methods **** */
public boolean validatePasswords(FacesContext context, List<UIInput> components, List<Object> values) { public boolean validatePasswords(FacesContext context, List<UIInput> components, List<Object> values) {
String password = components.get(0).getSubmittedValue().toString(); String password = components.get(0).getSubmittedValue().toString();
String passwordRepeat = components.get(1).getSubmittedValue().toString(); String passwordRepeat = components.get(1).getSubmittedValue().toString();
if ((password == null) || (passwordRepeat == null)) { if ((password == null) || (passwordRepeat == null)) {
return false; return false;
} }
boolean returnValue = password.equals(passwordRepeat); boolean returnValue = password.equals(passwordRepeat);
return returnValue; return returnValue;
} }
public void addAccountLogin() { public void addAccountLogin() {
if (currentAccount == null) { if (currentAccount == null) {
// TODO add error handling // TODO add error handling
} else { } else {
this.currentAccountLogin = accountService.createLoginWithRandomPassword(); this.currentAccountLogin = accountService.createLoginWithRandomPassword();
} }
} }
public void editAccountLogin() { public void editAccountLogin() {
if (currentAccount == null) { if (currentAccount == null) {
// TODO add error handling // TODO add error handling
} else { } else {
this.currentAccountLogin = currentAccount.getAccountLogin(); this.currentAccountLogin = currentAccount.getAccountLogin();
} }
} }
public void deleteAccountLogin() { public void deleteAccountLogin() {
if (currentAccount == null) { if (currentAccount == null) {
// TODO add error handling // TODO add error handling
} else { } else {
accountService.deleteLogin(currentAccount); accountService.deleteLogin(currentAccount);
currentAccount.setAccountLogin(null); currentAccount.setAccountLogin(null);
currentAccountLogin = null; currentAccountLogin = null;
accountList = null; // force reload accountList = null; // force reload
FacesUtil.addGlobalInfoMessage("Account saved", "Login removed"); FacesUtil.addGlobalInfoMessage("Account saved", "Login removed");
} }
} }
public void saveEditAccountLogin() { public void saveEditAccountLogin() {
// TODO move to account control - to much logic for the view // TODO move to account control - to much logic for the view
if ((currentAccountLogin == null) || (currentAccount == null)) { if ((currentAccountLogin == null) || (currentAccount == null)) {
// TODO add error handling // TODO add error handling
} else { } else {
// overwrite password if provided // overwrite password if provided
if ((password != null) && (!password.trim().equals(""))) { if ((password != null) && (!password.trim().equals(""))) {
// password has been specified // password has been specified
if (password.equals(repeatPassword)) { if (password.equals(repeatPassword)) {
currentAccount.getAccountLogin().setAccountPassword(accountService.getHashedPassword(password)); currentAccountLogin.setAccountPassword(accountService.getHashedPassword(password));
FacesUtil.addGlobalInfoMessage("Info", "Password updated"); FacesUtil.addGlobalInfoMessage("Info", "Password updated");
} else { } else {
// TODO connect to IPRS // TODO connect to IPRS
// frontend does validate passwords do match // frontend does validate passwords do match
// someone is trying to cheat // someone is trying to cheat
} }
} }
if (currentAccountLogin.getId() == null) { if (currentAccountLogin.getId() == null) {
accountService.addLogin(currentAccount, currentAccountLogin); accountService.addLogin(currentAccount, currentAccountLogin);
currentAccount.setAccountLogin(currentAccountLogin); currentAccount.setAccountLogin(currentAccountLogin);
accountList = null; // force reload of accounts accountList = null; // force reload of accounts
} else { } else {
accountService.updateLogin(currentAccountLogin); accountService.updateLogin(currentAccountLogin);
} }
currentAccountLogin = null; currentAccountLogin = null;
FacesUtil.addGlobalInfoMessage("Account saved", "Login data updated"); FacesUtil.addGlobalInfoMessage("Account saved", "Login data updated");
} }
} }
public void cancelEditAccountLogin() { public void cancelEditAccountLogin() {
this.currentAccountLogin = null; this.currentAccountLogin = null;
} }
public boolean getCurrentLoggedInUser() { public boolean getCurrentLoggedInUser() {
if (currentAccount == null) { if (currentAccount == null) {
return false; return false;
} }
Subject currentUser = SecurityUtils.getSubject(); Subject currentUser = SecurityUtils.getSubject();
if (currentUser == null) { if (currentUser == null) {
// TODO - connect to IPRS - how can this method be called if no user is logged in // TODO - connect to IPRS - how can this method be called if no user is logged in
return false; return false;
} }
String currentUserName = currentUser.getPrincipal().toString(); String currentUserName = currentUser.getPrincipal().toString();
return currentUserName.equals(currentAccount.getUsername()); return currentUserName.equals(currentAccount.getUsername());
} }
/* **** getter / setter **** */ /* **** getter / setter **** */
/** /**
* setter for managed property applicationView * setter for managed property applicationView
* *
* @param applicationView the applicaton view to inject * @param applicationView the applicaton view to inject
*/ */
public void setApplicationView(ApplicationView applicationView) { public void setApplicationView(ApplicationView applicationView) {
this.applicationView = applicationView; this.applicationView = applicationView;
} }
public AccountEntity getCurrentAccount() { public AccountEntity getCurrentAccount() {
return currentAccount; return currentAccount;
} }
public void setCurrentAccount(AccountEntity currentAccount) { public void setCurrentAccount(AccountEntity currentAccount) {
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
} }
public boolean isShowDisabledAccounts() { public boolean isShowDisabledAccounts() {
return showDisabledAccounts; return showDisabledAccounts;
} }
public void setShowDisabledAccounts(boolean showDisabledAccounts) { public void setShowDisabledAccounts(boolean showDisabledAccounts) {
this.showDisabledAccounts = showDisabledAccounts; this.showDisabledAccounts = showDisabledAccounts;
} }
public List<ApplicationRoleEntity> getCurrentAccountRoles() { public List<ApplicationRoleEntity> getCurrentAccountRoles() {
return currentAccountRoles; return currentAccountRoles;
} }
public void setCurrentAccountRoles(List<ApplicationRoleEntity> currentAccountRoles) { public void setCurrentAccountRoles(List<ApplicationRoleEntity> currentAccountRoles) {
this.currentAccountRoles = currentAccountRoles; this.currentAccountRoles = currentAccountRoles;
} }
public String getPassword() { public String getPassword() {
return password; return password;
} }
public void setPassword(String password) { public void setPassword(String password) {
this.password = password; this.password = password;
} }
public String getRepeatPassword() { public String getRepeatPassword() {
return repeatPassword; return repeatPassword;
} }
public void setRepeatPassword(String repeatPassword) { public void setRepeatPassword(String repeatPassword) {
this.repeatPassword = repeatPassword; this.repeatPassword = repeatPassword;
} }
} }

View File

@ -1,371 +1,371 @@
package de.muehlencord.shared.account.business.account.control; package de.muehlencord.shared.account.business.account.control;
import de.muehlencord.shared.account.business.account.entity.AccountException; import de.muehlencord.shared.account.business.account.entity.AccountException;
import de.muehlencord.shared.account.business.account.entity.AccountStatus; import de.muehlencord.shared.account.business.account.entity.AccountStatus;
import de.muehlencord.shared.account.business.mail.entity.MailException; import de.muehlencord.shared.account.business.mail.entity.MailException;
import de.muehlencord.shared.account.business.mail.boundary.MailService; import de.muehlencord.shared.account.business.mail.boundary.MailService;
import de.muehlencord.shared.account.business.account.entity.AccountEntity; import de.muehlencord.shared.account.business.account.entity.AccountEntity;
import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity; import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.account.util.AccountPU; import de.muehlencord.shared.account.util.AccountPU;
import de.muehlencord.shared.account.util.SecurityUtil; import de.muehlencord.shared.account.util.SecurityUtil;
import de.muehlencord.shared.util.DateUtil; import de.muehlencord.shared.util.DateUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.ejb.Stateless; import javax.ejb.Stateless;
import javax.inject.Inject; import javax.inject.Inject;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.NoResultException; import javax.persistence.NoResultException;
import javax.persistence.Query; import javax.persistence.Query;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
/** /**
* *
* @author joern.muehlencord * @author joern.muehlencord
*/ */
@Stateless @Stateless
public class AccountControl implements Serializable { public class AccountControl implements Serializable {
private static final Logger LOGGER = LoggerFactory.getLogger(AccountControl.class.getName()); private static final Logger LOGGER = LoggerFactory.getLogger(AccountControl.class.getName());
private static final long serialVersionUID = 3424816272598108101L; private static final long serialVersionUID = 3424816272598108101L;
@EJB @EJB
private MailService mailService; private MailService mailService;
@Inject @Inject
private ApplicationEntity application; private ApplicationEntity application;
@Inject @Inject
@AccountPU @AccountPU
EntityManager em; EntityManager em;
/** /**
* returns a list of active accounts * returns a list of active accounts
* *
* @return a list of active accounts * @return a list of active accounts
*/ */
public List<AccountEntity> getActiveAccounts() { public List<AccountEntity> getActiveAccounts() {
Query query = em.createQuery("SELECT a FROM AccountEntity a WHERE a.status <> :status", AccountEntity.class); Query query = em.createQuery("SELECT a FROM AccountEntity a WHERE a.status <> :status", AccountEntity.class);
query.setParameter("status", AccountStatus.DISABLED.name()); query.setParameter("status", AccountStatus.DISABLED.name());
return query.getResultList(); return query.getResultList();
} }
/** /**
* returns a list of active accounts * returns a list of active accounts
* *
* @return a list of active accounts * @return a list of active accounts
*/ */
public List<AccountEntity> getAllAccounts() { public List<AccountEntity> getAllAccounts() {
Query query = em.createNamedQuery("AccountEntity.findAll"); Query query = em.createNamedQuery("AccountEntity.findAll");
return query.getResultList(); return query.getResultList();
} }
public List<AccountEntity> getAccounts(boolean includeDisabled) { public List<AccountEntity> getAccounts(boolean includeDisabled) {
if (includeDisabled) { if (includeDisabled) {
return getAllAccounts(); return getAllAccounts();
} else { } else {
return getActiveAccounts(); return getActiveAccounts();
} }
} }
public AccountEntity getAccountEntity(String userName, boolean loadRoles) { public AccountEntity getAccountEntity(String userName, boolean loadRoles) {
StringBuilder queryBuilder = new StringBuilder(); StringBuilder queryBuilder = new StringBuilder();
queryBuilder.append("SELECT a FROM AccountEntity a "); queryBuilder.append("SELECT a FROM AccountEntity a ");
if (loadRoles) { if (loadRoles) {
queryBuilder.append("LEFT JOIN FETCH a.applicationRoleList "); queryBuilder.append("LEFT JOIN FETCH a.applicationRoleList ");
} }
queryBuilder.append("WHERE a.username = :username"); queryBuilder.append("WHERE a.username = :username");
Query query = em.createQuery(queryBuilder.toString()); Query query = em.createQuery(queryBuilder.toString());
query.setParameter("username", userName); query.setParameter("username", userName);
try { try {
return (AccountEntity) query.getSingleResult(); return (AccountEntity) query.getSingleResult();
} catch (NoResultException ex) { } catch (NoResultException ex) {
return null; return null;
} }
} }
@Transactional @Transactional
public AccountEntity saveAccount(AccountEntity account, List<ApplicationRoleEntity> applicationRoles) { public AccountEntity saveAccount(AccountEntity account, ApplicationEntity app, List<ApplicationRoleEntity> applicationRoles) {
Date now = DateUtil.getCurrentTimeInUTC(); Date now = DateUtil.getCurrentTimeInUTC();
Subject currentUser = SecurityUtils.getSubject(); Subject currentUser = SecurityUtils.getSubject();
String currentLoggedInUser = currentUser.getPrincipal().toString(); String currentLoggedInUser = currentUser.getPrincipal().toString();
account.setLastUpdatedBy(currentLoggedInUser); account.setLastUpdatedBy(currentLoggedInUser);
account.setLastUpdatedOn(now); account.setLastUpdatedOn(now);
boolean newAccount = (account.getCreatedOn() == null); boolean newAccount = (account.getCreatedOn() == null);
// new account // new account
if (newAccount) { if (newAccount) {
account.setCreatedOn(now); account.setCreatedOn(now);
account.setCreatedBy(currentLoggedInUser); account.setCreatedBy(currentLoggedInUser);
em.persist(account); em.persist(account);
} else { } else {
em.merge(account); em.merge(account);
// reload account from db and join roles // reload account from db and join roles
account = getAccountEntity(account.getUsername(), true); account = getAccountEntity(account.getUsername(), true);
} }
// assign roles to account // assign roles to account
if (account.getApplicationRoleList() == null) { if (account.getApplicationRoleList() == null) {
account.setApplicationRoleList(new ArrayList<>()); account.setApplicationRoleList(new ArrayList<>());
} }
boolean roleSetupChanged = false; boolean roleSetupChanged = false;
// remove roles which are no longer listed // remove roles which are no longer listed
// ensure this is only done for the given application - keep the other applications untouched // ensure this is only done for the given application - keep the other applications untouched
List<ApplicationRoleEntity> assignedRoles = new ArrayList<>(); List<ApplicationRoleEntity> assignedRoles = new ArrayList<>();
assignedRoles.addAll(account.getApplicationRoleList()); assignedRoles.addAll(account.getApplicationRoleList());
for (ApplicationRoleEntity currentlyAssignedRole : assignedRoles) { for (ApplicationRoleEntity currentlyAssignedRole : assignedRoles) {
if ((currentlyAssignedRole.getApplication().equals(application) && (!applicationRoles.contains(currentlyAssignedRole)))) { if ((currentlyAssignedRole.getApplication().equals(app) && (!applicationRoles.contains(currentlyAssignedRole)))) {
account.getApplicationRoleList().remove(currentlyAssignedRole); account.getApplicationRoleList().remove(currentlyAssignedRole);
roleSetupChanged = true; roleSetupChanged = true;
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Removed role {} ({}) from user {}", currentlyAssignedRole.getRoleName(), application.getApplicationName(), account.getUsername()); LOGGER.debug("Removed role {} ({}) from user {}", currentlyAssignedRole.getRoleName(), application.getApplicationName(), account.getUsername());
} }
} }
} }
// add newly added roles to role list // add newly added roles to role list
for (ApplicationRoleEntity applicationRole : applicationRoles) { for (ApplicationRoleEntity applicationRole : applicationRoles) {
if (!account.getApplicationRoleList().contains(applicationRole)) { if (!account.getApplicationRoleList().contains(applicationRole)) {
account.addApplicationRole(applicationRole); account.addApplicationRole(applicationRole);
roleSetupChanged = true; roleSetupChanged = true;
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Added role {} ({}) to account {}", applicationRole.getRoleName(), application.getApplicationName(), account.getUsername()); LOGGER.debug("Added role {} ({}) to account {}", applicationRole.getRoleName(), application.getApplicationName(), account.getUsername());
} }
} }
} }
// update account in database if roles changed // update account in database if roles changed
if (roleSetupChanged) { if (roleSetupChanged) {
em.merge(account); em.merge(account);
} }
return account; return account;
} }
@Transactional @Transactional
public void deleteAccount(AccountEntity account) throws AccountException { public void deleteAccount(AccountEntity account) throws AccountException {
Date now = new Date(); // Todo now in UTC Date now = new Date(); // Todo now in UTC
Subject currentUser = SecurityUtils.getSubject(); Subject currentUser = SecurityUtils.getSubject();
String currentUserName = currentUser.getPrincipal().toString(); String currentUserName = currentUser.getPrincipal().toString();
if (account.getUsername().equals(currentUserName)) { if (account.getUsername().equals(currentUserName)) {
throw new AccountException("Cannot delete own account"); throw new AccountException("Cannot delete own account");
} else { } else {
account.setStatus(AccountStatus.DISABLED.name()); account.setStatus(AccountStatus.DISABLED.name());
account.setLastUpdatedBy(currentUserName); account.setLastUpdatedBy(currentUserName);
account.setLastUpdatedOn(now); account.setLastUpdatedOn(now);
em.merge(account); em.merge(account);
} }
} }
public boolean initPasswordReset(String userName) { public boolean initPasswordReset(String userName) {
try { try {
AccountEntity account = getAccountEntity(userName, false); AccountEntity account = getAccountEntity(userName, false);
if (account == null) { if (account == null) {
LOGGER.warn("Account with name " + userName + " not found"); LOGGER.warn("Account with name " + userName + " not found");
return false; return false;
} }
if (account.getStatus().equals(AccountStatus.BLOCKED.name())) { if (account.getStatus().equals(AccountStatus.BLOCKED.name())) {
LOGGER.warn("Account " + userName + " is locked, cannot initialize password reset"); LOGGER.warn("Account " + userName + " is locked, cannot initialize password reset");
return false; return false;
} }
String randomString = RandomStringUtils.random(40, true, true); String randomString = RandomStringUtils.random(40, true, true);
Date validTo = new Date(); // TODO now in UTC Date validTo = new Date(); // TODO now in UTC
validTo = new Date(validTo.getTime() + 1000 * 600); // 10 minutes to react validTo = new Date(validTo.getTime() + 1000 * 600); // 10 minutes to react
// TODO rework password reset // TODO rework password reset
// account.setPasswordResetHash(randomString); // account.setPasswordResetHash(randomString);
// account.setPasswordResetOngoing(true); // account.setPasswordResetOngoing(true);
// account.setPasswordResetValidTo(validTo); // account.setPasswordResetValidTo(validTo);
mailService.sendPasswortResetStartEmail(account, randomString); mailService.sendPasswortResetStartEmail(account, randomString);
em.merge(account); em.merge(account);
return true; return true;
} catch (MailException ex) { } catch (MailException ex) {
LOGGER.error("Error while sending password reset mail. " + ex.toString()); LOGGER.error("Error while sending password reset mail. " + ex.toString());
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Error while sending password reset mail.", ex); LOGGER.debug("Error while sending password reset mail.", ex);
} }
return false; return false;
} }
} }
public boolean resetPassword(String userName, String newPassword, String resetPasswordToken) { public boolean resetPassword(String userName, String newPassword, String resetPasswordToken) {
AccountEntity account = getAccountEntity(userName, false); AccountEntity account = getAccountEntity(userName, false);
if (account == null) { if (account == null) {
LOGGER.warn("Error while resetting password, no account with username " + userName + " found"); LOGGER.warn("Error while resetting password, no account with username " + userName + " found");
// TODO add extra logging for intrusion protection system like fail2ban // TODO add extra logging for intrusion protection system like fail2ban
return false; return false;
} }
/* /*
if (account.getPasswordResetOngoing() && (account.getPasswordResetHash() != null) && (account.getPasswordResetValidTo() != null)) { if (account.getPasswordResetOngoing() && (account.getPasswordResetHash() != null) && (account.getPasswordResetValidTo() != null)) {
Date now = new Date(); // TODO now in UTC Date now = new Date(); // TODO now in UTC
String storedHash = account.getPasswordResetHash().trim(); String storedHash = account.getPasswordResetHash().trim();
if (account.getPasswordResetValidTo().after(now)) { if (account.getPasswordResetValidTo().after(now)) {
if (storedHash.equals(resetPasswordToken)) { if (storedHash.equals(resetPasswordToken)) {
// everything ok, reset password // everything ok, reset password
executePasswordReset(account, newPassword); executePasswordReset(account, newPassword);
LOGGER.info("Updated password for user " + userName); LOGGER.info("Updated password for user " + userName);
return true; return true;
} else { } else {
// token is not valid, refuse to change password // token is not valid, refuse to change password
LOGGER.warn("Trying to reset password for user " + userName + " but wrong token " + resetPasswordToken + " provided"); LOGGER.warn("Trying to reset password for user " + userName + " but wrong token " + resetPasswordToken + " provided");
addLoginError(account); addLoginError(account);
return false; return false;
} }
} else { } else {
// password reset token no longer valid // password reset token no longer valid
LOGGER.warn("Trying to reset password for user " + userName + " but token is no longer valid"); LOGGER.warn("Trying to reset password for user " + userName + " but token is no longer valid");
addLoginError(account); addLoginError(account);
return false; return false;
} }
} else { } else {
// user is not is password reset mode // user is not is password reset mode
LOGGER.warn("Trying to reset password for user " + userName + " but password reset was not requested"); LOGGER.warn("Trying to reset password for user " + userName + " but password reset was not requested");
addLoginError(account); addLoginError(account);
return false; return false;
} }
*/ */
return false; // FIMXE re-implement password reset return false; // FIMXE re-implement password reset
} }
private void executePasswordReset(AccountEntity account, String newPassword) { private void executePasswordReset(AccountEntity account, String newPassword) {
Date now = new Date(); // TODO now in UTC Date now = new Date(); // TODO now in UTC
String hashedPassword = SecurityUtil.createPassword(newPassword); String hashedPassword = SecurityUtil.createPassword(newPassword);
// account.setAccountPassword(hashedPassword); // account.setAccountPassword(hashedPassword);
// //
// account.setPasswordResetOngoing(false); // account.setPasswordResetOngoing(false);
// account.setPasswordResetHash(null); // account.setPasswordResetHash(null);
// account.setPasswordResetValidTo(null); // account.setPasswordResetValidTo(null);
account.setLastUpdatedBy(account.getUsername()); account.setLastUpdatedBy(account.getUsername());
account.setLastUpdatedOn(now); account.setLastUpdatedOn(now);
em.merge(account); em.merge(account);
} }
public AccountLoginEntity updateSuccessFullLogin(AccountLoginEntity login, String byUser) { public AccountLoginEntity updateSuccessFullLogin(AccountLoginEntity login, String byUser) {
Date now = DateUtil.getCurrentTimeInUTC(); Date now = DateUtil.getCurrentTimeInUTC();
// a scucessful login ends a password reset procedure // a scucessful login ends a password reset procedure
if (login.getPasswordResetOngoing()) { if (login.getPasswordResetOngoing()) {
login.setPasswordResetOngoing(false); login.setPasswordResetOngoing(false);
login.setPasswordResetHash(null); login.setPasswordResetHash(null);
login.setPasswordResetValidTo(null); login.setPasswordResetValidTo(null);
login.setLastUpdatedOn(now); login.setLastUpdatedOn(now);
login.setLastUpdatedBy(byUser); login.setLastUpdatedBy(byUser);
} }
login.setLastLogin(now); login.setLastLogin(now);
login.setFailureCount(0); login.setFailureCount(0);
return updateLogin(login); return updateLogin(login);
} }
public AccountLoginEntity updateLogin(AccountLoginEntity login) { public AccountLoginEntity updateLogin(AccountLoginEntity login) {
return em.merge(login); return em.merge(login);
} }
public void updateLogin(AccountEntity account) { public void updateLogin(AccountEntity account) {
if (account.getAccountLogin() == null) { if (account.getAccountLogin() == null) {
// TODO connect to IPRS - how can an account ask for an updated login if the user cannot login // TODO connect to IPRS - how can an account ask for an updated login if the user cannot login
} else { } else {
updateSuccessFullLogin(account.getAccountLogin(), account.getUsername()); updateSuccessFullLogin(account.getAccountLogin(), account.getUsername());
} }
} }
public void addLoginError(AccountEntity account) { public void addLoginError(AccountEntity account) {
// TODO reimplement // TODO reimplement
// try { // try {
// Date now = new Date(); // TODO now in UTC // Date now = new Date(); // TODO now in UTC
// account.setLastFailedLogin(now); // account.setLastFailedLogin(now);
// account.setFailureCount(account.getFailureCount() + 1); // account.setFailureCount(account.getFailureCount() + 1);
// //
// int maxFailedLogins = Integer.parseInt(configService.getConfigValue( "account.maxFailedLogins")); // int maxFailedLogins = Integer.parseInt(configService.getConfigValue( "account.maxFailedLogins"));
// if ((account.getFailureCount() >= maxFailedLogins) && (!account.getStatus().equals("LOCKED"))) { // TOD add status enum // if ((account.getFailureCount() >= maxFailedLogins) && (!account.getStatus().equals("LOCKED"))) { // TOD add status enum
// // max failed logins reached, disabling user // // max failed logins reached, disabling user
// LOGGER.info("Locking account " + account.getUsername() + " due to " + account.getFailureCount() + " failed logins"); // LOGGER.info("Locking account " + account.getUsername() + " due to " + account.getFailureCount() + " failed logins");
// account.setStatus(AccountStatus.BLOCKED.name()); // account.setStatus(AccountStatus.BLOCKED.name());
// } // }
// //
// // on a failed login request, disable password reset // // on a failed login request, disable password reset
// account.setPasswordResetOngoing(false); // account.setPasswordResetOngoing(false);
// account.setPasswordResetHash(null); // account.setPasswordResetHash(null);
// account.setPasswordResetValidTo(null); // account.setPasswordResetValidTo(null);
// //
// account.setLastUpdatedBy("system"); // account.setLastUpdatedBy("system");
// account.setLastUpdatedOn(now); // account.setLastUpdatedOn(now);
// em.merge(account); // em.merge(account);
// } catch (ConfigException ex) { // } catch (ConfigException ex) {
// if (LOGGER.isDebugEnabled()) { // if (LOGGER.isDebugEnabled()) {
// LOGGER.debug(ex.toString(), ex); // LOGGER.debug(ex.toString(), ex);
// } else { // } else {
// LOGGER.error(ex.toString()); // LOGGER.error(ex.toString());
// } // }
// } // }
} }
public AccountLoginEntity createLoginWithRandomPassword() { public AccountLoginEntity createLoginWithRandomPassword() {
AccountLoginEntity login = new AccountLoginEntity(); AccountLoginEntity login = new AccountLoginEntity();
String randomPassword = RandomStringUtils.random(20, true, true); String randomPassword = RandomStringUtils.random(20, true, true);
String hashedPassword = SecurityUtil.createPassword(randomPassword); String hashedPassword = SecurityUtil.createPassword(randomPassword);
login.setAccountPassword(hashedPassword); login.setAccountPassword(hashedPassword);
login.setLastLogin(null); login.setLastLogin(null);
login.setLastFailedLogin(null); login.setLastFailedLogin(null);
login.setFailureCount(0); login.setFailureCount(0);
return login; return login;
} }
public String getHashedPassword(String password) { public String getHashedPassword(String password) {
String hashedPassword = SecurityUtil.createPassword(password); String hashedPassword = SecurityUtil.createPassword(password);
return hashedPassword; return hashedPassword;
} }
@Transactional @Transactional
public void addLogin(AccountEntity accountToAdd, AccountLoginEntity accountLogin) { public void addLogin(AccountEntity accountToAdd, AccountLoginEntity accountLogin) {
Date now = DateUtil.getCurrentTimeInUTC(); Date now = DateUtil.getCurrentTimeInUTC();
Subject currentUser = SecurityUtils.getSubject(); Subject currentUser = SecurityUtils.getSubject();
String currentLoggedInUser = currentUser.getPrincipal().toString(); String currentLoggedInUser = currentUser.getPrincipal().toString();
AccountEntity account = em.merge(accountToAdd); AccountEntity account = em.merge(accountToAdd);
accountLogin.setAccount(account); accountLogin.setAccount(account);
accountLogin.setCreatedBy(currentLoggedInUser); accountLogin.setCreatedBy(currentLoggedInUser);
accountLogin.setCreatedOn(now); accountLogin.setCreatedOn(now);
accountLogin.setLastUpdatedBy(currentLoggedInUser); accountLogin.setLastUpdatedBy(currentLoggedInUser);
accountLogin.setLastUpdatedOn(now); accountLogin.setLastUpdatedOn(now);
em.persist(accountLogin); em.persist(accountLogin);
account.setAccountLogin(accountLogin); account.setAccountLogin(accountLogin);
em.merge(account); em.merge(account);
} }
@Transactional @Transactional
public void deleteLogin(AccountEntity accountToDelete) { public void deleteLogin(AccountEntity accountToDelete) {
AccountEntity account = em.merge(accountToDelete); AccountEntity account = em.merge(accountToDelete);
AccountLoginEntity login = account.getAccountLogin(); AccountLoginEntity login = account.getAccountLogin();
login.setAccount(null); login.setAccount(null);
account.setAccountLogin(null); account.setAccountLogin(null);
em.remove(login); em.remove(login);
em.merge(account); em.merge(account);
} }
} }