From 765589afdf2207cd19b6562124fead5c01fc1e04 Mon Sep 17 00:00:00 2001 From: jomu Date: Wed, 14 Nov 2018 17:16:12 +0100 Subject: [PATCH] completed update of account, splitted login from account --- account-ui/pom.xml | 285 ++++---- .../account/web/ApplicationProducer.java | 67 ++ .../account/web/presentation/AccountView.java | 486 +++++++----- .../web/presentation/PermissionView.java | 294 ++++---- .../UniqueApplicationRoleNameValidator.java | 116 ++- .../UniquePermissionNameValidator.java | 118 +-- .../main/resources/META-INF/persistence.xml | 7 +- .../web/presentation/messages.properties | 265 +++---- .../web/presentation/messages_de.properties | 267 +++---- .../web/presentation/messages_en.properties | 267 +++---- account-ui/src/main/webapp/WEB-INF/shiro.ini | 112 +-- account-ui/src/main/webapp/web/account.xhtml | 563 +++++++------- account-ui/src/main/webapp/web/index.xhtml | 166 ++--- account/pom.xml | 8 +- account/sql/account_prefill.sql | 32 +- .../account/boundary/AccountControl.java | 690 ++++++++++-------- .../ApplicationPermissionControl.java | 204 +++--- .../boundary/ApplicationRoleControl.java | 296 ++++---- .../account/entity/AccountEntity.java | 608 +++++++-------- .../account/entity/AccountLoginEntity.java | 513 ++++++------- .../boundary/ApplicationService.java | 169 ++--- .../application/entity/ApplicationEntity.java | 262 +++---- .../config/boundary/ConfigService.java | 441 ++++++----- .../business/config/entity/ConfigEntity.java | 276 +++---- .../business/mail/boundary/MailService.java | 2 +- .../config/boundary/ConfigServiceTest.java | 4 +- .../shared/account/util/SecurityUtilTest.java | 22 + 27 files changed, 3383 insertions(+), 3157 deletions(-) create mode 100644 account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationProducer.java create mode 100644 account/src/test/java/de/muehlencord/shared/account/util/SecurityUtilTest.java diff --git a/account-ui/pom.xml b/account-ui/pom.xml index 03293bc..bcae1a2 100644 --- a/account-ui/pom.xml +++ b/account-ui/pom.xml @@ -1,140 +1,145 @@ - - - 4.0.0 - - shared - de.muehlencord - 1.1-SNAPSHOT - - - de.muehlencord.shared - shared-account-ui - 1.1-SNAPSHOT - war - - shared-account-ui - - - UTF-8 - ${maven.build.timestamp} - 10 - 10 - - - development - - - - - org.primefaces - primefaces - - - - com.github.adminfaces - admin-template - 1.0.0-RC19 - - - - org.omnifaces - omnifaces - 2.7 - - - - org.apache.shiro - shiro-core - - - org.apache.shiro - shiro-web - - - de.muehlencord.shared - shared-shiro-faces - 1.1-SNAPSHOT - - - de.muehlencord.shared - shared-account - 1.1-SNAPSHOT - jar - - - de.muehlencord.sf - filter - 1.0 - - - javax - javaee-web-api - 7.0 - provided - - - - - - ${basedir}/src/main/filters/${filter.name}.properties - - - - - - src/main/resources - true - - **/*.properties - - - - - account - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 10 - 10 - - - - org.apache.maven.plugins - maven-war-plugin - 3.2.2 - - false - - - ${basedir}/src/main/webapp - true - - WEB-INF/web.xml - WEB-INF/shiro.ini - - - - - - - - - - - development - - development - - - - - production - - production - - - - + + + 4.0.0 + + shared + de.muehlencord + 1.1-SNAPSHOT + + + de.muehlencord.shared + shared-account-ui + 1.1-SNAPSHOT + war + + shared-account-ui + + + UTF-8 + ${maven.build.timestamp} + 10 + 10 + + + development + + + + + org.primefaces + primefaces + + + + com.github.adminfaces + admin-template + 1.0.0-RC19 + + + + org.omnifaces + omnifaces + 2.7 + + + + org.apache.shiro + shiro-core + + + org.apache.shiro + shiro-web + + + de.muehlencord.shared + shared-shiro-faces + 1.1-SNAPSHOT + + + de.muehlencord.shared + shared-account + 1.1-SNAPSHOT + + + de.muehlencord.shared + shared-util + 1.1-SNAPSHOT + + + de.muehlencord.sf + filter + 1.0 + + + javax + javaee-web-api + 7.0 + provided + + + + + + ${basedir}/src/main/filters/${filter.name}.properties + + + + + + src/main/resources + true + + **/*.properties + **/*.xml + + + + + account + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 10 + 10 + + + + org.apache.maven.plugins + maven-war-plugin + 3.2.2 + + false + + + ${basedir}/src/main/webapp + true + + WEB-INF/web.xml + WEB-INF/shiro.ini + + + + + + + + + + + development + + development + + + + + production + + production + + + + diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationProducer.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationProducer.java new file mode 100644 index 0000000..f6c4239 --- /dev/null +++ b/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationProducer.java @@ -0,0 +1,67 @@ +/* + * Copyright 2018 Joern Muehlencord . + * + * 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. + */ +package de.muehlencord.shared.account.web; + +import de.muehlencord.shared.account.business.application.boundary.ApplicationService; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.util.UUID; +import javax.annotation.PostConstruct; +import javax.ejb.EJB; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.inject.Named; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@Named("applicationProdiucer") +@ApplicationScoped +public class ApplicationProducer { + + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationProducer.class); + + @EJB + ApplicationService applicationService; + + private ApplicationEntity application = null; + + @PostConstruct + public void init() { + String id = "143a2bd3-7e0b-4162-a76e-3031331c7dfe"; // TODO load from properties file + this.application = applicationService.findById(UUID.fromString(id)); + if (application == null) { + LOGGER.error("Could not find application with id "); + } else { + LOGGER.info("Found application {} for id{}", application.getApplicationName(), id); + } + } + + /** + * needs to return link to "Account UI" and not to current selected + * application TODO: ensure only Account UI can call functions where + * appliction can be handed in all other applications need to call the + * function which use the injected application + */ + @Produces + public ApplicationEntity getApplication() { + return application; + + } + +} diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/AccountView.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/AccountView.java index beff1b7..94e2695 100644 --- a/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/AccountView.java +++ b/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/AccountView.java @@ -1,186 +1,300 @@ -package de.muehlencord.shared.account.web.presentation; - -import de.muehlencord.shared.account.business.account.boundary.AccountControl; -import de.muehlencord.shared.account.business.account.boundary.ApplicationRoleControl; -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.AccountStatus; -import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import de.muehlencord.shared.jeeutil.FacesUtil; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import javax.ejb.EJB; -import javax.faces.view.ViewScoped; -import javax.inject.Named; -import javax.inject.Inject; -import org.primefaces.event.SelectEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author jomu - */ -@ViewScoped -@Named("accountView") -public class AccountView implements Serializable { - - private static final long serialVersionUID = -8050582392249849438L; - private static final Logger LOGGER = LoggerFactory.getLogger(AccountView.class); - - @Inject - private ApplicationView applicationView; - @EJB - private AccountControl accountService; - @EJB - private ApplicationRoleControl appliationRoleService; - - /** - * boolean flag to determine wether disabled accounts should be shown - * accounts are not deleted but disabled and can be activated in case - */ - private boolean showDisabledAccounts = false; - - // cached accounts - private List accountList = null; - // cached application roles - private List applicationRoles = null; - - // account currently on edit - private AccountEntity currentAccount; - private List currentAccountRoles = null; - - public List getAccounts() { - if (accountList == null) { - accountList = accountService.getAccounts(showDisabledAccounts); - } - return accountList; - } - - public List getAllApplicationRoles() { - if (applicationRoles == null) { - ApplicationEntity application = applicationView.getCurrentApplication(); - applicationRoles = appliationRoleService.getAllRoles(application); - } - return applicationRoles; - } - - public void selectAccount(SelectEvent event) { - if (currentAccount == null) { - applicationRoles = null; - currentAccountRoles = null; - } - } - - public boolean getAccountSelected() { - return currentAccount != null; - } - - public void newAccount() { - currentAccount = new AccountEntity(); - currentAccount.setUsername(null); - currentAccount.setStatus("NEW"); // TODO add status enum - currentAccountRoles = new ArrayList<>(); - } - - public void editAccount() { - // function called by webpage - if (currentAccount == null) { - currentAccountRoles = null; - } else { - currentAccount = accountService.getAccountEntity(currentAccount.getUsername(), true); - this.currentAccountRoles = new ArrayList<>(); - if (currentAccount.getApplicationRoleList() != null) { - currentAccountRoles.addAll(currentAccount.getApplicationRoleList()); - } - } - } - - public void cancelEditAccount() { - currentAccount = null; - currentAccountRoles = null; - } - - public void saveEditAccount() { - String username = currentAccount.getUsername(); - AccountEntity existingEntity = accountService.getAccountEntity(username, true); - // check if it is a new user (createdBy == null) but a user with same name already exists - if ((currentAccount.getCreatedBy() == null) && (existingEntity != null)) { - currentAccount.setUsername(null); - FacesUtil.addErrorMessage("editDialogMessaegs", "Create new account failed", "Account with username " + username + " already exists"); - } else { - accountService.saveAccount(applicationView.getCurrentApplication(), currentAccount, currentAccountRoles); - if (currentAccount.getId() == null) { - // this was a new account - // force accounts to be loaded from database again - accountList = null; - } - } - } - - public void deleteAccount() { - try { - accountService.deleteAccount(currentAccount); - accountList.remove(currentAccount); - FacesUtil.addGlobalInfoMessage("Info", "Account " + currentAccount.getUsername() + " deleted"); - currentAccount = null; - currentAccountRoles = null; - } catch (AccountException ex) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(ex.toString(), ex); - } else { - LOGGER.error(ex.toString()); - } - - FacesUtil.addGlobalErrorMessage("Error deleting account", ex.getMessage()); - } - } - - public void showDisabledAccountsChange() { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("show diabled accounts changed to {}", showDisabledAccounts); - } - this.accountList = null; - } - - public List getStatusList() { - return AccountStatus.getAllStatusNames(); - } - - /* **** getter / setter **** */ - /** - * setter for managed property applicationView - * - * @param applicationView the applicaton view to inject - */ - public void setApplicationView(ApplicationView applicationView) { - this.applicationView = applicationView; - } - - public AccountEntity getCurrentAccount() { - return currentAccount; - } - - public void setCurrentAccount(AccountEntity currentAccount) { - this.currentAccount = currentAccount; - } - - public boolean isShowDisabledAccounts() { - return showDisabledAccounts; - } - - public void setShowDisabledAccounts(boolean showDisabledAccounts) { - this.showDisabledAccounts = showDisabledAccounts; - } - - public List getCurrentAccountRoles() { - return currentAccountRoles; - } - - public void setCurrentAccountRoles(List currentAccountRoles) { - this.currentAccountRoles = currentAccountRoles; - } - -} +package de.muehlencord.shared.account.web.presentation; + +import de.muehlencord.shared.account.business.account.boundary.AccountControl; +import de.muehlencord.shared.account.business.account.boundary.ApplicationRoleControl; +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.AccountLoginEntity; +import de.muehlencord.shared.account.business.account.entity.AccountStatus; +import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import de.muehlencord.shared.jeeutil.FacesUtil; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import javax.ejb.EJB; +import javax.faces.component.UIInput; +import javax.faces.context.FacesContext; +import javax.faces.view.ViewScoped; +import javax.inject.Named; +import javax.inject.Inject; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; +import org.primefaces.event.SelectEvent; +import org.primefaces.event.UnselectEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author jomu + */ +@ViewScoped +@Named("accountView") +public class AccountView implements Serializable { + + private static final long serialVersionUID = -8050582392249849438L; + private static final Logger LOGGER = LoggerFactory.getLogger(AccountView.class); + + @Inject + private ApplicationView applicationView; + @EJB + private AccountControl accountService; + @EJB + private ApplicationRoleControl appliationRoleService; + + /** + * boolean flag to determine wether disabled accounts should be shown + * accounts are not deleted but disabled and can be activated in case + */ + private boolean showDisabledAccounts = false; + + // cached accounts + private List accountList = null; + // cached application roles + private List applicationRoles = null; + + // account currently on edit + private AccountEntity currentAccount; + private List currentAccountRoles = null; + private AccountLoginEntity currentAccountLogin; + private String password = null; + private String repeatPassword = null; + + public List getAccounts() { + if (accountList == null) { + accountList = accountService.getAccounts(showDisabledAccounts); + } + return accountList; + } + + public List getAllApplicationRoles() { + if (applicationRoles == null) { + ApplicationEntity application = applicationView.getCurrentApplication(); + applicationRoles = appliationRoleService.getAllRoles(application); + } + return applicationRoles; + } + + public void selectAccount(SelectEvent event) { + // nothing to do, currentAccountRoles are loaded before dialog is shown + } + + public void unselectAccount(UnselectEvent event) { + applicationRoles = null; + currentAccountRoles = null; + } + + public boolean getAccountSelected() { + return currentAccount != null; + } + + public void newAccount() { + currentAccount = new AccountEntity(); + currentAccount.setStatus("NEW"); // TODO add status enum + currentAccountRoles = new ArrayList<>(); + } + + public void editAccount() { + // function called by webpage + if (currentAccount == null) { + currentAccountRoles = null; + } else { + currentAccount = accountService.getAccountEntity(currentAccount.getUsername(), true); + this.currentAccountRoles = new ArrayList<>(); + if (currentAccount.getApplicationRoleList() != null) { + currentAccountRoles.addAll(currentAccount.getApplicationRoleList()); + } + } + } + + public void cancelEditAccount() { + currentAccount = null; + currentAccountRoles = null; + } + + public void saveEditAccount() { + String username = currentAccount.getUsername(); + AccountEntity existingEntity = accountService.getAccountEntity(username, true); + // check if it is a new user (createdBy == null) but a user with same name already exists + if ((currentAccount.getCreatedBy() == null) && (existingEntity != null)) { + FacesUtil.addErrorMessage("editDialogMessaegs", "Create new account failed", "Account with username " + username + " already exists"); + } else { + accountService.saveAccount(currentAccount, currentAccountRoles); + // force accounts to be loaded from database again + accountList = null; + + } + } + + public void deleteAccount() { + try { + accountService.deleteAccount(currentAccount); + accountList.remove(currentAccount); + FacesUtil.addGlobalInfoMessage("Info", "Account " + currentAccount.getUsername() + " deleted"); + currentAccount = null; + currentAccountRoles = null; + } catch (AccountException ex) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(ex.toString(), ex); + } else { + LOGGER.error(ex.toString()); + } + + FacesUtil.addGlobalErrorMessage("Error deleting account", ex.getMessage()); + } + } + + public void showDisabledAccountsChange() { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("show diabled accounts changed to {}", showDisabledAccounts); + } + this.accountList = null; + } + + public List getStatusList() { + return AccountStatus.getAllStatusNames(); + } + + /* **** account login methods **** */ + public boolean validatePasswords(FacesContext context, List components, List values) { + String password = components.get(0).getSubmittedValue().toString(); + String passwordRepeat = components.get(1).getSubmittedValue().toString(); + + if ((password == null) || (passwordRepeat == null)) { + return false; + } + boolean returnValue = password.equals(passwordRepeat); + return returnValue; + } + + public void addAccountLogin() { + if (currentAccount == null) { + // TODO add error handling + } else { + this.currentAccountLogin = accountService.createLoginWithRandomPassword(); + } + } + + public void editAccountLogin() { + if (currentAccount == null) { + // TODO add error handling + } else { + this.currentAccountLogin = currentAccount.getAccountLogin(); + } + } + + public void deleteAccountLogin() { + if (currentAccount == null) { + // TODO add error handling + } else { + accountService.deleteLogin(currentAccount); + currentAccount.setAccountLogin(null); + currentAccountLogin = null; + accountList = null; // force reload + FacesUtil.addGlobalInfoMessage("Account saved", "Login removed"); + } + + } + + public void saveEditAccountLogin() { + // TODO move to account control - to much logic for the view + if ((currentAccountLogin == null) || (currentAccount == null)) { + // TODO add error handling + } else { + + // overwrite password if provided + if ((password != null) && (!password.trim().equals(""))) { + // password has been specified + if (password.equals(repeatPassword)) { + currentAccount.getAccountLogin().setAccountPassword(accountService.getHashedPassword(password)); + FacesUtil.addGlobalInfoMessage("Info", "Password updated"); + } else { + // TODO connect to IPRS + // frontend does validate passwords do match + // someone is trying to cheat + } + } + + if (currentAccountLogin.getId() == null) { + accountService.addLogin(currentAccount, currentAccountLogin); + currentAccount.setAccountLogin(currentAccountLogin); + accountList = null; // force reload of accounts + } else { + accountService.updateLogin(currentAccountLogin); + } + currentAccountLogin = null; + FacesUtil.addGlobalInfoMessage("Account saved", "Login data updated"); + } + } + + public void cancelEditAccountLogin() { + this.currentAccountLogin = null; + } + + public boolean getCurrentLoggedInUser() { + if (currentAccount == null) { + return false; + } + + Subject currentUser = SecurityUtils.getSubject(); + if (currentUser == null) { + // TODO - connect to IPRS - how can this method be called if no user is logged in + return false; + } + String currentUserName = currentUser.getPrincipal().toString(); + return currentUserName.equals(currentAccount.getUsername()); + } + + /* **** getter / setter **** */ + /** + * setter for managed property applicationView + * + * @param applicationView the applicaton view to inject + */ + public void setApplicationView(ApplicationView applicationView) { + this.applicationView = applicationView; + } + + public AccountEntity getCurrentAccount() { + return currentAccount; + } + + public void setCurrentAccount(AccountEntity currentAccount) { + this.currentAccount = currentAccount; + } + + public boolean isShowDisabledAccounts() { + return showDisabledAccounts; + } + + public void setShowDisabledAccounts(boolean showDisabledAccounts) { + this.showDisabledAccounts = showDisabledAccounts; + } + + public List getCurrentAccountRoles() { + return currentAccountRoles; + } + + public void setCurrentAccountRoles(List currentAccountRoles) { + this.currentAccountRoles = currentAccountRoles; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getRepeatPassword() { + return repeatPassword; + } + + public void setRepeatPassword(String repeatPassword) { + this.repeatPassword = repeatPassword; + } + +} diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/PermissionView.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/PermissionView.java index 6299d72..c38e5ba 100644 --- a/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/PermissionView.java +++ b/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/PermissionView.java @@ -1,149 +1,145 @@ -/* - * Copyright 2017 Joern Muehlencord . - * - * 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. - */ -package de.muehlencord.shared.account.web.presentation; - -import de.muehlencord.shared.account.business.account.boundary.ApplicationPermissionControl; -import de.muehlencord.shared.account.business.account.entity.AccountException; -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import de.muehlencord.shared.jeeutil.FacesUtil; -import java.io.Serializable; -import java.util.List; -import javax.ejb.EJB; -import javax.inject.Named; -import javax.faces.view.ViewScoped; -import javax.inject.Inject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Joern Muehlencord - */ -@ViewScoped -@Named("permissionView") -public class PermissionView implements Serializable { - - private static final long serialVersionUID = -1469453490360990772L; - private static final Logger LOGGER = LoggerFactory.getLogger(PermissionView.class); - - @Inject - private ApplicationView applicationView; - - @EJB - ApplicationPermissionControl applicationPermissionService; - private ApplicationPermissionEntity currentPermission; - - public List getAppPermissions() { - return applicationPermissionService.getApplicationPermissions(applicationView.getCurrentApplication()); - } - - public void saveEditPermission() throws AccountException { - if (currentPermission != null) { - ApplicationEntity currentApplication = applicationView.getCurrentApplication(); - String currentApplicationName = currentApplication.getApplicationName(); - String newPermissionName = currentPermission.getPermissionName(); - String newPermissionDescription = currentPermission.getPermissionDescription(); - if ((newPermissionName == null) || (newPermissionName.trim().length() == 0)) { - FacesUtil.addErrorMessage("editDialogMessages", "Error", "Permission name must not be null"); - } else if ((newPermissionDescription == null) || (newPermissionDescription.trim().length() == 0)) { - FacesUtil.addErrorMessage("editDialogMessages", "Error", "Permission name must not be null"); - } else { - if (currentPermission.getId() == null) { - applicationPermissionService.create(currentApplicationName, newPermissionName, newPermissionName); - FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " created"); -// deselectPermission(); - } else { - applicationPermissionService.update(currentPermission); - FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " updated"); -// deselectPermission(); - } - } - } - } - - public ApplicationEntity getCurrentApplication() { - if (applicationView.getCurrentApplication() == null) { - return null; - } else { - return applicationView.getCurrentApplication(); - } - } - - public void cancelEditPermission() { - this.currentPermission = null; - } - - public void newPermission() { - this.currentPermission = new ApplicationPermissionEntity(); - } - - public void editPermission() { - if (currentPermission == null) { - FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit"); - } - } - - public void deletePermission() { - if (currentPermission == null) { - FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit"); - } else { - try { - applicationPermissionService.delete(currentPermission); - currentPermission = null; - } catch (AccountException ex) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(ex.toString(), ex); - } else { - LOGGER.debug(ex.toString()); - } - FacesUtil.addGlobalErrorMessage("Error while deleting permission.", ex.toString()); - } - } - } - - public boolean getCanEdit() { - return isPermissionSelected(); - } - - public boolean getCanDelete() { - return isPermissionSelected(); - } - - /* *** getter / setter *** */ - /** - * required setter for managedProperty - * - * - * @param applicationView the injected applicationView - */ - public void setApplicationView(ApplicationView applicationView) { - this.applicationView = applicationView; - } - - public ApplicationPermissionEntity getCurrentPermission() { - return currentPermission; - } - - public void setCurrentPermission(ApplicationPermissionEntity newCurrentPermission) { - this.currentPermission = newCurrentPermission; - - } - - public boolean isPermissionSelected() { - return currentPermission != null; - } -} +/* + * Copyright 2017 Joern Muehlencord . + * + * 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. + */ +package de.muehlencord.shared.account.web.presentation; + +import de.muehlencord.shared.account.business.account.boundary.ApplicationPermissionControl; +import de.muehlencord.shared.account.business.account.entity.AccountException; +import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import de.muehlencord.shared.jeeutil.FacesUtil; +import java.io.Serializable; +import java.util.List; +import javax.ejb.EJB; +import javax.inject.Named; +import javax.faces.view.ViewScoped; +import javax.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@ViewScoped +@Named("permissionView") +public class PermissionView implements Serializable { + + private static final long serialVersionUID = -1469453490360990772L; + private static final Logger LOGGER = LoggerFactory.getLogger(PermissionView.class); + + @Inject + private ApplicationView applicationView; + + @EJB + ApplicationPermissionControl applicationPermissionService; + private ApplicationPermissionEntity currentPermission; + + public List getAppPermissions() { + return applicationPermissionService.getApplicationPermissions(applicationView.getCurrentApplication()); + } + + public void saveEditPermission() throws AccountException { + if (currentPermission != null) { + String newPermissionName = currentPermission.getPermissionName(); + String newPermissionDescription = currentPermission.getPermissionDescription(); + if ((newPermissionName == null) || (newPermissionName.trim().length() == 0)) { + FacesUtil.addErrorMessage("editDialogMessages", "Error", "Permission name must not be null"); + } else if ((newPermissionDescription == null) || (newPermissionDescription.trim().length() == 0)) { + FacesUtil.addErrorMessage("editDialogMessages", "Error", "Permission name must not be null"); + } else { + if (currentPermission.getId() == null) { + applicationPermissionService.create(applicationView.getCurrentApplication(), newPermissionName, newPermissionName); + FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " created"); + } else { + applicationPermissionService.update(currentPermission); + FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " updated"); + } + } + } + } + + public ApplicationEntity getCurrentApplication() { + if (applicationView.getCurrentApplication() == null) { + return null; + } else { + return applicationView.getCurrentApplication(); + } + } + + public void cancelEditPermission() { + this.currentPermission = null; + } + + public void newPermission() { + this.currentPermission = new ApplicationPermissionEntity(); + } + + public void editPermission() { + if (currentPermission == null) { + FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit"); + } + } + + public void deletePermission() { + if (currentPermission == null) { + FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit"); + } else { + try { + applicationPermissionService.delete(currentPermission); + currentPermission = null; + } catch (AccountException ex) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(ex.toString(), ex); + } else { + LOGGER.debug(ex.toString()); + } + FacesUtil.addGlobalErrorMessage("Error while deleting permission.", ex.toString()); + } + } + } + + public boolean getCanEdit() { + return isPermissionSelected(); + } + + public boolean getCanDelete() { + return isPermissionSelected(); + } + + /* *** getter / setter *** */ + /** + * required setter for managedProperty + * + * + * @param applicationView the injected applicationView + */ + public void setApplicationView(ApplicationView applicationView) { + this.applicationView = applicationView; + } + + public ApplicationPermissionEntity getCurrentPermission() { + return currentPermission; + } + + public void setCurrentPermission(ApplicationPermissionEntity newCurrentPermission) { + this.currentPermission = newCurrentPermission; + + } + + public boolean isPermissionSelected() { + return currentPermission != null; + } +} diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/UniqueApplicationRoleNameValidator.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/UniqueApplicationRoleNameValidator.java index 44be027..f12b5bc 100644 --- a/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/UniqueApplicationRoleNameValidator.java +++ b/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/UniqueApplicationRoleNameValidator.java @@ -1,60 +1,56 @@ -package de.muehlencord.shared.account.web.presentation; - -import de.muehlencord.shared.account.business.account.boundary.ApplicationPermissionControl; -import de.muehlencord.shared.account.business.account.boundary.ApplicationRoleControl; -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.io.Serializable; -import javax.ejb.EJB; -import javax.faces.application.FacesMessage; -import javax.faces.component.UIComponent; -import javax.faces.context.FacesContext; -import javax.faces.validator.FacesValidator; -import javax.faces.validator.Validator; -import javax.faces.validator.ValidatorException; -import javax.inject.Inject; -import javax.persistence.EntityManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Joern Muehlencord - */ -@FacesValidator("uniqueApplicationRoleNameValidator") -public class UniqueApplicationRoleNameValidator implements Validator, Serializable { - - private static final long serialVersionUID = 8165013107453616719L; - - @Inject - EntityManager em; - - @EJB - ApplicationRoleControl applicationRoleControl; - - @Override - public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { - Object applicationObj = component.getAttributes().get("application"); - if ((applicationObj != null) && (applicationObj instanceof ApplicationEntity)) { - ApplicationEntity application = (ApplicationEntity) applicationObj; - if (value == null) { - throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role name must not be empty")); - } - if (value instanceof String) { - String roleName = (String) value; - ApplicationRoleEntity existingRole = applicationRoleControl.findByName(application, roleName); - if (existingRole != null) { - throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role already exists")); - } - } else { - throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role name must be a string value")); - // TODO add IPRS logger - someone is trying to cheat - } - } else { - throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application not set", "Permission name cannot be set if application is unknown")); - } - - } - -} +package de.muehlencord.shared.account.web.presentation; + +import de.muehlencord.shared.account.business.account.boundary.ApplicationRoleControl; +import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; +import de.muehlencord.shared.account.business.application.boundary.ApplicationService; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.Serializable; +import javax.ejb.EJB; +import javax.faces.application.FacesMessage; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.validator.FacesValidator; +import javax.faces.validator.Validator; +import javax.faces.validator.ValidatorException; +import javax.inject.Inject; +import javax.persistence.EntityManager; + +/** + * + * @author Joern Muehlencord + */ +@FacesValidator("uniqueApplicationRoleNameValidator") +public class UniqueApplicationRoleNameValidator implements Validator, Serializable { + + private static final long serialVersionUID = 8165013107453616719L; + + @Inject + EntityManager em; + + @EJB + ApplicationRoleControl applicationRoleControl; + + @Override + public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { + Object applicationObj = component.getAttributes().get("application"); + if ((applicationObj != null) && (applicationObj instanceof ApplicationEntity)) { + ApplicationEntity application = (ApplicationEntity) applicationObj; + if (value == null) { + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role name must not be empty")); + } + if (value instanceof String) { + String roleName = (String) value; + ApplicationRoleEntity existingRole = applicationRoleControl.findByName(application, roleName); + if (existingRole != null) { + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role already exists")); + } + } else { + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role name must be a string value")); + // TODO add IPRS logger - someone is trying to cheat + } + } else { + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application not set", "Permission name cannot be set if application is unknown")); + } + } + +} diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/UniquePermissionNameValidator.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/UniquePermissionNameValidator.java index dc18a53..1cf90b3 100644 --- a/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/UniquePermissionNameValidator.java +++ b/account-ui/src/main/java/de/muehlencord/shared/account/web/presentation/UniquePermissionNameValidator.java @@ -1,59 +1,59 @@ -package de.muehlencord.shared.account.web.presentation; - -import de.muehlencord.shared.account.business.account.boundary.ApplicationPermissionControl; -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.io.Serializable; -import javax.ejb.EJB; -import javax.faces.application.FacesMessage; -import javax.faces.component.UIComponent; -import javax.faces.context.FacesContext; -import javax.faces.validator.FacesValidator; -import javax.faces.validator.Validator; -import javax.faces.validator.ValidatorException; -import javax.inject.Inject; -import javax.persistence.EntityManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Joern Muehlencord - */ -@FacesValidator("uniquePermissionNameValidator") -public class UniquePermissionNameValidator implements Validator, Serializable { - - private static final long serialVersionUID = 2526409681909574670L; - private static final Logger LOGGER = LoggerFactory.getLogger(UniquePermissionNameValidator.class); - - @Inject - EntityManager em; - - @EJB - ApplicationPermissionControl applicationPermissionControl; - - @Override - public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { - Object applicationObj = component.getAttributes().get("application"); - if ((applicationObj != null) && (applicationObj instanceof ApplicationEntity)) { - ApplicationEntity application = (ApplicationEntity) applicationObj; - if (value == null) { - throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission name must not be empty")); - } - if (value instanceof String) { - String permissionName = (String) value; - ApplicationPermissionEntity existingPermission = applicationPermissionControl.findPermissionByName(application, permissionName); - if (existingPermission != null) { - throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission already exists")); - } - } else { - throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission name must be a string value")); - // TODO add IPRS logger - someone is trying to cheat - } - } else { - throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application not set", "Permission name cannot be set if application is unknown")); - } - - } - -} +package de.muehlencord.shared.account.web.presentation; + +import de.muehlencord.shared.account.business.account.boundary.ApplicationPermissionControl; +import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.Serializable; +import javax.ejb.EJB; +import javax.faces.application.FacesMessage; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.validator.FacesValidator; +import javax.faces.validator.Validator; +import javax.faces.validator.ValidatorException; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@FacesValidator("uniquePermissionNameValidator") +public class UniquePermissionNameValidator implements Validator, Serializable { + + private static final long serialVersionUID = 2526409681909574670L; + private static final Logger LOGGER = LoggerFactory.getLogger(UniquePermissionNameValidator.class); + + @Inject + EntityManager em; + + @EJB + ApplicationPermissionControl applicationPermissionControl; + + @Override + public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { + Object applicationObj = component.getAttributes().get("application"); + if ((applicationObj != null) && (applicationObj instanceof ApplicationEntity)) { + ApplicationEntity application = (ApplicationEntity) applicationObj; + if (value == null) { + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission name must not be empty")); + } + if (value instanceof String) { + String permissionName = (String) value; + ApplicationPermissionEntity existingPermission = applicationPermissionControl.findPermissionByName(application, permissionName); + if (existingPermission != null) { + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission already exists")); + } + } else { + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission name must be a string value")); + // TODO add IPRS logger - someone is trying to cheat + } + } else { + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application not set", "Permission name cannot be set if application is unknown")); + } + + } + +} diff --git a/account-ui/src/main/resources/META-INF/persistence.xml b/account-ui/src/main/resources/META-INF/persistence.xml index 504dc3b..ce53a8a 100644 --- a/account-ui/src/main/resources/META-INF/persistence.xml +++ b/account-ui/src/main/resources/META-INF/persistence.xml @@ -1,14 +1,15 @@ - - java:/jboss/accountTestDs + + java:/jboss/accountTestDs de.muehlencord.shared.account.business.account.entity.AccountEntity de.muehlencord.shared.account.business.account.entity.AccountHistoryEntity + de.muehlencord.shared.account.business.account.entity.AccountLoginEntity de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity + de.muehlencord.shared.account.business.application.entity.ApplicationEntity de.muehlencord.shared.account.business.config.entity.ConfigEntity de.muehlencord.shared.account.business.mail.entity.MailTemplateEntity - de.muehlencord.shared.account.business.application.entity.ApplicationEntity true ENABLE_SELECTIVE NONE diff --git a/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages.properties b/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages.properties index 0531262..59c98b9 100644 --- a/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages.properties +++ b/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages.properties @@ -1,132 +1,133 @@ -header_login=Login -header_reset_password=Reset password -message_username_password=Please enter your user name and a new password -button_login=Login -button_cancel=Cancel -button_password_lost=Password lost? -label_username=Username -label_password=Password -label_new_password=New Password -button_password_reset=Reset password -header_passwort_lost=Lost password -message_start_password_reset=Please enter your username to start the password recovery procedure -menu_dashboard=Dashboard -menu_events=Events -menu_administration=Administration -menu_overview=Overview -menu_emails=Emails -menu_account=Account -menu_config=Config -menu_logout=Logout -button_new=New -button_delete=Delete -button_edit=Edit -button_reload=Reload -label_name=Name -label_description=Description -label_event_date=Event Date -label_reservation=Reservation -label_reservation_from_to=Reservation from/to -label_actions=Actions -message_confirm=Are you sure? -button_setup=Setup -button_reservations=Reservations -label_event_name=Event Name -label_event_item_desc=Event Item Description -label_timezone=Timezone -label_event_start=Event Start -label_event_end=Event End -label_reservation_autostart=Reservation start -label_reservation_autoend=Reservation end -label_reservation_active=Reservation active -label_reservation_max_items=Max Items -label_booking_deadline=Booking deadline -label_template_validation=Email validation mail template -label_template_confirmation=Event confirmation mail template -label_template_waitlist=Event waitlist mail template -message_event_not_found=Event not found -label_items=Items -label_costs=Costs -label_all=All -label_yes=Yes -label_no=No -label_status=Status -label_firstname=Firstname -label_lastname=Lastname -label_emailaddress=Emailaddress -label_comment=Comment -label_email_confirmed=Email confirmed -label_booking_number=Booking Number -label_booking_executed=booking executed -tt_log_entries=Show log entries -tt_cancel_reservation=Cancel the current reservation -tt_send_email_again=Send email again -tt_move_from_wl=Move from waitlist -tt_fix_reservation=Try to fix the current reservation -tt_edit_reservation=Edit the reservation -button_refresh_free=Refresh free -button_manual_reserve=Reserve -button_export=Export -label_amount=Amount -label_select=Select -label_created_by=Created by -label_ip=IP -label_ip_forwarded=IP (forwarded) -label_value=Value -label_useragent=Useragent -button_ok=Ok -message_comment=Please add a comment -menu_help=Help -label_event=Event -label_active=Active -label_waitlist=Waitlist -label_is_waitlist=Is waitlist -label_order=Order -message_dynamic_numbering=dynamic numbering (put %n as placeholder) -label_start_number=Start Number -label_end_number=End Number -header_item_def=Define items for event -message_no_event_items=No event item defined -button_overview=Overview -label_reservation_auto_start=Automatically switch on/off -label_item_public=Item public? -label_is_publicitem=Is public -label_customer_comment=Customer comment -label_change_comment=Change comment -label_existing_items=current items -label_new_items=new items -label_available_items=available items -label_no_records=No records found. -button_mail=Mail -header_email_distribution=Email distribution -label_template=Template -label_demomode=Demo mode -message_invalid_email=Please provide a valid email address -menu_permissions=Permissions -button_save=Save -menu_groups=Groups -message_email_sent=email sent -message_email_with_error=emails with error -message_no_email=no email address defined -message_email_not_sent=Error while sending emails -label_seating=Seating -label_attachments=Attachments -label_language=Language -label_subject=Subject -label_bytes=Bytes -label_upload=Upload -header_export=Export -label_export_type=Export Type -label_filtered=Filtered -label_include_deleted=Include deleted -label_include_log=Include Logs -label_template_booking_executed=Booking executed template -label_street=Street -label_zipCode=ZIP Code -label_city=City -label_groupName=Groupname -label_phoneNumber=Phone Number -label_template_waitlist_cancelled=Waitlist cancelled mail template -msgs_menu_status=Status -menu_status=Status -button_add=Add +header_login=Login +header_reset_password=Reset password +message_username_password=Please enter your user name and a new password +button_login=Login +button_cancel=Cancel +button_password_lost=Password lost? +label_username=Username +label_password=Password +label_new_password=New Password +button_password_reset=Reset password +header_passwort_lost=Lost password +message_start_password_reset=Please enter your username to start the password recovery procedure +menu_dashboard=Dashboard +menu_events=Events +menu_administration=Administration +menu_overview=Overview +menu_emails=Emails +menu_account=Account +menu_config=Config +menu_logout=Logout +button_new=New +button_delete=Delete +button_edit=Edit +button_reload=Reload +label_name=Name +label_description=Description +label_event_date=Event Date +label_reservation=Reservation +label_reservation_from_to=Reservation from/to +label_actions=Actions +message_confirm=Are you sure? +button_setup=Setup +button_reservations=Reservations +label_event_name=Event Name +label_event_item_desc=Event Item Description +label_timezone=Timezone +label_event_start=Event Start +label_event_end=Event End +label_reservation_autostart=Reservation start +label_reservation_autoend=Reservation end +label_reservation_active=Reservation active +label_reservation_max_items=Max Items +label_booking_deadline=Booking deadline +label_template_validation=Email validation mail template +label_template_confirmation=Event confirmation mail template +label_template_waitlist=Event waitlist mail template +message_event_not_found=Event not found +label_items=Items +label_costs=Costs +label_all=All +label_yes=Yes +label_no=No +label_status=Status +label_firstname=Firstname +label_lastname=Lastname +label_emailaddress=Emailaddress +label_comment=Comment +label_email_confirmed=Email confirmed +label_booking_number=Booking Number +label_booking_executed=booking executed +tt_log_entries=Show log entries +tt_cancel_reservation=Cancel the current reservation +tt_send_email_again=Send email again +tt_move_from_wl=Move from waitlist +tt_fix_reservation=Try to fix the current reservation +tt_edit_reservation=Edit the reservation +button_refresh_free=Refresh free +button_manual_reserve=Reserve +button_export=Export +label_amount=Amount +label_select=Select +label_created_by=Created by +label_ip=IP +label_ip_forwarded=IP (forwarded) +label_value=Value +label_useragent=Useragent +button_ok=Ok +message_comment=Please add a comment +menu_help=Help +label_event=Event +label_active=Active +label_waitlist=Waitlist +label_is_waitlist=Is waitlist +label_order=Order +message_dynamic_numbering=dynamic numbering (put %n as placeholder) +label_start_number=Start Number +label_end_number=End Number +header_item_def=Define items for event +message_no_event_items=No event item defined +button_overview=Overview +label_reservation_auto_start=Automatically switch on/off +label_item_public=Item public? +label_is_publicitem=Is public +label_customer_comment=Customer comment +label_change_comment=Change comment +label_existing_items=current items +label_new_items=new items +label_available_items=available items +label_no_records=No records found. +button_mail=Mail +header_email_distribution=Email distribution +label_template=Template +label_demomode=Demo mode +message_invalid_email=Please provide a valid email address +menu_permissions=Permissions +button_save=Save +menu_groups=Groups +message_email_sent=email sent +message_email_with_error=emails with error +message_no_email=no email address defined +message_email_not_sent=Error while sending emails +label_seating=Seating +label_attachments=Attachments +label_language=Language +label_subject=Subject +label_bytes=Bytes +label_upload=Upload +header_export=Export +label_export_type=Export Type +label_filtered=Filtered +label_include_deleted=Include deleted +label_include_log=Include Logs +label_template_booking_executed=Booking executed template +label_street=Street +label_zipCode=ZIP Code +label_city=City +label_groupName=Groupname +label_phoneNumber=Phone Number +label_template_waitlist_cancelled=Waitlist cancelled mail template +msgs_menu_status=Status +menu_status=Status +button_add=Add +passwords_different=Passwords do not match, please check input diff --git a/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages_de.properties b/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages_de.properties index b3cdd01..a07a382 100644 --- a/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages_de.properties +++ b/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages_de.properties @@ -1,133 +1,134 @@ - -header_login=Anmeldung -header_reset_password=Passwort zur\u00fccksetzten -message_username_password=Bitte geben Deinen Benutzernamen und dein Passwort ein -button_login=Anmelden -button_cancel=Abbruch -button_password_lost=Passwort vergessen? -label_username=Benutzername -label_password=Passwort -label_new_password=Neues Passwort -button_password_reset=Passwort zur\u00fccksetzten -header_passwort_lost=Passwort vergessen -message_start_password_reset=Bitte gib deinen Benutzernamen ein um das Zur\u00fccksetzten des Passworts zu starten. -menu_dashboard=Dashbaord -menu_events=Veranstaltungen -menu_administration=Administration -menu_overview=\u00dcbersicht -menu_emails=E-Mails -menu_account=Benutzer -menu_config=Konfiguration -menu_logout=Abmelden -button_new=Neu -button_delete=L\u00f6schen -button_edit=Bearbeiten -button_reload=Aktualisieren -label_name=Name -label_description=Beschreibung -label_event_date=Veranstaltungsdatum -label_reservation=Reservierung -label_reservation_from_to=Reservierung von/bis -label_actions=Aktionen -message_confirm=Bist du sicher? -button_setup=Setup -button_reservations=Reservierungen -label_event_name=Veranstaltungsname -label_event_item_desc=Veranstaltungsobjekte -label_timezone=Zeitzone -label_event_start=Veranstaltungsbeginn -label_event_end=Veranstaltungsende -label_reservation_autostart=Reservierung von -label_reservation_autoend=Reservierung bis -label_reservation_active=Reservierung aktiv -label_reservation_max_items=Maximale Objekte -label_booking_deadline=Buchungsfrist -label_template_validation=Vorlage Emailvalidierung -label_template_confirmation=Vorlage Reservierungsbest\u00e4tigung -label_template_waitlist=Vorlage Wartelist -message_event_not_found=Veranstaltung nicht gefunden -label_items=Objekte -label_costs=Kosten -label_all=Alle -label_yes=Ja -label_no=Nein -label_status=Status -label_firstname=Vorname -label_lastname=Nachname -label_emailaddress=E-Mail-Adresse -label_comment=Kommentar -label_email_confirmed=E-Mail best\u00e4tigt -label_booking_number=Buchungsnummer -label_booking_executed=Buchungs ausgef\u00fchrt -tt_log_entries=Logbucheintr\u00e4ge -tt_cancel_reservation=Storniere die Reservierung -tt_send_email_again=Sende E-Mail erneut -tt_move_from_wl=Schiebe von Warteliste -tt_fix_reservation=Versuche den Fehler zu beheben -tt_edit_reservation=Bearbeite die Reservierung -button_refresh_free=Frei aktualisieren -button_manual_reserve=Reservieren -button_export=Exportieren -label_amount=Anzahl -label_select=W\u00e4hlen -label_created_by=Erzeugt durch -label_ip=IP -label_ip_forwarded=IP (forwarded) -label_value=Wert -label_useragent=Useragent -button_ok=Ok -message_comment=Bitte geben Sie einen Kommentar an -menu_help=Hilfe -label_event=Veranstaltung -label_active=Aktiv -label_waitlist=Warteliste -label_is_waitlist=Ist Warteliste -label_order=Reihenfolge -message_dynamic_numbering=Dynamische Nummerierung (%n als Platzhalter) -label_start_number=Startnummer -label_end_number=Endnummer -header_item_def=Objekte f\u00fcr Veranstaltung -message_no_event_items=Keine Objekte definiert -button_overview=\u00dcbersicht -label_reservation_auto_start=Automatisch ein/ausschalten -label_item_public=\u00d6ffentlich verf\u00fcgar? -label_is_publicitem=\u00d6ffentlich -label_customer_comment=Kundenkommentar -label_change_comment=\u00c4nderungskommentar -label_existing_items=aktuelle Objekte -label_new_items=neue Objekte -label_available_items=verf\u00fcgbare Objekte -label_no_records=Keine Daten gefunden. -button_mail=E-Mail -header_email_distribution=Emailversand -label_template=Vorlage -label_demomode=Demomodus -message_invalid_email=Bitte geben Sie eine g\u00fcltige Emailadresse an -menu_permissions=Berechtigungen -button_save=Speichern -menu_groups=Gruppen -message_email_sent=Email gesendet -message_email_with_error=Emails mit Fehler -message_no_email=keine Emailadresse verf\u00fcgbar -message_email_not_sent=Fehler beim Versenden der Email -label_seating=Saalplan Platz -label_attachments=Attachments -label_language=Sprache -label_subject=Betreff -label_bytes=Bytes -label_upload=Upload -header_export=Exportieren -label_export_type=Export Art -label_filtered=Gefiltert -label_include_deleted=Einschlie\u00dflich gel\u00f6scht -label_include_log=mit Logbuch -label_template_booking_executed=Vorlage Buchung durchgef\u00fchrt -label_street=Stra\u00dfe -label_zipCode=PLZ -label_city=Ort -label_groupName=Gruppenname -label_phoneNumber=Telefonnummer -label_template_waitlist_cancelled=Vorlage Warteliste Abbruch -msgs_menu_status=Status -menu_status=Status -button_add=Hinzuf\u00fcgen + +header_login=Anmeldung +header_reset_password=Passwort zur\u00fccksetzten +message_username_password=Bitte geben Deinen Benutzernamen und dein Passwort ein +button_login=Anmelden +button_cancel=Abbruch +button_password_lost=Passwort vergessen? +label_username=Benutzername +label_password=Passwort +label_new_password=Neues Passwort +button_password_reset=Passwort zur\u00fccksetzten +header_passwort_lost=Passwort vergessen +message_start_password_reset=Bitte gib deinen Benutzernamen ein um das Zur\u00fccksetzten des Passworts zu starten. +menu_dashboard=Dashbaord +menu_events=Veranstaltungen +menu_administration=Administration +menu_overview=\u00dcbersicht +menu_emails=E-Mails +menu_account=Benutzer +menu_config=Konfiguration +menu_logout=Abmelden +button_new=Neu +button_delete=L\u00f6schen +button_edit=Bearbeiten +button_reload=Aktualisieren +label_name=Name +label_description=Beschreibung +label_event_date=Veranstaltungsdatum +label_reservation=Reservierung +label_reservation_from_to=Reservierung von/bis +label_actions=Aktionen +message_confirm=Bist du sicher? +button_setup=Setup +button_reservations=Reservierungen +label_event_name=Veranstaltungsname +label_event_item_desc=Veranstaltungsobjekte +label_timezone=Zeitzone +label_event_start=Veranstaltungsbeginn +label_event_end=Veranstaltungsende +label_reservation_autostart=Reservierung von +label_reservation_autoend=Reservierung bis +label_reservation_active=Reservierung aktiv +label_reservation_max_items=Maximale Objekte +label_booking_deadline=Buchungsfrist +label_template_validation=Vorlage Emailvalidierung +label_template_confirmation=Vorlage Reservierungsbest\u00e4tigung +label_template_waitlist=Vorlage Wartelist +message_event_not_found=Veranstaltung nicht gefunden +label_items=Objekte +label_costs=Kosten +label_all=Alle +label_yes=Ja +label_no=Nein +label_status=Status +label_firstname=Vorname +label_lastname=Nachname +label_emailaddress=E-Mail-Adresse +label_comment=Kommentar +label_email_confirmed=E-Mail best\u00e4tigt +label_booking_number=Buchungsnummer +label_booking_executed=Buchungs ausgef\u00fchrt +tt_log_entries=Logbucheintr\u00e4ge +tt_cancel_reservation=Storniere die Reservierung +tt_send_email_again=Sende E-Mail erneut +tt_move_from_wl=Schiebe von Warteliste +tt_fix_reservation=Versuche den Fehler zu beheben +tt_edit_reservation=Bearbeite die Reservierung +button_refresh_free=Frei aktualisieren +button_manual_reserve=Reservieren +button_export=Exportieren +label_amount=Anzahl +label_select=W\u00e4hlen +label_created_by=Erzeugt durch +label_ip=IP +label_ip_forwarded=IP (forwarded) +label_value=Wert +label_useragent=Useragent +button_ok=Ok +message_comment=Bitte geben Sie einen Kommentar an +menu_help=Hilfe +label_event=Veranstaltung +label_active=Aktiv +label_waitlist=Warteliste +label_is_waitlist=Ist Warteliste +label_order=Reihenfolge +message_dynamic_numbering=Dynamische Nummerierung (%n als Platzhalter) +label_start_number=Startnummer +label_end_number=Endnummer +header_item_def=Objekte f\u00fcr Veranstaltung +message_no_event_items=Keine Objekte definiert +button_overview=\u00dcbersicht +label_reservation_auto_start=Automatisch ein/ausschalten +label_item_public=\u00d6ffentlich verf\u00fcgar? +label_is_publicitem=\u00d6ffentlich +label_customer_comment=Kundenkommentar +label_change_comment=\u00c4nderungskommentar +label_existing_items=aktuelle Objekte +label_new_items=neue Objekte +label_available_items=verf\u00fcgbare Objekte +label_no_records=Keine Daten gefunden. +button_mail=E-Mail +header_email_distribution=Emailversand +label_template=Vorlage +label_demomode=Demomodus +message_invalid_email=Bitte geben Sie eine g\u00fcltige Emailadresse an +menu_permissions=Berechtigungen +button_save=Speichern +menu_groups=Gruppen +message_email_sent=Email gesendet +message_email_with_error=Emails mit Fehler +message_no_email=keine Emailadresse verf\u00fcgbar +message_email_not_sent=Fehler beim Versenden der Email +label_seating=Saalplan Platz +label_attachments=Attachments +label_language=Sprache +label_subject=Betreff +label_bytes=Bytes +label_upload=Upload +header_export=Exportieren +label_export_type=Export Art +label_filtered=Gefiltert +label_include_deleted=Einschlie\u00dflich gel\u00f6scht +label_include_log=mit Logbuch +label_template_booking_executed=Vorlage Buchung durchgef\u00fchrt +label_street=Stra\u00dfe +label_zipCode=PLZ +label_city=Ort +label_groupName=Gruppenname +label_phoneNumber=Telefonnummer +label_template_waitlist_cancelled=Vorlage Warteliste Abbruch +msgs_menu_status=Status +menu_status=Status +button_add=Hinzuf\u00fcgen +passwords_different=Passw\u00f6rter stimmen \u00fcberein, bitte \u00fcberpr\u00fcfen Sie ihre Eingabe diff --git a/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages_en.properties b/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages_en.properties index ceaabd1..e9f44f4 100644 --- a/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages_en.properties +++ b/account-ui/src/main/resources/de/muehlencord/shared/account/web/presentation/messages_en.properties @@ -1,133 +1,134 @@ - -header_login=Login -header_reset_password=Reset password -message_username_password=Please enter your user name and a new password -button_login=Login -button_cancel=Cancel -button_password_lost=Password lost? -label_username=Username -label_password=Password -label_new_password=New Password -button_password_reset=Reset password -header_passwort_lost=Lost password -message_start_password_reset=Please enter your username to start the password recovery procedure -menu_dashboard=Dashboard -menu_events=Events -menu_administration=Administration -menu_overview=Overview -menu_emails=Emails -menu_account=Account -menu_config=Config -menu_logout=Logout -button_new=New -button_delete=Delete -button_edit=Edit -button_reload=Reload -label_name=Name -label_description=Description -label_event_date=Event Date -label_reservation=Reservation -label_reservation_from_to=Reservation from/to -label_actions=Actions -message_confirm=Are you sure? -button_setup=Setup -button_reservations=Reservations -label_event_name=Event Name -label_event_item_desc=Event Item Description -label_timezone=Timezone -label_event_start=Event Start -label_event_end=Event End -label_reservation_autostart=Reservation Start -label_reservation_autoend=Reservation End -label_reservation_active=Reservation active -label_reservation_max_items=Max Items -label_booking_deadline=Booking deadline -label_template_validation=Email validation mail template -label_template_confirmation=Event confirmation mail template -label_template_waitlist=Event waitlist mail template -message_event_not_found=Event not found -label_items=Items -label_costs=Costs -label_all=All -label_yes=Yes -label_no=No -label_status=Status -label_firstname=Firstname -label_lastname=Lastname -label_emailaddress=Emailaddress -label_comment=Comment -label_email_confirmed=Email confirmed -label_booking_number=Booking Number -label_booking_executed=booking executed -tt_log_entries=Show log entries -tt_cancel_reservation=Cancel the current reservation -tt_send_email_again=Send email again -tt_move_from_wl=Move from waitlist -tt_fix_reservation=Try to fix the current reservation -tt_edit_reservation=Edit the reservation -button_refresh_free=Refresh free -button_manual_reserve=Reserve -button_export=Export -label_amount=Amount -label_select=Select -label_created_by=Created by -label_ip=IP -label_ip_forwarded=IP (forwarded) -label_value=Value -label_useragent=Useragent -button_ok=Ok -message_comment=Please add a comment -menu_help=Help -label_event=Event -label_active=Active -label_waitlist=Waitlist -label_is_waitlist=Is waitlist -label_order=Reservation Order -message_dynamic_numbering=dynamic numbering (put %n as placeholder) -label_start_number=Start Number -label_end_number=End Number -header_item_def=Define items for event -message_no_event_items=No event item defined -button_overview=Overview -label_reservation_auto_start=Automatically switch on/off -label_item_public=Item public? -label_is_publicitem=Is public -label_customer_comment=Customer comment -label_change_comment=Change comment -label_existing_items=current items -label_new_items=new items -label_available_items=available items -label_no_records=No records found. -button_mail=Mail -header_email_distribution=Email distribution -label_template=Template -label_demomode=Demo mode -message_invalid_email=Please provide a valid email address -menu_permissions=Permissions -button_save=Save -menu_groups=Groups -message_email_sent=email sent -message_email_with_error=emails with error -message_no_email=no email address defined -message_email_not_sent=Error while sending emails -label_seating=Seating -label_attachments=Anh\u00e4nge -label_language=Language -label_subject=Subject -label_bytes=Bytes -label_upload=Hochladen -header_export=Export -label_export_type=Export Type -label_filtered=Filtered -label_include_deleted=Include deleted -label_include_log=Include Logs -label_template_booking_executed=Booking executed template -label_street=Street -label_zipCode=ZIP Code -label_city=City -label_groupName=Groupname -label_phoneNumber=Phone Number -label_template_waitlist_cancelled=Waitlist cancelled mail template -msgs_menu_status=Status -menu_status=Status -button_add=Add + +header_login=Login +header_reset_password=Reset password +message_username_password=Please enter your user name and a new password +button_login=Login +button_cancel=Cancel +button_password_lost=Password lost? +label_username=Username +label_password=Password +label_new_password=New Password +button_password_reset=Reset password +header_passwort_lost=Lost password +message_start_password_reset=Please enter your username to start the password recovery procedure +menu_dashboard=Dashboard +menu_events=Events +menu_administration=Administration +menu_overview=Overview +menu_emails=Emails +menu_account=Account +menu_config=Config +menu_logout=Logout +button_new=New +button_delete=Delete +button_edit=Edit +button_reload=Reload +label_name=Name +label_description=Description +label_event_date=Event Date +label_reservation=Reservation +label_reservation_from_to=Reservation from/to +label_actions=Actions +message_confirm=Are you sure? +button_setup=Setup +button_reservations=Reservations +label_event_name=Event Name +label_event_item_desc=Event Item Description +label_timezone=Timezone +label_event_start=Event Start +label_event_end=Event End +label_reservation_autostart=Reservation Start +label_reservation_autoend=Reservation End +label_reservation_active=Reservation active +label_reservation_max_items=Max Items +label_booking_deadline=Booking deadline +label_template_validation=Email validation mail template +label_template_confirmation=Event confirmation mail template +label_template_waitlist=Event waitlist mail template +message_event_not_found=Event not found +label_items=Items +label_costs=Costs +label_all=All +label_yes=Yes +label_no=No +label_status=Status +label_firstname=Firstname +label_lastname=Lastname +label_emailaddress=Emailaddress +label_comment=Comment +label_email_confirmed=Email confirmed +label_booking_number=Booking Number +label_booking_executed=booking executed +tt_log_entries=Show log entries +tt_cancel_reservation=Cancel the current reservation +tt_send_email_again=Send email again +tt_move_from_wl=Move from waitlist +tt_fix_reservation=Try to fix the current reservation +tt_edit_reservation=Edit the reservation +button_refresh_free=Refresh free +button_manual_reserve=Reserve +button_export=Export +label_amount=Amount +label_select=Select +label_created_by=Created by +label_ip=IP +label_ip_forwarded=IP (forwarded) +label_value=Value +label_useragent=Useragent +button_ok=Ok +message_comment=Please add a comment +menu_help=Help +label_event=Event +label_active=Active +label_waitlist=Waitlist +label_is_waitlist=Is waitlist +label_order=Reservation Order +message_dynamic_numbering=dynamic numbering (put %n as placeholder) +label_start_number=Start Number +label_end_number=End Number +header_item_def=Define items for event +message_no_event_items=No event item defined +button_overview=Overview +label_reservation_auto_start=Automatically switch on/off +label_item_public=Item public? +label_is_publicitem=Is public +label_customer_comment=Customer comment +label_change_comment=Change comment +label_existing_items=current items +label_new_items=new items +label_available_items=available items +label_no_records=No records found. +button_mail=Mail +header_email_distribution=Email distribution +label_template=Template +label_demomode=Demo mode +message_invalid_email=Please provide a valid email address +menu_permissions=Permissions +button_save=Save +menu_groups=Groups +message_email_sent=email sent +message_email_with_error=emails with error +message_no_email=no email address defined +message_email_not_sent=Error while sending emails +label_seating=Seating +label_attachments=Anh\u00e4nge +label_language=Language +label_subject=Subject +label_bytes=Bytes +label_upload=Hochladen +header_export=Export +label_export_type=Export Type +label_filtered=Filtered +label_include_deleted=Include deleted +label_include_log=Include Logs +label_template_booking_executed=Booking executed template +label_street=Street +label_zipCode=ZIP Code +label_city=City +label_groupName=Groupname +label_phoneNumber=Phone Number +label_template_waitlist_cancelled=Waitlist cancelled mail template +msgs_menu_status=Status +menu_status=Status +button_add=Add +passwords_different=Passwords do not match, please check input diff --git a/account-ui/src/main/webapp/WEB-INF/shiro.ini b/account-ui/src/main/webapp/WEB-INF/shiro.ini index 981899f..f841c69 100644 --- a/account-ui/src/main/webapp/WEB-INF/shiro.ini +++ b/account-ui/src/main/webapp/WEB-INF/shiro.ini @@ -1,56 +1,56 @@ -[main] -cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager -securityManager.cacheManager = $cacheManager - -# DataSource Setup -datasource = org.apache.shiro.jndi.JndiObjectFactory -datasource.resourceName = java:/jboss/accountTestDs -# TODO - change to accountDs -datasource.resourceRef = true - -# HashService -hashService = org.apache.shiro.crypto.hash.DefaultHashService -hashService.hashIterations = 500000 -hashService.hashAlgorithmName = SHA-512 -hashService.generatePublicSalt = true - -# Password service -passwordService = org.apache.shiro.authc.credential.DefaultPasswordService -passwordService.hashService = $hashService - -# Required password matcher -passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher -passwordMatcher.passwordService = $passwordService - -# JDBC Realm setup -jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm -jdbcRealm.permissionsLookupEnabled=false -jdbcRealm.authenticationQuery = select account_password from account where username = ? and status not in ('LOCKED','DELETED') -jdbcRealm.userRolesQuery = select r.role_name from application_role r, account_role ar, account a WHERE a.username = ? AND a.id = ar.account AND ar.account_role = r.id -jdbcRealm.credentialsMatcher = $passwordMatcher -jdbcRealm.dataSource = $datasource - -# Activate realms -authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy -securityManager.realms = $jdbcRealm -securityManager.authenticator.authenticationStrategy = $authcStrategy - -# Setup authentication filter -authc = de.muehlencord.shirofaces.filter.FacesAjaxAwarePassThruAuthenticationFilter -authc.loginUrl = /login.xhtml -authc.successUrl = /web/account.xhtml - -roles.unauthorizedUrl = /error/accessDenied.xhtml - -# -# filter setup -# -[urls] -/public/**=anon -/resources/**=anon -/fonts/**=anon -/javax.faces.resource/**=anon -/login.xhtml=authc -/logout.xhtml=logout -/**=authc -# /web/**=authc +[main] +cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager +securityManager.cacheManager = $cacheManager + +# DataSource Setup +datasource = org.apache.shiro.jndi.JndiObjectFactory +datasource.resourceName = java:/jboss/accountTestDs +# TODO - change to accountDs +datasource.resourceRef = true + +# HashService +hashService = org.apache.shiro.crypto.hash.DefaultHashService +hashService.hashIterations = 500000 +hashService.hashAlgorithmName = SHA-512 +hashService.generatePublicSalt = true + +# Password service +passwordService = org.apache.shiro.authc.credential.DefaultPasswordService +passwordService.hashService = $hashService + +# Required password matcher +passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher +passwordMatcher.passwordService = $passwordService + +# JDBC Realm setup +jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm +jdbcRealm.permissionsLookupEnabled=false +jdbcRealm.authenticationQuery = select al.account_password from account a, account_login al where al.account = a.id and a.username = ? and status not in ('LOCKED','DELETED') +jdbcRealm.userRolesQuery = select r.role_name from application_role r, account_role ar, account a WHERE a.username = ? AND a.id = ar.account AND ar.account_role = r.id +jdbcRealm.credentialsMatcher = $passwordMatcher +jdbcRealm.dataSource = $datasource + +# Activate realms +authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy +securityManager.realms = $jdbcRealm +securityManager.authenticator.authenticationStrategy = $authcStrategy + +# Setup authentication filter +authc = de.muehlencord.shirofaces.filter.FacesAjaxAwarePassThruAuthenticationFilter +authc.loginUrl = /login.xhtml +authc.successUrl = /web/account.xhtml + +roles.unauthorizedUrl = /error/accessDenied.xhtml + +# +# filter setup +# +[urls] +/public/**=anon +/resources/**=anon +/fonts/**=anon +/javax.faces.resource/**=anon +/login.xhtml=authc +/logout.xhtml=logout +/**=authc +# /web/**=authc diff --git a/account-ui/src/main/webapp/web/account.xhtml b/account-ui/src/main/webapp/web/account.xhtml index cfb965a..1978a6b 100644 --- a/account-ui/src/main/webapp/web/account.xhtml +++ b/account-ui/src/main/webapp/web/account.xhtml @@ -1,251 +1,314 @@ - - - - - Account Overview - - - - for #{applicationView.currentApplication.applicationName} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - -
-
- -
- - -
-
- - -
-
- - - - -
-
-
- - -
- - - - - - - - -
-
- -
-
- - - - - - -
-
- -
- -
- -
-
- -
-
- -
- -
- -
-
- -
-
- -
- -
- -
-
- - - -
-
- -
- - - -
- -
-
- - - -
-
- -
- -
- -
-
- -
-
- -
- -
- -
-
- -
-
- -
- -
- -
-
- -
-
- -
- -
- -
-
- -
-
- -
- -
- -
-
- -
-
- -
-
- - -
- -
-
- - - - - - -
-
- -
- - -
- - -
-
- - -
-
-
-
- -
- + + + + + Account Overview + + + + for #{applicationView.currentApplication.applicationName} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + +
+
+ +
+ +
+
+ +
+
+ + + +
+ +
+ + + + + + + + + + + + + +
+
+
+ + + + +
+ + + + + + + + +
+
+ +
+
+ + + + + + +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ + + +
+
+ +
+ + + +
+ +
+
+ + + +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ +
+
+ + + + + + +
+
+ +
+ + +
+ + +
+
+ + +
+
+
+
+ + + + + + + +
+ + +
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ + +
+
+ + +
+
+
+
+ +
+
\ No newline at end of file diff --git a/account-ui/src/main/webapp/web/index.xhtml b/account-ui/src/main/webapp/web/index.xhtml index a5b64af..750dc31 100644 --- a/account-ui/src/main/webapp/web/index.xhtml +++ b/account-ui/src/main/webapp/web/index.xhtml @@ -1,84 +1,84 @@ - - - - - Applications - - - - - - -
-
- - - -
-
- -
-
- -
-
- - - -
- -
-
- - -
- - - - - - - -
-
- -
-
- - - -
-
- -
- -
- - -
-
- - -
- - -
-
-
- -
+ + + + + Applications + + + + + + +
+
+ + + +
+
+ +
+
+ +
+
+ + + +
+ +
+
+ + +
+ + + + + + + +
+
+ +
+
+ + + +
+
+ +
+ +
+ + +
+
+ + +
+ + +
+
+
+ +
\ No newline at end of file diff --git a/account/pom.xml b/account/pom.xml index f4818f2..9ced575 100644 --- a/account/pom.xml +++ b/account/pom.xml @@ -65,7 +65,13 @@ org.slf4j jcl-over-slf4j test - + + + de.muehlencord.shared + shared-util + 1.1-SNAPSHOT + jar + javax javaee-api diff --git a/account/sql/account_prefill.sql b/account/sql/account_prefill.sql index 80839b5..4f071bb 100644 --- a/account/sql/account_prefill.sql +++ b/account/sql/account_prefill.sql @@ -1,18 +1,32 @@ +DELETE FROM config; +DELETE FROM account_role; +DELETE FROM account_login; +DELETE FROM account; +DELETE FROM role_permission; +DELETE FROM application_role; +DELETE FROM application_permission; +DELETE FROM application; --- application configuration -INSERT INTO application_permission (id, permission_name, permission_description) values ('dfd0f8f1-4a51-4fdc-9a1c-a942bee9b649', 'test:view', 'Display test view'); -INSERT INTO application_role (id, role_name, role_description) values ('5cd0aca0-5466-483d-8f3e-c369f8061131','Admin', 'Admin role'); -INSERT INTO application_role (id, role_name, role_description) values ('da30060e-fd23-4016-a506-4e12e9322148', 'User', 'Standard user role'); +INSERT INTO application (id, application_name) values ('143a2bd3-7e0b-4162-a76e-3031331c7dfe', 'Account UI'); --- account -INSERT INTO account (id, username, firstname, lastname, emailaddress, account_password, created_by, last_updated_by) values ('2a712ed4-30f8-47b4-a002-7d87441b7013', 'system', 'system', 'system', 'n/a', 'n/a', 'system', 'system'); -INSERT INTO account (id, username, emailaddress, firstname, lastname, account_password, created_by, last_updated_by) values('ab5c8337-6872-4aea-a9b9-78ea63706b8f','admin', 'joern@muehlencord.de', 'Joern', 'Muehlencord','$shiro1$SHA-256$500000$4bHPNH9k539UjdFLgm/HOA==$T/n8skgoGSOtNw/c9ScDlXCiGrx2cZF0Esrvf6WPq6g=', 'admin','admin'); --admin/secret +-- permissions not used in Account UI +-- INSERT INTO application_permission (id, permission_name, permission_description) values ('dfd0f8f1-4a51-4fdc-9a1c-a942bee9b649', 'test:view', 'Display test view'); + +-- add roles to Account UI application +INSERT INTO application_role (id, application, role_name, role_description) values ('5cd0aca0-5466-483d-8f3e-c369f8061131','143a2bd3-7e0b-4162-a76e-3031331c7dfe', 'Admin', 'Admin role'); +INSERT INTO application_role (id, application, role_name, role_description) values ('da30060e-fd23-4016-a506-4e12e9322148','143a2bd3-7e0b-4162-a76e-3031331c7dfe', 'User', 'Standard user role'); + +-- create accounts +INSERT INTO account (id, username, firstname, lastname, emailaddress, created_by, last_updated_by) values ('2a712ed4-30f8-47b4-a002-7d87441b7013', 'system', 'system', 'system', 'n/a', 'system', 'system'); +INSERT INTO account (id, username, emailaddress, firstname, lastname, created_by, last_updated_by) values('ab5c8337-6872-4aea-a9b9-78ea63706b8f','admin', 'joern@muehlencord.de', 'Joern', 'Muehlencord','system','system'); --admin/secret +-- assign AccountUI.Admin role to admin user INSERT INTO account_role (account, account_role) values ('ab5c8337-6872-4aea-a9b9-78ea63706b8f', '5cd0aca0-5466-483d-8f3e-c369f8061131'); - +-- create login for user admin (login admin, password secret) +INSERT INTO account_login (account, account_password, created_by, last_updated_by) VALUES ('ab5c8337-6872-4aea-a9b9-78ea63706b8f', '$shiro1$SHA-256$500000$4bHPNH9k539UjdFLgm/HOA==$T/n8skgoGSOtNw/c9ScDlXCiGrx2cZF0Esrvf6WPq6g=', 'system', 'system'); -- config -INSERT INTO config (config_key, config_key_account, config_value) VALUES ('account.maxFailedLogins', '2a712ed4-30f8-47b4-a002-7d87441b7013', '5'); +INSERT INTO config (application, config_key, config_key_account, config_value) VALUES ('143a2bd3-7e0b-4162-a76e-3031331c7dfe', 'account.maxFailedLogins', '2a712ed4-30f8-47b4-a002-7d87441b7013', '5'); diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountControl.java b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountControl.java index e2e5f2f..64ae49c 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountControl.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountControl.java @@ -1,314 +1,376 @@ -package de.muehlencord.shared.account.business.account.boundary; - -import de.muehlencord.shared.account.business.account.entity.AccountException; -import de.muehlencord.shared.account.business.account.entity.AccountStatus; -import de.muehlencord.shared.account.business.config.boundary.ConfigService; -import de.muehlencord.shared.account.business.mail.entity.MailException; -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.ApplicationRoleEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import de.muehlencord.shared.account.business.config.entity.ConfigException; -import de.muehlencord.shared.account.util.SecurityUtil; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import javax.ejb.EJB; -import javax.ejb.Stateless; -import javax.inject.Inject; -import javax.persistence.EntityManager; -import javax.persistence.NoResultException; -import javax.persistence.Query; -import javax.transaction.Transactional; -import org.apache.commons.lang3.RandomStringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.shiro.SecurityUtils; -import org.apache.shiro.subject.Subject; - -/** - * - * @author joern.muehlencord - */ -@Stateless -public class AccountControl implements Serializable { - - private static final Logger LOGGER = LoggerFactory.getLogger(AccountControl.class.getName()); - private static final long serialVersionUID = 3424816272598108101L; - - @EJB - private ConfigService configService; - - @EJB - private MailService mailService; - - @Inject - EntityManager em; - - /** - * returns a list of active accounts - * - * @return a list of active accounts - */ - public List getActiveAccounts() { - Query query = em.createQuery("SELECT a FROM AccountEntity a WHERE a.status <> :status", AccountEntity.class); - query.setParameter("status", AccountStatus.DISABLED.name()); - return query.getResultList(); - } - - /** - * returns a list of active accounts - * - * @return a list of active accounts - */ - public List getAllAccounts() { - Query query = em.createNamedQuery("AccountEntity.findAll"); - return query.getResultList(); - } - - public List getAccounts(boolean includeDisabled) { - if (includeDisabled) { - return getAllAccounts(); - } else { - return getActiveAccounts(); - } - } - - public AccountEntity getAccountEntity(String userName, boolean loadRoles) { - StringBuilder queryBuilder = new StringBuilder(); - queryBuilder.append("SELECT a FROM AccountEntity a "); - if (loadRoles) { - queryBuilder.append("LEFT JOIN FETCH a.applicationRoleList "); - } - queryBuilder.append("WHERE a.username = :username"); - Query query = em.createQuery(queryBuilder.toString()); - query.setParameter("username", userName); - try { - return (AccountEntity) query.getSingleResult(); - } catch (NoResultException ex) { - return null; - } - } - - @Transactional - public AccountEntity saveAccount(ApplicationEntity application, AccountEntity account, List applicationRoles) { - Date now = new Date(); // Todo now in UTC - Subject currentUser = SecurityUtils.getSubject(); - String currentLoggedInUser = currentUser.getPrincipal().toString(); - - account.setLastUpdatedBy(currentLoggedInUser); - account.setLastUpdatedOn(now); - - boolean newAccount = (account.getCreatedOn() == null); - - // new account - if (newAccount) { - account.setCreatedOn(now); - account.setCreatedBy(currentLoggedInUser); - - // set default random password, user has to get password via lost passwort option afterwards - String randomPassword = RandomStringUtils.random(20, true, true); - String hashedPassword = SecurityUtil.createPassword(randomPassword); - account.setAccountPassword(hashedPassword); - em.persist(account); - } else { - em.merge(account); - - // reload account from db and join roles - account = getAccountEntity(account.getUsername(), true); - } - - // assign roles to account - if (account.getApplicationRoleList() == null) { - account.setApplicationRoleList(new ArrayList<>()); - } - - boolean roleSetupChanged = false; - // remove roles which are no longer listed - // ensure this is only done for the given application - keep the other applications untouched - List assignedRoles = new ArrayList<>(); - assignedRoles.addAll(account.getApplicationRoleList()); - for (ApplicationRoleEntity currentlyAssignedRole : assignedRoles) { - if ((currentlyAssignedRole.getApplication().equals(application) && (!applicationRoles.contains(currentlyAssignedRole)))) { - account.getApplicationRoleList().remove(currentlyAssignedRole); - roleSetupChanged = true; - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Removed role {} ({}) from user {}", currentlyAssignedRole.getRoleName(), application.getApplicationName(), account.getUsername()); - } - } - } - - // add newly added roles to role list - for (ApplicationRoleEntity applicationRole : applicationRoles) { - if (!account.getApplicationRoleList().contains(applicationRole)) { - account.addApplicationRole(applicationRole); - roleSetupChanged = true; - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Added role {} ({}) to account {}", applicationRole.getRoleName(), application.getApplicationName(), account.getUsername()); - } - } - } - - // update account in database if roles changed - if (roleSetupChanged) { - em.merge(account); - } - return account; - } - - @Transactional - public void deleteAccount(AccountEntity account) throws AccountException { - Date now = new Date(); // Todo now in UTC - Subject currentUser = SecurityUtils.getSubject(); - String currentUserName = currentUser.getPrincipal().toString(); - - if (account.getUsername().equals(currentUserName)) { - throw new AccountException("Cannot delete own account"); - } else { - account.setStatus(AccountStatus.DISABLED.name()); - account.setLastUpdatedBy(currentUserName); - account.setLastUpdatedOn(now); - em.merge(account); - } - - } - - public boolean initPasswordReset(String userName) { - try { - AccountEntity account = getAccountEntity(userName, false); - if (account == null) { - LOGGER.warn("Account with name " + userName + " not found"); - return false; - } - - if (account.getStatus().equals(AccountStatus.BLOCKED.name())) { - LOGGER.warn("Account " + userName + " is locked, cannot initialize password reset"); - return false; - } - - String randomString = RandomStringUtils.random(40, true, true); - - Date validTo = new Date(); // TODO now in UTC - validTo = new Date(validTo.getTime() + 1000 * 600); // 10 minutes to react - - account.setPasswordResetHash(randomString); - account.setPasswordResetOngoing(true); - account.setPasswordResetValidTo(validTo); - - mailService.sendPasswortResetStartEmail(account, randomString); - - em.merge(account); - return true; - } catch (MailException ex) { - LOGGER.error("Error while sending password reset mail. " + ex.toString()); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Error while sending password reset mail.", ex); - } - return false; - } - } - - public boolean resetPassword(String userName, String newPassword, String resetPasswordToken) { - AccountEntity account = getAccountEntity(userName, false); - - if (account == null) { - LOGGER.warn("Error while resetting password, no account with username " + userName + " found"); - // TODO add extra logging for intrusion protection system like fail2ban - return false; - } - - if (account.getPasswordResetOngoing() && (account.getPasswordResetHash() != null) && (account.getPasswordResetValidTo() != null)) { - Date now = new Date(); // TODO now in UTC - String storedHash = account.getPasswordResetHash().trim(); - if (account.getPasswordResetValidTo().after(now)) { - if (storedHash.equals(resetPasswordToken)) { - // everything ok, reset password - executePasswordReset(account, newPassword); - LOGGER.info("Updated password for user " + userName); - return true; - } else { - // token is not valid, refuse to change password - LOGGER.warn("Trying to reset password for user " + userName + " but wrong token " + resetPasswordToken + " provided"); - addLoginError(account); - return false; - } - } else { - // password reset token no longer valid - LOGGER.warn("Trying to reset password for user " + userName + " but token is no longer valid"); - addLoginError(account); - return false; - } - } else { - // user is not is password reset mode - LOGGER.warn("Trying to reset password for user " + userName + " but password reset was not requested"); - addLoginError(account); - return false; - } - } - - private void executePasswordReset(AccountEntity account, String newPassword) { - Date now = new Date(); // TODO now in UTC - - String hashedPassword = SecurityUtil.createPassword(newPassword); - account.setAccountPassword(hashedPassword); - - account.setPasswordResetOngoing(false); - account.setPasswordResetHash(null); - account.setPasswordResetValidTo(null); - - account.setLastUpdatedBy(account.getUsername()); - account.setLastUpdatedOn(now); - em.merge(account); - - } - - public void updateLogin(AccountEntity account) { - Date now = new Date(); // TODO now in UTC - // a scucessful login ends a password reset procedure - if (account.getPasswordResetOngoing()) { - account.setPasswordResetOngoing(false); - account.setPasswordResetHash(null); - account.setPasswordResetValidTo(null); - account.setLastUpdatedOn(now); - account.setLastUpdatedBy(account.getUsername()); - } - - account.setLastLogin(now); - account.setFailureCount(0); - account.setStatus(AccountStatus.NORMAL.name()); - - em.merge(account); - } - - public void addLoginError(ApplicationEntity application, AccountEntity account) { - try { - Date now = new Date(); // TODO now in UTC - account.setLastFailedLogin(now); - account.setFailureCount(account.getFailureCount() + 1); - - int maxFailedLogins = Integer.parseInt(configService.getConfigValue("account.maxFailedLogins")); - if ((account.getFailureCount() >= maxFailedLogins) && (!account.getStatus().equals("LOCKED"))) { // TOD add status enum - // max failed logins reached, disabling user - LOGGER.info("Locking account " + account.getUsername() + " due to " + account.getFailureCount() + " failed logins"); - account.setStatus(AccountStatus.BLOCKED.name()); - } - - // on a failed login request, disable password reset - account.setPasswordResetOngoing(false); - account.setPasswordResetHash(null); - account.setPasswordResetValidTo(null); - - account.setLastUpdatedBy("system"); - account.setLastUpdatedOn(now); - em.merge(account); - } catch (ConfigException ex) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(ex.toString(), ex); - } else { - LOGGER.error(ex.toString()); - } - } - } - -} +package de.muehlencord.shared.account.business.account.boundary; + +import de.muehlencord.shared.account.business.account.entity.AccountException; +import de.muehlencord.shared.account.business.account.entity.AccountStatus; +import de.muehlencord.shared.account.business.config.boundary.ConfigService; +import de.muehlencord.shared.account.business.mail.entity.MailException; +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.AccountLoginEntity; +import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import de.muehlencord.shared.account.util.SecurityUtil; +import de.muehlencord.shared.util.DateUtil; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.NoResultException; +import javax.persistence.Query; +import javax.transaction.Transactional; +import org.apache.commons.lang3.RandomStringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + +/** + * + * @author joern.muehlencord + */ +@Stateless +public class AccountControl implements Serializable { + + private static final Logger LOGGER = LoggerFactory.getLogger(AccountControl.class.getName()); + private static final long serialVersionUID = 3424816272598108101L; + + @EJB + private ConfigService configService; + + @EJB + private MailService mailService; + + @Inject + private ApplicationEntity application; + + @Inject + EntityManager em; + + /** + * returns a list of active accounts + * + * @return a list of active accounts + */ + public List getActiveAccounts() { + Query query = em.createQuery("SELECT a FROM AccountEntity a WHERE a.status <> :status", AccountEntity.class); + query.setParameter("status", AccountStatus.DISABLED.name()); + return query.getResultList(); + } + + /** + * returns a list of active accounts + * + * @return a list of active accounts + */ + public List getAllAccounts() { + Query query = em.createNamedQuery("AccountEntity.findAll"); + return query.getResultList(); + } + + public List getAccounts(boolean includeDisabled) { + if (includeDisabled) { + return getAllAccounts(); + } else { + return getActiveAccounts(); + } + } + + public AccountEntity getAccountEntity(String userName, boolean loadRoles) { + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("SELECT a FROM AccountEntity a "); + if (loadRoles) { + queryBuilder.append("LEFT JOIN FETCH a.applicationRoleList "); + } + queryBuilder.append("WHERE a.username = :username"); + Query query = em.createQuery(queryBuilder.toString()); + query.setParameter("username", userName); + try { + return (AccountEntity) query.getSingleResult(); + } catch (NoResultException ex) { + return null; + } + } + + @Transactional + public AccountEntity saveAccount(AccountEntity account, List applicationRoles) { + Date now = DateUtil.getCurrentTimeInUTC(); + Subject currentUser = SecurityUtils.getSubject(); + String currentLoggedInUser = currentUser.getPrincipal().toString(); + + account.setLastUpdatedBy(currentLoggedInUser); + account.setLastUpdatedOn(now); + + boolean newAccount = (account.getCreatedOn() == null); + + // new account + if (newAccount) { + account.setCreatedOn(now); + account.setCreatedBy(currentLoggedInUser); + em.persist(account); + } else { + em.merge(account); + + // reload account from db and join roles + account = getAccountEntity(account.getUsername(), true); + } + + // assign roles to account + if (account.getApplicationRoleList() == null) { + account.setApplicationRoleList(new ArrayList<>()); + } + + boolean roleSetupChanged = false; + // remove roles which are no longer listed + // ensure this is only done for the given application - keep the other applications untouched + List assignedRoles = new ArrayList<>(); + assignedRoles.addAll(account.getApplicationRoleList()); + for (ApplicationRoleEntity currentlyAssignedRole : assignedRoles) { + if ((currentlyAssignedRole.getApplication().equals(application) && (!applicationRoles.contains(currentlyAssignedRole)))) { + account.getApplicationRoleList().remove(currentlyAssignedRole); + roleSetupChanged = true; + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Removed role {} ({}) from user {}", currentlyAssignedRole.getRoleName(), application.getApplicationName(), account.getUsername()); + } + } + } + + // add newly added roles to role list + for (ApplicationRoleEntity applicationRole : applicationRoles) { + if (!account.getApplicationRoleList().contains(applicationRole)) { + account.addApplicationRole(applicationRole); + roleSetupChanged = true; + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Added role {} ({}) to account {}", applicationRole.getRoleName(), application.getApplicationName(), account.getUsername()); + } + } + } + + // update account in database if roles changed + if (roleSetupChanged) { + em.merge(account); + } + return account; + } + + @Transactional + public void deleteAccount(AccountEntity account) throws AccountException { + Date now = new Date(); // Todo now in UTC + Subject currentUser = SecurityUtils.getSubject(); + String currentUserName = currentUser.getPrincipal().toString(); + + if (account.getUsername().equals(currentUserName)) { + throw new AccountException("Cannot delete own account"); + } else { + account.setStatus(AccountStatus.DISABLED.name()); + account.setLastUpdatedBy(currentUserName); + account.setLastUpdatedOn(now); + em.merge(account); + } + + } + + public boolean initPasswordReset(String userName) { + try { + AccountEntity account = getAccountEntity(userName, false); + if (account == null) { + LOGGER.warn("Account with name " + userName + " not found"); + return false; + } + + if (account.getStatus().equals(AccountStatus.BLOCKED.name())) { + LOGGER.warn("Account " + userName + " is locked, cannot initialize password reset"); + return false; + } + + String randomString = RandomStringUtils.random(40, true, true); + + Date validTo = new Date(); // TODO now in UTC + validTo = new Date(validTo.getTime() + 1000 * 600); // 10 minutes to react + + // TODO rework password reset +// account.setPasswordResetHash(randomString); +// account.setPasswordResetOngoing(true); +// account.setPasswordResetValidTo(validTo); + mailService.sendPasswortResetStartEmail(account, randomString); + + em.merge(account); + return true; + } catch (MailException ex) { + LOGGER.error("Error while sending password reset mail. " + ex.toString()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Error while sending password reset mail.", ex); + } + return false; + } + } + + public boolean resetPassword(String userName, String newPassword, String resetPasswordToken) { + AccountEntity account = getAccountEntity(userName, false); + + if (account == null) { + LOGGER.warn("Error while resetting password, no account with username " + userName + " found"); + // TODO add extra logging for intrusion protection system like fail2ban + return false; + } + + /* + if (account.getPasswordResetOngoing() && (account.getPasswordResetHash() != null) && (account.getPasswordResetValidTo() != null)) { + Date now = new Date(); // TODO now in UTC + String storedHash = account.getPasswordResetHash().trim(); + if (account.getPasswordResetValidTo().after(now)) { + if (storedHash.equals(resetPasswordToken)) { + // everything ok, reset password + executePasswordReset(account, newPassword); + LOGGER.info("Updated password for user " + userName); + return true; + } else { + // token is not valid, refuse to change password + LOGGER.warn("Trying to reset password for user " + userName + " but wrong token " + resetPasswordToken + " provided"); + addLoginError(account); + return false; + } + } else { + // password reset token no longer valid + LOGGER.warn("Trying to reset password for user " + userName + " but token is no longer valid"); + addLoginError(account); + return false; + } + } else { + // user is not is password reset mode + LOGGER.warn("Trying to reset password for user " + userName + " but password reset was not requested"); + addLoginError(account); + return false; + } + */ + return false; // FIMXE re-implement password reset + } + + private void executePasswordReset(AccountEntity account, String newPassword) { + Date now = new Date(); // TODO now in UTC + + String hashedPassword = SecurityUtil.createPassword(newPassword); +// account.setAccountPassword(hashedPassword); +// +// account.setPasswordResetOngoing(false); +// account.setPasswordResetHash(null); +// account.setPasswordResetValidTo(null); + + account.setLastUpdatedBy(account.getUsername()); + account.setLastUpdatedOn(now); + em.merge(account); + + } + + public AccountLoginEntity updateSuccessFullLogin(AccountLoginEntity login, String byUser) { + Date now = DateUtil.getCurrentTimeInUTC(); + // a scucessful login ends a password reset procedure + if (login.getPasswordResetOngoing()) { + login.setPasswordResetOngoing(false); + login.setPasswordResetHash(null); + login.setPasswordResetValidTo(null); + login.setLastUpdatedOn(now); + login.setLastUpdatedBy(byUser); + } + + login.setLastLogin(now); + login.setFailureCount(0); + return updateLogin(login); + } + + + public AccountLoginEntity updateLogin(AccountLoginEntity login) { + return em.merge (login); + } + + public void updateLogin (AccountEntity account) { + if (account.getAccountLogin() == null) { + // TODO connect to IPRS - how can an account ask for an updated login if the user cannot login + } else { + updateSuccessFullLogin (account.getAccountLogin(), account.getUsername()); + } + } + + + + public void addLoginError(AccountEntity account) { + // TODO reimplement +// try { +// Date now = new Date(); // TODO now in UTC +// account.setLastFailedLogin(now); +// account.setFailureCount(account.getFailureCount() + 1); +// +// int maxFailedLogins = Integer.parseInt(configService.getConfigValue( "account.maxFailedLogins")); +// if ((account.getFailureCount() >= maxFailedLogins) && (!account.getStatus().equals("LOCKED"))) { // TOD add status enum +// // max failed logins reached, disabling user +// LOGGER.info("Locking account " + account.getUsername() + " due to " + account.getFailureCount() + " failed logins"); +// account.setStatus(AccountStatus.BLOCKED.name()); +// } +// +// // on a failed login request, disable password reset +// account.setPasswordResetOngoing(false); +// account.setPasswordResetHash(null); +// account.setPasswordResetValidTo(null); +// +// account.setLastUpdatedBy("system"); +// account.setLastUpdatedOn(now); +// em.merge(account); +// } catch (ConfigException ex) { +// if (LOGGER.isDebugEnabled()) { +// LOGGER.debug(ex.toString(), ex); +// } else { +// LOGGER.error(ex.toString()); +// } +// } + } + + public AccountLoginEntity createLoginWithRandomPassword() { + AccountLoginEntity login = new AccountLoginEntity(); + String randomPassword = RandomStringUtils.random(20, true, true); + String hashedPassword = SecurityUtil.createPassword(randomPassword); + login.setAccountPassword(hashedPassword); + login.setLastLogin(null); + login.setLastFailedLogin(null); + login.setFailureCount(0); + + return login; + } + + public String getHashedPassword (String password) { + String hashedPassword = SecurityUtil.createPassword(password); + return hashedPassword; + } + + @Transactional + public void addLogin(AccountEntity accountToAdd, AccountLoginEntity accountLogin) { + Date now = DateUtil.getCurrentTimeInUTC(); + Subject currentUser = SecurityUtils.getSubject(); + String currentLoggedInUser = currentUser.getPrincipal().toString(); + + AccountEntity account = em.merge(accountToAdd); + accountLogin.setAccount(account); + accountLogin.setCreatedBy(currentLoggedInUser); + accountLogin.setCreatedOn(now); + accountLogin.setLastUpdatedBy(currentLoggedInUser); + accountLogin.setLastUpdatedOn(now); + em.persist(accountLogin); + + account.setAccountLogin(accountLogin); + em.merge(account); + + } + + @Transactional + public void deleteLogin(AccountEntity accountToDelete) { + AccountEntity account = em.merge(accountToDelete); + AccountLoginEntity login = account.getAccountLogin(); + login.setAccount(null); + account.setAccountLogin(null); + em.remove(login); + em.merge(account); + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/ApplicationPermissionControl.java b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/ApplicationPermissionControl.java index 94ff625..fffbc16 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/ApplicationPermissionControl.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/ApplicationPermissionControl.java @@ -1,105 +1,99 @@ -package de.muehlencord.shared.account.business.account.boundary; - -import de.muehlencord.shared.account.business.account.entity.AccountException; -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.application.boundary.ApplicationService; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.io.Serializable; -import javax.ejb.Stateless; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import java.util.List; -import java.util.ArrayList; -import javax.ejb.EJB; -import javax.persistence.OptimisticLockException; -import javax.persistence.Query; -import javax.transaction.Transactional; - -/** - * - * @author Joern Muehlencord - */ -@Stateless -public class ApplicationPermissionControl implements Serializable { - - private static final long serialVersionUID = -3761100587901739481L; - - @EJB - ApplicationService applicationService; - - @PersistenceContext - EntityManager em; - - public List getApplicationPermissions(ApplicationEntity application) { - Query query = em.createNamedQuery("ApplicationPermissionEntity.findAll"); - query.setParameter("application", application); - List permissionList = query.getResultList(); - if (permissionList == null) { - return new ArrayList<>(); - } else { - return permissionList; - } - } - - public ApplicationPermissionEntity findPermissionByName(ApplicationEntity application, String permissionName) { - Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); - query.setParameter("application", application); - query.setParameter("permissionName", permissionName); - List resultList = query.getResultList(); - if ((resultList == null) || (resultList.isEmpty())) { - return null; - } else { - return resultList.get(0); - } - } - - @Transactional - public void create(String applicationName, String name, String description) { - ApplicationEntity application = applicationService.findByApplicationName(applicationName); - // TODO add error handling if not found - ApplicationPermissionEntity permission = new ApplicationPermissionEntity(application, name, description); - em.persist(permission); - } - - @Transactional - public void update(ApplicationPermissionEntity permission) throws AccountException { - ApplicationPermissionEntity existing = attach(permission); - em.merge(existing); - } - - @Transactional - public void createOrUpdate(String name, String description) { - ApplicationPermissionEntity permission = findByName(name); - if (permission == null) { - permission = new ApplicationPermissionEntity(name, description); - em.persist(permission); - } else { - permission.setPermissionDescription(description); - em.merge(permission); - } - } - - public void delete(ApplicationPermissionEntity permission) throws AccountException { - ApplicationPermissionEntity existingPermission = attach(permission); - em.remove(existingPermission); - } - - public ApplicationPermissionEntity attach(ApplicationPermissionEntity permission) throws AccountException { - try { - return em.merge(permission); - } catch (OptimisticLockException ex) { - throw new AccountException("Entity updated / deleted, please reload", true); - } - } - - private ApplicationPermissionEntity findByName(String name) { - Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); - query.setParameter("permissionName", name); - List permissions = query.getResultList(); - if ((permissions == null) || (permissions.isEmpty())) { - return null; - } else { - return permissions.get(0); - } - } -} +package de.muehlencord.shared.account.business.account.boundary; + +import de.muehlencord.shared.account.business.account.entity.AccountException; +import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.Serializable; +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; +import java.util.ArrayList; +import javax.persistence.OptimisticLockException; +import javax.persistence.Query; +import javax.transaction.Transactional; + +/** + * + * @author Joern Muehlencord + */ +@Stateless +public class ApplicationPermissionControl implements Serializable { + + private static final long serialVersionUID = -3761100587901739481L; + + @PersistenceContext + EntityManager em; + + public List getApplicationPermissions(ApplicationEntity app) { + Query query = em.createNamedQuery("ApplicationPermissionEntity.findAll"); + query.setParameter("application", app); + List permissionList = query.getResultList(); + if (permissionList == null) { + return new ArrayList<>(); + } else { + return permissionList; + } + } + + public ApplicationPermissionEntity findPermissionByName(ApplicationEntity application, String permissionName) { + Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); + query.setParameter("application", application); + query.setParameter("permissionName", permissionName); + List resultList = query.getResultList(); + if ((resultList == null) || (resultList.isEmpty())) { + return null; + } else { + return resultList.get(0); + } + } + + @Transactional + public void create(ApplicationEntity application,String name, String description) { + ApplicationPermissionEntity permission = new ApplicationPermissionEntity(application, name, description); + em.persist(permission); + } + + @Transactional + public void update(ApplicationPermissionEntity permission) throws AccountException { + ApplicationPermissionEntity existing = attach(permission); + em.merge(existing); + } + + @Transactional + public void createOrUpdate(ApplicationEntity application, String name, String description) { + ApplicationPermissionEntity permission = findByName(application, name); + if (permission == null) { + permission = new ApplicationPermissionEntity(name, description); + em.persist(permission); + } else { + permission.setPermissionDescription(description); + em.merge(permission); + } + } + + public void delete(ApplicationPermissionEntity permission) throws AccountException { + ApplicationPermissionEntity existingPermission = attach(permission); + em.remove(existingPermission); + } + + public ApplicationPermissionEntity attach(ApplicationPermissionEntity permission) throws AccountException { + try { + return em.merge(permission); + } catch (OptimisticLockException ex) { + throw new AccountException("Entity updated / deleted, please reload", true); + } + } + + private ApplicationPermissionEntity findByName(ApplicationEntity application, String name) { + Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); + query.setParameter("application", application); + query.setParameter("permissionName", name); + List permissions = query.getResultList(); + if ((permissions == null) || (permissions.isEmpty())) { + return null; + } else { + return permissions.get(0); + } + } +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/ApplicationRoleControl.java b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/ApplicationRoleControl.java index b20ecfb..3a0edbd 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/ApplicationRoleControl.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/ApplicationRoleControl.java @@ -1,149 +1,147 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package de.muehlencord.shared.account.business.account.boundary; - -import de.muehlencord.shared.account.business.account.entity.AccountException; -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import javax.ejb.EJB; -import javax.ejb.Stateless; -import javax.persistence.EntityManager; -import javax.persistence.OptimisticLockException; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; -import javax.transaction.Transactional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Joern Muehlencord - */ -@Stateless -public class ApplicationRoleControl implements Serializable { - - private static final long serialVersionUID = 5962478269550134748L; - private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRoleControl.class); - - @EJB - ApplicationPermissionControl applicationPermissionControl; - - @PersistenceContext - EntityManager em; - - public List getAllRoles(ApplicationEntity application) { - Query query = em.createNamedQuery("ApplicationRoleEntity.findAll"); - query.setParameter ("application", application); - - List roles = query.getResultList(); - if (roles == null) { - return new ArrayList<>(); - } else { - return roles; - } - } - - @Transactional - public void createOrUpdate(ApplicationEntity application, String name, String description) { - ApplicationRoleEntity role = findByName(application, name); - if (role == null) { - role = new ApplicationRoleEntity(application, name, description); - em.persist(role); - } else { - role.setRoleDescription(description); - em.merge(role); - } - } - - @Transactional - public void create(ApplicationRoleEntity role) { - em.persist(role); - } - - @Transactional - public void update (ApplicationRoleEntity role) { - em.merge(role); - } - - public void delete(ApplicationRoleEntity role) throws AccountException { - ApplicationRoleEntity existingRole = attach(role); - em.remove(existingRole); - } - - public ApplicationRoleEntity attach(ApplicationRoleEntity role) throws AccountException { - try { - return em.merge(role); - } catch (OptimisticLockException ex) { - throw new AccountException("Entity updated / deleted, please reload", true); - } - } - - public ApplicationRoleEntity findByName(ApplicationEntity application, String name) { - Query query = em.createNamedQuery("ApplicationRoleEntity.findByRoleName"); - query.setParameter("application", application); - query.setParameter("roleName", name); - List permissions = query.getResultList(); - if ((permissions == null) || (permissions.isEmpty())) { - return null; - } else { - return permissions.get(0); - } - } - - public List getRolePermissions(ApplicationRoleEntity role) throws AccountException { - ApplicationRoleEntity existingRole = em.find(ApplicationRoleEntity.class, role.getId()); - List permissions = existingRole.getApplicationPermissionList(); - permissions.size(); // force list to load - return permissions; - } - - public List getNotAssignedApplicationPermissions(ApplicationRoleEntity role) { - try { - List rolePermissions = getRolePermissions(role); - List allPermssions = applicationPermissionControl.getApplicationPermissions(role.getApplication()); - - List missingPermissions = new ArrayList<>(); - allPermssions.stream().filter((perm) -> (!rolePermissions.contains(perm))).forEachOrdered((perm) -> { - missingPermissions.add(perm); - }); - return missingPermissions; - } catch (AccountException ex) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(ex.toString(), ex); - } else { - LOGGER.debug(ex.toString()); - } - return null; - } - - } - - @Transactional - public void addPermission(ApplicationRoleEntity role, ApplicationPermissionEntity permission) throws AccountException { - ApplicationRoleEntity existingRole = attach(role); - if (existingRole.getApplicationPermissionList() == null) { - existingRole.setApplicationPermissionList(new ArrayList<>()); - } - existingRole.getApplicationPermissionList().add(permission); - em.merge(role); - } - - @Transactional - public void removePermission(ApplicationRoleEntity role, ApplicationPermissionEntity permission) throws AccountException { - ApplicationRoleEntity existingRole = attach(role); - if ((existingRole.getApplicationPermissionList() != null) && (existingRole.getApplicationPermissionList().contains(permission))) { - existingRole.getApplicationPermissionList().remove(permission); - } - em.merge(role); - } - - - -} +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.muehlencord.shared.account.business.account.boundary; + +import de.muehlencord.shared.account.business.account.entity.AccountException; +import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; +import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.OptimisticLockException; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; +import javax.transaction.Transactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@Stateless +public class ApplicationRoleControl implements Serializable { + + private static final long serialVersionUID = 5962478269550134748L; + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRoleControl.class); + + @EJB + ApplicationPermissionControl applicationPermissionControl; + + @PersistenceContext + EntityManager em; + + public List getAllRoles(ApplicationEntity app) { + Query query = em.createNamedQuery("ApplicationRoleEntity.findAll"); + query.setParameter("application", app); + + List roles = query.getResultList(); + if (roles == null) { + return new ArrayList<>(); + } else { + return roles; + } + } + + @Transactional + public void createOrUpdate(ApplicationEntity application, String name, String description) { + ApplicationRoleEntity role = findByName(application, name); + if (role == null) { + role = new ApplicationRoleEntity(application, name, description); + em.persist(role); + } else { + role.setRoleDescription(description); + em.merge(role); + } + } + + @Transactional + public void create(ApplicationRoleEntity role) { + em.persist(role); + } + + @Transactional + public void update(ApplicationRoleEntity role) { + em.merge(role); + } + + public void delete(ApplicationRoleEntity role) throws AccountException { + ApplicationRoleEntity existingRole = attach(role); + em.remove(existingRole); + } + + public ApplicationRoleEntity attach(ApplicationRoleEntity role) throws AccountException { + try { + return em.merge(role); + } catch (OptimisticLockException ex) { + throw new AccountException("Entity updated / deleted, please reload", true); + } + } + + public ApplicationRoleEntity findByName(ApplicationEntity application, String name) { + Query query = em.createNamedQuery("ApplicationRoleEntity.findByRoleName"); + query.setParameter("application", application); + query.setParameter("roleName", name); + List permissions = query.getResultList(); + if ((permissions == null) || (permissions.isEmpty())) { + return null; + } else { + return permissions.get(0); + } + } + + public List getRolePermissions(ApplicationRoleEntity role) throws AccountException { + ApplicationRoleEntity existingRole = em.find(ApplicationRoleEntity.class, role.getId()); + List permissions = existingRole.getApplicationPermissionList(); + permissions.size(); // force list to load + return permissions; + } + + public List getNotAssignedApplicationPermissions(ApplicationRoleEntity role) { + try { + List rolePermissions = getRolePermissions(role); + List allPermssions = applicationPermissionControl.getApplicationPermissions(role.getApplication()); + + List missingPermissions = new ArrayList<>(); + allPermssions.stream().filter((perm) -> (!rolePermissions.contains(perm))).forEachOrdered((perm) -> { + missingPermissions.add(perm); + }); + return missingPermissions; + } catch (AccountException ex) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(ex.toString(), ex); + } else { + LOGGER.debug(ex.toString()); + } + return null; + } + + } + + @Transactional + public void addPermission(ApplicationRoleEntity role, ApplicationPermissionEntity permission) throws AccountException { + ApplicationRoleEntity existingRole = attach(role); + if (existingRole.getApplicationPermissionList() == null) { + existingRole.setApplicationPermissionList(new ArrayList<>()); + } + existingRole.getApplicationPermissionList().add(permission); + em.merge(role); + } + + @Transactional + public void removePermission(ApplicationRoleEntity role, ApplicationPermissionEntity permission) throws AccountException { + ApplicationRoleEntity existingRole = attach(role); + if ((existingRole.getApplicationPermissionList() != null) && (existingRole.getApplicationPermissionList().contains(permission))) { + existingRole.getApplicationPermissionList().remove(permission); + } + em.merge(role); + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java index 3a83ac0..e697ad8 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java @@ -1,345 +1,263 @@ -package de.muehlencord.shared.account.business.account.entity; - -import de.muehlencord.shared.account.business.config.entity.ConfigEntity; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.UUID; -import javax.persistence.Basic; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Type; - -/** - * - * @author joern.muehlencord - */ -@Entity -@Table(name = "account") -@XmlRootElement -@NamedQueries({ - @NamedQuery(name = "AccountEntity.findAll", query = "SELECT a FROM AccountEntity a ORDER by a.username"), - @NamedQuery(name = "AccountEntity.findByUsername", query = "SELECT a FROM AccountEntity a WHERE a.username = :username"), - @NamedQuery(name = "AccountEntity.findByFirstname", query = "SELECT a FROM AccountEntity a WHERE a.firstname = :firstname ORDER BY a.username"), - @NamedQuery(name = "AccountEntity.findByLastname", query = "SELECT a FROM AccountEntity a WHERE a.lastname = :lastname ORDER BY a.username"), - @NamedQuery(name = "AccountEntity.findByAccountPassword", query = "SELECT a FROM AccountEntity a WHERE a.accountPassword = :accountPassword"), - @NamedQuery(name = "AccountEntity.findByLastLogin", query = "SELECT a FROM AccountEntity a WHERE a.lastLogin = :lastLogin"), - @NamedQuery(name = "AccountEntity.findByLastFailedLogin", query = "SELECT a FROM AccountEntity a WHERE a.lastFailedLogin = :lastFailedLogin"), - @NamedQuery(name = "AccountEntity.findByFailureCount", query = "SELECT a FROM AccountEntity a WHERE a.failureCount = :failureCount"), - @NamedQuery(name = "AccountEntity.findByStatus", query = "SELECT a FROM AccountEntity a WHERE a.status = :status"), - @NamedQuery(name = "AccountEntity.findByPasswordResetOngoing", query = "SELECT a FROM AccountEntity a WHERE a.passwordResetOngoing = :passwordResetOngoing"), - @NamedQuery(name = "AccountEntity.findByPasswordResetValidTo", query = "SELECT a FROM AccountEntity a WHERE a.passwordResetValidTo = :passwordResetValidTo"), - @NamedQuery(name = "AccountEntity.findByPasswordResetHash", query = "SELECT a FROM AccountEntity a WHERE a.passwordResetHash = :passwordResetHash"), - @NamedQuery(name = "AccountEntity.findByCreatedOn", query = "SELECT a FROM AccountEntity a WHERE a.createdOn = :createdOn"), - @NamedQuery(name = "AccountEntity.findByCreatedBy", query = "SELECT a FROM AccountEntity a WHERE a.createdBy = :createdBy"), - @NamedQuery(name = "AccountEntity.findByLastUpdatedOn", query = "SELECT a FROM AccountEntity a WHERE a.lastUpdatedOn = :lastUpdatedOn"), - @NamedQuery(name = "AccountEntity.findByLastUpdatedBy", query = "SELECT a FROM AccountEntity a WHERE a.lastUpdatedBy = :lastUpdatedBy")}) -public class AccountEntity implements Serializable, Account { - - @OneToMany(cascade = CascadeType.ALL, mappedBy = "account") - private List configEntityList; - - private static final long serialVersionUID = 6216991757526150935L; - - @Id - @Basic(optional = false) - @NotNull - @Column(name = "id") - @GeneratedValue(generator = "uuid2") - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Type(type = "pg-uuid") - private UUID id; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 100) - @Column(name = "firstname") - private String firstname; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 100) - @Column(name = "lastname") - private String lastname; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 200) - @Column(name = "account_password", columnDefinition = "bpchar(200)") - private String accountPassword; - @Column(name = "last_login") - @Temporal(TemporalType.TIMESTAMP) - private Date lastLogin; - @Column(name = "last_failed_login") - @Temporal(TemporalType.TIMESTAMP) - private Date lastFailedLogin; - @Basic(optional = false) - @NotNull - @Column(name = "failure_count") - private int failureCount; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 10) - @Column(name = "status") - private String status; - @Basic(optional = false) - @NotNull - @Column(name = "password_reset_ongoing") - private boolean passwordResetOngoing; - @Column(name = "password_reset_valid_to") - @Temporal(TemporalType.TIMESTAMP) - private Date passwordResetValidTo; - @Size(max = 200) - @Column(name = "password_reset_hash", columnDefinition = "bpchar(200)") - private String passwordResetHash; - @Basic(optional = false) - @NotNull - @Column(name = "created_on") - @Temporal(TemporalType.TIMESTAMP) - private Date createdOn; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 32) - @Column(name = "created_by") - private String createdBy; - @Basic(optional = false) - @NotNull - @Column(name = "last_updated_on") - @Temporal(TemporalType.TIMESTAMP) - private Date lastUpdatedOn; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 32) - @Column(name = "last_updated_by") - private String lastUpdatedBy; - @JoinTable(name = "account_role", joinColumns = { - @JoinColumn(name = "account", referencedColumnName = "id")}, inverseJoinColumns = { - @JoinColumn(name = "account_role", referencedColumnName = "id")}) - @ManyToMany(fetch = FetchType.LAZY) - private List applicationRoleList; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountId", fetch = FetchType.LAZY) - private List accountHistoryList; - @OneToOne(cascade = CascadeType.ALL, mappedBy = "account") - private AccountLoginEntity accountLogin; - - public AccountEntity() { - // empty constructor required for JPA - } - - @Override - public String getUsername() { - if (accountLogin == null) { - return null; - } else { - return accountLogin.getUsername(); - } - } - - public void addApplicationRole(ApplicationRoleEntity applicationRole) { - if (applicationRoleList == null) { - applicationRoleList = new ArrayList<>(); - } - applicationRoleList.add(applicationRole); - } - - /* **** getter / setter **** */ - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - @Override - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - @Override - public String getLastname() { - return lastname; - } - - public void setLastname(String lastname) { - this.lastname = lastname; - } - - public String getAccountPassword() { - return accountPassword; - } - - public void setAccountPassword(String accountPassword) { - this.accountPassword = accountPassword; - } - - public Date getLastLogin() { - return lastLogin; - } - - public void setLastLogin(Date lastLogin) { - this.lastLogin = lastLogin; - } - - public Date getLastFailedLogin() { - return lastFailedLogin; - } - - public void setLastFailedLogin(Date lastFailedLogin) { - this.lastFailedLogin = lastFailedLogin; - } - - public int getFailureCount() { - return failureCount; - } - - public void setFailureCount(int failureCount) { - this.failureCount = failureCount; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public boolean getPasswordResetOngoing() { - return passwordResetOngoing; - } - - public void setPasswordResetOngoing(boolean passwordResetOngoing) { - this.passwordResetOngoing = passwordResetOngoing; - } - - public Date getPasswordResetValidTo() { - return passwordResetValidTo; - } - - public void setPasswordResetValidTo(Date passwordResetValidTo) { - this.passwordResetValidTo = passwordResetValidTo; - } - - public String getPasswordResetHash() { - return passwordResetHash; - } - - public void setPasswordResetHash(String passwordResetHash) { - this.passwordResetHash = passwordResetHash; - } - - public Date getCreatedOn() { - return createdOn; - } - - public void setCreatedOn(Date createdOn) { - this.createdOn = createdOn; - } - - public String getCreatedBy() { - return createdBy; - } - - public void setCreatedBy(String createdBy) { - this.createdBy = createdBy; - } - - public Date getLastUpdatedOn() { - return lastUpdatedOn; - } - - public void setLastUpdatedOn(Date lastUpdatedOn) { - this.lastUpdatedOn = lastUpdatedOn; - } - - public String getLastUpdatedBy() { - return lastUpdatedBy; - } - - public void setLastUpdatedBy(String lastUpdatedBy) { - this.lastUpdatedBy = lastUpdatedBy; - } - - @XmlTransient - public List getApplicationRoleList() { - return applicationRoleList; - } - - public void setApplicationRoleList(List applicationRoleList) { - this.applicationRoleList = applicationRoleList; - } - - @XmlTransient - public List getAccountHistoryList() { - return accountHistoryList; - } - - public void setAccountHistoryList(List accountHistoryList) { - this.accountHistoryList = accountHistoryList; - } - - @Override - public int hashCode() { - int hash = 0; - hash += (id != null ? id.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof AccountEntity)) { - return false; - } - AccountEntity other = (AccountEntity) object; - if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { - return false; - } - return true; - } - - @Override - public String toString() { - return "de.muehlencord.shared.account.entity.Account[ id=" + id + " ]"; - } - - public AccountLoginEntity getAccountLogin() { - return accountLogin; - } - - public void setAccountLogin(AccountLoginEntity accountLogin) { - this.accountLogin = accountLogin; - } - - @XmlTransient - public List getConfigEntityList() { - return configEntityList; - } - - public void setConfigEntityList(List configEntityList) { - this.configEntityList = configEntityList; - } - -} +package de.muehlencord.shared.account.business.account.entity; + +import de.muehlencord.shared.account.business.config.entity.ConfigEntity; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import javax.persistence.Basic; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; + +/** + * + * @author joern.muehlencord + */ +@Entity +@Table(name = "account") +@XmlRootElement +@NamedQueries({ + @NamedQuery(name = "AccountEntity.findAll", query = "SELECT a FROM AccountEntity a ORDER by a.lastname, a.firstname"), + @NamedQuery(name = "AccountEntity.findByStatus", query = "SELECT a FROM AccountEntity a WHERE a.status = :status"), + @NamedQuery(name = "AccountEntity.findByCreatedOn", query = "SELECT a FROM AccountEntity a WHERE a.createdOn = :createdOn"), + @NamedQuery(name = "AccountEntity.findByCreatedBy", query = "SELECT a FROM AccountEntity a WHERE a.createdBy = :createdBy"), + @NamedQuery(name = "AccountEntity.findByLastUpdatedOn", query = "SELECT a FROM AccountEntity a WHERE a.lastUpdatedOn = :lastUpdatedOn"), + @NamedQuery(name = "AccountEntity.findByLastUpdatedBy", query = "SELECT a FROM AccountEntity a WHERE a.lastUpdatedBy = :lastUpdatedBy")}) +public class AccountEntity implements Serializable, Account { + + private static final long serialVersionUID = 6216991757526150935L; + + @Id + @Basic(optional = false) + @NotNull + @Column(name = "id") + @GeneratedValue(generator = "uuid2") + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Type(type = "pg-uuid") + private UUID id; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 32) + @Column(name = "username") + private String username; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 200) + @Column(name = "emailaddress") + private String emailaddress; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 100) + @Column(name = "firstname") + private String firstname; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 100) + @Column(name = "lastname") + private String lastname; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 10) + @Column(name = "status") + private String status; + @Basic(optional = false) + @NotNull + @Column(name = "created_on") + @Temporal(TemporalType.TIMESTAMP) + private Date createdOn; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 32) + @Column(name = "created_by") + private String createdBy; + @Basic(optional = false) + @NotNull + @Column(name = "last_updated_on") + @Temporal(TemporalType.TIMESTAMP) + private Date lastUpdatedOn; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 32) + @Column(name = "last_updated_by") + private String lastUpdatedBy; + @JoinTable(name = "account_role", joinColumns = { + @JoinColumn(name = "account", referencedColumnName = "id")}, inverseJoinColumns = { + @JoinColumn(name = "account_role", referencedColumnName = "id")}) + @ManyToMany(fetch = FetchType.LAZY) + private List applicationRoleList; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountId", fetch = FetchType.LAZY) + private List accountHistoryList; + @OneToOne(cascade = CascadeType.ALL, mappedBy = "account") + private AccountLoginEntity accountLogin; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "account") + private List configItems; + + public AccountEntity() { + // empty constructor required for JPA + } + + public void addApplicationRole(ApplicationRoleEntity applicationRole) { + if (applicationRoleList == null) { + applicationRoleList = new ArrayList<>(); + } + applicationRoleList.add(applicationRole); + } + + /* **** getter / setter **** */ + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmailaddress() { + return emailaddress; + } + + public void setEmailaddress(String emailaddress) { + this.emailaddress = emailaddress; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public Date getLastUpdatedOn() { + return lastUpdatedOn; + } + + public void setLastUpdatedOn(Date lastUpdatedOn) { + this.lastUpdatedOn = lastUpdatedOn; + } + + public String getLastUpdatedBy() { + return lastUpdatedBy; + } + + public void setLastUpdatedBy(String lastUpdatedBy) { + this.lastUpdatedBy = lastUpdatedBy; + } + + public List getApplicationRoleList() { + return applicationRoleList; + } + + public void setApplicationRoleList(List applicationRoleList) { + this.applicationRoleList = applicationRoleList; + } + + public List getAccountHistoryList() { + return accountHistoryList; + } + + public void setAccountHistoryList(List accountHistoryList) { + this.accountHistoryList = accountHistoryList; + } + + public AccountLoginEntity getAccountLogin() { + return accountLogin; + } + + public void setAccountLogin(AccountLoginEntity accountLogin) { + this.accountLogin = accountLogin; + } + + public List getConfigItems() { + return configItems; + } + + public void setConfigItems(List configItems) { + this.configItems = configItems; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof AccountEntity)) { + return false; + } + AccountEntity other = (AccountEntity) object; + if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "de.muehlencord.shared.account.entity.Account[ id=" + id + " ]"; + } +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountLoginEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountLoginEntity.java index b4f32eb..35817d0 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountLoginEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountLoginEntity.java @@ -1,270 +1,243 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package de.muehlencord.shared.account.business.account.entity; - -import java.io.Serializable; -import java.util.Date; -import java.util.UUID; -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.Lob; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Type; - -/** - * - * @author jomu - */ -@Entity -@Table(name = "account_login") -@XmlRootElement -@NamedQueries({ - @NamedQuery(name = "AccountLoginEntity.findAll", query = "SELECT a FROM AccountLoginEntity a"), - @NamedQuery(name = "AccountLoginEntity.findByAccountPassword", query = "SELECT a FROM AccountLoginEntity a WHERE a.accountPassword = :accountPassword"), - @NamedQuery(name = "AccountLoginEntity.findByLastLogin", query = "SELECT a FROM AccountLoginEntity a WHERE a.lastLogin = :lastLogin"), - @NamedQuery(name = "AccountLoginEntity.findByLastFailedLogin", query = "SELECT a FROM AccountLoginEntity a WHERE a.lastFailedLogin = :lastFailedLogin"), - @NamedQuery(name = "AccountLoginEntity.findByFailureCount", query = "SELECT a FROM AccountLoginEntity a WHERE a.failureCount = :failureCount"), - @NamedQuery(name = "AccountLoginEntity.findByPasswordResetOngoing", query = "SELECT a FROM AccountLoginEntity a WHERE a.passwordResetOngoing = :passwordResetOngoing"), - @NamedQuery(name = "AccountLoginEntity.findByPasswordResetValidTo", query = "SELECT a FROM AccountLoginEntity a WHERE a.passwordResetValidTo = :passwordResetValidTo"), - @NamedQuery(name = "AccountLoginEntity.findByPasswordResetHash", query = "SELECT a FROM AccountLoginEntity a WHERE a.passwordResetHash = :passwordResetHash"), - @NamedQuery(name = "AccountLoginEntity.findByCreatedOn", query = "SELECT a FROM AccountLoginEntity a WHERE a.createdOn = :createdOn"), - @NamedQuery(name = "AccountLoginEntity.findByCreatedBy", query = "SELECT a FROM AccountLoginEntity a WHERE a.createdBy = :createdBy"), - @NamedQuery(name = "AccountLoginEntity.findByLastUpdatedOn", query = "SELECT a FROM AccountLoginEntity a WHERE a.lastUpdatedOn = :lastUpdatedOn"), - @NamedQuery(name = "AccountLoginEntity.findByLastUpdatedBy", query = "SELECT a FROM AccountLoginEntity a WHERE a.lastUpdatedBy = :lastUpdatedBy")}) -public class AccountLoginEntity implements Serializable { - - private static final long serialVersionUID = -799045989045040077L; - - @Id - @Basic(optional = false) - @NotNull - @Column(name = "id") - @GeneratedValue(generator = "uuid2") - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Type(type = "pg-uuid") - private UUID id; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 32) - @Column(name = "username") - private String username; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 200) - @Column(name = "emailaddress") - private String emailaddress; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 200) - @Column(name = "account_password") - private String accountPassword; - @Column(name = "last_login") - @Temporal(TemporalType.TIMESTAMP) - private Date lastLogin; - @Column(name = "last_failed_login") - @Temporal(TemporalType.TIMESTAMP) - private Date lastFailedLogin; - @Basic(optional = false) - @NotNull - @Column(name = "failure_count") - private int failureCount; - @Basic(optional = false) - @NotNull - @Column(name = "password_reset_ongoing") - private boolean passwordResetOngoing; - @Column(name = "password_reset_valid_to") - @Temporal(TemporalType.TIMESTAMP) - private Date passwordResetValidTo; - @Size(max = 200) - @Column(name = "password_reset_hash") - private String passwordResetHash; - @Basic(optional = false) - @NotNull - @Column(name = "created_on") - @Temporal(TemporalType.TIMESTAMP) - private Date createdOn; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 32) - @Column(name = "created_by") - private String createdBy; - @Basic(optional = false) - @NotNull - @Column(name = "last_updated_on") - @Temporal(TemporalType.TIMESTAMP) - private Date lastUpdatedOn; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 32) - @Column(name = "last_updated_by") - private String lastUpdatedBy; - @JoinColumn(name = "account", referencedColumnName = "id") - @OneToOne(optional = false) - private AccountEntity account; - - public AccountLoginEntity() { - } - - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public String getAccountPassword() { - return accountPassword; - } - - public void setAccountPassword(String accountPassword) { - this.accountPassword = accountPassword; - } - - public Date getLastLogin() { - return lastLogin; - } - - public void setLastLogin(Date lastLogin) { - this.lastLogin = lastLogin; - } - - public Date getLastFailedLogin() { - return lastFailedLogin; - } - - public void setLastFailedLogin(Date lastFailedLogin) { - this.lastFailedLogin = lastFailedLogin; - } - - public int getFailureCount() { - return failureCount; - } - - public void setFailureCount(int failureCount) { - this.failureCount = failureCount; - } - - public boolean getPasswordResetOngoing() { - return passwordResetOngoing; - } - - public void setPasswordResetOngoing(boolean passwordResetOngoing) { - this.passwordResetOngoing = passwordResetOngoing; - } - - public Date getPasswordResetValidTo() { - return passwordResetValidTo; - } - - public void setPasswordResetValidTo(Date passwordResetValidTo) { - this.passwordResetValidTo = passwordResetValidTo; - } - - public String getPasswordResetHash() { - return passwordResetHash; - } - - public void setPasswordResetHash(String passwordResetHash) { - this.passwordResetHash = passwordResetHash; - } - - public Date getCreatedOn() { - return createdOn; - } - - public void setCreatedOn(Date createdOn) { - this.createdOn = createdOn; - } - - public String getCreatedBy() { - return createdBy; - } - - public void setCreatedBy(String createdBy) { - this.createdBy = createdBy; - } - - public Date getLastUpdatedOn() { - return lastUpdatedOn; - } - - public void setLastUpdatedOn(Date lastUpdatedOn) { - this.lastUpdatedOn = lastUpdatedOn; - } - - public String getLastUpdatedBy() { - return lastUpdatedBy; - } - - public void setLastUpdatedBy(String lastUpdatedBy) { - this.lastUpdatedBy = lastUpdatedBy; - } - - public AccountEntity getAccount() { - return account; - } - - public void setAccount(AccountEntity account) { - this.account = account; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmailaddress() { - return emailaddress; - } - - public void setEmailaddress(String emailaddress) { - this.emailaddress = emailaddress; - } - - @Override - public int hashCode() { - int hash = 0; - hash += (id != null ? id.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof AccountLoginEntity)) { - return false; - } - AccountLoginEntity other = (AccountLoginEntity) object; - if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { - return false; - } - return true; - } - - @Override - public String toString() { - return "de.muehlencord.shared.account.business.account.entity.AccountLoginEntity[ id=" + id + " ]"; - } - -} +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.muehlencord.shared.account.business.account.entity; + +import java.io.Serializable; +import java.util.Date; +import java.util.UUID; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; + +/** + * + * @author jomu + */ +@Entity +@Table(name = "account_login") +@XmlRootElement +@NamedQueries({ + @NamedQuery(name = "AccountLoginEntity.findAll", query = "SELECT a FROM AccountLoginEntity a"), + @NamedQuery(name = "AccountLoginEntity.findByAccountPassword", query = "SELECT a FROM AccountLoginEntity a WHERE a.accountPassword = :accountPassword"), + @NamedQuery(name = "AccountLoginEntity.findByLastLogin", query = "SELECT a FROM AccountLoginEntity a WHERE a.lastLogin = :lastLogin"), + @NamedQuery(name = "AccountLoginEntity.findByLastFailedLogin", query = "SELECT a FROM AccountLoginEntity a WHERE a.lastFailedLogin = :lastFailedLogin"), + @NamedQuery(name = "AccountLoginEntity.findByFailureCount", query = "SELECT a FROM AccountLoginEntity a WHERE a.failureCount = :failureCount"), + @NamedQuery(name = "AccountLoginEntity.findByPasswordResetOngoing", query = "SELECT a FROM AccountLoginEntity a WHERE a.passwordResetOngoing = :passwordResetOngoing"), + @NamedQuery(name = "AccountLoginEntity.findByPasswordResetValidTo", query = "SELECT a FROM AccountLoginEntity a WHERE a.passwordResetValidTo = :passwordResetValidTo"), + @NamedQuery(name = "AccountLoginEntity.findByPasswordResetHash", query = "SELECT a FROM AccountLoginEntity a WHERE a.passwordResetHash = :passwordResetHash"), + @NamedQuery(name = "AccountLoginEntity.findByCreatedOn", query = "SELECT a FROM AccountLoginEntity a WHERE a.createdOn = :createdOn"), + @NamedQuery(name = "AccountLoginEntity.findByCreatedBy", query = "SELECT a FROM AccountLoginEntity a WHERE a.createdBy = :createdBy"), + @NamedQuery(name = "AccountLoginEntity.findByLastUpdatedOn", query = "SELECT a FROM AccountLoginEntity a WHERE a.lastUpdatedOn = :lastUpdatedOn"), + @NamedQuery(name = "AccountLoginEntity.findByLastUpdatedBy", query = "SELECT a FROM AccountLoginEntity a WHERE a.lastUpdatedBy = :lastUpdatedBy")}) +public class AccountLoginEntity implements Serializable { + + private static final long serialVersionUID = -799045989045040077L; + + @Id + @Basic(optional = false) + @NotNull + @Column(name = "id") + @GeneratedValue(generator = "uuid2") + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Type(type = "pg-uuid") + private UUID id; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 200) + @Column(name = "account_password") + private String accountPassword; + @Column(name = "last_login") + @Temporal(TemporalType.TIMESTAMP) + private Date lastLogin; + @Column(name = "last_failed_login") + @Temporal(TemporalType.TIMESTAMP) + private Date lastFailedLogin; + @Basic(optional = false) + @NotNull + @Column(name = "failure_count") + private int failureCount; + @Basic(optional = false) + @NotNull + @Column(name = "password_reset_ongoing") + private boolean passwordResetOngoing; + @Column(name = "password_reset_valid_to") + @Temporal(TemporalType.TIMESTAMP) + private Date passwordResetValidTo; + @Size(max = 200) + @Column(name = "password_reset_hash") + private String passwordResetHash; + @Basic(optional = false) + @NotNull + @Column(name = "created_on") + @Temporal(TemporalType.TIMESTAMP) + private Date createdOn; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 32) + @Column(name = "created_by") + private String createdBy; + @Basic(optional = false) + @NotNull + @Column(name = "last_updated_on") + @Temporal(TemporalType.TIMESTAMP) + private Date lastUpdatedOn; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 32) + @Column(name = "last_updated_by") + private String lastUpdatedBy; + @JoinColumn(name = "account", referencedColumnName = "id") + @OneToOne(optional = false) + private AccountEntity account; + + public AccountLoginEntity() { + } + + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getAccountPassword() { + return accountPassword; + } + + public void setAccountPassword(String accountPassword) { + this.accountPassword = accountPassword; + } + + public Date getLastLogin() { + return lastLogin; + } + + public void setLastLogin(Date lastLogin) { + this.lastLogin = lastLogin; + } + + public Date getLastFailedLogin() { + return lastFailedLogin; + } + + public void setLastFailedLogin(Date lastFailedLogin) { + this.lastFailedLogin = lastFailedLogin; + } + + public int getFailureCount() { + return failureCount; + } + + public void setFailureCount(int failureCount) { + this.failureCount = failureCount; + } + + public boolean getPasswordResetOngoing() { + return passwordResetOngoing; + } + + public void setPasswordResetOngoing(boolean passwordResetOngoing) { + this.passwordResetOngoing = passwordResetOngoing; + } + + public Date getPasswordResetValidTo() { + return passwordResetValidTo; + } + + public void setPasswordResetValidTo(Date passwordResetValidTo) { + this.passwordResetValidTo = passwordResetValidTo; + } + + public String getPasswordResetHash() { + return passwordResetHash; + } + + public void setPasswordResetHash(String passwordResetHash) { + this.passwordResetHash = passwordResetHash; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public Date getLastUpdatedOn() { + return lastUpdatedOn; + } + + public void setLastUpdatedOn(Date lastUpdatedOn) { + this.lastUpdatedOn = lastUpdatedOn; + } + + public String getLastUpdatedBy() { + return lastUpdatedBy; + } + + public void setLastUpdatedBy(String lastUpdatedBy) { + this.lastUpdatedBy = lastUpdatedBy; + } + + public AccountEntity getAccount() { + return account; + } + + public void setAccount(AccountEntity account) { + this.account = account; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof AccountLoginEntity)) { + return false; + } + AccountLoginEntity other = (AccountLoginEntity) object; + if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "de.muehlencord.shared.account.business.account.entity.AccountLoginEntity[ id=" + id + " ]"; + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationService.java b/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationService.java index 27491ec..acb20ed 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationService.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationService.java @@ -1,82 +1,87 @@ -package de.muehlencord.shared.account.business.application.boundary; - -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import javax.ejb.Stateless; -import javax.inject.Inject; -import javax.persistence.EntityManager; -import javax.persistence.Query; -import javax.transaction.Transactional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Joern Muehlencord - */ -@Stateless -public class ApplicationService implements Serializable { - - private static final long serialVersionUID = 4262608935325326191L; - private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationService.class); - - @Inject - EntityManager em; - - public List getAllApplications() { - Query query = em.createNamedQuery("ApplicationEntity.findAll"); - List resultList = query.getResultList(); - if (resultList == null) { - return new ArrayList<>(); - } else { - return resultList; - } - } - - @Transactional - public ApplicationEntity createOrUpdate(ApplicationEntity app) { - if (app == null) { - // TODO add error handling - return null; - } else { - if (app.getId() == null) { - em.persist(app); - ApplicationEntity returnValue = findByApplicationName(app.getApplicationName()); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Application {} created", app.getApplicationName()); - } - - return returnValue; - } else { - ApplicationEntity returnValue = em.merge(app); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Applicateion {} updated", app.getApplicationName()); - } - return returnValue; - } - } - } - - public ApplicationEntity findByApplicationName(String applicationName) { - Query query = em.createNamedQuery("ApplicationEntity.findByApplicationName"); - query.setParameter("applicationName", applicationName); - List resultList = query.getResultList(); - if ((resultList == null) || (resultList.isEmpty())) { - return null; - } else { - return resultList.get(0); - } - } - - @Transactional - public void delete(ApplicationEntity app) { - ApplicationEntity attachedApp = em.find(ApplicationEntity.class, app.getId()); - em.remove(attachedApp); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Application {} deleted", app.getApplicationName()); - } - } - -} +package de.muehlencord.shared.account.business.application.boundary; + +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import javax.ejb.Stateless; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.transaction.Transactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@Stateless +public class ApplicationService implements Serializable { + + private static final long serialVersionUID = 4262608935325326191L; + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationService.class); + + @Inject + EntityManager em; + + public ApplicationEntity findById(UUID id) { + return em.find(ApplicationEntity.class, id); + } + + public List getAllApplications() { + Query query = em.createNamedQuery("ApplicationEntity.findAll"); + List resultList = query.getResultList(); + if (resultList == null) { + return new ArrayList<>(); + } else { + return resultList; + } + } + + @Transactional + public ApplicationEntity createOrUpdate(ApplicationEntity app) { + if (app == null) { + // TODO add error handling + return null; + } else { + if (app.getId() == null) { + em.persist(app); + ApplicationEntity returnValue = findByApplicationName(app.getApplicationName()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Application {} created", app.getApplicationName()); + } + + return returnValue; + } else { + ApplicationEntity returnValue = em.merge(app); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Applicateion {} updated", app.getApplicationName()); + } + return returnValue; + } + } + } + + public ApplicationEntity findByApplicationName(String applicationName) { + Query query = em.createNamedQuery("ApplicationEntity.findByApplicationName"); + query.setParameter("applicationName", applicationName); + List resultList = query.getResultList(); + if ((resultList == null) || (resultList.isEmpty())) { + return null; + } else { + return resultList.get(0); + } + } + + @Transactional + public void delete(ApplicationEntity app) { + ApplicationEntity attachedApp = em.find(ApplicationEntity.class, app.getId()); + em.remove(attachedApp); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Application {} deleted", app.getApplicationName()); + } + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationEntity.java index d1a4d53..4a2563a 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationEntity.java @@ -1,131 +1,131 @@ -package de.muehlencord.shared.account.business.application.entity; - -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; -import de.muehlencord.shared.account.business.config.entity.ConfigEntity; -import java.io.Serializable; -import java.util.List; -import java.util.UUID; -import javax.persistence.Basic; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Type; - -/** - * - * @author Joern Muehlencord - */ -@Entity -@Table(name = "application") -@XmlRootElement -@NamedQueries({ - @NamedQuery(name = "ApplicationEntity.findAll", query = "SELECT a FROM ApplicationEntity a"), - @NamedQuery(name = "ApplicationEntity.findByApplicationName", query = "SELECT a FROM ApplicationEntity a WHERE a.applicationName = :applicationName")}) -public class ApplicationEntity implements Serializable { - - private static final long serialVersionUID = -6407525020014743727L; - - @Id - @Basic(optional = false) - @NotNull - @Column(name = "id") - @GeneratedValue(generator = "uuid2") - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Type(type = "pg-uuid") - private UUID id; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 200) - @Column(name = "application_name", unique = true) - private String applicationName; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "application") - private List applicationRoleEntityList; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "application") - private List applicationPermissions; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "application") - private List configItems; - - public ApplicationEntity() { - } - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public String getApplicationName() { - return applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - @XmlTransient - public List getApplicationRoleEntityList() { - return applicationRoleEntityList; - } - - public void setApplicationRoleEntityList(List applicationRoleEntityList) { - this.applicationRoleEntityList = applicationRoleEntityList; - } - - @Override - public int hashCode() { - int hash = 0; - hash += (id != null ? id.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof ApplicationEntity)) { - return false; - } - ApplicationEntity other = (ApplicationEntity) object; - if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { - return false; - } - return true; - } - - @Override - public String toString() { - return "de.muehlencord.shared.account.business.application.entity.ApplicationEntity[ id=" + id + " ]"; - } - - @XmlTransient - public List getApplicationPermissions() { - return applicationPermissions; - } - - public void setApplicationPermissions(List applicationPermissions) { - this.applicationPermissions = applicationPermissions; - } - - @XmlTransient - public List getConfigItems() { - return configItems; - } - - public void setConfigItems(List configItems) { - this.configItems = configItems; - } - -} +package de.muehlencord.shared.account.business.application.entity; + +import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; +import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; +import de.muehlencord.shared.account.business.config.entity.ConfigEntity; +import java.io.Serializable; +import java.util.List; +import java.util.UUID; +import javax.persistence.Basic; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; + +/** + * + * @author Joern Muehlencord + */ +@Entity +@Table(name = "application") +@XmlRootElement +@NamedQueries({ + @NamedQuery(name = "ApplicationEntity.findAll", query = "SELECT a FROM ApplicationEntity a"), + @NamedQuery(name = "ApplicationEntity.findByApplicationName", query = "SELECT a FROM ApplicationEntity a WHERE a.applicationName = :applicationName")}) +public class ApplicationEntity implements Serializable { + + private static final long serialVersionUID = -6407525020014743727L; + + @Id + @Basic(optional = false) + @NotNull + @Column(name = "id") + @GeneratedValue(generator = "uuid2") + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Type(type = "pg-uuid") + private UUID id; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 200) + @Column(name = "application_name", unique = true) + private String applicationName; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "application") + private List applicationRoleEntityList; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "application") + private List applicationPermissions; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "application") + private List configEntityList; + + public ApplicationEntity() { + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + @XmlTransient + public List getApplicationRoleEntityList() { + return applicationRoleEntityList; + } + + public void setApplicationRoleEntityList(List applicationRoleEntityList) { + this.applicationRoleEntityList = applicationRoleEntityList; + } + + @XmlTransient + public List getApplicationPermissions() { + return applicationPermissions; + } + + public void setApplicationPermissions(List applicationPermissions) { + this.applicationPermissions = applicationPermissions; + } + + @XmlTransient + public List getConfigEntityList() { + return configEntityList; + } + + public void setConfigEntityList(List configEntityList) { + this.configEntityList = configEntityList; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof ApplicationEntity)) { + return false; + } + ApplicationEntity other = (ApplicationEntity) object; + if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "de.muehlencord.shared.account.business.application.entity.ApplicationEntity[ id=" + id + " ]"; + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/config/boundary/ConfigService.java b/account/src/main/java/de/muehlencord/shared/account/business/config/boundary/ConfigService.java index c3e44ca..0dd223d 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/config/boundary/ConfigService.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/config/boundary/ConfigService.java @@ -1,237 +1,204 @@ -package de.muehlencord.shared.account.business.config.boundary; - -import de.muehlencord.shared.account.business.account.entity.Account; -import de.muehlencord.shared.account.business.account.entity.AccountEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import de.muehlencord.shared.account.business.config.entity.ConfigEntity; -import de.muehlencord.shared.account.business.config.entity.ConfigEntityPK; -import de.muehlencord.shared.account.business.config.entity.ConfigException; -import java.io.Serializable; -import java.util.List; -import java.util.Optional; -import javax.annotation.PostConstruct; -import javax.ejb.Lock; -import javax.ejb.LockType; -import javax.ejb.Singleton; -import javax.ejb.Startup; -import javax.inject.Inject; -import javax.persistence.EntityManager; -import javax.persistence.Query; -import javax.transaction.Transactional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author joern.muehlencord - */ -@Singleton -@Startup -public class ConfigService implements Serializable { - - private static final long serialVersionUID = -3195224653632853003L; - - private static final Logger LOGGER = LoggerFactory.getLogger(ConfigService.class); - - @Inject - EntityManager em; - -// private String storagePath = null; -// private int maxFailedLogins = 5; - @PostConstruct - public void init() { -// ConfigEntity configEntity = em.find(ConfigEntity.class, "storage.path"); -// if (configEntity != null) { -// this.storagePath = configEntity.getConfigValue(); -// } -// configEntity = em.find(ConfigEntity.class, "account.maxFailedLogins"); -// if (configEntity != null) { -// this.maxFailedLogins = Integer.parseInt(configEntity.getConfigValue()); -// } - } - - /** - * returns global config key which is not assigned to any. If more than one - * value is defined for the given key, the key assigned to system is - * returned. If more than one key is defined but system key is not defined, - * an exception is thrown. - * - * @param configKey the key to return - * @return the configValue belonging to the given configKey - * @throws - * de.muehlencord.shared.account.business.config.entity.ConfigException if - * more than one value is defined for the given key but none of the values - * is defined for the system user - */ - public String getConfigValue(ApplicationEntity application, String configKey) throws ConfigException { - Query query = em.createNamedQuery("ConfigEntity.findByConfigKey"); - query.setParameter ("application", application); - query.setParameter("configKey", configKey); - List configList = query.getResultList(); - if ((configList == null) || (configList.isEmpty())) { - // key is not found in the database at all - return null; - } else if (configList.size() == 1) { - // exact one element found, return this one - return configList.get(0).getConfigValue(); - } else { - // if more than one result found, return the one which is assigned to system if present - // if not present, throw exception - Optional firstItem = configList.stream() - .filter(config -> config.getConfigPK().getConfigKeyAccount().getUsername().equals("system")) - .findFirst(); - if (firstItem.isPresent()) { - return firstItem.get().getConfigValue(); - } else { - throw new ConfigException("ConfigKey " + configKey + " not unique and system value not defined"); - } - } - } - - public String getConfigValue(ApplicationEntity application, String configKey, String defaultValue) throws ConfigException { - return getConfigValue(application, configKey, defaultValue, false); - } - - public String getConfigValue(ApplicationEntity application, String configKey, String defaultValue, boolean storeDefaultValue) throws ConfigException { - // get configValue as usual - String configValue = getConfigValue(application, configKey); - - // if config value is not found null has been returned - // in this case the value to return is the defaultValue - if (configValue == null) { - configValue = defaultValue; - } - - // check if the default value should be stored in the database - if (storeDefaultValue) { - AccountEntity account = getAccount("system"); - updateConfigValue(application, configKey, account, configValue); - } - - return defaultValue; - } - - public String getConfigValue(ApplicationEntity application, String configKey, Account account, boolean fallbackToSystem) throws ConfigException { - Query query = em.createNamedQuery("ConfigEntity.findByConfigKeyAndAccount"); - query.setParameter("configKey", configKey); - query.setParameter("account", account); - List configList = query.getResultList(); - if ((configList == null) || (configList.isEmpty())) { - // fallback to default / system value - if (fallbackToSystem) { - return getConfigValue(application, configKey); - } else { - return null; - } - } else if (configList.size() == 1) { - // exact one element found, return this one - return configList.get(0).getConfigValue(); - } else { - // more than one value must not happen - this is not possible per the defintion of the datamodel - throw new ConfigException("Cannot have more than one value for the the given key " + configKey + " and the given account " + account.getUsername()); - } - } - - public String getConfigValue(ApplicationEntity application, String configKey, String defaultValue, boolean storeDefaultValue, Account account, boolean fallbackToSystem) throws ConfigException { - String configValue = getConfigValue(application, configKey, account, fallbackToSystem); - - if (configValue == null) { - // value not found for given account and if allowed also not found for system user - configValue = defaultValue; - } - - // check if the default value should be stored in the database - if (storeDefaultValue) { - updateConfigValue(application, configKey, account, configValue); - } - - return configValue; - } - - @Transactional - @Lock(LockType.WRITE) - public boolean updateConfigValue(ApplicationEntity application,String configKey, String configValue) throws ConfigException { - Account account = getAccount("system"); - return updateConfigValue(application, configKey, account, configValue); - } - - @Transactional - @Lock(LockType.WRITE) - public boolean updateConfigValue(ApplicationEntity application,String configKey, String accountName, String configValue) { - Account account = getAccount(accountName); - if (accountName == null) { - return false; - } - if (account == null) { - LOGGER.error("Account for usreName {} not found", accountName); - return false; - } - return updateConfigValue(application, configKey, account, configValue); - } - - @Transactional - @Lock(LockType.WRITE) - public boolean updateConfigValue(ApplicationEntity application, String configKey, Account account, String configValue) { - if ((configKey == null) || (configKey.equals("")) || (configValue == null) || (configValue.equals(""))) { - // null or empty key / values are not possible - return false; - } - - if (account == null) { - LOGGER.error("Account must not be null, not updating"); - return false; - } - - AccountEntity accountEntity = getAccount (account.getUsername()); - ConfigEntityPK pk = new ConfigEntityPK(application, configKey, accountEntity); - ConfigEntity currentEntity = em.find(ConfigEntity.class, pk); - if (currentEntity == null) { - currentEntity = new ConfigEntity(pk); - currentEntity.setConfigValue(configValue); - em.persist(currentEntity); - return true; // config item created - udpate performed - } else { - if ((currentEntity.getConfigValue() != null) && (currentEntity.getConfigValue().equals(configValue))) { - // value is the same - no update - return false; - } else { - currentEntity.setConfigValue(configValue); - em.merge(currentEntity); - return true; - } - } - } - - private AccountEntity getAccount(String accountName) { - Query query = em.createNamedQuery("AccountEntity.findByUsername"); - query.setParameter("username", accountName); - List accountList = query.getResultList(); - if ((accountList == null) || (accountList.isEmpty())) { - return null; - } else { - return accountList.get(0); - } - } - - /* *** getter *** */ - /** - * FIXME remove, this is application specific - * - * @return - * @deprecated replace by getConfigValue ("storage.path") - */ -// @Deprecated -// public String getStoragePath() { -// return storagePath; -// } - /** - * // TODO move to accountControl - * - * @return - * @deprecated replace by getConfigValue ("account.maxFailedLogins") - */ -// @Deprecated -// public int getMaxFailedLogins() { -// return maxFailedLogins; -// } -} +package de.muehlencord.shared.account.business.config.boundary; + +import de.muehlencord.shared.account.business.account.entity.Account; +import de.muehlencord.shared.account.business.account.entity.AccountEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import de.muehlencord.shared.account.business.config.entity.ConfigEntity; +import de.muehlencord.shared.account.business.config.entity.ConfigEntityPK; +import de.muehlencord.shared.account.business.config.entity.ConfigException; +import java.io.Serializable; +import java.util.List; +import java.util.Optional; +import javax.annotation.PostConstruct; +import javax.ejb.Lock; +import javax.ejb.LockType; +import javax.ejb.Singleton; +import javax.ejb.Startup; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.transaction.Transactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author joern.muehlencord + */ +@Singleton +@Startup +public class ConfigService implements Serializable { + + private static final long serialVersionUID = -3195224653632853003L; + + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigService.class); + + @Inject + EntityManager em; + + @Inject + ApplicationEntity application; + + /** + * returns global config key which is not assigned to any. If more than one + * value is defined for the given key, the key assigned to system is + * returned. If more than one key is defined but system key is not defined, + * an exception is thrown. + * + * @param configKey the key to return + * @return the configValue belonging to the given configKey + * @throws + * de.muehlencord.shared.account.business.config.entity.ConfigException if + * more than one value is defined for the given key but none of the values + * is defined for the system user + */ + public String getConfigValue(String configKey) throws ConfigException { + Query query = em.createNamedQuery("ConfigEntity.findByConfigKey"); + query.setParameter("application", application); + query.setParameter("configKey", configKey); + List configList = query.getResultList(); + if ((configList == null) || (configList.isEmpty())) { + // key is not found in the database at all + return null; + } else if (configList.size() == 1) { + // exact one element found, return this one + return configList.get(0).getConfigValue(); + } else { + // if more than one result found, return the one which is assigned to system if present + // if not present, throw exception + Optional firstItem = configList.stream() + .filter(config -> config.getConfigPK().getConfigKeyAccount().getUsername().equals("system")) + .findFirst(); + if (firstItem.isPresent()) { + return firstItem.get().getConfigValue(); + } else { + throw new ConfigException("ConfigKey " + configKey + " not unique and system value not defined"); + } + } + } + + public String getConfigValue(String configKey, String defaultValue) throws ConfigException { + return getConfigValue(configKey, defaultValue, false); + } + + public String getConfigValue(String configKey, String defaultValue, boolean storeDefaultValue) throws ConfigException { + // get configValue as usual + String configValue = getConfigValue(configKey); + + // if config value is not found null has been returned + // in this case the value to return is the defaultValue + if (configValue == null) { + configValue = defaultValue; + } + + // check if the default value should be stored in the database + if (storeDefaultValue) { + AccountEntity account = getAccount("system"); + updateConfigValue(configKey, account, configValue); + } + + return defaultValue; + } + + public String getConfigValue(String configKey, Account account, boolean fallbackToSystem) throws ConfigException { + Query query = em.createNamedQuery("ConfigEntity.findByConfigKeyAndAccount"); + query.setParameter("configKey", configKey); + query.setParameter("account", account); + List configList = query.getResultList(); + if ((configList == null) || (configList.isEmpty())) { + // fallback to default / system value + if (fallbackToSystem) { + return getConfigValue(configKey); + } else { + return null; + } + } else if (configList.size() == 1) { + // exact one element found, return this one + return configList.get(0).getConfigValue(); + } else { + // more than one value must not happen - this is not possible per the defintion of the datamodel + throw new ConfigException("Cannot have more than one value for the the given key " + configKey + " and the given account " + account.getUsername()); + } + } + + public String getConfigValue(String configKey, String defaultValue, boolean storeDefaultValue, Account account, boolean fallbackToSystem) throws ConfigException { + String configValue = getConfigValue(configKey, account, fallbackToSystem); + + if (configValue == null) { + // value not found for given account and if allowed also not found for system user + configValue = defaultValue; + } + + // check if the default value should be stored in the database + if (storeDefaultValue) { + updateConfigValue(configKey, account, configValue); + } + + return configValue; + } + + @Transactional + @Lock(LockType.WRITE) + public boolean updateConfigValue(String configKey, String configValue) throws ConfigException { + Account account = getAccount("system"); + return updateConfigValue(configKey, account, configValue); + } + + @Transactional + @Lock(LockType.WRITE) + public boolean updateConfigValue(String configKey, String accountName, String configValue) { + Account account = getAccount(accountName); + if (accountName == null) { + return false; + } + if (account == null) { + LOGGER.error("Account for usreName {} not found", accountName); + return false; + } + return updateConfigValue(configKey, account, configValue); + } + + @Transactional + @Lock(LockType.WRITE) + public boolean updateConfigValue(String configKey, Account account, String configValue) { + if ((configKey == null) || (configKey.equals("")) || (configValue == null) || (configValue.equals(""))) { + // null or empty key / values are not possible + return false; + } + + if (account == null) { + LOGGER.error("Account must not be null, not updating"); + return false; + } + + AccountEntity accountEntity = getAccount(account.getUsername()); + ConfigEntityPK pk = new ConfigEntityPK(application, configKey, accountEntity); + ConfigEntity currentEntity = em.find(ConfigEntity.class, pk); + if (currentEntity == null) { + currentEntity = new ConfigEntity(pk); + currentEntity.setConfigValue(configValue); + em.persist(currentEntity); + return true; // config item created - udpate performed + } else { + if ((currentEntity.getConfigValue() != null) && (currentEntity.getConfigValue().equals(configValue))) { + // value is the same - no update + return false; + } else { + currentEntity.setConfigValue(configValue); + em.merge(currentEntity); + return true; + } + } + } + + private AccountEntity getAccount(String accountName) { + Query query = em.createNamedQuery("AccountEntity.findByUsername"); + query.setParameter("username", accountName); + List accountList = query.getResultList(); + if ((accountList == null) || (accountList.isEmpty())) { + return null; + } else { + return accountList.get(0); + } + } +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/config/entity/ConfigEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/config/entity/ConfigEntity.java index 0e50f11..59b9b7a 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/config/entity/ConfigEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/config/entity/ConfigEntity.java @@ -1,127 +1,149 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package de.muehlencord.shared.account.business.config.entity; - -import de.muehlencord.shared.account.business.account.entity.AccountEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.io.Serializable; -import javax.persistence.Cacheable; -import javax.persistence.Column; -import javax.persistence.EmbeddedId; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.QueryHint; -import javax.persistence.Table; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - -/** - * - * @author Joern Muehlencord - */ -@Entity -@Table(name = "config") -@XmlRootElement -@Cacheable(true) -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Configuration") -@NamedQueries({ - @NamedQuery(name = "ConfigEntity.findAll", query = "SELECT c FROM ConfigEntity c ORDER BY c.configPK.configKey", - hints = { - @QueryHint(name = "org.hibernate.cacheable", value = "true"), - @QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")}), - @NamedQuery(name = "ConfigEntity.findByConfigKey", query = "SELECT c FROM ConfigEntity c WHERE c.configPK.application = :application AND c.configPK.configKey = :configKey", - hints = { - @QueryHint(name = "org.hibernate.cacheable", value = "true"), - @QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")}), - @NamedQuery(name = "ConfigEntity.findByConfigKeyAndAccount", query = "SELECT c FROM ConfigEntity c WHERE c.configPK.application = :application AND c.configPK.configKey = :configKey AND c.configPK.configKeyAccount = :account", - hints = { - @QueryHint(name = "org.hibernate.cacheable", value = "true"), - @QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")}), - @NamedQuery(name = "ConfigEntity.findByConfigValue", query = "SELECT c FROM ConfigEntity c WHERE c.configPK.application = :application AND c.configValue = :configValue", - hints = { - @QueryHint(name = "org.hibernate.cacheable", value = "true"), - @QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")}) -}) - -public class ConfigEntity implements Serializable { - - private static final long serialVersionUID = -2013982316933782223L; - - @EmbeddedId - protected ConfigEntityPK configPK; - @Size(max = 200) - @Column(name = "config_value") - private String configValue; - @Size(max = 200) - @Column(name = "config_key_group") - private String configKeyGroup; - - public ConfigEntity() { - } - - public ConfigEntity(ApplicationEntity application, String configKey, AccountEntity account) { - this.configPK = new ConfigEntityPK(application, configKey, account); - } - - public ConfigEntity(ConfigEntityPK configPK) { - this.configPK = configPK; - } - - public ConfigEntityPK getConfigPK() { - return configPK; - } - - public void setConfigPK(ConfigEntityPK configPK) { - this.configPK = configPK; - } - - public String getConfigValue() { - return configValue; - } - - public void setConfigValue(String configValue) { - this.configValue = configValue; - } - - public String getConfigKeyGroup() { - return configKeyGroup; - } - - public void setConfigKeyGroup(String configKeyGroup) { - this.configKeyGroup = configKeyGroup; - } - - @Override - public int hashCode() { - int hash = 0; - hash += (configPK != null ? configPK.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof ConfigEntity)) { - return false; - } - ConfigEntity other = (ConfigEntity) object; - if ((this.configPK == null && other.configPK != null) || (this.configPK != null && !this.configPK.equals(other.configPK))) { - return false; - } - return true; - } - - @Override - public String toString() { - return "de.muehlencord.shared.account.business.config.entity.Config[ configPK=" + configPK + " ]"; - } - -} +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.muehlencord.shared.account.business.config.entity; + +import de.muehlencord.shared.account.business.account.entity.AccountEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.Serializable; +import javax.persistence.Cacheable; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.QueryHint; +import javax.persistence.Table; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; + +/** + * + * @author Joern Muehlencord + */ +@Entity +@Table(name = "config") +@XmlRootElement +@Cacheable(true) +@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Configuration") +@NamedQueries({ + @NamedQuery(name = "ConfigEntity.findAll", query = "SELECT c FROM ConfigEntity c ORDER BY c.configPK.configKey", + hints = { + @QueryHint(name = "org.hibernate.cacheable", value = "true"), + @QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")}), + @NamedQuery(name = "ConfigEntity.findByConfigKey", query = "SELECT c FROM ConfigEntity c WHERE c.configPK.application = :application AND c.configPK.configKey = :configKey", + hints = { + @QueryHint(name = "org.hibernate.cacheable", value = "true"), + @QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")}), + @NamedQuery(name = "ConfigEntity.findByConfigKeyAndAccount", query = "SELECT c FROM ConfigEntity c WHERE c.configPK.application = :application AND c.configPK.configKey = :configKey AND c.configPK.configKeyAccount = :account", + hints = { + @QueryHint(name = "org.hibernate.cacheable", value = "true"), + @QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")}), + @NamedQuery(name = "ConfigEntity.findByConfigValue", query = "SELECT c FROM ConfigEntity c WHERE c.configPK.application = :application AND c.configValue = :configValue", + hints = { + @QueryHint(name = "org.hibernate.cacheable", value = "true"), + @QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")}) +}) + +public class ConfigEntity implements Serializable { + + private static final long serialVersionUID = -2013982316933782223L; + + @EmbeddedId + protected ConfigEntityPK configPK; + @Size(max = 200) + @Column(name = "config_value") + private String configValue; + @Size(max = 200) + @Column(name = "config_key_group") + private String configKeyGroup; + @JoinColumn(name = "config_key_account", referencedColumnName = "id", insertable = false, updatable = false) + @ManyToOne(optional = false) + private AccountEntity account; + @JoinColumn(name = "application", referencedColumnName = "id", insertable = false, updatable = false) + @ManyToOne(optional = false) + private ApplicationEntity application; + + public ConfigEntity() { + } + + public ConfigEntity(ApplicationEntity application, String configKey, AccountEntity account) { + this.configPK = new ConfigEntityPK(application, configKey, account); + } + + public ConfigEntity(ConfigEntityPK configPK) { + this.configPK = configPK; + } + + public ConfigEntityPK getConfigPK() { + return configPK; + } + + public void setConfigPK(ConfigEntityPK configPK) { + this.configPK = configPK; + } + + public String getConfigValue() { + return configValue; + } + + public void setConfigValue(String configValue) { + this.configValue = configValue; + } + + public String getConfigKeyGroup() { + return configKeyGroup; + } + + public void setConfigKeyGroup(String configKeyGroup) { + this.configKeyGroup = configKeyGroup; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (configPK != null ? configPK.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof ConfigEntity)) { + return false; + } + ConfigEntity other = (ConfigEntity) object; + if ((this.configPK == null && other.configPK != null) || (this.configPK != null && !this.configPK.equals(other.configPK))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "de.muehlencord.shared.account.business.config.entity.Config[ configPK=" + configPK + " ]"; + } + + public AccountEntity getAccount() { + return account; + } + + public void setAccount(AccountEntity account) { + this.account = account; + } + + public ApplicationEntity getApplication() { + return application; + } + + public void setApplication(ApplicationEntity application) { + this.application = application; + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/mail/boundary/MailService.java b/account/src/main/java/de/muehlencord/shared/account/business/mail/boundary/MailService.java index 096a26d..23c56ef 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/mail/boundary/MailService.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/mail/boundary/MailService.java @@ -189,7 +189,7 @@ public class MailService implements Serializable { String resetUrlWithToken = passwordResetUrl + "?token=" + token; model.addParameter("url", baseUrl); model.addParameter("resetUrl", resetUrlWithToken); - return sendHTMLMail(account.getAccountLogin().getEmailaddress(), "Reset your password", model, "password_reset_html"); + return sendHTMLMail(account.getEmailaddress(), "Reset your password", model, "password_reset_html"); } private String transportMail(Message message) throws MessagingException { diff --git a/account/src/test/java/de/muehlencord/shared/account/business/config/boundary/ConfigServiceTest.java b/account/src/test/java/de/muehlencord/shared/account/business/config/boundary/ConfigServiceTest.java index 534b60f..eb2fb24 100644 --- a/account/src/test/java/de/muehlencord/shared/account/business/config/boundary/ConfigServiceTest.java +++ b/account/src/test/java/de/muehlencord/shared/account/business/config/boundary/ConfigServiceTest.java @@ -37,9 +37,9 @@ public class ConfigServiceTest { application.setApplicationName("Test App"); AccountEntity account = new AccountEntity(); + account.setUsername("system"); AccountLoginEntity login = new AccountLoginEntity(); login.setAccount (account); - login.setUsername("system"); account.setAccountLogin(login); ConfigEntityPK pk = new ConfigEntityPK(application, "account.maxFailedLogins", account); @@ -52,7 +52,7 @@ public class ConfigServiceTest { @Ignore // TODO move to account test public void testGetMaxFailedLogins() { - configService.init(); +// configService.init(); // assertEquals ("maxFailedLogins", 7, configService.getMaxFailedLogins()); } diff --git a/account/src/test/java/de/muehlencord/shared/account/util/SecurityUtilTest.java b/account/src/test/java/de/muehlencord/shared/account/util/SecurityUtilTest.java new file mode 100644 index 0000000..f699a85 --- /dev/null +++ b/account/src/test/java/de/muehlencord/shared/account/util/SecurityUtilTest.java @@ -0,0 +1,22 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.muehlencord.shared.account.util; + +import org.junit.Test; + +/** + * + * @author Joern Muehlencord + */ +public class SecurityUtilTest { + + + @Test + public void testCreatePassword() { + System.out.println (SecurityUtil.createPassword("secret")); + } + +}