completed update of account, splitted login from account

This commit is contained in:
2018-11-14 17:16:12 +01:00
parent 939f043b01
commit 765589afdf
27 changed files with 3383 additions and 3157 deletions

View File

@ -59,7 +59,11 @@
<groupId>de.muehlencord.shared</groupId> <groupId>de.muehlencord.shared</groupId>
<artifactId>shared-account</artifactId> <artifactId>shared-account</artifactId>
<version>1.1-SNAPSHOT</version> <version>1.1-SNAPSHOT</version>
<type>jar</type> </dependency>
<dependency>
<groupId>de.muehlencord.shared</groupId>
<artifactId>shared-util</artifactId>
<version>1.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>de.muehlencord.sf</groupId> <groupId>de.muehlencord.sf</groupId>
@ -86,6 +90,7 @@
<filtering>true</filtering> <filtering>true</filtering>
<includes> <includes>
<include>**/*.properties</include> <include>**/*.properties</include>
<include>**/*.xml</include>
</includes> </includes>
</resource> </resource>
</resources> </resources>

View File

@ -0,0 +1,67 @@
/*
* Copyright 2018 Joern Muehlencord <joern at muehlencord.de>.
*
* 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 <joern at muehlencord.de>
*/
@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;
}
}

View File

@ -4,6 +4,7 @@ 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.boundary.ApplicationRoleControl;
import de.muehlencord.shared.account.business.account.entity.AccountEntity; import de.muehlencord.shared.account.business.account.entity.AccountEntity;
import de.muehlencord.shared.account.business.account.entity.AccountException; import de.muehlencord.shared.account.business.account.entity.AccountException;
import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity;
import de.muehlencord.shared.account.business.account.entity.AccountStatus; import de.muehlencord.shared.account.business.account.entity.AccountStatus;
import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
@ -11,11 +12,17 @@ import de.muehlencord.shared.jeeutil.FacesUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped; import javax.faces.view.ViewScoped;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.primefaces.event.SelectEvent; import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -51,6 +58,9 @@ public class AccountView implements Serializable {
// account currently on edit // account currently on edit
private AccountEntity currentAccount; private AccountEntity currentAccount;
private List<ApplicationRoleEntity> currentAccountRoles = null; private List<ApplicationRoleEntity> currentAccountRoles = null;
private AccountLoginEntity currentAccountLogin;
private String password = null;
private String repeatPassword = null;
public List<AccountEntity> getAccounts() { public List<AccountEntity> getAccounts() {
if (accountList == null) { if (accountList == null) {
@ -68,11 +78,13 @@ public class AccountView implements Serializable {
} }
public void selectAccount(SelectEvent event) { public void selectAccount(SelectEvent event) {
if (currentAccount == null) { // nothing to do, currentAccountRoles are loaded before dialog is shown
}
public void unselectAccount(UnselectEvent event) {
applicationRoles = null; applicationRoles = null;
currentAccountRoles = null; currentAccountRoles = null;
} }
}
public boolean getAccountSelected() { public boolean getAccountSelected() {
return currentAccount != null; return currentAccount != null;
@ -80,7 +92,6 @@ public class AccountView implements Serializable {
public void newAccount() { public void newAccount() {
currentAccount = new AccountEntity(); currentAccount = new AccountEntity();
currentAccount.setUsername(null);
currentAccount.setStatus("NEW"); // TODO add status enum currentAccount.setStatus("NEW"); // TODO add status enum
currentAccountRoles = new ArrayList<>(); currentAccountRoles = new ArrayList<>();
} }
@ -108,15 +119,12 @@ public class AccountView implements Serializable {
AccountEntity existingEntity = accountService.getAccountEntity(username, true); AccountEntity existingEntity = accountService.getAccountEntity(username, true);
// check if it is a new user (createdBy == null) but a user with same name already exists // check if it is a new user (createdBy == null) but a user with same name already exists
if ((currentAccount.getCreatedBy() == null) && (existingEntity != null)) { if ((currentAccount.getCreatedBy() == null) && (existingEntity != null)) {
currentAccount.setUsername(null);
FacesUtil.addErrorMessage("editDialogMessaegs", "Create new account failed", "Account with username " + username + " already exists"); FacesUtil.addErrorMessage("editDialogMessaegs", "Create new account failed", "Account with username " + username + " already exists");
} else { } else {
accountService.saveAccount(applicationView.getCurrentApplication(), currentAccount, currentAccountRoles); accountService.saveAccount(currentAccount, currentAccountRoles);
if (currentAccount.getId() == null) {
// this was a new account
// force accounts to be loaded from database again // force accounts to be loaded from database again
accountList = null; accountList = null;
}
} }
} }
@ -149,6 +157,96 @@ public class AccountView implements Serializable {
return AccountStatus.getAllStatusNames(); return AccountStatus.getAllStatusNames();
} }
/* **** account login methods **** */
public boolean validatePasswords(FacesContext context, List<UIInput> components, List<Object> 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 **** */ /* **** getter / setter **** */
/** /**
* setter for managed property applicationView * setter for managed property applicationView
@ -183,4 +281,20 @@ public class AccountView implements Serializable {
this.currentAccountRoles = 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;
}
} }

View File

@ -53,8 +53,6 @@ public class PermissionView implements Serializable {
public void saveEditPermission() throws AccountException { public void saveEditPermission() throws AccountException {
if (currentPermission != null) { if (currentPermission != null) {
ApplicationEntity currentApplication = applicationView.getCurrentApplication();
String currentApplicationName = currentApplication.getApplicationName();
String newPermissionName = currentPermission.getPermissionName(); String newPermissionName = currentPermission.getPermissionName();
String newPermissionDescription = currentPermission.getPermissionDescription(); String newPermissionDescription = currentPermission.getPermissionDescription();
if ((newPermissionName == null) || (newPermissionName.trim().length() == 0)) { if ((newPermissionName == null) || (newPermissionName.trim().length() == 0)) {
@ -63,13 +61,11 @@ public class PermissionView implements Serializable {
FacesUtil.addErrorMessage("editDialogMessages", "Error", "Permission name must not be null"); FacesUtil.addErrorMessage("editDialogMessages", "Error", "Permission name must not be null");
} else { } else {
if (currentPermission.getId() == null) { if (currentPermission.getId() == null) {
applicationPermissionService.create(currentApplicationName, newPermissionName, newPermissionName); applicationPermissionService.create(applicationView.getCurrentApplication(), newPermissionName, newPermissionName);
FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " created"); FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " created");
// deselectPermission();
} else { } else {
applicationPermissionService.update(currentPermission); applicationPermissionService.update(currentPermission);
FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " updated"); FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " updated");
// deselectPermission();
} }
} }
} }

View File

@ -1,9 +1,8 @@
package de.muehlencord.shared.account.web.presentation; 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.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.account.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.application.boundary.ApplicationService;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import java.io.Serializable; import java.io.Serializable;
import javax.ejb.EJB; import javax.ejb.EJB;
@ -15,8 +14,6 @@ import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException; import javax.faces.validator.ValidatorException;
import javax.inject.Inject; import javax.inject.Inject;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
@ -54,7 +51,6 @@ public class UniqueApplicationRoleNameValidator implements Validator, Serializab
} else { } else {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application not set", "Permission name cannot be set if application is unknown")); throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application not set", "Permission name cannot be set if application is unknown"));
} }
} }
} }

View File

@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="com.wincornixdorf.pcd_pu" transaction-type="JTA"> <persistence-unit name="de.muehlencord.shared.accountUiPu" transaction-type="JTA">
<jta-data-source>java:/jboss/accountTestDs</jta-data-source> <jta-data-source>java:/jboss/accountTestDs</jta-data-source>
<class>de.muehlencord.shared.account.business.account.entity.AccountEntity</class> <class>de.muehlencord.shared.account.business.account.entity.AccountEntity</class>
<class>de.muehlencord.shared.account.business.account.entity.AccountHistoryEntity</class> <class>de.muehlencord.shared.account.business.account.entity.AccountHistoryEntity</class>
<class>de.muehlencord.shared.account.business.account.entity.AccountLoginEntity</class>
<class>de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity</class> <class>de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity</class>
<class>de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity</class> <class>de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity</class>
<class>de.muehlencord.shared.account.business.application.entity.ApplicationEntity</class>
<class>de.muehlencord.shared.account.business.config.entity.ConfigEntity</class> <class>de.muehlencord.shared.account.business.config.entity.ConfigEntity</class>
<class>de.muehlencord.shared.account.business.mail.entity.MailTemplateEntity</class> <class>de.muehlencord.shared.account.business.mail.entity.MailTemplateEntity</class>
<class>de.muehlencord.shared.account.business.application.entity.ApplicationEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes> <exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<validation-mode>NONE</validation-mode> <validation-mode>NONE</validation-mode>

View File

@ -130,3 +130,4 @@ label_template_waitlist_cancelled=Waitlist cancelled mail template
msgs_menu_status=Status msgs_menu_status=Status
menu_status=Status menu_status=Status
button_add=Add button_add=Add
passwords_different=Passwords do not match, please check input

View File

@ -131,3 +131,4 @@ label_template_waitlist_cancelled=Vorlage Warteliste Abbruch
msgs_menu_status=Status msgs_menu_status=Status
menu_status=Status menu_status=Status
button_add=Hinzuf\u00fcgen button_add=Hinzuf\u00fcgen
passwords_different=Passw\u00f6rter stimmen \u00fcberein, bitte \u00fcberpr\u00fcfen Sie ihre Eingabe

View File

@ -131,3 +131,4 @@ label_template_waitlist_cancelled=Waitlist cancelled mail template
msgs_menu_status=Status msgs_menu_status=Status
menu_status=Status menu_status=Status
button_add=Add button_add=Add
passwords_different=Passwords do not match, please check input

View File

@ -25,7 +25,7 @@ passwordMatcher.passwordService = $passwordService
# JDBC Realm setup # JDBC Realm setup
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled=false jdbcRealm.permissionsLookupEnabled=false
jdbcRealm.authenticationQuery = select account_password from account where username = ? and status not in ('LOCKED','DELETED') 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.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.credentialsMatcher = $passwordMatcher
jdbcRealm.dataSource = $datasource jdbcRealm.dataSource = $datasource

View File

@ -7,6 +7,7 @@
xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:co="http://java.sun.com/jsf/composite/composite" xmlns:co="http://java.sun.com/jsf/composite/composite"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:o="http://omnifaces.org/ui"
xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite"> xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite">
<ui:define name="title"> <ui:define name="title">
@ -18,11 +19,11 @@
</ui:define> </ui:define>
<ui:define name="body"> <ui:define name="body">
<h:form id="accountForm"> <h:form id="accountForm" prependId="false">
<p:dataTable id="accountTable" value="#{accountView.accounts}" var="account" rowKey="#{account.username}" selectionMode="single" selection="#{accountView.currentAccount}" <p:dataTable id="accountTable" value="#{accountView.accounts}" var="account" rowKey="#{account.username}" selectionMode="single" selection="#{accountView.currentAccount}"
styleClass="box-primary"> styleClass="box-primary">
<p:ajax event="rowSelect" update="deleteButton,editButton" listener="#{accountView.selectAccount}" /> <p:ajax event="rowSelect" update="buttonPanel" listener="#{accountView.selectAccount}" />
<p:ajax event="rowUnselect" update="deleteButton,editButton" listener="#{accountView.selectAccount}" /> <p:ajax event="rowUnselect" update="buttonPanel" listener="#{accountView.unselectAccount}" />
<p:column headerText="Username"> <p:column headerText="Username">
<h:outputText value="#{account.username}" /> <h:outputText value="#{account.username}" />
</p:column> </p:column>
@ -35,12 +36,12 @@
<p:column headerText="Email"> <p:column headerText="Email">
<h:outputText value="#{account.emailaddress}" /> <h:outputText value="#{account.emailaddress}" />
</p:column> </p:column>
<p:column headerText="Last login">
<h:outputText value="#{account.lastLogin}" />
</p:column>
<p:column headerText="Status"> <p:column headerText="Status">
<h:outputText value="#{account.status}" /> <h:outputText value="#{account.status}" />
</p:column> </p:column>
<p:column headerText="Can login" >
<p:selectBooleanCheckbox id="canLogin" disabled="true" value="#{!empty account.accountLogin}" />
</p:column>
<p:column headerText="CreatedOn"> <p:column headerText="CreatedOn">
<h:outputText value="#{account.createdOn}" > <h:outputText value="#{account.createdOn}" >
<f:convertDateTime type="both" dateStyle="full" timeStyle="short" timeZone="Europe/Berlin"/> <f:convertDateTime type="both" dateStyle="full" timeStyle="short" timeZone="Europe/Berlin"/>
@ -57,10 +58,12 @@
<p:column headerText="LastUpdatedBy"> <p:column headerText="LastUpdatedBy">
<h:outputText value="#{account.lastUpdatedBy}" /> <h:outputText value="#{account.lastUpdatedBy}" />
</p:column> </p:column>
<f:facet name="footer" > </p:dataTable>
<div class="col-sm-12 col-md-3" style="margin-top:10px">
<p:spacer height="10px" /> <p:spacer height="10px" />
<p:panel id="buttonPanel" styleClass="box-primary" style="margin-bottom:20px">
<div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-4" style="margin-top:10px">
<div class="ui-inputgroup" > <div class="ui-inputgroup" >
<h:outputLabel for="includeDisabledCheckbox" value="Include disabled accounts?" /> <h:outputLabel for="includeDisabledCheckbox" value="Include disabled accounts?" />
<p:inputSwitch id="includeDisabledCheckbox" value="#{accountView.showDisabledAccounts}" styleClass="btn-teal btn-block" > <p:inputSwitch id="includeDisabledCheckbox" value="#{accountView.showDisabledAccounts}" styleClass="btn-teal btn-block" >
@ -69,27 +72,48 @@
</div> </div>
</div> </div>
<div class="col-sm-12 col-md-3"> <div class="col-sm-12 col-md-2">
<p:spacer height="10px" />
<p:commandButton value="New" id="newButton" icon="fa fa-plus" <p:commandButton value="New" id="newButton" icon="fa fa-plus"
update="editDialog" oncomplete="PF('editDialogVar').show();" update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{accountView.newAccount}" styleClass="btn-primary btn-block" /> actionListener="#{accountView.newAccount}" styleClass="btn-primary btn-block" />
</div> </div>
<div class="col-sm-12 col-md-3"> <div class="col-sm-12 col-md-2">
<p:spacer height="10px" />
<p:commandButton value="Edit" id="editButton" icon="fa fa-pencil" <p:commandButton value="Edit" id="editButton" icon="fa fa-pencil"
update="editDialog" oncomplete="PF('editDialogVar').show();" update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{accountView.editAccount}" disabled="#{!accountView.accountSelected}" styleClass="btn-teal btn-block" /> actionListener="#{accountView.editAccount}" disabled="#{!accountView.accountSelected}" styleClass="btn-teal btn-block" />
</div> </div>
<div class="col-sm-12 col-md-3"> <div class="col-sm-12 col-md-2">
<p:spacer height="10px" />
<p:commandButton value="Delete" id="deleteButton" icon="fa fa-trash-o" <p:commandButton value="Delete" id="deleteButton" icon="fa fa-trash-o"
update=":accountForm:accountTable" action="#{accountView.deleteAccount}" disabled="#{!accountView.accountSelected}" styleClass="btn-danger btn-block"> update=":accountForm:accountTable" action="#{accountView.deleteAccount}" disabled="#{accountView.accountSelected eq false or accountView.currentLoggedInUser eq true}" styleClass="btn-danger btn-block">
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" /> <p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
</p:commandButton> </p:commandButton>
</div> </div>
</f:facet>
</p:dataTable> <div class="col-sm-12 col-md-2">
<c:if test="#{empty accountView.currentAccount.accountLogin}">
<p:commandButton value="Add login" id="addLoginButton" icon="fa fa-plus" disabled="#{!accountView.accountSelected}"
update="editLoginDialog" oncomplete="PF('editLoginDialogVar').show();"
action="#{accountView.addAccountLogin}" styleClass="btn-teal btn-block">
</p:commandButton>
</c:if>
<c:if test="#{!empty accountView.currentAccount.accountLogin}">
<p:splitButton value="Edit login" id="editLoginButton" icon="fa fa-pencil" disabled="#{!accountView.accountSelected}"
update="editLoginDialog" oncomplete="PF('editLoginDialogVar').show();"
action="#{accountView.editAccountLogin}" styleClass="btn-success btn-block">
<p:menuitem value="Delete login" icon="fa fa-trash-o" disabled="#{accountView.currentLoggedInUser}"
update="accountTable,buttonPanel" styleClass="btn-danger btn-block"
action="#{accountView.deleteAccountLogin}" >
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
</p:menuitem>
</p:splitButton>
</c:if>
</div>
</div>
</p:panel>
<composite:confirmationDialog /> <composite:confirmationDialog />
</h:form> </h:form>
@ -164,16 +188,6 @@
<p:message for="status" /> <p:message for="status" />
</div> </div>
<div class="col-sm-12 col-md-3">
<p:outputLabel for="lastlogin" value="Lastlogin" />
</div>
<div class="col-sm-12 col-md-3">
<h:outputText id="lastlogin" value="#{accountView.currentAccount.lastLogin}" />
</div>
<div class="col-sm-12 col-md-6">
<p:message for="lastlogin" />
</div>
<div class="col-sm-12 col-md-3"> <div class="col-sm-12 col-md-3">
<p:outputLabel for="createdon" value="Created on" /> <p:outputLabel for="createdon" value="Created on" />
</div> </div>
@ -246,6 +260,55 @@
</h:form> </h:form>
</p:dialog> </p:dialog>
<p:dialog id="editLoginDialog" widgetVar="editLoginDialogVar" header="Edit account login" width="600"
modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" >
<h:form id="editLoginDialogForm">
<p:messages id="editLoginDialogMessages" showDetail="true" showIcon="true" showSummary="true">
<p:autoUpdate />
</p:messages>
<div class="ui-g ui-fluid">
<o:validateMultiple id="myId" components="password repeatPassword"
validator="#{accountView.validatePasswords}" message="#{msgs.passwords_different}" />
<div class="col-sm-12">
<p:outputLabel value="Enter a new password or keep values empty to keep existing / autogenrated value" />
</div>
<div class="col-sm-12 col-md-3">
<p:outputLabel for="password" value="Password" />
</div>
<div class="col-sm-12 col-md-6">
<p:password id="password" value="#{accountView.password}" maxlength="32" size="32" required="false"/>
</div>
<div class="col-sm-12 col-md-3">
<p:message for="password" />
</div>
<div class="col-sm-12 col-md-3">
<p:outputLabel for="repeatPassword" value="repeat Password" />
</div>
<div class="col-sm-12 col-md-6">
<p:password id="repeatPassword" value="#{accountView.repeatPassword}" maxlength="32" size="32" required="false"/>
</div>
<div class="col-sm-12 col-md-3">
<p:message for="repeatPassword" />
</div>
<div class="col-sm-12 col-md-6">
<p:spacer height="10px" />
<p:commandButton value="Save" action="#{accountView.saveEditAccountLogin}" styleClass="btn-primary btn-block"
oncomplete="if (args &amp;&amp; !args.validationFailed) PF('editLoginDialogVar').hide();" update=":accountForm:accountTable,:accountForm:buttonPanel" />
</div>
<div class="col-sm-12 col-md-6">
<p:spacer height="10px" />
<p:commandButton value="Cancel" action="#{accountView.cancelEditAccountLogin}" immediate="true" styleClass="btn-teal btn-block"
oncomplete="PF('editLoginDialogVar').hide();" />
</div>
</div>
</h:form>
</p:dialog>
</ui:define> </ui:define>
</ui:composition> </ui:composition>

View File

@ -15,7 +15,7 @@
<ui:define name="body" > <ui:define name="body" >
<h:form id="applicationForm"> <h:form id="applicationForm" prependId="false">
<p:panel styleClass="box-solid"> <p:panel styleClass="box-solid">
<div class="ui-g ui-fluid"> <div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-6"> <div class="col-sm-12 col-md-6">

View File

@ -66,6 +66,12 @@
<artifactId>jcl-over-slf4j</artifactId> <artifactId>jcl-over-slf4j</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>de.muehlencord.shared</groupId>
<artifactId>shared-util</artifactId>
<version>1.1-SNAPSHOT</version>
<type>jar</type>
</dependency>
<dependency> <dependency>
<groupId>javax</groupId> <groupId>javax</groupId>
<artifactId>javaee-api</artifactId> <artifactId>javaee-api</artifactId>

View File

@ -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 (id, application_name) values ('143a2bd3-7e0b-4162-a76e-3031331c7dfe', 'Account UI');
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');
-- account -- permissions not used in Account UI
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 application_permission (id, permission_name, permission_description) values ('dfd0f8f1-4a51-4fdc-9a1c-a942bee9b649', 'test:view', 'Display test view');
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
-- 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'); 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 -- 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');

View File

@ -6,10 +6,11 @@ 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.entity.MailException;
import de.muehlencord.shared.account.business.mail.boundary.MailService; import de.muehlencord.shared.account.business.mail.boundary.MailService;
import de.muehlencord.shared.account.business.account.entity.AccountEntity; import de.muehlencord.shared.account.business.account.entity.AccountEntity;
import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity;
import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.account.business.config.entity.ConfigException;
import de.muehlencord.shared.account.util.SecurityUtil; import de.muehlencord.shared.account.util.SecurityUtil;
import de.muehlencord.shared.util.DateUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -43,6 +44,9 @@ public class AccountControl implements Serializable {
@EJB @EJB
private MailService mailService; private MailService mailService;
@Inject
private ApplicationEntity application;
@Inject @Inject
EntityManager em; EntityManager em;
@ -92,8 +96,8 @@ public class AccountControl implements Serializable {
} }
@Transactional @Transactional
public AccountEntity saveAccount(ApplicationEntity application, AccountEntity account, List<ApplicationRoleEntity> applicationRoles) { public AccountEntity saveAccount(AccountEntity account, List<ApplicationRoleEntity> applicationRoles) {
Date now = new Date(); // Todo now in UTC Date now = DateUtil.getCurrentTimeInUTC();
Subject currentUser = SecurityUtils.getSubject(); Subject currentUser = SecurityUtils.getSubject();
String currentLoggedInUser = currentUser.getPrincipal().toString(); String currentLoggedInUser = currentUser.getPrincipal().toString();
@ -106,11 +110,6 @@ public class AccountControl implements Serializable {
if (newAccount) { if (newAccount) {
account.setCreatedOn(now); account.setCreatedOn(now);
account.setCreatedBy(currentLoggedInUser); 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); em.persist(account);
} else { } else {
em.merge(account); em.merge(account);
@ -192,10 +191,10 @@ public class AccountControl implements Serializable {
Date validTo = new Date(); // TODO now in UTC Date validTo = new Date(); // TODO now in UTC
validTo = new Date(validTo.getTime() + 1000 * 600); // 10 minutes to react validTo = new Date(validTo.getTime() + 1000 * 600); // 10 minutes to react
account.setPasswordResetHash(randomString); // TODO rework password reset
account.setPasswordResetOngoing(true); // account.setPasswordResetHash(randomString);
account.setPasswordResetValidTo(validTo); // account.setPasswordResetOngoing(true);
// account.setPasswordResetValidTo(validTo);
mailService.sendPasswortResetStartEmail(account, randomString); mailService.sendPasswortResetStartEmail(account, randomString);
em.merge(account); em.merge(account);
@ -218,6 +217,7 @@ public class AccountControl implements Serializable {
return false; return false;
} }
/*
if (account.getPasswordResetOngoing() && (account.getPasswordResetHash() != null) && (account.getPasswordResetValidTo() != null)) { if (account.getPasswordResetOngoing() && (account.getPasswordResetHash() != null) && (account.getPasswordResetValidTo() != null)) {
Date now = new Date(); // TODO now in UTC Date now = new Date(); // TODO now in UTC
String storedHash = account.getPasswordResetHash().trim(); String storedHash = account.getPasswordResetHash().trim();
@ -245,17 +245,19 @@ public class AccountControl implements Serializable {
addLoginError(account); addLoginError(account);
return false; return false;
} }
*/
return false; // FIMXE re-implement password reset
} }
private void executePasswordReset(AccountEntity account, String newPassword) { private void executePasswordReset(AccountEntity account, String newPassword) {
Date now = new Date(); // TODO now in UTC Date now = new Date(); // TODO now in UTC
String hashedPassword = SecurityUtil.createPassword(newPassword); String hashedPassword = SecurityUtil.createPassword(newPassword);
account.setAccountPassword(hashedPassword); // account.setAccountPassword(hashedPassword);
//
account.setPasswordResetOngoing(false); // account.setPasswordResetOngoing(false);
account.setPasswordResetHash(null); // account.setPasswordResetHash(null);
account.setPasswordResetValidTo(null); // account.setPasswordResetValidTo(null);
account.setLastUpdatedBy(account.getUsername()); account.setLastUpdatedBy(account.getUsername());
account.setLastUpdatedOn(now); account.setLastUpdatedOn(now);
@ -263,52 +265,112 @@ public class AccountControl implements Serializable {
} }
public void updateLogin(AccountEntity account) { public AccountLoginEntity updateSuccessFullLogin(AccountLoginEntity login, String byUser) {
Date now = new Date(); // TODO now in UTC Date now = DateUtil.getCurrentTimeInUTC();
// a scucessful login ends a password reset procedure // a scucessful login ends a password reset procedure
if (account.getPasswordResetOngoing()) { if (login.getPasswordResetOngoing()) {
account.setPasswordResetOngoing(false); login.setPasswordResetOngoing(false);
account.setPasswordResetHash(null); login.setPasswordResetHash(null);
account.setPasswordResetValidTo(null); login.setPasswordResetValidTo(null);
account.setLastUpdatedOn(now); login.setLastUpdatedOn(now);
account.setLastUpdatedBy(account.getUsername()); login.setLastUpdatedBy(byUser);
} }
account.setLastLogin(now); login.setLastLogin(now);
account.setFailureCount(0); login.setFailureCount(0);
account.setStatus(AccountStatus.NORMAL.name()); return updateLogin(login);
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")); public AccountLoginEntity updateLogin(AccountLoginEntity login) {
if ((account.getFailureCount() >= maxFailedLogins) && (!account.getStatus().equals("LOCKED"))) { // TOD add status enum return em.merge (login);
// 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 public void updateLogin (AccountEntity account) {
account.setPasswordResetOngoing(false); if (account.getAccountLogin() == null) {
account.setPasswordResetHash(null); // TODO connect to IPRS - how can an account ask for an updated login if the user cannot login
account.setPasswordResetValidTo(null);
account.setLastUpdatedBy("system");
account.setLastUpdatedOn(now);
em.merge(account);
} catch (ConfigException ex) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex);
} else { } else {
LOGGER.error(ex.toString()); 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);
} }
} }

View File

@ -2,7 +2,6 @@ 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.AccountException;
import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; 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 de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import java.io.Serializable; import java.io.Serializable;
import javax.ejb.Stateless; import javax.ejb.Stateless;
@ -10,7 +9,6 @@ import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContext;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import javax.ejb.EJB;
import javax.persistence.OptimisticLockException; import javax.persistence.OptimisticLockException;
import javax.persistence.Query; import javax.persistence.Query;
import javax.transaction.Transactional; import javax.transaction.Transactional;
@ -24,15 +22,12 @@ public class ApplicationPermissionControl implements Serializable {
private static final long serialVersionUID = -3761100587901739481L; private static final long serialVersionUID = -3761100587901739481L;
@EJB
ApplicationService applicationService;
@PersistenceContext @PersistenceContext
EntityManager em; EntityManager em;
public List<ApplicationPermissionEntity> getApplicationPermissions(ApplicationEntity application) { public List<ApplicationPermissionEntity> getApplicationPermissions(ApplicationEntity app) {
Query query = em.createNamedQuery("ApplicationPermissionEntity.findAll"); Query query = em.createNamedQuery("ApplicationPermissionEntity.findAll");
query.setParameter("application", application); query.setParameter("application", app);
List<ApplicationPermissionEntity> permissionList = query.getResultList(); List<ApplicationPermissionEntity> permissionList = query.getResultList();
if (permissionList == null) { if (permissionList == null) {
return new ArrayList<>(); return new ArrayList<>();
@ -54,9 +49,7 @@ public class ApplicationPermissionControl implements Serializable {
} }
@Transactional @Transactional
public void create(String applicationName, String name, String description) { public void create(ApplicationEntity application,String name, String description) {
ApplicationEntity application = applicationService.findByApplicationName(applicationName);
// TODO add error handling if not found
ApplicationPermissionEntity permission = new ApplicationPermissionEntity(application, name, description); ApplicationPermissionEntity permission = new ApplicationPermissionEntity(application, name, description);
em.persist(permission); em.persist(permission);
} }
@ -68,8 +61,8 @@ public class ApplicationPermissionControl implements Serializable {
} }
@Transactional @Transactional
public void createOrUpdate(String name, String description) { public void createOrUpdate(ApplicationEntity application, String name, String description) {
ApplicationPermissionEntity permission = findByName(name); ApplicationPermissionEntity permission = findByName(application, name);
if (permission == null) { if (permission == null) {
permission = new ApplicationPermissionEntity(name, description); permission = new ApplicationPermissionEntity(name, description);
em.persist(permission); em.persist(permission);
@ -92,8 +85,9 @@ public class ApplicationPermissionControl implements Serializable {
} }
} }
private ApplicationPermissionEntity findByName(String name) { private ApplicationPermissionEntity findByName(ApplicationEntity application, String name) {
Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName");
query.setParameter("application", application);
query.setParameter("permissionName", name); query.setParameter("permissionName", name);
List<ApplicationPermissionEntity> permissions = query.getResultList(); List<ApplicationPermissionEntity> permissions = query.getResultList();
if ((permissions == null) || (permissions.isEmpty())) { if ((permissions == null) || (permissions.isEmpty())) {

View File

@ -38,9 +38,9 @@ public class ApplicationRoleControl implements Serializable {
@PersistenceContext @PersistenceContext
EntityManager em; EntityManager em;
public List<ApplicationRoleEntity> getAllRoles(ApplicationEntity application) { public List<ApplicationRoleEntity> getAllRoles(ApplicationEntity app) {
Query query = em.createNamedQuery("ApplicationRoleEntity.findAll"); Query query = em.createNamedQuery("ApplicationRoleEntity.findAll");
query.setParameter ("application", application); query.setParameter("application", app);
List<ApplicationRoleEntity> roles = query.getResultList(); List<ApplicationRoleEntity> roles = query.getResultList();
if (roles == null) { if (roles == null) {
@ -68,7 +68,7 @@ public class ApplicationRoleControl implements Serializable {
} }
@Transactional @Transactional
public void update (ApplicationRoleEntity role) { public void update(ApplicationRoleEntity role) {
em.merge(role); em.merge(role);
} }
@ -144,6 +144,4 @@ public class ApplicationRoleControl implements Serializable {
em.merge(role); em.merge(role);
} }
} }

View File

@ -26,7 +26,6 @@ import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
@ -38,27 +37,14 @@ import org.hibernate.annotations.Type;
@Table(name = "account") @Table(name = "account")
@XmlRootElement @XmlRootElement
@NamedQueries({ @NamedQueries({
@NamedQuery(name = "AccountEntity.findAll", query = "SELECT a FROM AccountEntity a ORDER by a.username"), @NamedQuery(name = "AccountEntity.findAll", query = "SELECT a FROM AccountEntity a ORDER by a.lastname, a.firstname"),
@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.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.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.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.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")}) @NamedQuery(name = "AccountEntity.findByLastUpdatedBy", query = "SELECT a FROM AccountEntity a WHERE a.lastUpdatedBy = :lastUpdatedBy")})
public class AccountEntity implements Serializable, Account { public class AccountEntity implements Serializable, Account {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "account")
private List<ConfigEntity> configEntityList;
private static final long serialVersionUID = 6216991757526150935L; private static final long serialVersionUID = 6216991757526150935L;
@Id @Id
@ -71,6 +57,16 @@ public class AccountEntity implements Serializable, Account {
private UUID id; private UUID id;
@Basic(optional = false) @Basic(optional = false)
@NotNull @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) @Size(min = 1, max = 100)
@Column(name = "firstname") @Column(name = "firstname")
private String firstname; private String firstname;
@ -81,36 +77,11 @@ public class AccountEntity implements Serializable, Account {
private String lastname; private String lastname;
@Basic(optional = false) @Basic(optional = false)
@NotNull @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) @Size(min = 1, max = 10)
@Column(name = "status") @Column(name = "status")
private String status; private String status;
@Basic(optional = false) @Basic(optional = false)
@NotNull @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") @Column(name = "created_on")
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
private Date createdOn; private Date createdOn;
@ -138,20 +109,13 @@ public class AccountEntity implements Serializable, Account {
private List<AccountHistoryEntity> accountHistoryList; private List<AccountHistoryEntity> accountHistoryList;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "account") @OneToOne(cascade = CascadeType.ALL, mappedBy = "account")
private AccountLoginEntity accountLogin; private AccountLoginEntity accountLogin;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "account")
private List<ConfigEntity> configItems;
public AccountEntity() { public AccountEntity() {
// empty constructor required for JPA // empty constructor required for JPA
} }
@Override
public String getUsername() {
if (accountLogin == null) {
return null;
} else {
return accountLogin.getUsername();
}
}
public void addApplicationRole(ApplicationRoleEntity applicationRole) { public void addApplicationRole(ApplicationRoleEntity applicationRole) {
if (applicationRoleList == null) { if (applicationRoleList == null) {
applicationRoleList = new ArrayList<>(); applicationRoleList = new ArrayList<>();
@ -168,7 +132,22 @@ public class AccountEntity implements Serializable, Account {
this.id = id; this.id = id;
} }
@Override 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() { public String getFirstname() {
return firstname; return firstname;
} }
@ -177,7 +156,6 @@ public class AccountEntity implements Serializable, Account {
this.firstname = firstname; this.firstname = firstname;
} }
@Override
public String getLastname() { public String getLastname() {
return lastname; return lastname;
} }
@ -186,38 +164,6 @@ public class AccountEntity implements Serializable, Account {
this.lastname = 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() { public String getStatus() {
return status; return status;
} }
@ -226,30 +172,6 @@ public class AccountEntity implements Serializable, Account {
this.status = 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() { public Date getCreatedOn() {
return createdOn; return createdOn;
} }
@ -282,7 +204,6 @@ public class AccountEntity implements Serializable, Account {
this.lastUpdatedBy = lastUpdatedBy; this.lastUpdatedBy = lastUpdatedBy;
} }
@XmlTransient
public List<ApplicationRoleEntity> getApplicationRoleList() { public List<ApplicationRoleEntity> getApplicationRoleList() {
return applicationRoleList; return applicationRoleList;
} }
@ -291,7 +212,6 @@ public class AccountEntity implements Serializable, Account {
this.applicationRoleList = applicationRoleList; this.applicationRoleList = applicationRoleList;
} }
@XmlTransient
public List<AccountHistoryEntity> getAccountHistoryList() { public List<AccountHistoryEntity> getAccountHistoryList() {
return accountHistoryList; return accountHistoryList;
} }
@ -300,6 +220,22 @@ public class AccountEntity implements Serializable, Account {
this.accountHistoryList = accountHistoryList; this.accountHistoryList = accountHistoryList;
} }
public AccountLoginEntity getAccountLogin() {
return accountLogin;
}
public void setAccountLogin(AccountLoginEntity accountLogin) {
this.accountLogin = accountLogin;
}
public List<ConfigEntity> getConfigItems() {
return configItems;
}
public void setConfigItems(List<ConfigEntity> configItems) {
this.configItems = configItems;
}
@Override @Override
public int hashCode() { public int hashCode() {
int hash = 0; int hash = 0;
@ -324,22 +260,4 @@ public class AccountEntity implements Serializable, Account {
public String toString() { public String toString() {
return "de.muehlencord.shared.account.entity.Account[ id=" + id + " ]"; 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<ConfigEntity> getConfigEntityList() {
return configEntityList;
}
public void setConfigEntityList(List<ConfigEntity> configEntityList) {
this.configEntityList = configEntityList;
}
} }

View File

@ -14,7 +14,6 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.NamedQueries; import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery; import javax.persistence.NamedQuery;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
@ -61,16 +60,6 @@ public class AccountLoginEntity implements Serializable {
private UUID id; private UUID id;
@Basic(optional = false) @Basic(optional = false)
@NotNull @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) @Size(min = 1, max = 200)
@Column(name = "account_password") @Column(name = "account_password")
private String accountPassword; private String accountPassword;
@ -226,22 +215,6 @@ public class AccountLoginEntity implements Serializable {
this.account = 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 @Override
public int hashCode() { public int hashCode() {
int hash = 0; int hash = 0;

View File

@ -4,6 +4,7 @@ import de.muehlencord.shared.account.business.application.entity.ApplicationEnti
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
import javax.ejb.Stateless; import javax.ejb.Stateless;
import javax.inject.Inject; import javax.inject.Inject;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
@ -25,6 +26,10 @@ public class ApplicationService implements Serializable {
@Inject @Inject
EntityManager em; EntityManager em;
public ApplicationEntity findById(UUID id) {
return em.find(ApplicationEntity.class, id);
}
public List<ApplicationEntity> getAllApplications() { public List<ApplicationEntity> getAllApplications() {
Query query = em.createNamedQuery("ApplicationEntity.findAll"); Query query = em.createNamedQuery("ApplicationEntity.findAll");
List<ApplicationEntity> resultList = query.getResultList(); List<ApplicationEntity> resultList = query.getResultList();

View File

@ -55,7 +55,7 @@ public class ApplicationEntity implements Serializable {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "application") @OneToMany(cascade = CascadeType.ALL, mappedBy = "application")
private List<ApplicationPermissionEntity> applicationPermissions; private List<ApplicationPermissionEntity> applicationPermissions;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "application") @OneToMany(cascade = CascadeType.ALL, mappedBy = "application")
private List<ConfigEntity> configItems; private List<ConfigEntity> configEntityList;
public ApplicationEntity() { public ApplicationEntity() {
} }
@ -85,6 +85,24 @@ public class ApplicationEntity implements Serializable {
this.applicationRoleEntityList = applicationRoleEntityList; this.applicationRoleEntityList = applicationRoleEntityList;
} }
@XmlTransient
public List<ApplicationPermissionEntity> getApplicationPermissions() {
return applicationPermissions;
}
public void setApplicationPermissions(List<ApplicationPermissionEntity> applicationPermissions) {
this.applicationPermissions = applicationPermissions;
}
@XmlTransient
public List<ConfigEntity> getConfigEntityList() {
return configEntityList;
}
public void setConfigEntityList(List<ConfigEntity> configEntityList) {
this.configEntityList = configEntityList;
}
@Override @Override
public int hashCode() { public int hashCode() {
int hash = 0; int hash = 0;
@ -110,22 +128,4 @@ public class ApplicationEntity implements Serializable {
return "de.muehlencord.shared.account.business.application.entity.ApplicationEntity[ id=" + id + " ]"; return "de.muehlencord.shared.account.business.application.entity.ApplicationEntity[ id=" + id + " ]";
} }
@XmlTransient
public List<ApplicationPermissionEntity> getApplicationPermissions() {
return applicationPermissions;
}
public void setApplicationPermissions(List<ApplicationPermissionEntity> applicationPermissions) {
this.applicationPermissions = applicationPermissions;
}
@XmlTransient
public List<ConfigEntity> getConfigItems() {
return configItems;
}
public void setConfigItems(List<ConfigEntity> configItems) {
this.configItems = configItems;
}
} }

View File

@ -36,19 +36,8 @@ public class ConfigService implements Serializable {
@Inject @Inject
EntityManager em; EntityManager em;
// private String storagePath = null; @Inject
// private int maxFailedLogins = 5; ApplicationEntity application;
@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 * returns global config key which is not assigned to any. If more than one
@ -63,9 +52,9 @@ public class ConfigService implements Serializable {
* more than one value is defined for the given key but none of the values * more than one value is defined for the given key but none of the values
* is defined for the system user * is defined for the system user
*/ */
public String getConfigValue(ApplicationEntity application, String configKey) throws ConfigException { public String getConfigValue(String configKey) throws ConfigException {
Query query = em.createNamedQuery("ConfigEntity.findByConfigKey"); Query query = em.createNamedQuery("ConfigEntity.findByConfigKey");
query.setParameter ("application", application); query.setParameter("application", application);
query.setParameter("configKey", configKey); query.setParameter("configKey", configKey);
List<ConfigEntity> configList = query.getResultList(); List<ConfigEntity> configList = query.getResultList();
if ((configList == null) || (configList.isEmpty())) { if ((configList == null) || (configList.isEmpty())) {
@ -88,13 +77,13 @@ public class ConfigService implements Serializable {
} }
} }
public String getConfigValue(ApplicationEntity application, String configKey, String defaultValue) throws ConfigException { public String getConfigValue(String configKey, String defaultValue) throws ConfigException {
return getConfigValue(application, configKey, defaultValue, false); return getConfigValue(configKey, defaultValue, false);
} }
public String getConfigValue(ApplicationEntity application, String configKey, String defaultValue, boolean storeDefaultValue) throws ConfigException { public String getConfigValue(String configKey, String defaultValue, boolean storeDefaultValue) throws ConfigException {
// get configValue as usual // get configValue as usual
String configValue = getConfigValue(application, configKey); String configValue = getConfigValue(configKey);
// if config value is not found null has been returned // if config value is not found null has been returned
// in this case the value to return is the defaultValue // in this case the value to return is the defaultValue
@ -105,13 +94,13 @@ public class ConfigService implements Serializable {
// check if the default value should be stored in the database // check if the default value should be stored in the database
if (storeDefaultValue) { if (storeDefaultValue) {
AccountEntity account = getAccount("system"); AccountEntity account = getAccount("system");
updateConfigValue(application, configKey, account, configValue); updateConfigValue(configKey, account, configValue);
} }
return defaultValue; return defaultValue;
} }
public String getConfigValue(ApplicationEntity application, String configKey, Account account, boolean fallbackToSystem) throws ConfigException { public String getConfigValue(String configKey, Account account, boolean fallbackToSystem) throws ConfigException {
Query query = em.createNamedQuery("ConfigEntity.findByConfigKeyAndAccount"); Query query = em.createNamedQuery("ConfigEntity.findByConfigKeyAndAccount");
query.setParameter("configKey", configKey); query.setParameter("configKey", configKey);
query.setParameter("account", account); query.setParameter("account", account);
@ -119,7 +108,7 @@ public class ConfigService implements Serializable {
if ((configList == null) || (configList.isEmpty())) { if ((configList == null) || (configList.isEmpty())) {
// fallback to default / system value // fallback to default / system value
if (fallbackToSystem) { if (fallbackToSystem) {
return getConfigValue(application, configKey); return getConfigValue(configKey);
} else { } else {
return null; return null;
} }
@ -132,8 +121,8 @@ public class ConfigService implements Serializable {
} }
} }
public String getConfigValue(ApplicationEntity application, String configKey, String defaultValue, boolean storeDefaultValue, Account account, boolean fallbackToSystem) throws ConfigException { public String getConfigValue(String configKey, String defaultValue, boolean storeDefaultValue, Account account, boolean fallbackToSystem) throws ConfigException {
String configValue = getConfigValue(application, configKey, account, fallbackToSystem); String configValue = getConfigValue(configKey, account, fallbackToSystem);
if (configValue == null) { if (configValue == null) {
// value not found for given account and if allowed also not found for system user // value not found for given account and if allowed also not found for system user
@ -142,7 +131,7 @@ public class ConfigService implements Serializable {
// check if the default value should be stored in the database // check if the default value should be stored in the database
if (storeDefaultValue) { if (storeDefaultValue) {
updateConfigValue(application, configKey, account, configValue); updateConfigValue(configKey, account, configValue);
} }
return configValue; return configValue;
@ -150,14 +139,14 @@ public class ConfigService implements Serializable {
@Transactional @Transactional
@Lock(LockType.WRITE) @Lock(LockType.WRITE)
public boolean updateConfigValue(ApplicationEntity application,String configKey, String configValue) throws ConfigException { public boolean updateConfigValue(String configKey, String configValue) throws ConfigException {
Account account = getAccount("system"); Account account = getAccount("system");
return updateConfigValue(application, configKey, account, configValue); return updateConfigValue(configKey, account, configValue);
} }
@Transactional @Transactional
@Lock(LockType.WRITE) @Lock(LockType.WRITE)
public boolean updateConfigValue(ApplicationEntity application,String configKey, String accountName, String configValue) { public boolean updateConfigValue(String configKey, String accountName, String configValue) {
Account account = getAccount(accountName); Account account = getAccount(accountName);
if (accountName == null) { if (accountName == null) {
return false; return false;
@ -166,12 +155,12 @@ public class ConfigService implements Serializable {
LOGGER.error("Account for usreName {} not found", accountName); LOGGER.error("Account for usreName {} not found", accountName);
return false; return false;
} }
return updateConfigValue(application, configKey, account, configValue); return updateConfigValue(configKey, account, configValue);
} }
@Transactional @Transactional
@Lock(LockType.WRITE) @Lock(LockType.WRITE)
public boolean updateConfigValue(ApplicationEntity application, String configKey, Account account, String configValue) { public boolean updateConfigValue(String configKey, Account account, String configValue) {
if ((configKey == null) || (configKey.equals("")) || (configValue == null) || (configValue.equals(""))) { if ((configKey == null) || (configKey.equals("")) || (configValue == null) || (configValue.equals(""))) {
// null or empty key / values are not possible // null or empty key / values are not possible
return false; return false;
@ -182,7 +171,7 @@ public class ConfigService implements Serializable {
return false; return false;
} }
AccountEntity accountEntity = getAccount (account.getUsername()); AccountEntity accountEntity = getAccount(account.getUsername());
ConfigEntityPK pk = new ConfigEntityPK(application, configKey, accountEntity); ConfigEntityPK pk = new ConfigEntityPK(application, configKey, accountEntity);
ConfigEntity currentEntity = em.find(ConfigEntity.class, pk); ConfigEntity currentEntity = em.find(ConfigEntity.class, pk);
if (currentEntity == null) { if (currentEntity == null) {
@ -212,26 +201,4 @@ public class ConfigService implements Serializable {
return accountList.get(0); 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;
// }
} }

View File

@ -63,6 +63,12 @@ public class ConfigEntity implements Serializable {
@Size(max = 200) @Size(max = 200)
@Column(name = "config_key_group") @Column(name = "config_key_group")
private String configKeyGroup; 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() {
} }
@ -124,4 +130,20 @@ public class ConfigEntity implements Serializable {
return "de.muehlencord.shared.account.business.config.entity.Config[ configPK=" + configPK + " ]"; 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;
}
} }

View File

@ -189,7 +189,7 @@ public class MailService implements Serializable {
String resetUrlWithToken = passwordResetUrl + "?token=" + token; String resetUrlWithToken = passwordResetUrl + "?token=" + token;
model.addParameter("url", baseUrl); model.addParameter("url", baseUrl);
model.addParameter("resetUrl", resetUrlWithToken); 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 { private String transportMail(Message message) throws MessagingException {

View File

@ -37,9 +37,9 @@ public class ConfigServiceTest {
application.setApplicationName("Test App"); application.setApplicationName("Test App");
AccountEntity account = new AccountEntity(); AccountEntity account = new AccountEntity();
account.setUsername("system");
AccountLoginEntity login = new AccountLoginEntity(); AccountLoginEntity login = new AccountLoginEntity();
login.setAccount (account); login.setAccount (account);
login.setUsername("system");
account.setAccountLogin(login); account.setAccountLogin(login);
ConfigEntityPK pk = new ConfigEntityPK(application, "account.maxFailedLogins", account); ConfigEntityPK pk = new ConfigEntityPK(application, "account.maxFailedLogins", account);
@ -52,7 +52,7 @@ public class ConfigServiceTest {
@Ignore @Ignore
// TODO move to account test // TODO move to account test
public void testGetMaxFailedLogins() { public void testGetMaxFailedLogins() {
configService.init(); // configService.init();
// assertEquals ("maxFailedLogins", 7, configService.getMaxFailedLogins()); // assertEquals ("maxFailedLogins", 7, configService.getMaxFailedLogins());
} }

View File

@ -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 <joern at muehlencord.de>
*/
public class SecurityUtilTest {
@Test
public void testCreatePassword() {
System.out.println (SecurityUtil.createPassword("secret"));
}
}