diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountPermissions.java b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountPermissions.java new file mode 100644 index 0000000..3dc64bf --- /dev/null +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountPermissions.java @@ -0,0 +1,41 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.muehlencord.shared.account.business.account.boundary; + +import de.muehlencord.shared.account.util.Permission; + +/** + * + * @author Joern Muehlencord + */ +public enum AccountPermissions implements Permission { + + 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 create a login for a user"), + ACCOUNT_LOGIN_EDIT ("account:login:edit", "Allow to change a login for a user"), + ACCOUNT_LOGIN_DELETE ("account:login:delete", "Allow to delete a login for a user"); + + private final String name; + private final String description; + + private AccountPermissions(String permissionName, String permissionDesc) { + this.name = permissionName; + this.description = permissionDesc; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return description; + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountProducer.java b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountProducer.java index 9481bfd..97b4e54 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountProducer.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/boundary/AccountProducer.java @@ -22,11 +22,15 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.ManagedBean; +import javax.annotation.PostConstruct; import javax.ejb.EJB; import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Produces; +import javax.faces.context.FacesContext; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -36,6 +40,7 @@ import org.apache.shiro.subject.Subject; @SessionScoped public class AccountProducer implements Serializable { + private static final Logger LOGGER = LoggerFactory.getLogger(AccountProducer.class); private static final long serialVersionUID = -3806204732038165311L; private final Map objectMap = new ConcurrentHashMap<>(); @@ -43,6 +48,24 @@ public class AccountProducer implements Serializable { AccountControl accountController; private Account account = null; + private Locale locale = null; + + @PostConstruct + public void init() { + FacesContext currentInstance = FacesContext.getCurrentInstance(); + if (currentInstance == null) { + locale = Locale.ENGLISH; + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Using default locale {}", locale); + } + + } else { + locale = currentInstance.getExternalContext().getRequestLocale(); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Using browser locale {}", locale); + } + } + } @Produces public Account getAccount() { @@ -59,10 +82,12 @@ public class AccountProducer implements Serializable { accountName = subject.getPrincipal().toString(); } account = accountController.getAccountEntity(accountName, true); + // TODO introduce locale support to account and switch + // to pre-defined locale if set } return account; } - + public T getValue(String key, Class clazz) { if (objectMap.containsKey(key)) { Object obj = objectMap.get(key); @@ -82,10 +107,10 @@ public class AccountProducer implements Serializable { public void setValue(String key, Object obj) { objectMap.put(key, obj); } - + @Produces public Locale getLocale() { - return Locale.ENGLISH; // TODO depend lcoale on account or on incoming request + return locale; } } diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/control/AccountControl.java b/account/src/main/java/de/muehlencord/shared/account/business/account/control/AccountControl.java index d683305..d38e789 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/control/AccountControl.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/control/AccountControl.java @@ -6,7 +6,7 @@ import de.muehlencord.shared.account.business.mail.entity.MailException; import de.muehlencord.shared.account.business.mail.boundary.MailService; import de.muehlencord.shared.account.business.account.entity.AccountEntity; import de.muehlencord.shared.account.business.account.entity.AccountLoginEntity; -import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.util.AccountPU; import de.muehlencord.shared.account.util.SecurityUtil; diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/Account.java b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/Account.java index 667a040..5979fab 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/Account.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/Account.java @@ -1,18 +1,18 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package de.muehlencord.shared.account.business.account.entity; - -/** - * - * @author Joern Muehlencord - */ -public interface Account { - - String getUsername(); - String getFirstname(); - String getLastname(); - -} +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.muehlencord.shared.account.business.account.entity; + +/** + * + * @author Joern Muehlencord + */ +public interface Account { + + String getUsername(); + String getFirstname(); + String getLastname(); + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java index 735b4a9..0535324 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java @@ -1,5 +1,6 @@ package de.muehlencord.shared.account.business.account.entity; +import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.config.entity.ConfigEntity; import java.io.Serializable; import java.util.ArrayList; @@ -123,7 +124,7 @@ public class AccountEntity implements Serializable, Account { } applicationRoleList.add(applicationRole); } - + /* **** getter / setter **** */ public UUID getId() { return id; diff --git a/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationPermissions.java b/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationPermissions.java new file mode 100644 index 0000000..d3bb859 --- /dev/null +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationPermissions.java @@ -0,0 +1,41 @@ +package de.muehlencord.shared.account.business.application.boundary; + +import de.muehlencord.shared.account.util.Permission; + +/** + * + * @author Joern Muehlencord + */ +public enum ApplicationPermissions implements Permission { + + APP_LISTALL("application:listall", "Allows to list all avaiable applications"), + APP_ADD("application:add", "Allow to add a new application"), + APP_EDIT("application:edit", "Allow to edit an application"), + APP_DELETE("application:delete", "Allow to delete an application"), + PERMISSION_ADD("permission:add", "Allow to add a permission to an application"), + PERMISSION_EDIT("permission:edit", "Allow to edit a permission"), + PERMISSION_DELETE("permmission:delete", "Allow to delete a permission"), + ROLE_ADD("role:add", "Allow to add a role to an application"), + ROLE_EDIT("role:edit", "Allow to edit 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_REVOKE("role:permission:revoke", "All ow to revoke a permission from a role"); + + private final String name; + private final String description; + + private ApplicationPermissions(String permissionName, String permissionDesc) { + this.name = permissionName; + this.description = permissionDesc; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return description; + } +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationService.java b/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationService.java index 2445810..4fc5b98 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationService.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationService.java @@ -2,6 +2,8 @@ package de.muehlencord.shared.account.business.application.boundary; import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; import de.muehlencord.shared.account.util.AccountPU; +import de.muehlencord.shared.account.util.AccountSecurityException; +import de.muehlencord.shared.account.util.SecurityUtil; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -32,7 +34,8 @@ public class ApplicationService implements Serializable { return em.find(ApplicationEntity.class, id); } - public List getAllApplications() { + public List getAllApplications() throws AccountSecurityException { + SecurityUtil.checkPermission(ApplicationPermissions.APP_LISTALL, ApplicationServiceError.LISTALL_DENIED); Query query = em.createNamedQuery("ApplicationEntity.findAll"); List resultList = query.getResultList(); if (resultList == null) { diff --git a/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError.java b/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError.java new file mode 100644 index 0000000..d040421 --- /dev/null +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError.java @@ -0,0 +1,31 @@ +package de.muehlencord.shared.account.business.application.boundary; + +import de.muehlencord.shared.account.util.SecurityError; + +/** + * + * @author Joern Muehlencord + */ +public enum ApplicationServiceError implements SecurityError { + + LISTALL_DENIED("1000", "listall_denied"); + + private final String errorCode; + private final String messageKey; + + private ApplicationServiceError(String errorCode, String messageKey) { + this.errorCode = errorCode; + this.messageKey = messageKey; + } + + @Override + public String getErrorCode() { + return errorCode; + } + + @Override + public String getMessageKey() { + return messageKey; + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/application/control/ApplicationPermissionControl.java b/account/src/main/java/de/muehlencord/shared/account/business/application/control/ApplicationPermissionControl.java index fbf6f81..4af8bea 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/application/control/ApplicationPermissionControl.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/control/ApplicationPermissionControl.java @@ -1,102 +1,142 @@ -package de.muehlencord.shared.account.business.application.control; - -import de.muehlencord.shared.account.business.account.entity.AccountException; -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import de.muehlencord.shared.account.util.AccountPU; -import java.io.Serializable; -import javax.ejb.Stateless; -import javax.persistence.EntityManager; -import java.util.List; -import java.util.ArrayList; -import javax.inject.Inject; -import javax.persistence.OptimisticLockException; -import javax.persistence.Query; -import javax.transaction.Transactional; - -/** - * - * @author Joern Muehlencord - */ -@Stateless -public class ApplicationPermissionControl implements Serializable { - - private static final long serialVersionUID = -3761100587901739481L; - - @Inject - @AccountPU - EntityManager em; - - public List getApplicationPermissions(ApplicationEntity app) { - Query query = em.createNamedQuery("ApplicationPermissionEntity.findAll"); - query.setParameter("application", app); - List permissionList = query.getResultList(); - if (permissionList == null) { - return new ArrayList<>(); - } else { - return permissionList; - } - } - - public ApplicationPermissionEntity findPermissionByName(ApplicationEntity application, String permissionName) { - Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); - query.setParameter("application", application); - query.setParameter("permissionName", permissionName); - List resultList = query.getResultList(); - if ((resultList == null) || (resultList.isEmpty())) { - return null; - } else { - return resultList.get(0); - } - } - - @Transactional - public void create(ApplicationEntity application, String name, String description) { - ApplicationPermissionEntity permission = new ApplicationPermissionEntity(application, name, description); - em.persist(permission); - } - - @Transactional - public void update(ApplicationPermissionEntity permission) throws AccountException { - ApplicationPermissionEntity existing = attach(permission); - em.merge(existing); - } - - @Transactional - public void createOrUpdate(ApplicationEntity application, String name, String description) { - ApplicationPermissionEntity permission = findByName(application, name); - if (permission == null) { - permission = new ApplicationPermissionEntity(name, description); - em.persist(permission); - } else { - permission.setPermissionDescription(description); - em.merge(permission); - } - } - - @Transactional - public void delete(ApplicationPermissionEntity permission) throws AccountException { - ApplicationPermissionEntity existingPermission = attach(permission); - em.remove(existingPermission); - } - - public ApplicationPermissionEntity attach(ApplicationPermissionEntity permission) throws AccountException { - try { - return em.merge(permission); - } catch (OptimisticLockException ex) { - throw new AccountException("Entity updated / deleted, please reload", true); - } - } - - private ApplicationPermissionEntity findByName(ApplicationEntity application, String name) { - Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); - query.setParameter("application", application); - query.setParameter("permissionName", name); - List permissions = query.getResultList(); - if ((permissions == null) || (permissions.isEmpty())) { - return null; - } else { - return permissions.get(0); - } - } -} +package de.muehlencord.shared.account.business.application.control; + +import de.muehlencord.shared.account.business.account.entity.AccountException; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationPermissionEntity; +import de.muehlencord.shared.account.util.AccountPU; +import de.muehlencord.shared.account.util.Permission; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import javax.ejb.Stateless; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.OptimisticLockException; +import javax.persistence.Query; +import javax.transaction.Transactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@Stateless +public class ApplicationPermissionControl implements Serializable { + + private static final long serialVersionUID = -3761100587901739481L; + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationPermissionControl.class); + + @Inject + @AccountPU + EntityManager em; + + @Inject + ApplicationEntity application; + + public List getApplicationPermissions(ApplicationEntity app) { + Query query = em.createNamedQuery("ApplicationPermissionEntity.findAll"); + query.setParameter("application", app); + List permissionList = query.getResultList(); + if (permissionList == null) { + return new ArrayList<>(); + } else { + return permissionList; + } + } + + public ApplicationPermissionEntity findPermissionByName(ApplicationEntity application, String permissionName) { + Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); + query.setParameter("application", application); + query.setParameter("permissionName", permissionName); + List resultList = query.getResultList(); + if ((resultList == null) || (resultList.isEmpty())) { + return null; + } else { + return resultList.get(0); + } + } + + @Transactional + public void create(ApplicationEntity application, String name, String description) { + ApplicationPermissionEntity permission = new ApplicationPermissionEntity(application, name, description); + em.persist(permission); + } + + @Transactional + public void update(ApplicationPermissionEntity permission) throws AccountException { + ApplicationPermissionEntity existing = attach(permission); + em.merge(existing); + } + + @Transactional + public void createOrUpdate(ApplicationEntity application, String name, String description) { + ApplicationPermissionEntity permission = findByName(application, name); + if (permission == null) { + permission = new ApplicationPermissionEntity(name, description); + em.persist(permission); + } else { + permission.setPermissionDescription(description); + em.merge(permission); + } + } + + @Transactional + public void delete(ApplicationPermissionEntity permission) throws AccountException { + ApplicationPermissionEntity existingPermission = attach(permission); + em.remove(existingPermission); + } + + public ApplicationPermissionEntity attach(ApplicationPermissionEntity permission) throws AccountException { + try { + return em.merge(permission); + } catch (OptimisticLockException ex) { + throw new AccountException("Entity updated / deleted, please reload", true); + } + } + + private ApplicationPermissionEntity findByName(ApplicationEntity application, String name) { + Query query = em.createNamedQuery("ApplicationPermissionEntity.findByPermissionName"); + query.setParameter("application", application); + query.setParameter("permissionName", name); + List permissions = query.getResultList(); + if ((permissions == null) || (permissions.isEmpty())) { + return null; + } else { + return permissions.get(0); + } + } + + @Transactional + public void setupPermissions(List permissions) { + for (Permission permission : permissions) { + ApplicationPermissionEntity existingPermission = findByName(application, permission.getName()); + if (existingPermission == null) { + // permission not available, create it + LOGGER.info("missing permission {} of {}", permission.getName(), application.getApplicationName()); + existingPermission = new ApplicationPermissionEntity(permission.getName(), permission.getDescription()); + existingPermission.setApplication(application); + em.persist(existingPermission); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("missing permission {} added to {}", permission.getName(), application.getApplicationName()); + } + } else { + if (existingPermission.getPermissionDescription().equals(permission.getDescription())) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Permission {} for {} already exists, skipping", permission.getName(), application.getApplicationName()); + } + } else { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("description of permssion {} for {} differs, resetting to orignal value {}", permission.getName(), application.getApplicationName(), permission.getDescription()); + } + + existingPermission.setPermissionDescription(permission.getDescription()); + em.merge (existingPermission); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("updated permission description {} for {}", permission.getName(), application.getApplicationName()); + } + } + } + } + } +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/application/control/ApplicationRoleControl.java b/account/src/main/java/de/muehlencord/shared/account/business/application/control/ApplicationRoleControl.java index 9902cab..c0ccad6 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/application/control/ApplicationRoleControl.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/control/ApplicationRoleControl.java @@ -1,150 +1,191 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package de.muehlencord.shared.account.business.application.control; - -import de.muehlencord.shared.account.business.account.entity.AccountException; -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import de.muehlencord.shared.account.util.AccountPU; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import javax.ejb.EJB; -import javax.ejb.Stateless; -import javax.inject.Inject; -import javax.persistence.EntityManager; -import javax.persistence.OptimisticLockException; -import javax.persistence.Query; -import javax.transaction.Transactional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Joern Muehlencord - */ -@Stateless -public class ApplicationRoleControl implements Serializable { - - private static final long serialVersionUID = 5962478269550134748L; - private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRoleControl.class); - - @EJB - ApplicationPermissionControl applicationPermissionControl; - - @Inject - @AccountPU - EntityManager em; - - public List getAllRoles(ApplicationEntity app) { - Query query = em.createNamedQuery("ApplicationRoleEntity.findAll"); - query.setParameter("application", app); - - List roles = query.getResultList(); - if (roles == null) { - return new ArrayList<>(); - } else { - return roles; - } - } - - @Transactional - public void createOrUpdate(ApplicationEntity application, String name, String description) { - ApplicationRoleEntity role = findByName(application, name); - if (role == null) { - role = new ApplicationRoleEntity(application, name, description); - em.persist(role); - } else { - role.setRoleDescription(description); - em.merge(role); - } - } - - @Transactional - public void create(ApplicationRoleEntity role) { - em.persist(role); - } - - @Transactional - public void update(ApplicationRoleEntity role) { - em.merge(role); - } - - @Transactional - public void delete(ApplicationRoleEntity role) throws AccountException { - ApplicationRoleEntity existingRole = attach(role); - em.remove(existingRole); - } - - public ApplicationRoleEntity attach(ApplicationRoleEntity role) throws AccountException { - try { - return em.merge(role); - } catch (OptimisticLockException ex) { - throw new AccountException("Entity updated / deleted, please reload", true); - } - } - - public ApplicationRoleEntity findByName(ApplicationEntity application, String name) { - Query query = em.createNamedQuery("ApplicationRoleEntity.findByRoleName"); - query.setParameter("application", application); - query.setParameter("roleName", name); - List permissions = query.getResultList(); - if ((permissions == null) || (permissions.isEmpty())) { - return null; - } else { - return permissions.get(0); - } - } - - public List getRolePermissions(ApplicationRoleEntity role) throws AccountException { - ApplicationRoleEntity existingRole = em.find(ApplicationRoleEntity.class, role.getId()); - List permissions = existingRole.getApplicationPermissionList(); - permissions.size(); // force list to load - return permissions; - } - - public List getNotAssignedApplicationPermissions(ApplicationRoleEntity role) { - try { - List rolePermissions = getRolePermissions(role); - List allPermssions = applicationPermissionControl.getApplicationPermissions(role.getApplication()); - - List missingPermissions = new ArrayList<>(); - allPermssions.stream().filter((perm) -> (!rolePermissions.contains(perm))).forEachOrdered((perm) -> { - missingPermissions.add(perm); - }); - return missingPermissions; - } catch (AccountException ex) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(ex.toString(), ex); - } else { - LOGGER.debug(ex.toString()); - } - return null; - } - - } - - @Transactional - public void addPermission(ApplicationRoleEntity role, ApplicationPermissionEntity permission) throws AccountException { - ApplicationRoleEntity existingRole = attach(role); - if (existingRole.getApplicationPermissionList() == null) { - existingRole.setApplicationPermissionList(new ArrayList<>()); - } - existingRole.getApplicationPermissionList().add(permission); - em.merge(role); - } - - @Transactional - public void removePermission(ApplicationRoleEntity role, ApplicationPermissionEntity permission) throws AccountException { - ApplicationRoleEntity existingRole = attach(role); - if ((existingRole.getApplicationPermissionList() != null) && (existingRole.getApplicationPermissionList().contains(permission))) { - existingRole.getApplicationPermissionList().remove(permission); - } - em.merge(role); - } - -} +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.muehlencord.shared.account.business.application.control; + +import de.muehlencord.shared.account.business.account.entity.AccountException; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationPermissionEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationRoleEntity; +import de.muehlencord.shared.account.util.AccountPU; +import de.muehlencord.shared.account.util.Permission; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.OptimisticLockException; +import javax.persistence.Query; +import javax.transaction.Transactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@Stateless +public class ApplicationRoleControl implements Serializable { + + private static final long serialVersionUID = 5962478269550134748L; + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRoleControl.class); + + @EJB + ApplicationPermissionControl applicationPermissionControl; + + @Inject + @AccountPU + EntityManager em; + + @Inject + ApplicationEntity application; + + // TODO requires special role to maintain role for other allication + public List getAllRoles(ApplicationEntity app) { + Query query = em.createNamedQuery("ApplicationRoleEntity.findAll"); + query.setParameter("application", app); + + List roles = query.getResultList(); + if (roles == null) { + return new ArrayList<>(); + } else { + return roles; + } + } + + @Transactional + // TODO requires special role to maintain role for other allication + public void createOrUpdate(ApplicationEntity app, String name, String description) { + ApplicationRoleEntity role = findByName(app, name); + if (role == null) { + role = new ApplicationRoleEntity(app, name, description); + em.persist(role); + } else { + role.setRoleDescription(description); + em.merge(role); + } + } + + @Transactional + // TODO requires special role to maintain role for other allication + public void create(ApplicationRoleEntity role) { + em.persist(role); + } + + @Transactional + // TODO requires special role to maintain role for other allication + public void update(ApplicationRoleEntity role) { + em.merge(role); + } + + @Transactional + // TODO requires special role to maintain role for other allication + public void delete(ApplicationRoleEntity role) throws AccountException { + ApplicationRoleEntity existingRole = attach(role); + em.remove(existingRole); + } + + public ApplicationRoleEntity attach(ApplicationRoleEntity role) throws AccountException { + try { + return em.merge(role); + } catch (OptimisticLockException ex) { + throw new AccountException("Entity updated / deleted, please reload", true); + } + } + + public ApplicationRoleEntity findByName(ApplicationEntity application, String name) { + Query query = em.createNamedQuery("ApplicationRoleEntity.findByRoleName"); + query.setParameter("application", application); + query.setParameter("roleName", name); + List permissions = query.getResultList(); + if ((permissions == null) || (permissions.isEmpty())) { + return null; + } else { + return permissions.get(0); + } + } + + public List getRolePermissions(ApplicationRoleEntity role) throws AccountException { + ApplicationRoleEntity existingRole = em.find(ApplicationRoleEntity.class, role.getId()); + List permissions = existingRole.getApplicationPermissionList(); + permissions.size(); // force list to load + return permissions; + } + + public List getNotAssignedApplicationPermissions(ApplicationRoleEntity role) { + try { + List rolePermissions = getRolePermissions(role); + List allPermssions = applicationPermissionControl.getApplicationPermissions(role.getApplication()); + + List missingPermissions = new ArrayList<>(); + allPermssions.stream().filter((perm) -> (!rolePermissions.contains(perm))).forEachOrdered((perm) -> { + missingPermissions.add(perm); + }); + return missingPermissions; + } catch (AccountException ex) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(ex.toString(), ex); + } else { + LOGGER.debug(ex.toString()); + } + return null; + } + + } + + @Transactional + // TODO requires special role to maintain role for other allication + public void addPermission(ApplicationRoleEntity role, ApplicationPermissionEntity permission) throws AccountException { + ApplicationRoleEntity existingRole = attach(role); + if (existingRole.getApplicationPermissionList() == null) { + existingRole.setApplicationPermissionList(new ArrayList<>()); + } + existingRole.getApplicationPermissionList().add(permission); + em.merge(role); + } + + @Transactional + // TODO requires special role to maintain role for other allication + public void removePermission(ApplicationRoleEntity role, ApplicationPermissionEntity permission) throws AccountException { + ApplicationRoleEntity existingRole = attach(role); + if ((existingRole.getApplicationPermissionList() != null) && (existingRole.getApplicationPermissionList().contains(permission))) { + existingRole.getApplicationPermissionList().remove(permission); + } + em.merge(role); + } + + @Transactional + public void setupRolePermission(List permissions, String roleName) throws AccountException { + ApplicationRoleEntity role = findByName(application, roleName); + if (role == null) { + LOGGER.error("A role with name " + roleName + " is not defined for application " + application.getApplicationName()); + } else { + for (Permission permission : permissions) { + ApplicationPermissionEntity existingPermission = applicationPermissionControl.findPermissionByName(application, permission.getName()); + if (existingPermission == null) { + LOGGER.error("Required permission " + permission.getName() + " of application " + application.getApplicationName() + " does not exist. Ensure to call setupPermissions first"); + } else { + if (role.getApplicationPermissionList().contains(existingPermission)) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Permission {} already assigned to role {} of {}, skipping", permission.getName(), roleName, application.getApplicationName()); + } + } else { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Permission {} not assigned to role {} of {}", permission.getName(), roleName, application.getApplicationName()); + } + addPermission(role, existingPermission); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Added permission {} to role {} of {}", permission.getName(), roleName, application.getApplicationName()); + } + } + } + } + } + + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationEntity.java index 4a2563a..57306da 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationEntity.java @@ -1,7 +1,5 @@ package de.muehlencord.shared.account.business.application.entity; -import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity; -import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity; import de.muehlencord.shared.account.business.config.entity.ConfigEntity; import java.io.Serializable; import java.util.List; diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/ApplicationPermissionEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationPermissionEntity.java similarity index 96% rename from account/src/main/java/de/muehlencord/shared/account/business/account/entity/ApplicationPermissionEntity.java rename to account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationPermissionEntity.java index 4c2fa33..1f88d2c 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/ApplicationPermissionEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationPermissionEntity.java @@ -1,158 +1,158 @@ -package de.muehlencord.shared.account.business.account.entity; - -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.io.Serializable; -import java.util.List; -import java.util.UUID; -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Type; - -/** - * - * @author joern.muehlencord - */ -@Entity -@Table(name = "application_permission") -@XmlRootElement -@NamedQueries({ - @NamedQuery(name = "ApplicationPermissionEntity.findAll", query = "SELECT a FROM ApplicationPermissionEntity a WHERE a.application=:application order by a.permissionName"), - @NamedQuery(name = "ApplicationPermissionEntity.findNotAssigned", query = "SELECT a FROM ApplicationPermissionEntity a LEFT OUTER JOIN a.applicationRoles r WHERE a.application=:application AND r NOT IN :permissions"), - @NamedQuery(name = "ApplicationPermissionEntity.findByPermissionName", query = "SELECT a FROM ApplicationPermissionEntity a WHERE a.application=:application AND a.permissionName = :permissionName"), - @NamedQuery(name = "ApplicationPermissionEntity.findByPermissionDescription", query = "SELECT a FROM ApplicationPermissionEntity a WHERE a.application=:application AND a.permissionDescription = :permissionDescription")}) -public class ApplicationPermissionEntity implements Serializable { - - private static final long serialVersionUID = -8985982754544829534L; - - @Id - @Basic(optional = false) - @NotNull - @Column(name = "id") - @GeneratedValue(generator = "uuid2") - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Type(type = "pg-uuid") - private UUID id; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 80) - @Column(name = "permission_name") - private String permissionName; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 200) - @Column(name = "permission_description") - private String permissionDescription; - @JoinColumn(name = "application", referencedColumnName = "id") - @ManyToOne(optional = false) - private ApplicationEntity application; - @ManyToMany(mappedBy = "applicationPermissionList") - private List applicationRoles; - - public ApplicationPermissionEntity() { - } - - public ApplicationPermissionEntity(UUID id) { - this.id = id; - } - - public ApplicationPermissionEntity(String permissionName, String permissionDescription) { - this.id = null; - this.permissionName = permissionName; - this.permissionDescription = permissionDescription; - } - - public ApplicationPermissionEntity(ApplicationEntity application, String permissionName, String permissionDescription) { - this.id = null; - this.application = application; - this.permissionName = permissionName; - this.permissionDescription = permissionDescription; - } - - public ApplicationPermissionEntity(UUID id, ApplicationEntity application, String permissionName, String permissionDescription) { - this.id = id; - this.application = application; - this.permissionName = permissionName; - this.permissionDescription = permissionDescription; - } - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public String getPermissionName() { - return permissionName; - } - - public void setPermissionName(String permissionName) { - this.permissionName = permissionName; - } - - public String getPermissionDescription() { - return permissionDescription; - } - - public void setPermissionDescription(String permissionDescription) { - this.permissionDescription = permissionDescription; - } - - @XmlTransient - public List getApplicationRoles() { - return applicationRoles; - } - - public void setApplicationRoles(List applicationRoles) { - this.applicationRoles = applicationRoles; - } - - @Override - public int hashCode() { - int hash = 0; - hash += (id != null ? id.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof ApplicationPermissionEntity)) { - return false; - } - ApplicationPermissionEntity other = (ApplicationPermissionEntity) object; - if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { - return false; - } - return true; - } - - @Override - public String toString() { - return "de.muehlencord.shared.account.entity.ApplicationPermission[ id=" + id + " ]"; - } - - public ApplicationEntity getApplication() { - return application; - } - - public void setApplication(ApplicationEntity application) { - this.application = application; - } - -} +package de.muehlencord.shared.account.business.application.entity; + +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.Serializable; +import java.util.List; +import java.util.UUID; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; + +/** + * + * @author joern.muehlencord + */ +@Entity +@Table(name = "application_permission") +@XmlRootElement +@NamedQueries({ + @NamedQuery(name = "ApplicationPermissionEntity.findAll", query = "SELECT a FROM ApplicationPermissionEntity a WHERE a.application=:application order by a.permissionName"), + @NamedQuery(name = "ApplicationPermissionEntity.findNotAssigned", query = "SELECT a FROM ApplicationPermissionEntity a LEFT OUTER JOIN a.applicationRoles r WHERE a.application=:application AND r NOT IN :permissions"), + @NamedQuery(name = "ApplicationPermissionEntity.findByPermissionName", query = "SELECT a FROM ApplicationPermissionEntity a WHERE a.application=:application AND a.permissionName = :permissionName"), + @NamedQuery(name = "ApplicationPermissionEntity.findByPermissionDescription", query = "SELECT a FROM ApplicationPermissionEntity a WHERE a.application=:application AND a.permissionDescription = :permissionDescription")}) +public class ApplicationPermissionEntity implements Serializable { + + private static final long serialVersionUID = -8985982754544829534L; + + @Id + @Basic(optional = false) + @NotNull + @Column(name = "id") + @GeneratedValue(generator = "uuid2") + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Type(type = "pg-uuid") + private UUID id; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 80) + @Column(name = "permission_name") + private String permissionName; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 200) + @Column(name = "permission_description") + private String permissionDescription; + @JoinColumn(name = "application", referencedColumnName = "id") + @ManyToOne(optional = false) + private ApplicationEntity application; + @ManyToMany(mappedBy = "applicationPermissionList") + private List applicationRoles; + + public ApplicationPermissionEntity() { + } + + public ApplicationPermissionEntity(UUID id) { + this.id = id; + } + + public ApplicationPermissionEntity(String permissionName, String permissionDescription) { + this.id = null; + this.permissionName = permissionName; + this.permissionDescription = permissionDescription; + } + + public ApplicationPermissionEntity(ApplicationEntity application, String permissionName, String permissionDescription) { + this.id = null; + this.application = application; + this.permissionName = permissionName; + this.permissionDescription = permissionDescription; + } + + public ApplicationPermissionEntity(UUID id, ApplicationEntity application, String permissionName, String permissionDescription) { + this.id = id; + this.application = application; + this.permissionName = permissionName; + this.permissionDescription = permissionDescription; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getPermissionName() { + return permissionName; + } + + public void setPermissionName(String permissionName) { + this.permissionName = permissionName; + } + + public String getPermissionDescription() { + return permissionDescription; + } + + public void setPermissionDescription(String permissionDescription) { + this.permissionDescription = permissionDescription; + } + + @XmlTransient + public List getApplicationRoles() { + return applicationRoles; + } + + public void setApplicationRoles(List applicationRoles) { + this.applicationRoles = applicationRoles; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof ApplicationPermissionEntity)) { + return false; + } + ApplicationPermissionEntity other = (ApplicationPermissionEntity) object; + if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "de.muehlencord.shared.account.entity.ApplicationPermission[ id=" + id + " ]"; + } + + public ApplicationEntity getApplication() { + return application; + } + + public void setApplication(ApplicationEntity application) { + this.application = application; + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/ApplicationRoleEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationRoleEntity.java similarity index 94% rename from account/src/main/java/de/muehlencord/shared/account/business/account/entity/ApplicationRoleEntity.java rename to account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationRoleEntity.java index 5457eec..7e159d2 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/ApplicationRoleEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/application/entity/ApplicationRoleEntity.java @@ -1,170 +1,171 @@ -package de.muehlencord.shared.account.business.account.entity; - -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.io.Serializable; -import java.util.List; -import java.util.UUID; -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Type; - -/** - * - * @author joern.muehlencord - */ -@Entity -@Table(name = "application_role") -@XmlRootElement -@NamedQueries({ - @NamedQuery(name = "ApplicationRoleEntity.findAll", query = "SELECT a FROM ApplicationRoleEntity a WHERE a.application = :application ORDER BY a.roleName"), - @NamedQuery(name = "ApplicationRoleEntity.findByRoleName", query = "SELECT a FROM ApplicationRoleEntity a WHERE a.application = :application AND a.roleName = :roleName"), - @NamedQuery(name = "ApplicationRoleEntity.findByRoleDescription", query = "SELECT a FROM ApplicationRoleEntity a WHERE a.application = :application AND a.roleDescription = :roleDescription")}) - -public class ApplicationRoleEntity implements Serializable { - - private static final long serialVersionUID = -8324054525780893823L; - - @Id - @Basic(optional = false) - @NotNull - @Column(name = "id") - @GeneratedValue(generator = "uuid2") - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Type(type = "pg-uuid") - private UUID id; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 80) - @Column(name = "role_name") - private String roleName; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 200) - @Column(name = "role_description") - private String roleDescription; - @ManyToMany(mappedBy = "applicationRoleList") - private List accountList; - @JoinTable(name = "role_permission", joinColumns = { - @JoinColumn(name = "application_role", referencedColumnName = "id")}, inverseJoinColumns = { - @JoinColumn(name = "role_permission", referencedColumnName = "id")}) - @ManyToMany - private List applicationPermissionList; - @JoinColumn(name = "application", referencedColumnName = "id") - @ManyToOne(optional = false) - private ApplicationEntity application; - - public ApplicationRoleEntity() { - } - - public ApplicationRoleEntity(ApplicationEntity application) { - this.id = null; - this.application = application; - this.roleName = ""; - this.roleDescription = ""; - } - - public ApplicationRoleEntity(ApplicationEntity application, String roleName, String roleDescription) { - this.id = null; - this.application = application; - this.roleName = roleName; - this.roleDescription = roleDescription; - } - - public ApplicationRoleEntity(UUID id, ApplicationEntity application, String roleName, String roleDescription) { - this.id = id; - this.application = application; - this.roleName = roleName; - this.roleDescription = roleDescription; - } - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public String getRoleName() { - return roleName; - } - - public void setRoleName(String roleName) { - this.roleName = roleName; - } - - public String getRoleDescription() { - return roleDescription; - } - - public void setRoleDescription(String roleDescription) { - this.roleDescription = roleDescription; - } - - @XmlTransient - public List getAccountList() { - return accountList; - } - - public void setAccountList(List accountList) { - this.accountList = accountList; - } - - @XmlTransient - public List getApplicationPermissionList() { - return applicationPermissionList; - } - - public void setApplicationPermissionList(List applicationPermissionList) { - this.applicationPermissionList = applicationPermissionList; - } - - public ApplicationEntity getApplication() { - return application; - } - - public void setApplication(ApplicationEntity application) { - this.application = application; - } - - @Override - public int hashCode() { - int hash = 0; - hash += (id != null ? id.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof ApplicationRoleEntity)) { - return false; - } - ApplicationRoleEntity other = (ApplicationRoleEntity) object; - if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { - return false; - } - return true; - } - - @Override - public String toString() { - return "de.muehlencord.shared.account.entity.ApplicationRole[ id=" + id + " ]"; - } - -} +package de.muehlencord.shared.account.business.application.entity; + +import de.muehlencord.shared.account.business.account.entity.AccountEntity; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.Serializable; +import java.util.List; +import java.util.UUID; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; + +/** + * + * @author joern.muehlencord + */ +@Entity +@Table(name = "application_role") +@XmlRootElement +@NamedQueries({ + @NamedQuery(name = "ApplicationRoleEntity.findAll", query = "SELECT a FROM ApplicationRoleEntity a WHERE a.application = :application ORDER BY a.roleName"), + @NamedQuery(name = "ApplicationRoleEntity.findByRoleName", query = "SELECT a FROM ApplicationRoleEntity a WHERE a.application = :application AND a.roleName = :roleName"), + @NamedQuery(name = "ApplicationRoleEntity.findByRoleDescription", query = "SELECT a FROM ApplicationRoleEntity a WHERE a.application = :application AND a.roleDescription = :roleDescription")}) + +public class ApplicationRoleEntity implements Serializable { + + private static final long serialVersionUID = -8324054525780893823L; + + @Id + @Basic(optional = false) + @NotNull + @Column(name = "id") + @GeneratedValue(generator = "uuid2") + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Type(type = "pg-uuid") + private UUID id; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 80) + @Column(name = "role_name") + private String roleName; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 200) + @Column(name = "role_description") + private String roleDescription; + @ManyToMany(mappedBy = "applicationRoleList") + private List accountList; + @JoinTable(name = "role_permission", joinColumns = { + @JoinColumn(name = "application_role", referencedColumnName = "id")}, inverseJoinColumns = { + @JoinColumn(name = "role_permission", referencedColumnName = "id")}) + @ManyToMany + private List applicationPermissionList; + @JoinColumn(name = "application", referencedColumnName = "id") + @ManyToOne(optional = false) + private ApplicationEntity application; + + public ApplicationRoleEntity() { + } + + public ApplicationRoleEntity(ApplicationEntity application) { + this.id = null; + this.application = application; + this.roleName = ""; + this.roleDescription = ""; + } + + public ApplicationRoleEntity(ApplicationEntity application, String roleName, String roleDescription) { + this.id = null; + this.application = application; + this.roleName = roleName; + this.roleDescription = roleDescription; + } + + public ApplicationRoleEntity(UUID id, ApplicationEntity application, String roleName, String roleDescription) { + this.id = id; + this.application = application; + this.roleName = roleName; + this.roleDescription = roleDescription; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + public String getRoleDescription() { + return roleDescription; + } + + public void setRoleDescription(String roleDescription) { + this.roleDescription = roleDescription; + } + + @XmlTransient + public List getAccountList() { + return accountList; + } + + public void setAccountList(List accountList) { + this.accountList = accountList; + } + + @XmlTransient + public List getApplicationPermissionList() { + return applicationPermissionList; + } + + public void setApplicationPermissionList(List applicationPermissionList) { + this.applicationPermissionList = applicationPermissionList; + } + + public ApplicationEntity getApplication() { + return application; + } + + public void setApplication(ApplicationEntity application) { + this.application = application; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof ApplicationRoleEntity)) { + return false; + } + ApplicationRoleEntity other = (ApplicationRoleEntity) object; + if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "de.muehlencord.shared.account.entity.ApplicationRole[ id=" + id + " ]"; + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/util/AccountSecurityException.java b/account/src/main/java/de/muehlencord/shared/account/util/AccountSecurityException.java new file mode 100644 index 0000000..e3a60e7 --- /dev/null +++ b/account/src/main/java/de/muehlencord/shared/account/util/AccountSecurityException.java @@ -0,0 +1,44 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.muehlencord.shared.account.util; + +import java.io.Serializable; +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * + * @author Joern Muehlencord + */ +public class AccountSecurityException extends Exception implements Serializable { + + private static final long serialVersionUID = 8135850463689587815L; + + private final SecurityError securityError; + + public AccountSecurityException(SecurityError securityError) { + this.securityError = securityError; + } + + public String getErrorCode() { + return securityError.getErrorCode(); + } + + public String getMessageKey() { + return securityError.getMessageKey(); + } + + public String getMessage() { + ResourceBundle resourceBundle = ResourceBundle.getBundle(securityError.getClass().getName(), Locale.ENGLISH); + return resourceBundle.getString(securityError.getMessageKey()); + } + + public String getLocalizedMessage(Locale locale) { + ResourceBundle resourceBundle = ResourceBundle.getBundle(securityError.getClass().getName(), locale); + return resourceBundle.getString(securityError.getMessageKey()); + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/util/Permission.java b/account/src/main/java/de/muehlencord/shared/account/util/Permission.java new file mode 100644 index 0000000..c2501e6 --- /dev/null +++ b/account/src/main/java/de/muehlencord/shared/account/util/Permission.java @@ -0,0 +1,13 @@ +package de.muehlencord.shared.account.util; + +/** + * + * @author Joern Muehlencord + */ +public interface Permission { + + String getName(); + String getDescription(); + + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/util/SecurityError.java b/account/src/main/java/de/muehlencord/shared/account/util/SecurityError.java new file mode 100644 index 0000000..51415cd --- /dev/null +++ b/account/src/main/java/de/muehlencord/shared/account/util/SecurityError.java @@ -0,0 +1,12 @@ +package de.muehlencord.shared.account.util; + +/** + * + * @author Joern Muehlencord + */ +public interface SecurityError { + + String getErrorCode(); + String getMessageKey(); + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/util/SecurityUtil.java b/account/src/main/java/de/muehlencord/shared/account/util/SecurityUtil.java index 2dde294..97a2f73 100644 --- a/account/src/main/java/de/muehlencord/shared/account/util/SecurityUtil.java +++ b/account/src/main/java/de/muehlencord/shared/account/util/SecurityUtil.java @@ -1,10 +1,12 @@ package de.muehlencord.shared.account.util; +import org.apache.shiro.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.shiro.authc.credential.DefaultPasswordService; import org.apache.shiro.crypto.hash.DefaultHashService; import org.apache.shiro.crypto.hash.Sha512Hash; +import org.apache.shiro.subject.Subject; /** * @@ -30,4 +32,15 @@ public class SecurityUtil { return encryptedPassword; } + public static void checkPermission(Permission permission, SecurityError error) throws AccountSecurityException { + Subject currentUser = SecurityUtils.getSubject(); + if ((currentUser == null) || (!currentUser.isAuthenticated())) { + throw new AccountSecurityException(error); // TODO support special error for not logged in + } + + String requiredPermissions = permission.getName(); + if (!currentUser.isPermitted(requiredPermissions)) { + throw new AccountSecurityException(error); + } + } } diff --git a/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError.properties b/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError.properties new file mode 100644 index 0000000..6e61888 --- /dev/null +++ b/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError.properties @@ -0,0 +1,5 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +listall_denied=You are not allowed to list all applications diff --git a/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError_de_DE.properties b/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError_de_DE.properties new file mode 100644 index 0000000..c4a81a0 --- /dev/null +++ b/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError_de_DE.properties @@ -0,0 +1,5 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +listall_denied=Sie haben nicht die n\u00f6tige Rechte alle Applikationen aufzulisten diff --git a/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError_en_US.properties b/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError_en_US.properties new file mode 100644 index 0000000..baa311f --- /dev/null +++ b/account/src/main/resources/de/muehlencord/shared/account/business/application/boundary/ApplicationServiceError_en_US.properties @@ -0,0 +1,5 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +listall_denied=User not allowed to list all applications