started to implement permission handling into views and pages

This commit is contained in:
2018-11-22 14:54:48 +01:00
parent 79c9ab623c
commit c05ba11044
22 changed files with 955 additions and 743 deletions

View File

@ -0,0 +1,81 @@
/*
* 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.account.boundary.AccountPermissions;
import de.muehlencord.shared.account.business.account.entity.AccountException;
import de.muehlencord.shared.account.business.application.boundary.ApplicationPermissions;
import de.muehlencord.shared.account.business.application.control.ApplicationPermissionControl;
import de.muehlencord.shared.account.business.application.control.ApplicationRoleControl;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import java.util.Arrays;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Joern Muehlencord <joern at muehlencord.de>
*/
@ApplicationScoped
public class EnsurePermissionsBean {
@Inject
ApplicationEntity application;
@Inject
ApplicationPermissionControl applicationPermissionControl;
@Inject
ApplicationRoleControl applicationRoleControl;
private static final Logger LOGGER = LoggerFactory.getLogger(EnsurePermissionsBean.class);
public void init(@Observes @Initialized(ApplicationScoped.class) Object init) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ensure all permissions for {} are available", application.getApplicationName());
}
applicationPermissionControl.setupPermissions(Arrays.asList(ApplicationPermissions.values()));
applicationPermissionControl.setupPermissions(Arrays.asList(AccountPermissions.values()));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("All permissions added to application", application.getApplicationName());
}
// all permissions available - ensure permission is assigned to Admin role
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ensuring Admin role for {} has all permissions", application.getApplicationName());
}
try {
applicationRoleControl.setupRolePermission(Arrays.asList(ApplicationPermissions.values()), "Admin"); // NOI18N
applicationRoleControl.setupRolePermission(Arrays.asList(AccountPermissions.values()), "Admin"); // NOI18N
} catch (AccountException ex) {
LOGGER.error("Error adding permission to Admin role");
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex);
} else {
LOGGER.error(ex.toString());
}
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("All permissions added to Admin role of {}", application.getApplicationName());
}
}
}

View File

@ -15,6 +15,7 @@
*/ */
package de.muehlencord.shared.account.web; package de.muehlencord.shared.account.web;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.ContextNotActiveException; import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces; import javax.enterprise.inject.Produces;
@ -24,6 +25,7 @@ import javax.faces.context.FacesContext;
* *
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
@ApplicationScoped
public class FacesContextProducer { public class FacesContextProducer {
@Produces @Produces

View File

@ -0,0 +1,48 @@
/*
* 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.ApplicationPermissions;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
/**
* TODO replace with omnifaces:importConstants currently problems with Netbeans
* to import omnifaces taglib
*
* @author Joern Muehlencord <joern at muehlencord.de>
*/
@Named(value = "permissionConstants")
@ApplicationScoped
public class PermissionConstants {
public String getApplicationListAll() {
return ApplicationPermissions.APP_LISTALL.getName();
}
public String getPermissionsCombined() {
return ApplicationPermissions.PERMISSION_ADD.getName() + ","
+ ApplicationPermissions.PERMISSION_EDIT.getName() + ","
+ ApplicationPermissions.PERMISSION_DELETE.getName();
}
public String getRolesCombined() {
return ApplicationPermissions.ROLE_ADD.getName() + ","
+ ApplicationPermissions.ROLE_EDIT.getName() + ","
+ ApplicationPermissions.ROLE_DELETE.getName();
}
}

View File

@ -6,7 +6,7 @@ import de.muehlencord.shared.account.business.account.entity.AccountEntity;
import de.muehlencord.shared.account.business.account.entity.AccountException; import de.muehlencord.shared.account.business.account.entity.AccountException;
import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity; import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity;
import de.muehlencord.shared.account.business.account.entity.AccountStatus; import de.muehlencord.shared.account.business.account.entity.AccountStatus;
import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.jeeutil.FacesUtil; import de.muehlencord.shared.jeeutil.FacesUtil;
import java.io.Serializable; import java.io.Serializable;

View File

@ -2,9 +2,12 @@ package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.application.boundary.ApplicationService; 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 de.muehlencord.shared.account.util.AccountSecurityException;
import de.muehlencord.shared.jeeutil.FacesUtil; import de.muehlencord.shared.jeeutil.FacesUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import javax.inject.Named; import javax.inject.Named;
@ -27,6 +30,9 @@ public class ApplicationView implements Serializable {
@Inject @Inject
ApplicationService applicationService; ApplicationService applicationService;
@Inject
Locale locale;
private ApplicationEntity currentApplication = null; private ApplicationEntity currentApplication = null;
private ApplicationEntity editApplication = null; private ApplicationEntity editApplication = null;
private List<ApplicationEntity> applicationList = null; private List<ApplicationEntity> applicationList = null;
@ -53,7 +59,18 @@ public class ApplicationView implements Serializable {
public List<ApplicationEntity> getAllApplications() { public List<ApplicationEntity> getAllApplications() {
if (applicationList == null) { if (applicationList == null) {
applicationList = applicationService.getAllApplications(); try {
applicationList = applicationService.getAllApplications();
return applicationList;
} catch (AccountSecurityException ex) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex);
} else {
LOGGER.error(ex.toString());
}
FacesUtil.addGlobalErrorMessage("Error " + ex.getErrorCode(), ex.getLocalizedMessage(locale));
return new ArrayList<>();
}
} }
return applicationList; return applicationList;
} }

View File

@ -16,7 +16,7 @@
package de.muehlencord.shared.account.web.presentation; package de.muehlencord.shared.account.web.presentation;
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.application.entity.ApplicationPermissionEntity;
import de.muehlencord.shared.account.business.application.control.ApplicationPermissionControl; import de.muehlencord.shared.account.business.application.control.ApplicationPermissionControl;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.jeeutil.FacesUtil; import de.muehlencord.shared.jeeutil.FacesUtil;
@ -61,7 +61,7 @@ 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(applicationView.getCurrentApplication(), newPermissionName, newPermissionName); applicationPermissionService.create(applicationView.getCurrentApplication(), newPermissionName, newPermissionDescription);
FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " created"); FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " created");
} else { } else {
applicationPermissionService.update(currentPermission); applicationPermissionService.update(currentPermission);

View File

@ -17,8 +17,8 @@ package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.application.control.ApplicationRoleControl; import de.muehlencord.shared.account.business.application.control.ApplicationRoleControl;
import de.muehlencord.shared.account.business.account.entity.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.application.entity.ApplicationPermissionEntity;
import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.jeeutil.FacesUtil; import de.muehlencord.shared.jeeutil.FacesUtil;
import java.io.Serializable; import java.io.Serializable;

View File

@ -1,13 +1,14 @@
package de.muehlencord.shared.account.web.presentation; package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.application.control.ApplicationRoleControl; import de.muehlencord.shared.account.business.application.control.ApplicationRoleControl;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.account.util.AccountPU; import de.muehlencord.shared.account.util.AccountPU;
import java.io.Serializable; import java.io.Serializable;
import javax.ejb.EJB; import java.util.UUID;
import javax.faces.application.FacesMessage; import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent; import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator; import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator; import javax.faces.validator.Validator;
@ -33,6 +34,13 @@ public class UniqueApplicationRoleNameValidator implements Validator, Serializab
@Override @Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
Object oldRoleNameObj = ((UIInput) component).getValue();
String oldRoleName = "";
if (oldRoleNameObj != null) {
oldRoleName = oldRoleNameObj.toString();
}
Object applicationObj = component.getAttributes().get("application"); Object applicationObj = component.getAttributes().get("application");
if ((applicationObj != null) && (applicationObj instanceof ApplicationEntity)) { if ((applicationObj != null) && (applicationObj instanceof ApplicationEntity)) {
ApplicationEntity application = (ApplicationEntity) applicationObj; ApplicationEntity application = (ApplicationEntity) applicationObj;
@ -43,7 +51,10 @@ public class UniqueApplicationRoleNameValidator implements Validator, Serializab
String roleName = (String) value; String roleName = (String) value;
ApplicationRoleEntity existingRole = applicationRoleControl.findByName(application, roleName); ApplicationRoleEntity existingRole = applicationRoleControl.findByName(application, roleName);
if (existingRole != null) { if (existingRole != null) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role already exists")); if (!oldRoleName.equals(roleName)) {
// name of role changed and there is another role with the new name already --> this must not happen
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role already exists"));
}
} }
} else { } else {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role name must be a string value")); throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Role name invalid", "Role name must be a string value"));

View File

@ -3,8 +3,10 @@ package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.application.boundary.ApplicationService; 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 java.util.UUID;
import javax.faces.application.FacesMessage; import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent; import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator; import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator; import javax.faces.validator.Validator;
@ -28,6 +30,13 @@ public class UniqueApplicationValidator implements Validator, Serializable {
@Override @Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
Object oldAppNameObj = ((UIInput) component).getValue();
String oldAppName = "";
if (oldAppNameObj != null) {
oldAppName = oldAppNameObj.toString();
}
if (value == null) { if (value == null) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application name invalid", "Application name must not be empty")); throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application name invalid", "Application name must not be empty"));
} }
@ -35,7 +44,11 @@ public class UniqueApplicationValidator implements Validator, Serializable {
String applicationname = (String) value; String applicationname = (String) value;
ApplicationEntity existingApplication = applicationService.findByApplicationName(applicationname); ApplicationEntity existingApplication = applicationService.findByApplicationName(applicationname);
if (existingApplication != null) { if (existingApplication != null) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application name invalid", "Application already exists")); if (!oldAppName.equals(applicationname)) {
// name of application changed and there is another application with the new
// name already --> this must not happen
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Application name invalid", "Application already exists"));
}
} }
LOGGER.info("Name = {}", applicationname); LOGGER.info("Name = {}", applicationname);
} else { } else {

View File

@ -1,20 +1,19 @@
package de.muehlencord.shared.account.web.presentation; package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationPermissionEntity;
import de.muehlencord.shared.account.business.application.control.ApplicationPermissionControl; import de.muehlencord.shared.account.business.application.control.ApplicationPermissionControl;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.account.util.AccountPU; import de.muehlencord.shared.account.util.AccountPU;
import java.io.Serializable; import java.io.Serializable;
import javax.faces.application.FacesMessage; import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent; import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator; import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator; 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;
/** /**
* *
@ -24,7 +23,6 @@ import org.slf4j.LoggerFactory;
public class UniquePermissionNameValidator implements Validator, Serializable { public class UniquePermissionNameValidator implements Validator, Serializable {
private static final long serialVersionUID = 2526409681909574670L; private static final long serialVersionUID = 2526409681909574670L;
private static final Logger LOGGER = LoggerFactory.getLogger(UniquePermissionNameValidator.class);
@Inject @Inject
@AccountPU @AccountPU
@ -35,6 +33,13 @@ public class UniquePermissionNameValidator implements Validator, Serializable {
@Override @Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
Object oldPermissionNameObj = ((UIInput) component).getValue();
String oldPermissionName = "";
if (oldPermissionNameObj != null) {
oldPermissionName = oldPermissionNameObj.toString();
}
Object applicationObj = component.getAttributes().get("application"); Object applicationObj = component.getAttributes().get("application");
if ((applicationObj != null) && (applicationObj instanceof ApplicationEntity)) { if ((applicationObj != null) && (applicationObj instanceof ApplicationEntity)) {
ApplicationEntity application = (ApplicationEntity) applicationObj; ApplicationEntity application = (ApplicationEntity) applicationObj;
@ -45,7 +50,11 @@ public class UniquePermissionNameValidator implements Validator, Serializable {
String permissionName = (String) value; String permissionName = (String) value;
ApplicationPermissionEntity existingPermission = applicationPermissionControl.findPermissionByName(application, permissionName); ApplicationPermissionEntity existingPermission = applicationPermissionControl.findPermissionByName(application, permissionName);
if (existingPermission != null) { if (existingPermission != null) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission already exists")); if ((!oldPermissionName.equals (permissionName))) {
// name of permission changed and there is another permission with the new
// name already --> this must not happen
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission already exists"));
}
} }
} else { } else {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission name must be a string value")); throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Permission name invalid", "Permission name must be a string value"));
@ -54,7 +63,6 @@ public class UniquePermissionNameValidator implements Validator, Serializable {
} 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

@ -5,9 +5,10 @@
<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.AccountLoginEntity</class>
<class>de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity</class> <class>de.muehlencord.shared.account.business.account.entity.ApiKeyEntity</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.application.entity.ApplicationEntity</class>
<class>de.muehlencord.shared.account.business.application.entity.ApplicationPermissionEntity</class>
<class>de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity</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>
<exclude-unlisted-classes>true</exclude-unlisted-classes> <exclude-unlisted-classes>true</exclude-unlisted-classes>
@ -15,7 +16,7 @@
<validation-mode>NONE</validation-mode> <validation-mode>NONE</validation-mode>
<properties> <properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL94Dialect"/> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL94Dialect"/>
<property name="hibernate.show_sql" value="true"/> <property name="hibernate.show_sql" value="false"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/> <property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/> <property name="hibernate.cache.use_query_cache" value="true"/>
</properties> </properties>

View File

@ -1,5 +1,5 @@
admin.loginPage=/login.xhtml admin.loginPage=/login.xhtml
admin.indexPage=/web/account.xhtml admin.indexPage=/web/index.xhtml
#admin.dateFormat= #admin.dateFormat=
#admin.breadcrumbSize=5 #admin.breadcrumbSize=5
admin.renderMessages=true admin.renderMessages=true

View File

@ -29,10 +29,10 @@ ${shiro.ldapRealm}
# 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=true
# 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.authenticationQuery = SELECT accl.account_password from account acc, account_login accl, account_role accr, application_role appr WHERE accl.account = acc.id AND acc.id = accr.account AND accr.account_role = appr.id AND appr.application = '143a2bd3-7e0b-4162-a76e-3031331c7dfe' AND acc.status not in ('LOCKED','DELETED') AND acc.username = ? jdbcRealm.authenticationQuery = SELECT accl.account_password from account acc, account_login accl, account_role accr, application_role appr WHERE accl.account = acc.id AND acc.id = accr.account AND accr.account_role = appr.id AND appr.application = '143a2bd3-7e0b-4162-a76e-3031331c7dfe' AND acc.status not in ('LOCKED','DELETED') AND acc.username = ?
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.permissionsQuery = select permission_name from application_role appr, role_permission rp, application_permission appp WHERE appr.role_name = ? AND appr.application = '${applicationUuid}' AND rp.application_role = appr.id AND rp.role_permission = appp.id
jdbcRealm.credentialsMatcher = $passwordMatcher jdbcRealm.credentialsMatcher = $passwordMatcher
jdbcRealm.dataSource = $datasource jdbcRealm.dataSource = $datasource
@ -44,7 +44,7 @@ securityManager.authenticator.authenticationStrategy = $authcStrategy
# Setup authentication filter # Setup authentication filter
authc = de.muehlencord.shirofaces.filter.FacesAjaxAwarePassThruAuthenticationFilter authc = de.muehlencord.shirofaces.filter.FacesAjaxAwarePassThruAuthenticationFilter
authc.loginUrl = /login.xhtml authc.loginUrl = /login.xhtml
authc.successUrl = /web/account.xhtml authc.successUrl = /web/index.xhtml
roles.unauthorizedUrl = /error/accessDenied.xhtml roles.unauthorizedUrl = /error/accessDenied.xhtml

View File

@ -36,7 +36,7 @@
</session-timeout> </session-timeout>
</session-config> </session-config>
<welcome-file-list> <welcome-file-list>
<welcome-file>web/account.xhtml</welcome-file> <welcome-file>web/index.xhtml</welcome-file>
</welcome-file-list> </welcome-file-list>
<!-- Shiro Web Environment --> <!-- Shiro Web Environment -->
<listener> <listener>

View File

@ -56,7 +56,7 @@
<div class="login-box"> <div class="login-box">
<div class="login-logo"> <div class="login-logo">
<p:link href="/web/account.xhtml"><b>Account&nbsp;</b>Management</p:link> <p:link href="/web/accounts.xhtml"><b>Account&nbsp;</b>Management</p:link>
<h:outputLabel rendered="#{instanceView.developmentVersion}" value="#{instanceView.instanceName}" /> <h:outputLabel rendered="#{instanceView.developmentVersion}" value="#{instanceView.instanceName}" />
</div> </div>
<!-- /.login-logo --> <!-- /.login-logo -->

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml" <ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
xmlns:shiro="http://shiro.apache.org/tags"> xmlns:shiro="http://shiro.apache.org/tags">
@ -8,26 +7,42 @@
<shiro:authenticated> <shiro:authenticated>
<ul class="sidebar-menu tree" data-widget="tree"> <ul class="sidebar-menu tree" data-widget="tree">
<li> <li>
<p:link outcome="/web/index.xhtml"> <p:link outcome="/web/index.xhtml">
<i class="fa fa-tablet"></i> <i class="fa fa-home"></i>
<span>Application</span> <span>Home</span>
</p:link> </p:link>
</li> </li>
<shiro:hasPermission name="#{permissionConstants.applicationListAll}">
<li>
<p:link outcome="/web/applications.xhtml">
<i class="fa fa-tablet"></i>
<span>Applications</span>
</p:link>
</li>
</shiro:hasPermission>
<shiro:hasAnyPermission name="#{permissionConstants.permissionsCombined}">
<li>
<p:link outcome="/web/permissions.xhtml">
<i class="fa fa-list-ul"></i>
<span>Permissions</span>
</p:link>
</li>
</shiro:hasAnyPermission>
<shiro:hasAnyPermission name="#{permissionConstants.rolesCombined}">
<li>
<p:link outcome="/web/roles.xhtml">
<i class="fa fa-circle"></i>
<span>Roles</span>
</p:link>
</li>
</shiro:hasAnyPermission>
<li> <li>
<p:link outcome="/web/permissions.xhtml"> <p:link outcome="/web/accounts.xhtml">
<i class="fa fa-list-ul"></i>
<span>Permissions</span>
</p:link>
</li>
<li>
<p:link outcome="/web/roles.xhtml">
<i class="fa fa-circle"></i>
<span>Roles</span>
</p:link>
</li>
<li>
<p:link outcome="/web/account.xhtml">
<i class="fa fa-user"></i> <i class="fa fa-user"></i>
<span>Accounts</span> <span>Accounts</span>
</p:link> </p:link>

View File

@ -19,104 +19,106 @@
</ui:define> </ui:define>
<ui:define name="body"> <ui:define name="body">
<h:form id="accountForm" prependId="false"> <p:panel styleClass="box-solid" rendered="#{! empty applicationView.currentApplication}">
<p:dataTable id="accountTable" value="#{accountView.accounts}" var="account" rowKey="#{account.username}" selectionMode="single" selection="#{accountView.currentAccount}" <h:form id="accountForm" prependId="false">
styleClass="box-primary"> <p:dataTable id="accountTable" value="#{accountView.accounts}" var="account" rowKey="#{account.username}" selectionMode="single" selection="#{accountView.currentAccount}"
<p:ajax event="rowSelect" update="buttonPanel" listener="#{accountView.selectAccount}" /> styleClass="box-primary">
<p:ajax event="rowUnselect" update="buttonPanel" listener="#{accountView.unselectAccount}" /> <p:ajax event="rowSelect" update="buttonPanel" listener="#{accountView.selectAccount}" />
<p:column headerText="Username"> <p:ajax event="rowUnselect" update="buttonPanel" listener="#{accountView.unselectAccount}" />
<h:outputText value="#{account.username}" /> <p:column headerText="Username">
</p:column> <h:outputText value="#{account.username}" />
<p:column headerText="Lastname"> </p:column>
<h:outputText value="#{account.lastname}" /> <p:column headerText="Lastname">
</p:column> <h:outputText value="#{account.lastname}" />
<p:column headerText="Firstname"> </p:column>
<h:outputText value="#{account.firstname}" /> <p:column headerText="Firstname">
</p:column> <h:outputText value="#{account.firstname}" />
<p:column headerText="Email"> </p:column>
<h:outputText value="#{account.emailaddress}" /> <p:column headerText="Email">
</p:column> <h:outputText value="#{account.emailaddress}" />
<p:column headerText="Status"> </p:column>
<h:outputText value="#{account.status}" /> <p:column headerText="Status">
</p:column> <h:outputText value="#{account.status}" />
<p:column headerText="Can login" > </p:column>
<p:selectBooleanCheckbox id="canLogin" disabled="true" value="#{!empty account.accountLogin}" /> <p:column headerText="Can login" >
</p:column> <p:selectBooleanCheckbox id="canLogin" disabled="true" value="#{!empty account.accountLogin}" />
<p:column headerText="CreatedOn"> </p:column>
<h:outputText value="#{account.createdOn}" > <p:column headerText="CreatedOn">
<f:convertDateTime type="both" dateStyle="full" timeStyle="short" timeZone="Europe/Berlin"/> <h:outputText value="#{account.createdOn}" >
</h:outputText> <f:convertDateTime type="both" dateStyle="full" timeStyle="short" timeZone="Europe/Berlin"/>
</p:column> </h:outputText>
<p:column headerText="CreatedBy"> </p:column>
<h:outputText value="#{account.createdBy}" /> <p:column headerText="CreatedBy">
</p:column> <h:outputText value="#{account.createdBy}" />
<p:column headerText="LastUpdatedOn"> </p:column>
<h:outputText value="#{account.lastUpdatedOn}"> <p:column headerText="LastUpdatedOn">
<f:convertDateTime type="both" dateStyle="full" timeStyle="short" timeZone="Europe/Berlin"/> <h:outputText value="#{account.lastUpdatedOn}">
</h:outputText> <f:convertDateTime type="both" dateStyle="full" timeStyle="short" timeZone="Europe/Berlin"/>
</p:column> </h:outputText>
<p:column headerText="LastUpdatedBy"> </p:column>
<h:outputText value="#{account.lastUpdatedBy}" /> <p:column headerText="LastUpdatedBy">
</p:column> <h:outputText value="#{account.lastUpdatedBy}" />
</p:dataTable> </p:column>
</p:dataTable>
<p:spacer height="10px" /> <p:spacer height="10px" />
<p:panel id="buttonPanel" styleClass="box-primary" style="margin-bottom:20px"> <p:panel id="buttonPanel" styleClass="box-primary" style="margin-bottom:20px">
<div class="ui-g ui-fluid"> <div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-4" style="margin-top:10px"> <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" >
<p:ajax listener="#{accountView.showDisabledAccountsChange}" update="accountTable" /> <p:ajax listener="#{accountView.showDisabledAccountsChange}" update="accountTable" />
</p:inputSwitch> </p:inputSwitch>
</div>
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="New" id="newButton" icon="fa fa-plus"
update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{accountView.newAccount}" styleClass="btn-primary btn-block" />
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="Edit" id="editButton" icon="fa fa-pencil"
update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{accountView.editAccount}" disabled="#{!accountView.accountSelected}" styleClass="btn-teal btn-block" />
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="Delete" id="deleteButton" icon="fa fa-trash-o"
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:commandButton>
</div>
<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>
</div> </div>
</p:panel>
<div class="col-sm-12 col-md-2">
<p:commandButton value="New" id="newButton" icon="fa fa-plus"
update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{accountView.newAccount}" styleClass="btn-primary btn-block" />
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="Edit" id="editButton" icon="fa fa-pencil"
update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{accountView.editAccount}" disabled="#{!accountView.accountSelected}" styleClass="btn-teal btn-block" />
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="Delete" id="deleteButton" icon="fa fa-trash-o"
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:commandButton>
</div>
<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>
</p:panel>
<p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600" <p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600"

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
template="/resources/template/template.xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:co="http://java.sun.com/jsf/composite/composite"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite">
<ui:define name="title">
Applications
</ui:define>
<ui:define name="body" >
<p:panel styleClass="box-solid" rendered="#{! empty applicationView.currentApplication}">
<h:form id="applicationForm" prependId="false">
<div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-6">
<p:selectOneMenu id="applicationSelect" value="#{applicationView.currentApplication}" converter="omnifaces.SelectItemsConverter" required="true">
<f:selectItems value="#{applicationView.allApplications}" var="app" itemLabel="#{app.applicationName}" itemValue="#{app}" />
</p:selectOneMenu>
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="Select" styleClass="btn-primary btn-solid}" actionListener="#{applicationView.selectApplication}" />
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="New" id="newButton" icon="fa fa-plus"
update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{applicationView.newApplication}" styleClass="btn-teal btn-block" />
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton id="deletePermissionButton" icon="fa fa-trash-o" value="#{msgs.button_delete}" actionListener="#{applicationView.deleteApplication}"
update="applicationSelect" styleClass="btn-danger btn-block" >
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
</p:commandButton>
</div>
</div>
<composite:confirmationDialog />
</h:form>
</p:panel>
<p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600"
modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" >
<h:form id="editDialogForm">
<p:messages id="editDialogMessages" showDetail="true" showIcon="true" showSummary="true">
<p:autoUpdate />
</p:messages>
<div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-3">
<p:outputLabel for="applicationName" value="Application name" />
</div>
<div class="col-sm-12 col-md-6">
<p:inputText id="applicationName" value="#{applicationView.editApplication.applicationName}">
<f:validator validatorId="uniqueApplicationValidator"/>
</p:inputText>
</div>
<div class="col-sm-12 col-md-3">
<p:message for="applicationName"><p:autoUpdate /></p:message>
</div>
<div class="col-sm-12 col-md-3">
<p:spacer height="10px" />
<p:commandButton value="Save" action="#{applicationView.saveEditApplication}" styleClass="btn-primary btn-block"
oncomplete="if (args &amp;&amp; !args.validationFailed) PF('editDialogVar').hide();" update=":applicationForm" />
</div>
<div class="col-sm-12 col-md-3">
<p:spacer height="10px" />
<p:commandButton value="Cancel" action="#{applicationView.cancelEditApplication}" immediate="true" styleClass="btn-teal btn-block"
oncomplete="PF('editDialogVar').hide();" />
</div>
</div>
</h:form>
</p:dialog>
</ui:define>
</ui:composition>

View File

@ -1,84 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml" <ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" template="/resources/template/template.xhtml">
template="/resources/template/template.xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:co="http://java.sun.com/jsf/composite/composite"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite">
<ui:define name="title"> <ui:define name="title">
Applications Home
</ui:define> </ui:define>
<ui:define name="body" > <ui:define name="body" >
Home
<h:form id="applicationForm" prependId="false">
<p:panel styleClass="box-solid">
<div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-6">
<p:selectOneMenu id="applicationSelect" value="#{applicationView.currentApplication}" converter="omnifaces.SelectItemsConverter" required="true">
<f:selectItems value="#{applicationView.allApplications}" var="app" itemLabel="#{app.applicationName}" itemValue="#{app}" />
</p:selectOneMenu>
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="Select" styleClass="btn-primary btn-solid}" actionListener="#{applicationView.selectApplication}" />
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton value="New" id="newButton" icon="fa fa-plus"
update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{applicationView.newApplication}" styleClass="btn-teal btn-block" />
</div>
<div class="col-sm-12 col-md-2">
<p:commandButton id="deletePermissionButton" icon="fa fa-trash-o" value="#{msgs.button_delete}" actionListener="#{applicationView.deleteApplication}"
update="applicationSelect" styleClass="btn-danger btn-block" >
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
</p:commandButton>
</div>
</div>
</p:panel>
<composite:confirmationDialog />
</h:form>
<p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600"
modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" >
<h:form id="editDialogForm">
<p:messages id="editDialogMessages" showDetail="true" showIcon="true" showSummary="true">
<p:autoUpdate />
</p:messages>
<div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-3">
<p:outputLabel for="applicationName" value="Application name" />
</div>
<div class="col-sm-12 col-md-6">
<p:inputText id="applicationName" value="#{applicationView.editApplication.applicationName}">
<f:validator validatorId="uniqueApplicationValidator"/>
</p:inputText>
</div>
<div class="col-sm-12 col-md-3">
<p:message for="applicationName"><p:autoUpdate /></p:message>
</div>
<div class="col-sm-12 col-md-3">
<p:spacer height="10px" />
<p:commandButton value="Save" action="#{applicationView.saveEditApplication}" styleClass="btn-primary btn-block"
oncomplete="if (args &amp;&amp; !args.validationFailed) PF('editDialogVar').hide();" update=":applicationForm" />
</div>
<div class="col-sm-12 col-md-3">
<p:spacer height="10px" />
<p:commandButton value="Cancel" action="#{applicationView.cancelEditApplication}" immediate="true" styleClass="btn-teal btn-block"
oncomplete="PF('editDialogVar').hide();" />
</div>
</div>
</h:form>
</p:dialog>
</ui:define> </ui:define>
</ui:composition> </ui:composition>

View File

@ -18,41 +18,41 @@
</ui:define> </ui:define>
<ui:define name="body"> <ui:define name="body">
<h:form id="permissionForm"> <p:panel styleClass="box-solid" rendered="#{! empty applicationView.currentApplication}">
<h:form id="permissionForm">
<p:dataTable id="permissionTable" value="#{permissionView.appPermissions}" var="permission" rowKey="#{permission.id}"
selectionMode="single" selection="#{permissionView.currentPermission}" styleClass="box-primary">
<p:ajax event="rowSelect" update=":permissionForm:permissionTable:editPermissionButton,:permissionForm:permissionTable:deletePermissionButton" />
<p:ajax event="rowUnselect" update=":permissionForm:permissionTable:editPermissionButton,:permissionForm:permissionTable:deletePermissionButton" />
<p:dataTable id="permissionTable" value="#{permissionView.appPermissions}" var="permission" rowKey="#{permission.id}" <p:column headerText="Permission name">
selectionMode="single" selection="#{permissionView.currentPermission}" styleClass="box-primary"> <h:outputText value="#{permission.permissionName}" />
<p:ajax event="rowSelect" update=":permissionForm:permissionTable:editPermissionButton,:permissionForm:permissionTable:deletePermissionButton" /> </p:column>
<p:ajax event="rowUnselect" update=":permissionForm:permissionTable:editPermissionButton,:permissionForm:permissionTable:deletePermissionButton" /> <p:column headerText="Permission description">
<h:outputText value="#{permission.permissionDescription}" />
</p:column>
<p:column headerText="Permission name"> <f:facet name="footer">
<h:outputText value="#{permission.permissionName}" /> <div class="ui-g-12 ui-md-2">
</p:column> <p:commandButton id="newPermissionButton" icon="fa fa-plus" value="#{msgs.button_new}" action="#{permissionView.newPermission}"
<p:column headerText="Permission description"> oncomplete="PF('editDialogVar').show();" update="editDialog" styleClass="btn-primary btn-block" />
<h:outputText value="#{permission.permissionDescription}" /> </div>
</p:column> <div class="ui-g-12 ui-md-2">
<p:commandButton id="editPermissionButton" icon="fa fa-pencil" value="#{msgs.button_edit}" action="#{permissionView.editPermission}"
oncomplete="PF('editDialogVar').show();" update="editDialog" styleClass="btn-teal btn-block" disabled="#{!permissionView.canEdit}" />
</div>
<div class="ui-g-12 ui-md-2">
<p:commandButton id="deletePermissionButton" icon="fa fa-trash-o" value="#{msgs.button_delete}" actionListener="#{permissionView.deletePermission}"
update="permissionForm" styleClass="btn-danger btn-block" disabled="#{!permissionView.canDelete}">
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
</p:commandButton>
</div>
</f:facet>
</p:dataTable>
<f:facet name="footer"> <composite:confirmationDialog />
<div class="ui-g-12 ui-md-2"> </h:form>
<p:commandButton id="newPermissionButton" icon="fa fa-plus" value="#{msgs.button_new}" action="#{permissionView.newPermission}" </p:panel>
oncomplete="PF('editDialogVar').show();" update="editDialog" styleClass="btn-primary btn-block" />
</div>
<div class="ui-g-12 ui-md-2">
<p:commandButton id="editPermissionButton" icon="fa fa-pencil" value="#{msgs.button_edit}" action="#{permissionView.editPermission}"
oncomplete="PF('editDialogVar').show();" update="editDialog" styleClass="btn-teal btn-block" disabled="#{!permissionView.canEdit}" />
</div>
<div class="ui-g-12 ui-md-2">
<p:commandButton id="deletePermissionButton" icon="fa fa-trash-o" value="#{msgs.button_delete}" actionListener="#{permissionView.deletePermission}"
update="permissionForm" styleClass="btn-danger btn-block" disabled="#{!permissionView.canDelete}">
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
</p:commandButton>
</div>
</f:facet>
</p:dataTable>
<composite:confirmationDialog />
</h:form>
<p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit permission" width="600" <p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit permission" width="600"

View File

@ -17,74 +17,75 @@
</ui:define> </ui:define>
<ui:define name="body"> <ui:define name="body">
<h:form id="roleForm"> <p:panel styleClass="box-solid" rendered="#{! empty applicationView.currentApplication}">
<p:dataTable id="roleTable" value="#{roleView.allRoles}" var="role" rowKey="#{role.id}" styleClass="box-primary" <h:form id="roleForm">
selectionMode="single" selection="#{roleView.currentRole}"> <p:dataTable id="roleTable" value="#{roleView.allRoles}" var="role" rowKey="#{role.id}" styleClass="box-primary"
<p:ajax event="rowSelect" update=":roleForm:permissionTable, editRoleButton, deleteRoleButton" listener="#{roleView.onRoleSelect}"/> selectionMode="single" selection="#{roleView.currentRole}">
<p:ajax event="rowUnselect" update=":roleForm:permissionTable, editRoleButton, deleteRoleButton" /> <p:ajax event="rowSelect" update=":roleForm:permissionTable, editRoleButton, deleteRoleButton" listener="#{roleView.onRoleSelect}"/>
<p:ajax event="rowUnselect" update=":roleForm:permissionTable, editRoleButton, deleteRoleButton" />
<p:column headerText="Role name"> <p:column headerText="Role name">
<h:outputText value="#{role.roleName}" /> <h:outputText value="#{role.roleName}" />
</p:column> </p:column>
<p:column headerText="Role description"> <p:column headerText="Role description">
<h:outputText value="#{role.roleDescription}" /> <h:outputText value="#{role.roleDescription}" />
</p:column> </p:column>
<f:facet name="footer"> <f:facet name="footer">
<div class="ui-g ui-fluid"> <div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-2" style="margin-top:10px"> <div class="col-sm-12 col-md-2" style="margin-top:10px">
<p:commandButton id="newRoleButton" icon="fa fa-plus" value="#{msgs.button_new}" actionListener="#{roleView.startNewRole}" <p:commandButton id="newRoleButton" icon="fa fa-plus" value="#{msgs.button_new}" actionListener="#{roleView.startNewRole}"
update="editDialog" oncomplete="PF('editDialogVar').show();" styleClass="btn-primary btn-block"/> update="editDialog" oncomplete="PF('editDialogVar').show();" styleClass="btn-primary btn-block"/>
</div>
<div class="col-sm-12 col-md-2" style="margin-top:10px">
<p:commandButton id="editRoleButton" icon="fa fa-pencil" value="#{msgs.button_edit}" disabled="#{!roleView.roleSelected}"
update="editDialog" oncomplete="PF('editDialogVar').show();" styleClass="btn-teal btn-block"/>
</div>
<div class="col-sm-12 col-md-2" style="margin-top:10px">
<p:commandButton id="deleteRoleButton" icon="fa fa-trash-o" value="#{msgs.button_delete}" disabled="#{!roleView.roleSelected}"
action="#{roleView.deleteRole}" update=":roleForm:roleTable" styleClass="btn-danger btn-block">
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
</p:commandButton>
</div>
</div> </div>
<div class="col-sm-12 col-md-2" style="margin-top:10px"> </f:facet>
<p:commandButton id="editRoleButton" icon="fa fa-pencil" value="#{msgs.button_edit}" disabled="#{!roleView.roleSelected}" </p:dataTable>
update="editDialog" oncomplete="PF('editDialogVar').show();" styleClass="btn-teal btn-block"/>
<p:spacer height="15px;" />
<p:dataTable id="permissionTable" value="#{roleView.rolePermissions}" var="permission" rowKey="#{permission.id}" styleClass="box-teal"
selectionMode="single" selection="#{roleView.currentPermission}">
<p:ajax event="rowSelect" update="addPermissionButton, deletePermissionButton" />
<p:ajax event="rowUnselect" update="addPermissionButton, deletePermissionButton" />
<p:column headerText="Permission name">
<h:outputText value="#{permission.permissionName}" />
</p:column>
<p:column headerText="Permission description">
<h:outputText value="#{permission.permissionDescription}" />
</p:column>
<f:facet name="footer" >
<p:selectOneMenu value="#{roleView.newPermission}" converter="omnifaces.SelectItemsConverter" >
<f:selectItems id="permissionListItems" value="#{roleView.missingPermissions}" var="missingPermission" itemLabel="#{missingPermission.permissionName}" itemValue="#{missingPermission}" />
</p:selectOneMenu>
<div class="ui-g-12 ui-md-2">
<p:commandButton id="addPermissionButton" icon="fa fa-plus" value="#{msgs.button_add}" action="#{roleView.addRolePermission}"
update="permissionTable" styleClass="btn-primary btn-block" disabled="#{!roleView.missingPermissionAvailable}" />
</div> </div>
<div class="col-sm-12 col-md-2" style="margin-top:10px"> <div class="ui-g-12 ui-md-2">
<p:commandButton id="deleteRoleButton" icon="fa fa-trash-o" value="#{msgs.button_delete}" disabled="#{!roleView.roleSelected}" <p:commandButton id="deletePermissionButton" icon="fa fa-trash-o" value="#{msgs.button_delete}" update=":roleForm:permissionTable"
action="#{roleView.deleteRole}" update=":roleForm:roleTable" styleClass="btn-danger btn-block"> action="#{roleView.removeRolePermission}" styleClass="btn-danger btn-block"
disabled="#{!roleView.permissionSelected}" >
<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>
</div> </f:facet>
</f:facet> </p:dataTable>
</p:dataTable>
<p:spacer height="15px;" /> <composite:confirmationDialog />
</h:form>
<p:dataTable id="permissionTable" value="#{roleView.rolePermissions}" var="permission" rowKey="#{permission.id}" styleClass="box-teal" </p:panel>
selectionMode="single" selection="#{roleView.currentPermission}">
<p:ajax event="rowSelect" update="addPermissionButton, deletePermissionButton" />
<p:ajax event="rowUnselect" update="addPermissionButton, deletePermissionButton" />
<p:column headerText="Permission name">
<h:outputText value="#{permission.permissionName}" />
</p:column>
<p:column headerText="Permission description">
<h:outputText value="#{permission.permissionDescription}" />
</p:column>
<f:facet name="footer" >
<p:selectOneMenu value="#{roleView.newPermission}" converter="omnifaces.SelectItemsConverter" >
<f:selectItems id="permissionListItems" value="#{roleView.missingPermissions}" var="missingPermission" itemLabel="#{missingPermission.permissionName}" itemValue="#{missingPermission}" />
</p:selectOneMenu>
<div class="ui-g-12 ui-md-2">
<p:commandButton id="addPermissionButton" icon="fa fa-plus" value="#{msgs.button_add}" action="#{roleView.addRolePermission}"
update="permissionTable" styleClass="btn-primary btn-block" disabled="#{!roleView.missingPermissionAvailable}" />
</div>
<div class="ui-g-12 ui-md-2">
<p:commandButton id="deletePermissionButton" icon="fa fa-trash-o" value="#{msgs.button_delete}" update=":roleForm:permissionTable"
action="#{roleView.removeRolePermission}" styleClass="btn-danger btn-block"
disabled="#{!roleView.permissionSelected}" >
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
</p:commandButton>
</div>
</f:facet>
</p:dataTable>
<composite:confirmationDialog />
</h:form>
<p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600" <p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600"
modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" > modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" >