restructured code

enhanced permission system
This commit is contained in:
2019-01-10 18:08:36 +01:00
parent b552e0b8bc
commit ecedc1872b
25 changed files with 1158 additions and 1033 deletions

View File

@ -1,81 +1,80 @@
/* /*
* Copyright 2018 Joern Muehlencord <joern at muehlencord.de>. * Copyright 2018 Joern Muehlencord <joern at muehlencord.de>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.web; package de.muehlencord.shared.account.web;
import de.muehlencord.shared.account.business.account.boundary.AccountPermissions; import de.muehlencord.shared.account.business.account.boundary.AccountPermissions;
import de.muehlencord.shared.account.business.account.entity.AccountException; import de.muehlencord.shared.account.business.account.entity.AccountException;
import de.muehlencord.shared.account.business.application.boundary.ApplicationPermissions; import de.muehlencord.shared.account.business.instance.boundary.ApplicationPermissions;
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.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 java.util.Arrays; import java.util.Arrays;
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Initialized; import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes; import javax.enterprise.event.Observes;
import javax.inject.Inject; import javax.inject.Inject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* *
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
@ApplicationScoped @ApplicationScoped
public class EnsurePermissionsBean { public class EnsurePermissionsBean {
@Inject @Inject
ApplicationEntity application; ApplicationEntity application;
@Inject @Inject
ApplicationPermissionControl applicationPermissionControl; ApplicationPermissionControl applicationPermissionControl;
@Inject @Inject
ApplicationRoleControl applicationRoleControl; ApplicationRoleControl applicationRoleControl;
private static final Logger LOGGER = LoggerFactory.getLogger(EnsurePermissionsBean.class); private static final Logger LOGGER = LoggerFactory.getLogger(EnsurePermissionsBean.class);
public void init(@Observes @Initialized(ApplicationScoped.class) Object init) { public void init(@Observes @Initialized(ApplicationScoped.class) Object init) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ensure all permissions for {} are available", application.getApplicationName()); LOGGER.debug("Ensure all permissions for {} are available", application.getApplicationName());
} }
applicationPermissionControl.setupPermissions(Arrays.asList(ApplicationPermissions.values())); applicationPermissionControl.setupPermissions(Arrays.asList(ApplicationPermissions.values()));
applicationPermissionControl.setupPermissions(Arrays.asList(AccountPermissions.values())); applicationPermissionControl.setupPermissions(Arrays.asList(AccountPermissions.values()));
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("All permissions added to application", application.getApplicationName()); LOGGER.debug("All permissions added to application", application.getApplicationName());
} }
// all permissions available - ensure permission is assigned to Admin role // all permissions available - ensure permission is assigned to Admin role
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ensuring Admin role for {} has all permissions", application.getApplicationName()); LOGGER.debug("Ensuring Admin role for {} has all permissions", application.getApplicationName());
} }
try { try {
applicationRoleControl.setupRolePermission(Arrays.asList(ApplicationPermissions.values()), "Admin"); // NOI18N applicationRoleControl.setupRolePermission(Arrays.asList(ApplicationPermissions.values()), "Admin"); // NOI18N
applicationRoleControl.setupRolePermission(Arrays.asList(AccountPermissions.values()), "Admin"); // NOI18N applicationRoleControl.setupRolePermission(Arrays.asList(AccountPermissions.values()), "Admin"); // NOI18N
} catch (AccountException ex) { } catch (AccountException ex) {
LOGGER.error("Error adding permission to Admin role"); LOGGER.error("Error adding permission to Admin role. Reason={}", ex.getMessage());
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex); LOGGER.debug("Detailed stacktrace", new Object[]{ex});
} else { }
LOGGER.error(ex.toString());
} }
} if (LOGGER.isDebugEnabled()) {
if (LOGGER.isDebugEnabled()) { LOGGER.debug("All permissions added to Admin role of {}", application.getApplicationName());
LOGGER.debug("All permissions added to Admin role of {}", application.getApplicationName()); }
}
}
}
}
}

View File

@ -1,48 +1,86 @@
/* /*
* Copyright 2018 Joern Muehlencord <joern at muehlencord.de>. * Copyright 2018 Joern Muehlencord <joern at muehlencord.de>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.web; package de.muehlencord.shared.account.web;
import de.muehlencord.shared.account.business.application.boundary.ApplicationPermissions; import de.muehlencord.shared.account.business.instance.boundary.ApplicationPermissions;
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named; import javax.inject.Named;
/** /**
* TODO replace with omnifaces:importConstants currently problems with Netbeans * TODO replace with omnifaces:importConstants currently problems with Netbeans
* to import omnifaces taglib * to import omnifaces taglib
* *
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
@Named(value = "permissionConstants") @Named(value = "permissionConstants")
@ApplicationScoped @ApplicationScoped
public class PermissionConstants { public class PermissionConstants {
public String getApplicationListAll() { public String getApplicationListAll() {
return ApplicationPermissions.APP_LISTALL.getName(); return ApplicationPermissions.APP_LIST.getName();
} }
public String getPermissionsCombined() { public String getPermissionsCombined() {
return ApplicationPermissions.PERMISSION_ADD.getName() + "," return ApplicationPermissions.PERMISSION_ADD.getName() + ","
+ ApplicationPermissions.PERMISSION_EDIT.getName() + "," + ApplicationPermissions.PERMISSION_EDIT.getName() + ","
+ ApplicationPermissions.PERMISSION_DELETE.getName(); + ApplicationPermissions.PERMISSION_DELETE.getName();
} }
public String getRolesCombined() { public String getRolesCombined() {
return ApplicationPermissions.ROLE_ADD.getName() + "," return ApplicationPermissions.ROLE_ADD.getName() + ","
+ ApplicationPermissions.ROLE_EDIT.getName() + "," + ApplicationPermissions.ROLE_EDIT.getName() + ","
+ ApplicationPermissions.ROLE_DELETE.getName(); + ApplicationPermissions.ROLE_DELETE.getName();
} }
} public String getAccountsCombined() {
return ApplicationPermissions.ACCOUNT_ADD.getName() + ","
+ ApplicationPermissions.ACCOUNT_DELETE.getName() + ","
+ ApplicationPermissions.ACCOUNT_EDIT.getName() + ","
+ ApplicationPermissions.ACCOUNT_LIST.getName() + ","
+ ApplicationPermissions.ACCOUNT_LOGIN_ADD.getName() + ","
+ ApplicationPermissions.ACCOUNT_LOGIN_DELETE.getName() + ","
+ ApplicationPermissions.ACCOUNT_LOGIN_EDIT.getName();
}
public String getAccountAdd() {
return ApplicationPermissions.ACCOUNT_ADD.getName();
}
public String getAccountDelete() {
return ApplicationPermissions.ACCOUNT_DELETE.getName();
}
public String getAccountEdit() {
return ApplicationPermissions.ACCOUNT_EDIT.getName();
}
public String getAccountList() {
return ApplicationPermissions.ACCOUNT_LIST.getName();
}
public String getAccountLoginAdd() {
return ApplicationPermissions.ACCOUNT_LOGIN_ADD.getName();
}
public String getAccountLoginDelete() {
return ApplicationPermissions.ACCOUNT_LOGIN_DELETE.getName();
}
public String getAccountLoginEdit() {
return ApplicationPermissions.ACCOUNT_LOGIN_EDIT.getName();
}
}

View File

@ -63,7 +63,7 @@ public class AccountView implements Serializable {
public List<AccountEntity> getAccounts() { public List<AccountEntity> getAccounts() {
if (accountList == null) { if (accountList == null) {
accountList = accountService.getAccounts(showDisabledAccounts); accountList = accountService.getAllAccounts(showDisabledAccounts);
} }
return accountList; return accountList;
} }
@ -136,11 +136,8 @@ public class AccountView implements Serializable {
currentAccountRoles = null; currentAccountRoles = null;
} catch (AccountException ex) { } catch (AccountException ex) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex); LOGGER.debug("Detailed stacktrace", new Object[]{ex});
} else {
LOGGER.error(ex.toString());
} }
FacesUtil.addGlobalErrorMessage("Error deleting account", ex.getMessage()); FacesUtil.addGlobalErrorMessage("Error deleting account", ex.getMessage());
} }
} }
@ -158,13 +155,13 @@ public class AccountView implements Serializable {
/* **** account login methods **** */ /* **** account login methods **** */
public boolean validatePasswords(FacesContext context, List<UIInput> components, List<Object> values) { public boolean validatePasswords(FacesContext context, List<UIInput> components, List<Object> values) {
String password = components.get(0).getSubmittedValue().toString(); String currentPassword = components.get(0).getSubmittedValue().toString();
String passwordRepeat = components.get(1).getSubmittedValue().toString(); String currentPasswordRepeat = components.get(1).getSubmittedValue().toString();
if ((password == null) || (passwordRepeat == null)) { if ((currentPassword == null) || (currentPasswordRepeat == null)) {
return false; return false;
} }
boolean returnValue = password.equals(passwordRepeat); boolean returnValue = currentPassword.equals(currentPasswordRepeat);
return returnValue; return returnValue;
} }
@ -202,13 +199,13 @@ public class AccountView implements Serializable {
if ((currentAccountLogin == null) || (currentAccount == null)) { if ((currentAccountLogin == null) || (currentAccount == null)) {
// TODO add error handling // TODO add error handling
} else { } else {
// overwrite password if provided // overwrite password if provided
if ((password != null) && (!password.trim().equals(""))) { if ((password != null) && (!password.trim().equals(""))) {
// password has been specified // password has been specified
if (password.equals(repeatPassword)) { if (password.equals(repeatPassword)) {
currentAccountLogin.setAccountPassword(accountService.getHashedPassword(password)); currentAccountLogin.setAccountPassword(accountService.getHashedPassword(password));
FacesUtil.addGlobalInfoMessage("Info", "Password updated"); FacesUtil.addGlobalInfoMessage("Info", "Password updated");
} else { } else {
// TODO connect to IPRS // TODO connect to IPRS
// frontend does validate passwords do match // frontend does validate passwords do match

View File

@ -1,143 +1,151 @@
package de.muehlencord.shared.account.web.presentation; package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.application.boundary.ApplicationService; import de.muehlencord.shared.account.business.application.control.ApplicationControl;
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.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.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; 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.enterprise.context.SessionScoped;
import javax.enterprise.context.SessionScoped; import javax.inject.Inject;
import javax.inject.Inject; import javax.inject.Named;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* *
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
@SessionScoped @SessionScoped
@Named("applicationView") @Named("applicationView")
public class ApplicationView implements Serializable { public class ApplicationView implements Serializable {
private static final long serialVersionUID = -5515249316880163539L; private static final long serialVersionUID = -5515249316880163539L;
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationView.class); private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationView.class);
@Inject @Inject
ApplicationService applicationService; ApplicationControl applicationService;
@Inject @Inject
Locale locale; InstanceView instanceView;
private ApplicationEntity currentApplication = null; @Inject
private ApplicationEntity editApplication = null; Locale locale;
private List<ApplicationEntity> applicationList = null;
private ApplicationEntity currentApplication = null;
@PostConstruct private ApplicationEntity editApplication = null;
public void selectDefaultCurrentApplication() { private List<ApplicationEntity> applicationList = null;
// force applications to be loaded from database
getAllApplications(); @PostConstruct
if ((applicationList != null) && (!applicationList.isEmpty())) { public void selectDefaultCurrentApplication() {
currentApplication = applicationList.get(0); // force applications to be loaded from database
} getAllApplications();
if (LOGGER.isDebugEnabled()) { if ((applicationList != null) && (!applicationList.isEmpty())) {
LOGGER.debug("post construct executed"); currentApplication = applicationList.get(0);
} }
} if (LOGGER.isDebugEnabled()) {
LOGGER.debug("post construct executed");
@PreDestroy }
public void predestroy() { }
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Predestroy executed"); @PreDestroy
} public void predestroy() {
if (LOGGER.isDebugEnabled()) {
} LOGGER.debug("Predestroy executed");
}
public List<ApplicationEntity> getAllApplications() {
if (applicationList == null) { }
try {
applicationList = applicationService.getAllApplications(); public List<ApplicationEntity> getAllApplications() {
return applicationList; if (applicationList == null) {
} catch (AccountSecurityException ex) { try {
if (LOGGER.isDebugEnabled()) { applicationList = applicationService.getAllApplications();
LOGGER.debug(ex.toString(), ex);
} else { // if no role is assigned to user, ensure that at least current application is added
LOGGER.error(ex.toString()); if ((applicationList == null) || (applicationList.isEmpty())) {
} applicationList = new ArrayList<>();
FacesUtil.addGlobalErrorMessage("Error " + ex.getErrorCode(), ex.getLocalizedMessage(locale)); applicationList.add(instanceView.getInstanceApplication());
return new ArrayList<>(); }
}
} return applicationList;
return applicationList; } catch (AccountSecurityException ex) {
} if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Detailed stacktrace", new Object[]{ex});
public void selectApplication() { }
if (currentApplication != null) { FacesUtil.addGlobalErrorMessage("Error " + ex.getErrorCode(), ex.getLocalizedMessage(locale));
LOGGER.info("selected application: {}", currentApplication.getApplicationName()); return new ArrayList<>();
FacesUtil.addGlobalInfoMessage("Success", "Selected application " + currentApplication.getApplicationName()); }
} }
} return applicationList;
}
public void newApplication() {
this.editApplication = new ApplicationEntity(); public void selectApplication() {
} if (currentApplication != null) {
LOGGER.info("selected application: {}", currentApplication.getApplicationName());
public void cancelEditApplication() { FacesUtil.addGlobalInfoMessage("Success", "Selected application " + currentApplication.getApplicationName());
this.editApplication = null; }
} }
public void saveEditApplication() { public void newApplication() {
if (editApplication == null) { this.editApplication = new ApplicationEntity();
FacesUtil.addGlobalErrorMessage("Error", "Need to provide data"); }
} else if ((editApplication.getApplicationName() == null) || (editApplication.getApplicationName().trim().equals(""))) {
String hint; public void cancelEditApplication() {
if (editApplication.getId() == null) { this.editApplication = null;
hint = "Cannot create application"; }
} else {
hint = "Cannot save application"; public void saveEditApplication() {
} if (editApplication == null) {
FacesUtil.addGlobalErrorMessage(hint, "Application name must not be empty"); FacesUtil.addGlobalErrorMessage("Error", "Need to provide data");
} else { } else if ((editApplication.getApplicationName() == null) || (editApplication.getApplicationName().trim().equals(""))) {
currentApplication = applicationService.createOrUpdate(editApplication); String hint;
// force reload of to update view if (editApplication.getId() == null) {
applicationList = null; hint = "Cannot create application";
FacesUtil.addGlobalInfoMessage("Info", "Application saved"); } else {
} hint = "Cannot save application";
} }
FacesUtil.addGlobalErrorMessage(hint, "Application name must not be empty");
public void deleteApplication() { } else {
if (currentApplication == null) { currentApplication = applicationService.createOrUpdate(editApplication);
FacesUtil.addGlobalErrorMessage("Error", "Need to provide data"); // force reload of to update view
} else if (currentApplication.getId() == null) { applicationList = null;
FacesUtil.addGlobalErrorMessage("Error", "Cannot delete non persistent data"); FacesUtil.addGlobalInfoMessage("Info", "Application saved");
} else { }
String applicationName = currentApplication.getApplicationName(); }
applicationService.delete(currentApplication);
applicationList = null; // force reload to update view public void deleteApplication() {
currentApplication = null; if (currentApplication == null) {
selectDefaultCurrentApplication(); FacesUtil.addGlobalErrorMessage("Error", "Need to provide data");
FacesUtil.addGlobalInfoMessage("Info", "Application " + applicationName + " deleted"); } else if (currentApplication.getId() == null) {
} FacesUtil.addGlobalErrorMessage("Error", "Cannot delete non persistent data");
} } else {
String applicationName = currentApplication.getApplicationName();
/* *** getter / setter *** */ applicationService.delete(currentApplication);
public ApplicationEntity getCurrentApplication() { applicationList = null; // force reload to update view
return currentApplication; currentApplication = null;
} selectDefaultCurrentApplication();
FacesUtil.addGlobalInfoMessage("Info", "Application " + applicationName + " deleted");
public void setCurrentApplication(ApplicationEntity currentApplication) { }
this.currentApplication = currentApplication; }
}
/* *** getter / setter *** */
public ApplicationEntity getEditApplication() { public ApplicationEntity getCurrentApplication() {
return editApplication; return currentApplication;
} }
public void setEditApplication(ApplicationEntity editApplication) { public void setCurrentApplication(ApplicationEntity currentApplication) {
this.editApplication = editApplication; this.currentApplication = currentApplication;
} }
}
public ApplicationEntity getEditApplication() {
return editApplication;
}
public void setEditApplication(ApplicationEntity editApplication) {
this.editApplication = editApplication;
}
}

View File

@ -1,26 +1,32 @@
package de.muehlencord.shared.account.web.presentation; package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.instance.control.ApplicationController;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.account.business.config.boundary.ConfigService; import de.muehlencord.shared.account.business.config.boundary.ConfigService;
import de.muehlencord.shared.account.business.config.entity.ConfigException; import de.muehlencord.shared.account.business.config.entity.ConfigException;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* TODO - move to shared-account and remove from all applications and archetype * TODO - move to shared-account and remove from all applications and archetype
*
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
@Named(value = "instanceView") @Named(value = "instanceView")
@ApplicationScoped @ApplicationScoped
public class InstanceView { public class InstanceView {
private static final Logger LOGGER = LoggerFactory.getLogger(InstanceView.class); private static final Logger LOGGER = LoggerFactory.getLogger(InstanceView.class);
@EJB @Inject
ConfigService configService; ConfigService configService;
@Inject
ApplicationController applicationController;
public boolean isDevelopmentVersion() { public boolean isDevelopmentVersion() {
String instanceName = getInstanceName(); String instanceName = getInstanceName();
return !instanceName.equals("Production"); return !instanceName.equals("Production");
@ -32,9 +38,7 @@ public class InstanceView {
instanceName = configService.getConfigValue("base.instance"); instanceName = configService.getConfigValue("base.instance");
} catch (ConfigException ex) { } catch (ConfigException ex) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex); LOGGER.debug("Detailed stacktrace", new Object[]{ex});
} else {
LOGGER.error(ex.toString());
} }
instanceName = "unknown (" + ex.toString() + ")"; instanceName = "unknown (" + ex.toString() + ")";
} }
@ -44,4 +48,8 @@ public class InstanceView {
return instanceName; return instanceName;
} }
} }
public ApplicationEntity getInstanceApplication() {
return applicationController.getApplication();
}
} }

View File

@ -1,145 +1,143 @@
/* /*
* Copyright 2017 Joern Muehlencord <joern at muehlencord.de>. * Copyright 2017 Joern Muehlencord <joern at muehlencord.de>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
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.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.business.application.entity.ApplicationPermissionEntity;
import de.muehlencord.shared.jeeutil.FacesUtil; import de.muehlencord.shared.jeeutil.FacesUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.inject.Named; import javax.faces.view.ViewScoped;
import javax.faces.view.ViewScoped; import javax.inject.Inject;
import javax.inject.Inject; import javax.inject.Named;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* *
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
@ViewScoped @ViewScoped
@Named("permissionView") @Named("permissionView")
public class PermissionView implements Serializable { public class PermissionView implements Serializable {
private static final long serialVersionUID = -1469453490360990772L; private static final long serialVersionUID = -1469453490360990772L;
private static final Logger LOGGER = LoggerFactory.getLogger(PermissionView.class); private static final Logger LOGGER = LoggerFactory.getLogger(PermissionView.class);
@Inject @Inject
private ApplicationView applicationView; private ApplicationView applicationView;
@EJB @EJB
ApplicationPermissionControl applicationPermissionService; ApplicationPermissionControl applicationPermissionService;
private ApplicationPermissionEntity currentPermission; private ApplicationPermissionEntity currentPermission;
public List<ApplicationPermissionEntity> getAppPermissions() { public List<ApplicationPermissionEntity> getAppPermissions() {
return applicationPermissionService.getApplicationPermissions(applicationView.getCurrentApplication()); return applicationPermissionService.getApplicationPermissions(applicationView.getCurrentApplication());
} }
public void saveEditPermission() throws AccountException { public void saveEditPermission() throws AccountException {
if (currentPermission != null) { if (currentPermission != null) {
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)) {
FacesUtil.addErrorMessage("editDialogMessages", "Error", "Permission name must not be null"); FacesUtil.addErrorMessage("editDialogMessages", "Error", "Permission name must not be null");
} else if ((newPermissionDescription == null) || (newPermissionDescription.trim().length() == 0)) { } else if ((newPermissionDescription == null) || (newPermissionDescription.trim().length() == 0)) {
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, newPermissionDescription); 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);
FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " updated"); FacesUtil.addGlobalInfoMessage("Info", "Permission " + newPermissionName + " updated");
} }
} }
} }
} }
public ApplicationEntity getCurrentApplication() { public ApplicationEntity getCurrentApplication() {
if (applicationView.getCurrentApplication() == null) { if (applicationView.getCurrentApplication() == null) {
return null; return null;
} else { } else {
return applicationView.getCurrentApplication(); return applicationView.getCurrentApplication();
} }
} }
public void cancelEditPermission() { public void cancelEditPermission() {
this.currentPermission = null; this.currentPermission = null;
} }
public void newPermission() { public void newPermission() {
this.currentPermission = new ApplicationPermissionEntity(); this.currentPermission = new ApplicationPermissionEntity();
} }
public void editPermission() { public void editPermission() {
if (currentPermission == null) { if (currentPermission == null) {
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit"); FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit");
} }
} }
public void deletePermission() { public void deletePermission() {
if (currentPermission == null) { if (currentPermission == null) {
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit"); FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit");
} else { } else {
try { try {
applicationPermissionService.delete(currentPermission); applicationPermissionService.delete(currentPermission);
currentPermission = null; currentPermission = null;
} catch (AccountException ex) { } catch (AccountException ex) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex); LOGGER.debug("Detailed stacktrace", new Object[]{ex});
} else { }
LOGGER.debug(ex.toString()); FacesUtil.addGlobalErrorMessage("Error while deleting permission.", ex.toString());
} }
FacesUtil.addGlobalErrorMessage("Error while deleting permission.", ex.toString()); }
} }
}
} public boolean getCanEdit() {
return isPermissionSelected();
public boolean getCanEdit() { }
return isPermissionSelected();
} public boolean getCanDelete() {
return isPermissionSelected();
public boolean getCanDelete() { }
return isPermissionSelected();
} /* *** getter / setter *** */
/**
/* *** getter / setter *** */ * required setter for managedProperty
/** *
* required setter for managedProperty *
* * @param applicationView the injected applicationView
* */
* @param applicationView the injected applicationView public void setApplicationView(ApplicationView applicationView) {
*/ this.applicationView = applicationView;
public void setApplicationView(ApplicationView applicationView) { }
this.applicationView = applicationView;
} public ApplicationPermissionEntity getCurrentPermission() {
return currentPermission;
public ApplicationPermissionEntity getCurrentPermission() { }
return currentPermission;
} public void setCurrentPermission(ApplicationPermissionEntity newCurrentPermission) {
this.currentPermission = newCurrentPermission;
public void setCurrentPermission(ApplicationPermissionEntity newCurrentPermission) {
this.currentPermission = newCurrentPermission; }
} public boolean isPermissionSelected() {
return currentPermission != null;
public boolean isPermissionSelected() { }
return currentPermission != null; }
}
}

View File

@ -1,240 +1,236 @@
/* /*
* Copyright 2017 Joern Muehlencord <joern at muehlencord.de>. * Copyright 2017 Joern Muehlencord <joern at muehlencord.de>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.web.presentation; package de.muehlencord.shared.account.web.presentation;
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.application.control.ApplicationRoleControl;
import de.muehlencord.shared.account.business.application.entity.ApplicationPermissionEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationPermissionEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity;
import de.muehlencord.shared.jeeutil.FacesUtil; import de.muehlencord.shared.jeeutil.FacesUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.faces.view.ViewScoped; import javax.faces.view.ViewScoped;
import javax.inject.Named; import javax.inject.Inject;
import javax.inject.Inject; import javax.inject.Named;
import org.primefaces.event.SelectEvent; import org.primefaces.event.SelectEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* *
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
@ViewScoped @ViewScoped
@Named("roleView") @Named("roleView")
public class RoleView implements Serializable { public class RoleView implements Serializable {
private static final long serialVersionUID = 1669321020398119007L; private static final long serialVersionUID = 1669321020398119007L;
private static final Logger LOGGER = LoggerFactory.getLogger(RoleView.class); private static final Logger LOGGER = LoggerFactory.getLogger(RoleView.class);
@Inject @Inject
private ApplicationView applicationView; private ApplicationView applicationView;
@EJB @EJB
ApplicationRoleControl applicationRoleControl; ApplicationRoleControl applicationRoleControl;
private List<ApplicationRoleEntity> allRoles = null; private List<ApplicationRoleEntity> allRoles = null;
private List<ApplicationPermissionEntity> currentRolePermissions = null; private List<ApplicationPermissionEntity> currentRolePermissions = null;
private List<ApplicationPermissionEntity> missingApplicationsPermissions = null; private List<ApplicationPermissionEntity> missingApplicationsPermissions = null;
private ApplicationRoleEntity currentRole; private ApplicationRoleEntity currentRole;
private ApplicationPermissionEntity currentPermission; private ApplicationPermissionEntity currentPermission;
private ApplicationPermissionEntity newPermission; private ApplicationPermissionEntity newPermission;
public ApplicationEntity getCurrentApplication() { public ApplicationEntity getCurrentApplication() {
return applicationView.getCurrentApplication(); return applicationView.getCurrentApplication();
} }
public List<ApplicationRoleEntity> getAllRoles() { public List<ApplicationRoleEntity> getAllRoles() {
if (allRoles == null) { if (allRoles == null) {
allRoles = applicationRoleControl.getAllRoles(applicationView.getCurrentApplication()); allRoles = applicationRoleControl.getAllRoles(applicationView.getCurrentApplication());
} }
return allRoles; return allRoles;
} }
public void startNewRole() { public void startNewRole() {
this.currentRole = new ApplicationRoleEntity(applicationView.getCurrentApplication()); this.currentRole = new ApplicationRoleEntity(applicationView.getCurrentApplication());
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Created new current role: {}", currentRole.toString()); LOGGER.debug("Created new current role: {}", currentRole.toString());
} }
} }
public void cancelEditRole() { public void cancelEditRole() {
this.currentRole = null; this.currentRole = null;
} }
public void saveEditRole() { public void saveEditRole() {
if ((currentRole == null) || (currentRole.getRoleName() == null) || (currentRole.getRoleName().trim().length() == 0)) { if ((currentRole == null) || (currentRole.getRoleName() == null) || (currentRole.getRoleName().trim().length() == 0)) {
FacesUtil.addGlobalErrorMessage("Error", "Permission name must not be null"); FacesUtil.addGlobalErrorMessage("Error", "Permission name must not be null");
} else if (currentRole.getId() == null) { } else if (currentRole.getId() == null) {
applicationRoleControl.create(currentRole); applicationRoleControl.create(currentRole);
allRoles = null; // force reload allRoles = null; // force reload
FacesUtil.addGlobalInfoMessage("Info", "Role " + currentRole.getRoleName() + " created"); FacesUtil.addGlobalInfoMessage("Info", "Role " + currentRole.getRoleName() + " created");
} else { } else {
applicationRoleControl.update(currentRole); applicationRoleControl.update(currentRole);
allRoles = null; // force reload allRoles = null; // force reload
FacesUtil.addGlobalInfoMessage("Info", "Role " + currentRole.getRoleName() + " updated"); FacesUtil.addGlobalInfoMessage("Info", "Role " + currentRole.getRoleName() + " updated");
} }
} }
public void deleteRole() { public void deleteRole() {
if (currentRole == null) { if (currentRole == null) {
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit"); FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit");
} else { } else {
try { try {
applicationRoleControl.delete(currentRole); applicationRoleControl.delete(currentRole);
allRoles = null; // force reload allRoles = null; // force reload
currentRole = null; currentRole = null;
currentRolePermissions = null; currentRolePermissions = null;
} catch (AccountException ex) { } catch (AccountException ex) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex); LOGGER.debug("Detailed stacktrace", new Object[]{ex});
} else { }
LOGGER.debug(ex.toString());
} FacesUtil.addGlobalErrorMessage("Error while deleting permission.", ex.toString());
FacesUtil.addGlobalErrorMessage("Error while deleting permission.", ex.toString()); }
} }
} }
}
public boolean getRoleSelected() {
public boolean getRoleSelected() { return currentRole != null;
return currentRole != null; }
}
public boolean getPermissionSelected() {
public boolean getPermissionSelected() { return currentPermission != null;
return currentPermission != null; }
}
public boolean getMissingPermissionAvailable() {
public boolean getMissingPermissionAvailable() { return ((missingApplicationsPermissions != null) && (!missingApplicationsPermissions.isEmpty()));
return ((missingApplicationsPermissions != null) && (!missingApplicationsPermissions.isEmpty())); }
}
public void onRoleSelect(SelectEvent event) {
public void onRoleSelect(SelectEvent event) { currentRolePermissions = null;
currentRolePermissions = null; currentRolePermissions = getRolePermissions();
currentRolePermissions = getRolePermissions(); missingApplicationsPermissions = null;
missingApplicationsPermissions = null; missingApplicationsPermissions = getMissingPermissions();
missingApplicationsPermissions = getMissingPermissions(); }
}
public List<ApplicationPermissionEntity> getRolePermissions() {
public List<ApplicationPermissionEntity> getRolePermissions() { if (currentRole == null) {
if (currentRole == null) { currentRolePermissions = new ArrayList<>();
currentRolePermissions = new ArrayList<>(); return currentRolePermissions;
return currentRolePermissions; } else {
} else { if (currentRolePermissions == null) {
if (currentRolePermissions == null) { try {
try { currentRolePermissions = applicationRoleControl.getRolePermissions(currentRole);
currentRolePermissions = applicationRoleControl.getRolePermissions(currentRole); } catch (AccountException ex) {
} catch (AccountException ex) { LOGGER.error(ex.getMessage());
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(ex.toString(), ex); LOGGER.debug("Detailed stacktrace", new Object[]{ex});
} else { }
LOGGER.debug(ex.toString());
} FacesUtil.addGlobalErrorMessage("Error while fetching role permissions", "see log for details");
FacesUtil.addGlobalErrorMessage("Error while fetching role permissions", "see log for details"); currentRolePermissions = new ArrayList<>();
currentRolePermissions = new ArrayList<>(); }
} }
} return currentRolePermissions;
return currentRolePermissions; }
} }
}
public List<ApplicationPermissionEntity> getMissingPermissions() {
public List<ApplicationPermissionEntity> getMissingPermissions() { if (currentRole == null) {
if (currentRole == null) { missingApplicationsPermissions = new ArrayList<>();
missingApplicationsPermissions = new ArrayList<>(); return missingApplicationsPermissions;
return missingApplicationsPermissions; } else {
} else { if (missingApplicationsPermissions == null) {
if (missingApplicationsPermissions == null) { missingApplicationsPermissions = applicationRoleControl.getNotAssignedApplicationPermissions(currentRole);
missingApplicationsPermissions = applicationRoleControl.getNotAssignedApplicationPermissions(currentRole);
}
} return missingApplicationsPermissions;
return missingApplicationsPermissions; }
} }
}
public void addRolePermission() {
public void addRolePermission() { if (newPermission == null) {
if (newPermission == null) { FacesUtil.addGlobalErrorMessage("Error", "Please select a new permission first");
FacesUtil.addGlobalErrorMessage("Error", "Please select a new permission first"); } else {
} else { try {
try { applicationRoleControl.addPermission(currentRole, newPermission);
applicationRoleControl.addPermission(currentRole, newPermission); currentRolePermissions = null;
currentRolePermissions = null; missingApplicationsPermissions = null;
missingApplicationsPermissions = null; } catch (AccountException ex) {
} catch (AccountException ex) { if (LOGGER.isDebugEnabled()) {
if (LOGGER.isDebugEnabled()) { LOGGER.debug("Detailed stacktrace", new Object[]{ex});
LOGGER.debug(ex.toString(), ex); }
} else {
LOGGER.debug(ex.toString()); FacesUtil.addGlobalErrorMessage("Error while adding permission", ex.getMessage());
} }
FacesUtil.addGlobalErrorMessage("Error while adding permission", ex.getMessage()); }
}
} }
} public void removeRolePermission() {
if (currentPermission == null) {
public void removeRolePermission() { FacesUtil.addGlobalErrorMessage("Error", "Please select a permission first");
if (currentPermission == null) { } else {
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission first"); try {
} else { applicationRoleControl.removePermission(currentRole, currentPermission);
try { currentRolePermissions = null;
applicationRoleControl.removePermission(currentRole, currentPermission); missingApplicationsPermissions = null;
currentRolePermissions = null; } catch (AccountException ex) {
missingApplicationsPermissions = null; if (LOGGER.isDebugEnabled()) {
} catch (AccountException ex) { LOGGER.debug("Detailed stacktrace", new Object[]{ex});
if (LOGGER.isDebugEnabled()) { }
LOGGER.debug(ex.toString(), ex); FacesUtil.addGlobalErrorMessage("Error while adding permission", ex.getMessage());
} else { }
LOGGER.debug(ex.toString()); }
}
FacesUtil.addGlobalErrorMessage("Error while adding permission", ex.getMessage()); }
}
} /* *** getter / setter *** */
public void setApplicationView(ApplicationView applicationView) {
} this.applicationView = applicationView;
}
/* *** getter / setter *** */
public void setApplicationView(ApplicationView applicationView) { public ApplicationRoleEntity getCurrentRole() {
this.applicationView = applicationView; return currentRole;
} }
public ApplicationRoleEntity getCurrentRole() { public void setCurrentRole(ApplicationRoleEntity currentRole) {
return currentRole; this.currentRole = currentRole;
} }
public void setCurrentRole(ApplicationRoleEntity currentRole) { public ApplicationPermissionEntity getCurrentPermission() {
this.currentRole = currentRole; return currentPermission;
} }
public ApplicationPermissionEntity getCurrentPermission() { public void setCurrentPermission(ApplicationPermissionEntity currentPermission) {
return currentPermission; this.currentPermission = currentPermission;
} }
public void setCurrentPermission(ApplicationPermissionEntity currentPermission) { public ApplicationPermissionEntity getNewPermission() {
this.currentPermission = currentPermission; return newPermission;
} }
public ApplicationPermissionEntity getNewPermission() { public void setNewPermission(ApplicationPermissionEntity newPermission) {
return newPermission; this.newPermission = newPermission;
} }
public void setNewPermission(ApplicationPermissionEntity newPermission) { }
this.newPermission = newPermission;
}
}

View File

@ -1,6 +1,6 @@
package de.muehlencord.shared.account.web.presentation; package de.muehlencord.shared.account.web.presentation;
import de.muehlencord.shared.account.business.application.boundary.ApplicationService; import de.muehlencord.shared.account.business.application.control.ApplicationControl;
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 java.util.UUID;
@ -26,7 +26,7 @@ public class UniqueApplicationValidator implements Validator, Serializable {
private static final Logger LOGGER = LoggerFactory.getLogger(UniqueApplicationValidator.class); private static final Logger LOGGER = LoggerFactory.getLogger(UniqueApplicationValidator.class);
@Inject @Inject
ApplicationService applicationService; ApplicationControl applicationService;
@Override @Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {

View File

@ -41,6 +41,7 @@
<i class="fa fa-circle"></i> <i class="fa fa-circle"></i>
<span>Roles</span> <span>Roles</span>
</p:link> </p:link>
<a href="footer.xhtml"></a>
</li> </li>
</shiro:hasAnyPermission> </shiro:hasAnyPermission>
<li> <li>

View File

@ -1,316 +1,341 @@
<?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" 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:h="http://xmlns.jcp.org/jsf/html"
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:o="http://omnifaces.org/ui"
xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite"> xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite"
xmlns:shiro="http://shiro.apache.org/tags">
<ui:define name="title">
Account Overview <ui:define name="title">
</ui:define> Account Overview
</ui:define>
<ui:define name="description">
for #{applicationView.currentApplication.applicationName} <ui:define name="description">
</ui:define> for #{applicationView.currentApplication.applicationName}
</ui:define>
<ui:define name="body">
<p:panel styleClass="box-solid" rendered="#{! empty applicationView.currentApplication}"> <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:panel id="buttonPanel" styleClass="box-primary" style="margin-bottom:20px"> <p:spacer height="10px" />
<div class="ui-g ui-fluid"> <p:panel id="buttonPanel" styleClass="box-primary" style="margin-bottom:20px">
<div class="col-sm-12 col-md-4" style="margin-top:10px"> <div class="ui-g ui-fluid">
<div class="ui-inputgroup" >
<h:outputLabel for="includeDisabledCheckbox" value="Include disabled accounts?" /> <shiro:hasPermission name="#{permissionConstants.accountDelete}">
<p:inputSwitch id="includeDisabledCheckbox" value="#{accountView.showDisabledAccounts}" styleClass="btn-teal btn-block" > <div class="col-sm-12 col-md-4" style="margin-top:10px">
<p:ajax listener="#{accountView.showDisabledAccountsChange}" update="accountTable" /> <div class="ui-inputgroup" >
</p:inputSwitch> <h:outputLabel for="includeDisabledCheckbox" value="Include disabled accounts?" />
</div> <p:inputSwitch id="includeDisabledCheckbox" value="#{accountView.showDisabledAccounts}" styleClass="btn-teal btn-block" >
</div> <p:ajax listener="#{accountView.showDisabledAccountsChange}" update="accountTable" />
</p:inputSwitch>
<div class="col-sm-12 col-md-2"> </div>
<p:commandButton value="New" id="newButton" icon="fa fa-plus" </div>
update="editDialog" oncomplete="PF('editDialogVar').show();" </shiro:hasPermission>
actionListener="#{accountView.newAccount}" styleClass="btn-primary btn-block" />
</div> <shiro:hasPermission name="#{permissionConstants.accountAdd}">
<div class="col-sm-12 col-md-2"> <div class="col-sm-12 col-md-2">
<p:commandButton value="Edit" id="editButton" icon="fa fa-pencil" <p:commandButton value="New" id="newButton" icon="fa fa-plus"
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.newAccount}" styleClass="btn-primary btn-block" />
</div> </div>
<div class="col-sm-12 col-md-2"> </shiro:hasPermission>
<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"> <shiro:hasPermission name="#{permissionConstants.accountEdit}">
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" /> <div class="col-sm-12 col-md-2">
</p:commandButton> <p:commandButton value="Edit" id="editButton" icon="fa fa-pencil"
</div> update="editDialog" oncomplete="PF('editDialogVar').show();"
actionListener="#{accountView.editAccount}" disabled="#{!accountView.accountSelected}" styleClass="btn-teal btn-block" />
<div class="col-sm-12 col-md-2"> </div>
<c:if test="#{empty accountView.currentAccount.accountLogin}"> </shiro:hasPermission>
<p:commandButton value="Add login" id="addLoginButton" icon="fa fa-plus" disabled="#{!accountView.accountSelected}"
update="editLoginDialog" oncomplete="PF('editLoginDialogVar').show();" <shiro:hasPermission name="#{permissionConstants.accountDelete}">
action="#{accountView.addAccountLogin}" styleClass="btn-teal btn-block"> <div class="col-sm-12 col-md-2">
</p:commandButton> <p:commandButton value="Delete" id="deleteButton" icon="fa fa-trash-o"
</c:if> update=":accountForm:accountTable" action="#{accountView.deleteAccount}" disabled="#{accountView.accountSelected eq false or accountView.currentLoggedInUser eq true}" styleClass="btn-danger btn-block">
<c:if test="#{!empty accountView.currentAccount.accountLogin}"> <p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
<p:splitButton value="Edit login" id="editLoginButton" icon="fa fa-pencil" disabled="#{!accountView.accountSelected}" </p:commandButton>
update="editLoginDialog" oncomplete="PF('editLoginDialogVar').show();" </div>
action="#{accountView.editAccountLogin}" styleClass="btn-success btn-block"> </shiro:hasPermission>
<p:menuitem value="Delete login" icon="fa fa-trash-o" disabled="#{accountView.currentLoggedInUser}" <shiro:hasPermission name="#{permissionConstants.accountsCombined}">
update="accountTable,buttonPanel" styleClass="btn-danger btn-block" <div class="col-sm-12 col-md-2">
action="#{accountView.deleteAccountLogin}" > <shiro:hasPermission name="#{permissionConstants.accountLoginAdd}">
<c:if test="#{empty accountView.currentAccount.accountLogin}">
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" /> <p:commandButton value="Add login" id="addLoginButton" icon="fa fa-plus" disabled="#{!accountView.accountSelected}"
</p:menuitem> update="editLoginDialog" oncomplete="PF('editLoginDialogVar').show();"
</p:splitButton> action="#{accountView.addAccountLogin}" styleClass="btn-teal btn-block">
</c:if> </p:commandButton>
</div> </c:if>
</div> </shiro:hasPermission>
</p:panel>
<c:if test="#{!empty accountView.currentAccount.accountLogin}">
<p:splitButton value="Edit login" id="editLoginButton" icon="fa fa-pencil" disabled="#{!accountView.accountSelected}" styleClass="btn-success btn-block">
<composite:confirmationDialog /> <shiro:hasPermission name="#{permissionConstants.accountLoginEdit}">
</h:form> <p:menuitem value="Edit login" icon="fa fa-pencil" disabled="#{!accountView.accountSelected}"
</p:panel> update="editLoginDialog" oncomplete="PF('editLoginDialogVar').show();"
action="#{accountView.editAccountLogin}" >
</p:menuitem>
<p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600" </shiro:hasPermission>
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"> <shiro:hasPermission name="#{permissionConstants.accountLoginDelete}">
<p:autoUpdate /> <p:menuitem value="Delete login" icon="fa fa-trash-o" disabled="#{accountView.currentLoggedInUser}"
</p:messages> update="accountTable,buttonPanel" styleClass="btn-danger btn-block"
action="#{accountView.deleteAccountLogin}" >
<div class="ui-g ui-fluid"> <p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
<div class="col-sm-12 col-md-3"> </p:menuitem>
<p:outputLabel for="username" value="Username" /> </shiro:hasPermission>
</div>
<div class="col-sm-12 col-md-6"> </p:splitButton>
<c:if test="#{accountView.currentAccount.createdBy != null}"> </c:if>
<h:outputText id="username" value="#{accountView.currentAccount.username}" /> </div>
</c:if> </shiro:hasPermission>
<c:if test="#{accountView.currentAccount.createdBy == null}"> </div>
<p:inputText id="username" value="#{accountView.currentAccount.username}" /> </p:panel>
</c:if>
</div>
<div class="col-sm-12 col-md-3">
<p:message for="username"><p:autoUpdate /></p:message> <composite:confirmationDialog />
</div> </h:form>
</p:panel>
<div class="col-sm-12 col-md-3">
<p:outputLabel for="lastname" value="Lastname" />
</div> <p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600"
<div class="col-sm-12 col-md-6"> modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" >
<p:inputText id="lastname" value="#{accountView.currentAccount.lastname}" size="40" maxlength="100"/> <h:form id="editDialogForm">
</div> <p:messages id="editDialogMessages" showDetail="true" showIcon="true" showSummary="true">
<div class="col-sm-12 col-md-3 "> <p:autoUpdate />
<p:message for="lastname"> <p:autoUpdate /></p:message> </p:messages>
</div>
<div class="ui-g ui-fluid">
<div class="col-sm-12 col-md-3"> <div class="col-sm-12 col-md-3">
<p:outputLabel for="firstname" value="Firstname" /> <p:outputLabel for="username" value="Username" />
</div> </div>
<div class="col-sm-12 col-md-6"> <div class="col-sm-12 col-md-6">
<p:inputText id="firstname" value="#{accountView.currentAccount.firstname}" size="40" maxlength="100" /> <c:if test="#{accountView.currentAccount.createdBy != null}">
</div> <h:outputText id="username" value="#{accountView.currentAccount.username}" />
<div class="col-sm-12 col-md-3"> </c:if>
<p:message for="firstname"> <p:autoUpdate /></p:message> <c:if test="#{accountView.currentAccount.createdBy == null}">
</div> <p:inputText id="username" value="#{accountView.currentAccount.username}" />
</c:if>
<div class="col-sm-12 col-md-3"> </div>
<p:outputLabel for="emailaddress" value="emailaddress" /> <div class="col-sm-12 col-md-3">
</div> <p:message for="username"><p:autoUpdate /></p:message>
<div class="col-sm-12 col-md-6"> </div>
<p:inputText id="emailaddress" value="#{accountView.currentAccount.emailaddress}" size="40" maxlength="200">
<f:validator validatorId="de.muehlencord.shared.jeeutil.validator.EmailValidator" /> <div class="col-sm-12 col-md-3">
</p:inputText> <p:outputLabel for="lastname" value="Lastname" />
</div> </div>
<div class="col-sm-12 col-md-3"> <div class="col-sm-12 col-md-6">
<p:message for="emailaddress"> <p:autoUpdate /></p:message> <p:inputText id="lastname" value="#{accountView.currentAccount.lastname}" size="40" maxlength="100"/>
</div> </div>
<div class="col-sm-12 col-md-3 ">
<c:if test="#{accountView.currentAccount.username != null}"> <p:message for="lastname"> <p:autoUpdate /></p:message>
</div>
<div class="col-sm-12 col-md-3">
<p:outputLabel for="status" value="Status" /> <div class="col-sm-12 col-md-3">
</div> <p:outputLabel for="firstname" value="Firstname" />
<div class="col-sm-12 col-md-6"> </div>
<p:selectOneMenu id="status" value="#{accountView.currentAccount.status}" > <div class="col-sm-12 col-md-6">
<f:selectItems value="#{accountView.statusList}" /> <p:inputText id="firstname" value="#{accountView.currentAccount.firstname}" size="40" maxlength="100" />
</p:selectOneMenu> </div>
</div> <div class="col-sm-12 col-md-3">
<div class="col-sm-12 col-md-3"> <p:message for="firstname"> <p:autoUpdate /></p:message>
<p:message for="status" /> </div>
</div>
<div class="col-sm-12 col-md-3">
<div class="col-sm-12 col-md-3"> <p:outputLabel for="emailaddress" value="emailaddress" />
<p:outputLabel for="createdon" value="Created on" /> </div>
</div> <div class="col-sm-12 col-md-6">
<div class="col-sm-12 col-md-6"> <p:inputText id="emailaddress" value="#{accountView.currentAccount.emailaddress}" size="40" maxlength="200">
<h:outputText id="createdon" value="#{accountView.currentAccount.createdOn}" /> <f:validator validatorId="de.muehlencord.shared.jeeutil.validator.EmailValidator" />
</div> </p:inputText>
<div class="col-sm-12 col-md-3"> </div>
<p:message for="createdon" /> <div class="col-sm-12 col-md-3">
</div> <p:message for="emailaddress"> <p:autoUpdate /></p:message>
</div>
<div class="col-sm-12 col-md-3">
<p:outputLabel for="createdby" value="Created by" /> <c:if test="#{accountView.currentAccount.username != null}">
</div>
<div class="col-sm-12 col-md-6"> <div class="col-sm-12 col-md-3">
<h:outputText id="createdby" value="#{accountView.currentAccount.createdBy}" /> <p:outputLabel for="status" value="Status" />
</div> </div>
<div class="col-sm-12 col-md-3"> <div class="col-sm-12 col-md-6">
<p:message for="createdby" /> <p:selectOneMenu id="status" value="#{accountView.currentAccount.status}" >
</div> <f:selectItems value="#{accountView.statusList}" />
</p:selectOneMenu>
<div class="col-sm-12 col-md-3"> </div>
<p:outputLabel for="lastupdatedon" value="Last updated on" /> <div class="col-sm-12 col-md-3">
</div> <p:message for="status" />
<div class="col-sm-12 col-md-6"> </div>
<h:outputText id="lastupdatedon" value="#{accountView.currentAccount.lastUpdatedOn}" />
</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:message for="lastupdatedon" /> </div>
</div> <div class="col-sm-12 col-md-6">
<h:outputText id="createdon" value="#{accountView.currentAccount.createdOn}" />
<div class="col-sm-12 col-md-3"> </div>
<p:outputLabel for="lastupdatedby" value="Last updated by" /> <div class="col-sm-12 col-md-3">
</div> <p:message for="createdon" />
<div class="col-sm-12 col-md-6"> </div>
<h:outputText id="lastupdatedby" value="#{accountView.currentAccount.lastUpdatedBy}" />
</div> <div class="col-sm-12 col-md-3">
<div class="col-sm-12 col-md-3"> <p:outputLabel for="createdby" value="Created by" />
<p:message for="lastupdatedby" /> </div>
</div> <div class="col-sm-12 col-md-6">
</c:if> <h:outputText id="createdby" value="#{accountView.currentAccount.createdBy}" />
</div>
<div class="col-sm-12 col-md-3">
<div class="col-sm-12 col-md-3"> <p:message for="createdby" />
<p:outputLabel for="roles" value="Roles" /> </div>
</div>
<div class="col-sm-12 col-md-6"> <div class="col-sm-12 col-md-3">
<p:selectManyMenu id="roles" var="role" label="#{role.roleName}" value="#{accountView.currentAccountRoles}" converter="omnifaces.SelectItemsConverter" required="false" > <p:outputLabel for="lastupdatedon" value="Last updated on" />
<f:selectItems value="#{accountView.allApplicationRoles}" var="roleItem" itemValue="#{roleItem}" /> </div>
<p:column> <div class="col-sm-12 col-md-6">
<h:outputText value="#{role.application.applicationName}-#{role.roleName}"/> <h:outputText id="lastupdatedon" value="#{accountView.currentAccount.lastUpdatedOn}" />
</p:column> </div>
</p:selectManyMenu> <div class="col-sm-12 col-md-3">
</div> <p:message for="lastupdatedon" />
<div class="col-sm-12 col-md-3"> </div>
<p:message for="roles" />
</div> <div class="col-sm-12 col-md-3">
<p:outputLabel for="lastupdatedby" value="Last updated by" />
</div>
<div class="col-sm-12 col-md-6"> <div class="col-sm-12 col-md-6">
<p:spacer height="10px" /> <h:outputText id="lastupdatedby" value="#{accountView.currentAccount.lastUpdatedBy}" />
<p:commandButton value="Save" action="#{accountView.saveEditAccount}" styleClass="btn-primary btn-block" </div>
oncomplete="if (args &amp;&amp; !args.validationFailed) PF('editDialogVar').hide();" update=":accountForm:accountTable" /> <div class="col-sm-12 col-md-3">
</div> <p:message for="lastupdatedby" />
<div class="col-sm-12 col-md-6"> </div>
<p:spacer height="10px" /> </c:if>
<p:commandButton value="Cancel" action="#{accountView.cancelEditAccount}" immediate="true" styleClass="btn-teal btn-block"
oncomplete="PF('editDialogVar').hide();" />
</div> <div class="col-sm-12 col-md-3">
</div> <p:outputLabel for="roles" value="Roles" />
</h:form> </div>
</p:dialog> <div class="col-sm-12 col-md-6">
<p:selectManyMenu id="roles" var="role" label="#{role.roleName}" value="#{accountView.currentAccountRoles}" converter="omnifaces.SelectItemsConverter" required="false" >
<p:dialog id="editLoginDialog" widgetVar="editLoginDialogVar" header="Edit account login" width="600" <f:selectItems value="#{accountView.allApplicationRoles}" var="roleItem" itemValue="#{roleItem}" />
modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" > <p:column>
<h:form id="editLoginDialogForm"> <h:outputText value="#{role.application.applicationName}-#{role.roleName}"/>
<p:messages id="editLoginDialogMessages" showDetail="true" showIcon="true" showSummary="true"> </p:column>
<p:autoUpdate /> </p:selectManyMenu>
</p:messages> </div>
<div class="col-sm-12 col-md-3">
<div class="ui-g ui-fluid"> <p:message for="roles" />
<o:validateMultiple id="myId" components="password repeatPassword" </div>
validator="#{accountView.validatePasswords}" message="#{msgs.passwords_different}" />
<div class="col-sm-12"> <div class="col-sm-12 col-md-6">
<p:outputLabel value="Enter a new password or keep values empty to keep existing / autogenrated value" /> <p:spacer height="10px" />
</div> <p:commandButton value="Save" action="#{accountView.saveEditAccount}" styleClass="btn-primary btn-block"
oncomplete="if (args &amp;&amp; !args.validationFailed) PF('editDialogVar').hide();" update=":accountForm:accountTable" />
<div class="col-sm-12 col-md-3"> </div>
<p:outputLabel for="password" value="Password" /> <div class="col-sm-12 col-md-6">
</div> <p:spacer height="10px" />
<div class="col-sm-12 col-md-6"> <p:commandButton value="Cancel" action="#{accountView.cancelEditAccount}" immediate="true" styleClass="btn-teal btn-block"
<p:password id="password" value="#{accountView.password}" maxlength="32" size="32" required="false"/> oncomplete="PF('editDialogVar').hide();" />
</div> </div>
<div class="col-sm-12 col-md-3"> </div>
<p:message for="password" /> </h:form>
</div> </p:dialog>
<div class="col-sm-12 col-md-3"> <p:dialog id="editLoginDialog" widgetVar="editLoginDialogVar" header="Edit account login" width="600"
<p:outputLabel for="repeatPassword" value="repeat Password" /> modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" >
</div> <h:form id="editLoginDialogForm">
<div class="col-sm-12 col-md-6"> <p:messages id="editLoginDialogMessages" showDetail="true" showIcon="true" showSummary="true">
<p:password id="repeatPassword" value="#{accountView.repeatPassword}" maxlength="32" size="32" required="false"/> <p:autoUpdate />
</div> </p:messages>
<div class="col-sm-12 col-md-3">
<p:message for="repeatPassword" /> <div class="ui-g ui-fluid">
</div> <o:validateMultiple id="myId" components="password repeatPassword"
validator="#{accountView.validatePasswords}" message="#{msgs.passwords_different}" />
<div class="col-sm-12 col-md-6">
<p:spacer height="10px" /> <div class="col-sm-12">
<p:commandButton value="Save" action="#{accountView.saveEditAccountLogin}" styleClass="btn-primary btn-block" <p:outputLabel value="Enter a new password or keep values empty to keep existing / autogenrated value" />
oncomplete="if (args &amp;&amp; !args.validationFailed) PF('editLoginDialogVar').hide();" update=":accountForm:accountTable,:accountForm:buttonPanel" /> </div>
</div>
<div class="col-sm-12 col-md-6"> <div class="col-sm-12 col-md-3">
<p:spacer height="10px" /> <p:outputLabel for="password" value="Password" />
<p:commandButton value="Cancel" action="#{accountView.cancelEditAccountLogin}" immediate="true" styleClass="btn-teal btn-block" </div>
oncomplete="PF('editLoginDialogVar').hide();" /> <div class="col-sm-12 col-md-6">
</div> <p:password id="password" value="#{accountView.password}" maxlength="32" size="32" required="false"/>
</div> </div>
</h:form> <div class="col-sm-12 col-md-3">
</p:dialog> <p:message for="password" />
</div>
</ui:define>
<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:composition> </ui:composition>

View File

@ -21,6 +21,7 @@ import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity;
import de.muehlencord.shared.account.business.account.entity.AccountStatus; import de.muehlencord.shared.account.business.account.entity.AccountStatus;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity;
import de.muehlencord.shared.account.business.instance.boundary.ApplicationPermissions;
import de.muehlencord.shared.account.business.mail.boundary.MailService; import de.muehlencord.shared.account.business.mail.boundary.MailService;
import de.muehlencord.shared.account.business.mail.entity.MailException; import de.muehlencord.shared.account.business.mail.entity.MailException;
import de.muehlencord.shared.account.util.AccountPU; import de.muehlencord.shared.account.util.AccountPU;
@ -30,6 +31,7 @@ import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.ejb.Stateless; import javax.ejb.Stateless;
import javax.inject.Inject; import javax.inject.Inject;
@ -63,12 +65,31 @@ public class AccountControl implements Serializable {
@AccountPU @AccountPU
EntityManager em; EntityManager em;
public List<AccountEntity> getAllAccounts(boolean includeDisabled) {
List<AccountEntity> resultList;
if (includeDisabled) {
resultList = getAllAccounts();
} else {
resultList = getActiveAccounts();
}
if (SecurityUtil.checkPermission(ApplicationPermissions.ACCOUNT_LIST)) {
return resultList;
} else {
String currentUserName = SecurityUtils.getSubject().getPrincipal().toString();
return resultList.stream()
.filter(account -> account.getAccountLogin() != null)
.filter (account -> account.getUsername().equals (currentUserName))
.collect(Collectors.toList());
}
}
/** /**
* returns a list of active accounts * returns a list of active accounts
* *
* @return a list of active accounts * @return a list of active accounts
*/ */
public List<AccountEntity> getActiveAccounts() { private List<AccountEntity> getActiveAccounts() {
Query query = em.createQuery("SELECT a FROM AccountEntity a WHERE a.status <> :status", AccountEntity.class); Query query = em.createQuery("SELECT a FROM AccountEntity a WHERE a.status <> :status", AccountEntity.class);
query.setParameter("status", AccountStatus.DISABLED.name()); query.setParameter("status", AccountStatus.DISABLED.name());
return query.getResultList(); return query.getResultList();
@ -79,18 +100,11 @@ public class AccountControl implements Serializable {
* *
* @return a list of active accounts * @return a list of active accounts
*/ */
public List<AccountEntity> getAllAccounts() { private List<AccountEntity> getAllAccounts() {
Query query = em.createNamedQuery("AccountEntity.findAll"); Query query = em.createNamedQuery("AccountEntity.findAll");
return query.getResultList(); return query.getResultList();
} }
public List<AccountEntity> getAccounts(boolean includeDisabled) {
if (includeDisabled) {
return getAllAccounts();
} else {
return getActiveAccounts();
}
}
public AccountEntity getAccountEntity(String userName, boolean loadRoles) { public AccountEntity getAccountEntity(String userName, boolean loadRoles) {
StringBuilder queryBuilder = new StringBuilder(); StringBuilder queryBuilder = new StringBuilder();

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.business.accountconfig.entity; package de.muehlencord.shared.account.business.account.entity;
/** /**
* *

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.business.accountconfig.entity; package de.muehlencord.shared.account.business.account.entity;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -21,14 +21,14 @@ import de.muehlencord.shared.account.util.SecurityError;
* *
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
public enum ApplicationServiceError implements SecurityError { public enum ApplicationError implements SecurityError {
LISTALL_DENIED("1000", "listall_denied"); LIST_DENIED("1000", "list_denied");
private final String errorCode; private final String errorCode;
private final String messageKey; private final String messageKey;
private ApplicationServiceError(String errorCode, String messageKey) { private ApplicationError(String errorCode, String messageKey) {
this.errorCode = errorCode; this.errorCode = errorCode;
this.messageKey = messageKey; this.messageKey = messageKey;
} }

View File

@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.business.application.boundary; package de.muehlencord.shared.account.business.application.control;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import de.muehlencord.shared.account.business.instance.boundary.ApplicationPermissions;
import de.muehlencord.shared.account.util.AccountPU; import de.muehlencord.shared.account.util.AccountPU;
import de.muehlencord.shared.account.util.AccountSecurityException; import de.muehlencord.shared.account.util.AccountSecurityException;
import de.muehlencord.shared.account.util.SecurityUtil; import de.muehlencord.shared.account.util.SecurityUtil;
@ -28,6 +29,8 @@ import javax.inject.Inject;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.Query; import javax.persistence.Query;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -36,10 +39,10 @@ import org.slf4j.LoggerFactory;
* @author Joern Muehlencord <joern at muehlencord.de> * @author Joern Muehlencord <joern at muehlencord.de>
*/ */
@Stateless @Stateless
public class ApplicationService implements Serializable { public class ApplicationControl implements Serializable {
private static final long serialVersionUID = 4262608935325326191L; private static final long serialVersionUID = 4262608935325326191L;
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationService.class); private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationControl.class);
@Inject @Inject
@AccountPU @AccountPU
@ -50,14 +53,34 @@ public class ApplicationService implements Serializable {
} }
public List<ApplicationEntity> getAllApplications() throws AccountSecurityException { public List<ApplicationEntity> getAllApplications() throws AccountSecurityException {
SecurityUtil.checkPermission(ApplicationPermissions.APP_LISTALL, ApplicationServiceError.LISTALL_DENIED); List<ApplicationEntity> resultList = new ArrayList<>();
Query query = em.createNamedQuery("ApplicationEntity.findAll"); Query query = em.createNamedQuery("ApplicationEntity.findAll");
List<ApplicationEntity> resultList = query.getResultList(); List<ApplicationEntity> queryList = query.getResultList();
if (resultList == null) { if ((queryList == null) || (queryList.isEmpty())) {
return new ArrayList<>();
} else {
return resultList; return resultList;
} }
Subject currentUser = SecurityUtils.getSubject();
if (currentUser == null)
return resultList;
String userName = currentUser.getPrincipal().toString();
queryList.stream().forEach(app -> {
String applicationName = app.getApplicationName(); // TODO add unique short cut to db model
applicationName = applicationName.toLowerCase();
applicationName = applicationName.replace (" ", "");
String permissionName = ApplicationPermissions.APP_LIST.getName()+":"+applicationName;
boolean userHasPermissionToListApplication = SecurityUtil.checkPermission (permissionName);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("validating if user {} has permission {} = {}", userName, permissionName, userHasPermissionToListApplication);
}
if (userHasPermissionToListApplication) {
resultList.add (app);
}
});
return resultList;
} }
@Transactional @Transactional

View File

@ -15,8 +15,8 @@
*/ */
package de.muehlencord.shared.account.business.config.boundary; package de.muehlencord.shared.account.business.config.boundary;
import de.muehlencord.shared.account.business.accountconfig.entity.AccountConfigurationKey; import de.muehlencord.shared.account.business.account.entity.AccountConfigurationKey;
import de.muehlencord.shared.account.business.accountconfig.entity.AccountConfigurationValue; import de.muehlencord.shared.account.business.account.entity.AccountConfigurationValue;
import de.muehlencord.shared.account.business.config.entity.ConfigException; import de.muehlencord.shared.account.business.config.entity.ConfigException;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.enterprise.context.Dependent; import javax.enterprise.context.Dependent;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.business.application.boundary; package de.muehlencord.shared.account.business.instance.boundary;
import de.muehlencord.shared.account.util.Permission; import de.muehlencord.shared.account.util.Permission;
@ -23,7 +23,7 @@ import de.muehlencord.shared.account.util.Permission;
*/ */
public enum ApplicationPermissions implements Permission { public enum ApplicationPermissions implements Permission {
APP_LISTALL("application:listall", "Allows to list all avaiable applications"), APP_LIST("application:list", "Allows to list all avaiable applications"),
APP_ADD("application:add", "Allow to add a new application"), APP_ADD("application:add", "Allow to add a new application"),
APP_EDIT("application:edit", "Allow to edit an application"), APP_EDIT("application:edit", "Allow to edit an application"),
APP_DELETE("application:delete", "Allow to delete an application"), APP_DELETE("application:delete", "Allow to delete an application"),
@ -34,7 +34,14 @@ public enum ApplicationPermissions implements Permission {
ROLE_EDIT("role:edit", "Allow to edit a role"), ROLE_EDIT("role:edit", "Allow to edit a role"),
ROLE_DELETE("role:delete", "Allow to delete a role"), ROLE_DELETE("role:delete", "Allow to delete a role"),
ROLE_PERMISSION_ASSIGN("role:permission:assign", "Allow to assign a permission to role"), ROLE_PERMISSION_ASSIGN("role:permission:assign", "Allow to assign a permission to role"),
ROLE_PERMISSION_REVOKE("role:permission:revoke", "All ow to revoke a permission from a role"); ROLE_PERMISSION_REVOKE("role:permission:revoke", "All ow to revoke a permission from a role"),
ACCOUNT_LIST ("account:list", "Allow to list all accounts of an application"),
ACCOUNT_ADD ("account:add", "Allow to create a new account"),
ACCOUNT_EDIT ("account:edit", "Allow to edit an existing account"),
ACCOUNT_DELETE ("account:delete", "Allow to delete an existing account"),
ACCOUNT_LOGIN_ADD ("account:login:add", "Allow to add a login to an account"),
ACCOUNT_LOGIN_EDIT ("account:login:edit", "Allow to overwrite the password of an account"),
ACCOUNT_LOGIN_DELETE ("account:login:delete", "Allow to delete the login of an account");
private final String name; private final String name;
private final String description; private final String description;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.business.application.boundary; package de.muehlencord.shared.account.business.instance.boundary;
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.boundary.ConfigService; import de.muehlencord.shared.account.business.config.boundary.ConfigService;

View File

@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.muehlencord.shared.account.business.application.control; package de.muehlencord.shared.account.business.instance.control;
import de.muehlencord.shared.account.business.application.boundary.ApplicationService; import de.muehlencord.shared.account.business.application.control.ApplicationControl;
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -40,7 +40,7 @@ public class ApplicationController {
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationController.class); private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationController.class);
@EJB @EJB
ApplicationService applicationService; ApplicationControl applicationService;
private String version; private String version;
private String buildDate; private String buildDate;

View File

@ -16,7 +16,7 @@
package de.muehlencord.shared.account.business.mail.boundary; package de.muehlencord.shared.account.business.mail.boundary;
import de.muehlencord.shared.account.business.mail.entity.MailTemplateException; import de.muehlencord.shared.account.business.mail.entity.MailTemplateException;
import de.muehlencord.shared.account.business.accountconfig.entity.AccountConfigurationKey; import de.muehlencord.shared.account.business.account.entity.AccountConfigurationKey;
import de.muehlencord.shared.account.business.account.entity.AccountEntity; import de.muehlencord.shared.account.business.account.entity.AccountEntity;
import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity; import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity;
import de.muehlencord.shared.account.business.mail.entity.MailDatamodel; import de.muehlencord.shared.account.business.mail.entity.MailDatamodel;
@ -38,7 +38,7 @@ import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeMultipart;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import de.muehlencord.shared.account.business.accountconfig.entity.AccountConfigurationValue; import de.muehlencord.shared.account.business.account.entity.AccountConfigurationValue;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;

View File

@ -25,7 +25,6 @@ import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped; import javax.faces.view.ViewScoped;
import javax.inject.Named; import javax.inject.Named;
import javax.naming.NamingException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
@ -119,7 +118,10 @@ public class LoginView implements Serializable {
currentUser.logout(); currentUser.logout();
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
// ensure faces session is invalidated so beans are destroyed
ec.invalidateSession();
// check if redirect shall be executed // check if redirect shall be executed
// default setting is yes to /login.xhtml // default setting is yes to /login.xhtml
// can be overwritten using parameters // can be overwritten using parameters

View File

@ -46,16 +46,25 @@ public class SecurityUtil {
LOGGER.trace(encryptedPassword); LOGGER.trace(encryptedPassword);
return encryptedPassword; return encryptedPassword;
} }
public static boolean checkPermission(Permission permission) {
return checkPermission (permission.getName());
}
public static void checkPermission(Permission permission, SecurityError error) throws AccountSecurityException { public static boolean checkPermission(String permissionName) {
Subject currentUser = SecurityUtils.getSubject(); Subject currentUser = SecurityUtils.getSubject();
if ((currentUser == null) || (!currentUser.isAuthenticated())) { if ((currentUser == null) || (!currentUser.isAuthenticated())) {
throw new AccountSecurityException(error); // TODO support special error for not logged in return false;
} }
String requiredPermissions = permission.getName(); String requiredPermissions = permissionName;
if (!currentUser.isPermitted(requiredPermissions)) { return currentUser.isPermitted(requiredPermissions);
}
public static void checkPermission(Permission permission, SecurityError error) throws AccountSecurityException {
if (!checkPermission(permission)) {
throw new AccountSecurityException(error); throw new AccountSecurityException(error);
} }
} }
} }

View File

@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
listall_denied=You are not allowed to list all applications list_denied=You are not allowed to list any application

View File

@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
listall_denied=Sie haben nicht die n\u00f6tige Rechte alle Applikationen aufzulisten list_denied=Sie haben nicht die n\u00f6tige Rechte eine Applikationen aufzulisten.

View File

@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
listall_denied=User not allowed to list all applications list_denied=User not allowed to list any application