From 292db1b4f0c5474f725fd81b225d5e99f3b29a60 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 10 Jan 2019 16:20:40 +0100 Subject: [PATCH] [Major] Added has* methods in privilege validation --- .../runtime/privilege/ModelPrivilege.java | 36 +++-- .../strolch/privilege/model/IPrivilege.java | 20 +-- .../privilege/model/PrivilegeContext.java | 43 +++++- .../privilege/policy/DefaultPrivilege.java | 35 +++-- .../privilege/policy/PrivilegePolicy.java | 22 ++- .../policy/PrivilegePolicyHelper.java | 32 +++-- .../privilege/policy/RoleAccessPrivilege.java | 55 ++++---- .../privilege/policy/UserAccessPrivilege.java | 131 +++++------------- ...erAccessWithSameOrganisationPrivilege.java | 54 ++++++-- .../UsernameFromCertificatePrivilege.java | 21 ++- ...tificateWithSameOrganisationPrivilege.java | 36 +++-- 11 files changed, 293 insertions(+), 192 deletions(-) diff --git a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/ModelPrivilege.java b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/ModelPrivilege.java index a381502d4..43997b01f 100644 --- a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/ModelPrivilege.java +++ b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/ModelPrivilege.java @@ -1,5 +1,8 @@ package li.strolch.runtime.privilege; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.checkByAllowDenyValues; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.preValidate; + import java.text.MessageFormat; import li.strolch.model.StrolchRootElement; @@ -11,37 +14,52 @@ import li.strolch.privilege.model.PrivilegeContext; import li.strolch.privilege.model.Restrictable; import li.strolch.privilege.model.internal.Role; import li.strolch.privilege.policy.PrivilegePolicy; -import li.strolch.privilege.policy.PrivilegePolicyHelper; public class ModelPrivilege implements PrivilegePolicy { /** * The value of {@link Restrictable#getPrivilegeValue()} is used to check if the {@link Role} has this privilege - * - * @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(IPrivilege, Restrictable) + * + * @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, IPrivilege, Restrictable) */ @Override public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException { - PrivilegePolicyHelper.preValidate(privilege, restrictable); + validateAction(ctx, privilege, restrictable, true); + } + + /** + * The value of {@link Restrictable#getPrivilegeValue()} is used to check if the {@link Role} has this privilege + * + * @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, IPrivilege, Restrictable) + */ + @Override + public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws PrivilegeException { + return validateAction(ctx, privilege, restrictable, false); + } + + protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, + boolean assertHasPrivilege) throws AccessDeniedException { + + preValidate(privilege, restrictable); // get the value on which the action is to be performed Object object = restrictable.getPrivilegeValue(); // DefaultPrivilege policy expects the privilege value to be a string if (!(object instanceof StrolchRootElement)) { - String msg = Restrictable.class.getName() - + PrivilegeMessages.getString("Privilege.illegalArgument.nonstrolchrootelement"); //$NON-NLS-1$ + String msg = Restrictable.class.getName() + PrivilegeMessages + .getString("Privilege.illegalArgument.nonstrolchrootelement"); //$NON-NLS-1$ msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName()); throw new PrivilegeException(msg); } // if everything is allowed, then no need to carry on if (privilege.isAllAllowed()) - return; + return true; StrolchRootElement rootElement = (StrolchRootElement) object; - - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, rootElement.getType()); + return checkByAllowDenyValues(ctx, privilege, restrictable, rootElement.getType(), assertHasPrivilege); } } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/model/IPrivilege.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/model/IPrivilege.java index df8099b1c..633953995 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/model/IPrivilege.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/model/IPrivilege.java @@ -35,51 +35,51 @@ public interface IPrivilege { /** * @return a {@link PrivilegeRep} which is a representation of this object used to serialize and view on clients */ - public abstract PrivilegeRep asPrivilegeRep(); + PrivilegeRep asPrivilegeRep(); /** * @return the name */ - public abstract String getName(); + String getName(); /** * @return the policy */ - public abstract String getPolicy(); + String getPolicy(); /** * @return the allAllowed */ - public abstract boolean isAllAllowed(); + boolean isAllAllowed(); /** * @return the allowList */ - public abstract Set getAllowList(); + Set getAllowList(); /** * @return the denyList */ - public abstract Set getDenyList(); + Set getDenyList(); /** * @return true if there are values in the allow list */ - public abstract boolean hasAllowed(); + boolean hasAllowed(); /** * @return if the value is in the allow list */ - public abstract boolean isAllowed(String value); + boolean isAllowed(String value); /** * @return true if there are values in the deny list */ - public abstract boolean hasDenied(); + boolean hasDenied(); /** * @return true if the value is in the deny list */ - public abstract boolean isDenied(String value); + boolean isDenied(String value); } \ No newline at end of file diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/model/PrivilegeContext.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/model/PrivilegeContext.java index dd70e321b..d62e117ba 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/model/PrivilegeContext.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/model/PrivilegeContext.java @@ -81,6 +81,10 @@ public class PrivilegeContext { } } + public boolean hasRole(String roleName) { + return this.userRep.hasRole(roleName); + } + public void assertHasRole(String roleName) throws AccessDeniedException { if (!this.userRep.hasRole(roleName)) { String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.role"), //$NON-NLS-1$ @@ -100,6 +104,15 @@ public class PrivilegeContext { throw new AccessDeniedException(msg); } + public boolean hasAnyRole(String... roleNames) throws AccessDeniedException { + for (String roleName : roleNames) { + if (this.userRep.hasRole(roleName)) + return true; + } + + return false; + } + public IPrivilege getPrivilege(String privilegeName) throws AccessDeniedException { assertHasPrivilege(privilegeName); return this.privileges.get(privilegeName); @@ -114,7 +127,7 @@ public class PrivilegeContext { return policy; } - // + // // business logic // @@ -151,4 +164,32 @@ public class PrivilegeContext { // delegate to the policy policy.validateAction(this, privilege, restrictable); } + + /** + * Validates if the user for this context has the privilege to access to the given {@link Restrictable}. Returning + * true if the user has the privilege, and false if not + * + * @param restrictable + * the {@link Restrictable} which the user wants to access + * + * @return returns true if the user has the privilege, and false if not + * + * @throws PrivilegeException + * if there is an internal error due to wrongly configured privileges or programming errors + */ + public boolean hasPrivilege(Restrictable restrictable) throws PrivilegeException { + + // the privilege for the restrictable + String privilegeName = restrictable.getPrivilegeName(); + IPrivilege privilege = this.privileges.get(privilegeName); + if (privilege == null) + return false; + + // get the policy referenced by the restrictable + String policyName = privilege.getPolicy(); + PrivilegePolicy policy = getPolicy(policyName); + + // delegate to the policy + return policy.hasPrivilege(this, privilege, restrictable); + } } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/DefaultPrivilege.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/DefaultPrivilege.java index 807175dcc..d135c5c07 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/DefaultPrivilege.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/DefaultPrivilege.java @@ -15,6 +15,8 @@ */ package li.strolch.privilege.policy; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.checkByAllowDenyValues; + import java.text.MessageFormat; import li.strolch.privilege.base.AccessDeniedException; @@ -36,11 +38,34 @@ public class DefaultPrivilege implements PrivilegePolicy { /** * The value of {@link Restrictable#getPrivilegeValue()} is used to check if the {@link Role} has this privilege * - * @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(IPrivilege, Restrictable) + * @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, IPrivilege, Restrictable) */ @Override public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException { + + String privilegeValue = validatePrivilegeValue(privilege, restrictable); + + // if everything is allowed, then no need to carry on + if (privilege.isAllAllowed()) + return; + + checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue, true); + } + + @Override + public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + + String privilegeValue = validatePrivilegeValue(privilege, restrictable); + + // if everything is allowed, then no need to carry on + if (privilege.isAllAllowed()) + return true; + + return checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue, false); + } + + private String validatePrivilegeValue(IPrivilege privilege, Restrictable restrictable) { PrivilegePolicyHelper.preValidate(privilege, restrictable); // get the value on which the action is to be performed @@ -54,12 +79,6 @@ public class DefaultPrivilege implements PrivilegePolicy { throw new PrivilegeException(msg); } - // if everything is allowed, then no need to carry on - if (privilege.isAllAllowed()) - return; - - String privilegeValue = (String) object; - - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); + return (String) object; } } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/PrivilegePolicy.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/PrivilegePolicy.java index 70bc06364..dcdd97d2d 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/PrivilegePolicy.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/PrivilegePolicy.java @@ -16,6 +16,7 @@ package li.strolch.privilege.policy; import li.strolch.privilege.base.AccessDeniedException; +import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.model.IPrivilege; import li.strolch.privilege.model.PrivilegeContext; import li.strolch.privilege.model.Restrictable; @@ -49,6 +50,25 @@ public interface PrivilegePolicy { * @throws AccessDeniedException * if action not allowed */ - public void validateAction(PrivilegeContext context, IPrivilege privilege, Restrictable restrictable) + void validateAction(PrivilegeContext context, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException; + + /** + * Returns true if the given {@link Role} and the given {@link IPrivilege} has access to the given {@link + * Restrictable} + * + * @param context + * the privilege context + * @param privilege + * the {@link IPrivilege} containing the permissions + * @param restrictable + * the {@link Restrictable} to which the user wants access + * + * @return true if the user has the privilege, false if not + * + * @throws AccessDeniedException + * if something goes wrong with the validate + */ + boolean hasPrivilege(PrivilegeContext context, IPrivilege privilege, Restrictable restrictable) + throws PrivilegeException; } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/PrivilegePolicyHelper.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/PrivilegePolicyHelper.java index fadf408b5..1ef85099c 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/PrivilegePolicyHelper.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/PrivilegePolicyHelper.java @@ -79,32 +79,40 @@ public class PrivilegePolicyHelper { * the restrictable * @param privilegeValue * the privilege value + * @param assertHasPrivilege + * if true and the privilege is missing, then an {@link AccessDeniedException} is thrown if privilege, otherwise a + * false is returned + * + * @return true if access is allowed, false if not allowed and assertHasPrivilege is false * * @throws AccessDeniedException * if access is denied */ - public static void checkByAllowDenyValues(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, - String privilegeValue) throws AccessDeniedException { + public static boolean checkByAllowDenyValues(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, + String privilegeValue, boolean assertHasPrivilege) throws AccessDeniedException { + + // first check values not allowed + if (privilege.isDenied(privilegeValue)) + return handleAccessDenied(ctx, privilege, restrictable, privilegeValue, assertHasPrivilege); // now check values allowed if (privilege.isAllowed(privilegeValue)) - return; + return true; - // first check values not allowed - if (privilege.isDenied(privilegeValue)) { + return handleAccessDenied(ctx, privilege, restrictable, privilegeValue, assertHasPrivilege); + } - // then throw access denied + private static boolean handleAccessDenied(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, + String privilegeValue, boolean assertHasPrivilege) { + + if (assertHasPrivilege) { String msg = MessageFormat .format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege.value"), //$NON-NLS-1$ ctx.getUsername(), privilege.getName(), privilegeValue, restrictable.getClass().getName()); + throw new AccessDeniedException(msg); } - // default is not allowed - String msg = MessageFormat - .format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege.value"), //$NON-NLS-1$ - ctx.getUsername(), privilege.getName(), privilegeValue, restrictable.getClass().getName()); - - throw new AccessDeniedException(msg); + return false; } } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/RoleAccessPrivilege.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/RoleAccessPrivilege.java index dd267b739..56c78d672 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/RoleAccessPrivilege.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/RoleAccessPrivilege.java @@ -15,6 +15,9 @@ */ package li.strolch.privilege.policy; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.checkByAllowDenyValues; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.preValidate; + import java.text.MessageFormat; import li.strolch.privilege.base.AccessDeniedException; @@ -41,14 +44,26 @@ public class RoleAccessPrivilege implements PrivilegePolicy { @Override public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException { - String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable); + validateAction(ctx, privilege, restrictable, true); + } + + @Override + public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws PrivilegeException { + return validateAction(ctx, privilege, restrictable, false); + } + + private boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, + boolean assertHasPrivilege) throws AccessDeniedException { + + String privilegeName = preValidate(privilege, restrictable); // get the value on which the action is to be performed Object object = restrictable.getPrivilegeValue(); - // if the object is null, then it means the validation is that the privilege must exist + // if the object is null, then the validation is only that the privilege must exist if (object == null) - return; + return true; // RoleAccessPrivilege policy expects the privilege value to be a role if (!(object instanceof Tuple)) { @@ -60,7 +75,7 @@ public class RoleAccessPrivilege implements PrivilegePolicy { // if everything is allowed, then no need to carry on if (privilege.isAllAllowed()) - return; + return true; Tuple tuple = (Tuple) object; @@ -69,25 +84,17 @@ public class RoleAccessPrivilege implements PrivilegePolicy { Role newRole = tuple.getSecond(); switch (privilegeName) { - case PrivilegeHandler.PRIVILEGE_GET_ROLE: { + + case PrivilegeHandler.PRIVILEGE_GET_ROLE: + case PrivilegeHandler.PRIVILEGE_ADD_ROLE: + case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE: { DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole); DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole); String privilegeValue = newRole.getName(); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; + return checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue, assertHasPrivilege); } - case PrivilegeHandler.PRIVILEGE_ADD_ROLE: { - DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole); - - String privilegeValue = newRole.getName(); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; - } case PrivilegeHandler.PRIVILEGE_MODIFY_ROLE: { DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldRole); DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole); @@ -95,21 +102,11 @@ public class RoleAccessPrivilege implements PrivilegePolicy { String privilegeValue = newRole.getName(); DBC.INTERIM.assertEquals("oldRole and newRole names must be the same", oldRole.getName(), privilegeValue); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; - } - case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE: { - DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole); - - String privilegeValue = newRole.getName(); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; + return checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue, assertHasPrivilege); } default: + String msg = Restrictable.class.getName() + PrivilegeMessages .getString("Privilege.roleAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$ msg = MessageFormat.format(msg, privilegeName); diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UserAccessPrivilege.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UserAccessPrivilege.java index 8031cb17c..528145847 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UserAccessPrivilege.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UserAccessPrivilege.java @@ -15,6 +15,9 @@ */ package li.strolch.privilege.policy; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.checkByAllowDenyValues; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.preValidate; + import java.text.MessageFormat; import li.strolch.privilege.base.AccessDeniedException; @@ -40,14 +43,26 @@ public class UserAccessPrivilege implements PrivilegePolicy { @Override public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException { - String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable); + validateAction(ctx, privilege, restrictable, true); + } + + @Override + public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws PrivilegeException { + return validateAction(ctx, privilege, restrictable, false); + } + + protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, + boolean assertHasPrivilege) throws AccessDeniedException { + + String privilegeName = preValidate(privilege, restrictable); // get the value on which the action is to be performed Object object = restrictable.getPrivilegeValue(); - // if the object is null, then it means the validation is that the privilege must exist + // if the object is null, then the validation is only that the privilege must exist if (object == null) - return; + return true; // RoleAccessPrivilege policy expects the privilege value to be a role if (!(object instanceof Tuple)) { @@ -59,48 +74,16 @@ public class UserAccessPrivilege implements PrivilegePolicy { // if everything is allowed, then no need to carry on if (privilege.isAllAllowed()) - return; + return true; Tuple tuple = (Tuple) object; switch (privilegeName) { - case PrivilegeHandler.PRIVILEGE_GET_USER: { - User oldUser = tuple.getFirst(); - User newUser = tuple.getSecond(); - - DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser); - - String privilegeValue = newUser.getUsername(); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; - } - case PrivilegeHandler.PRIVILEGE_ADD_USER: { - User oldUser = tuple.getFirst(); - User newUser = tuple.getSecond(); - - DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser); - - String privilegeValue = newUser.getUsername(); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; - } - case PrivilegeHandler.PRIVILEGE_REMOVE_USER: { - User oldUser = tuple.getFirst(); - User newUser = tuple.getSecond(); - - DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser); - - String privilegeValue = newUser.getUsername(); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; - } - case PrivilegeHandler.PRIVILEGE_MODIFY_USER: { + case PrivilegeHandler.PRIVILEGE_GET_USER: + case PrivilegeHandler.PRIVILEGE_ADD_USER: + case PrivilegeHandler.PRIVILEGE_REMOVE_USER: + case PrivilegeHandler.PRIVILEGE_MODIFY_USER: + case PrivilegeHandler.PRIVILEGE_SET_USER_STATE: { User oldUser = tuple.getFirst(); User newUser = tuple.getSecond(); @@ -110,45 +93,11 @@ public class UserAccessPrivilege implements PrivilegePolicy { String privilegeValue = newUser.getUsername(); DBC.INTERIM .assertEquals("oldUser and newUser names must be the same", oldUser.getUsername(), privilegeValue); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; + return checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue, assertHasPrivilege); } - case PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER: { - User user = tuple.getFirst(); - String roleName = tuple.getSecond(); - DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", roleName); - - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, roleName); - - break; - } - case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER: { - User user = tuple.getFirst(); - String roleName = tuple.getSecond(); - - DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", roleName); - - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, roleName); - - break; - } - case PrivilegeHandler.PRIVILEGE_SET_USER_STATE: { - User oldUser = tuple.getFirst(); - User newUser = tuple.getSecond(); - - DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldUser); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser); - - String privilegeValue = newUser.getUserState().name(); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; - } - case PrivilegeHandler.PRIVILEGE_SET_USER_LOCALE: { + case PrivilegeHandler.PRIVILEGE_SET_USER_LOCALE: + case PrivilegeHandler.PRIVILEGE_SET_USER_PASSWORD: { User oldUser = tuple.getFirst(); User newUser = tuple.getSecond(); @@ -159,28 +108,20 @@ public class UserAccessPrivilege implements PrivilegePolicy { // user can set their own locale if (ctx.getUsername().equals(privilegeValue)) - return; + return true; - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; + return checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue, assertHasPrivilege); } - case PrivilegeHandler.PRIVILEGE_SET_USER_PASSWORD: { - User oldUser = tuple.getFirst(); - User newUser = tuple.getSecond(); - DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldUser); - DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser); + case PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER: + case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER: { + User user = tuple.getFirst(); + String roleName = tuple.getSecond(); - String privilegeValue = newUser.getUsername(); + DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user); + DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", roleName); - // user can set their own password - if (ctx.getUsername().equals(privilegeValue)) - return; - - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); - - break; + return checkByAllowDenyValues(ctx, privilege, restrictable, roleName, assertHasPrivilege); } default: diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UserAccessWithSameOrganisationPrivilege.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UserAccessWithSameOrganisationPrivilege.java index a8761159d..15fe39677 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UserAccessWithSameOrganisationPrivilege.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UserAccessWithSameOrganisationPrivilege.java @@ -15,6 +15,9 @@ */ package li.strolch.privilege.policy; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.preValidate; +import static li.strolch.utils.helper.StringHelper.isEmpty; + import java.text.MessageFormat; import li.strolch.privilege.base.AccessDeniedException; @@ -27,7 +30,6 @@ import li.strolch.privilege.model.Restrictable; import li.strolch.privilege.model.internal.User; import li.strolch.utils.collections.Tuple; import li.strolch.utils.dbc.DBC; -import li.strolch.utils.helper.StringHelper; /** * Validates that any access to a privilege User is done only by users in the same organisation @@ -41,7 +43,19 @@ public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege @Override public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException { - String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable); + validateAction(ctx, privilege, restrictable, true); + } + + @Override + public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws PrivilegeException { + return validateAction(ctx, privilege, restrictable, false); + } + + protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, + boolean assertHasPrivilege) throws AccessDeniedException { + + String privilegeName = preValidate(privilege, restrictable); // get the value on which the action is to be performed Object object = restrictable.getPrivilegeValue(); @@ -56,9 +70,8 @@ public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege // get user organisation String userOrg = ctx.getCertificate().getProperty(PARAM_ORGANISATION); - if (StringHelper.isEmpty(userOrg)) { - throw new AccessDeniedException("No organisation configured for user " + ctx.getUsername()); - } + if (isEmpty(userOrg)) + throw new PrivilegeException("No organisation configured for user " + ctx.getUsername()); Tuple tuple = (Tuple) object; @@ -73,9 +86,12 @@ public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege if (oldUser != null) { String oldOrg = oldUser.getProperty(PARAM_ORGANISATION); if (!userOrg.equals(oldOrg)) { - throw new AccessDeniedException( - "User " + ctx.getUsername() + " may not access users outside of their organisation: " - + userOrg + " / " + oldOrg); + if (assertHasPrivilege) + throw new AccessDeniedException( + "User " + ctx.getUsername() + " may not access users outside of their organisation: " + + userOrg + " / " + oldOrg); + + return false; } } @@ -83,10 +99,14 @@ public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege User newUser = tuple.getSecond(); DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser); String newdOrg = newUser.getProperty(PARAM_ORGANISATION); + if (!userOrg.equals(newdOrg)) { - throw new AccessDeniedException( - "User " + ctx.getUsername() + " may not access users outside of their organisations: " + userOrg - + " / " + newdOrg); + if (assertHasPrivilege) + throw new AccessDeniedException( + "User " + ctx.getUsername() + " may not access users outside of their organisations: " + + userOrg + " / " + newdOrg); + + return false; } break; @@ -98,9 +118,13 @@ public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user); String org = user.getProperty(PARAM_ORGANISATION); if (!userOrg.equals(org)) { - throw new AccessDeniedException( - "User " + ctx.getUsername() + " may not access users outside of their organisation: " + userOrg - + " / " + org); + + if (assertHasPrivilege) + throw new AccessDeniedException( + "User " + ctx.getUsername() + " may not access users outside of their organisation: " + + userOrg + " / " + org); + + return false; } break; @@ -114,6 +138,6 @@ public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege } // now delegate the rest of the validation to the super class - super.validateAction(ctx, privilege, restrictable); + return super.validateAction(ctx, privilege, restrictable, assertHasPrivilege); } } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UsernameFromCertificatePrivilege.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UsernameFromCertificatePrivilege.java index b1d2fd83f..e3d3b7087 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UsernameFromCertificatePrivilege.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UsernameFromCertificatePrivilege.java @@ -15,6 +15,9 @@ */ package li.strolch.privilege.policy; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.checkByAllowDenyValues; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.preValidate; + import java.text.MessageFormat; import li.strolch.privilege.base.AccessDeniedException; @@ -43,7 +46,19 @@ public class UsernameFromCertificatePrivilege implements PrivilegePolicy { @Override public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException { - PrivilegePolicyHelper.preValidate(privilege, restrictable); + validateAction(ctx, privilege, restrictable, true); + } + + @Override + public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws PrivilegeException { + return validateAction(ctx, privilege, restrictable, false); + } + + protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, + boolean assertHasPrivilege) throws AccessDeniedException { + + preValidate(privilege, restrictable); // get the value on which the action is to be performed Object object = restrictable.getPrivilegeValue(); @@ -58,10 +73,10 @@ public class UsernameFromCertificatePrivilege implements PrivilegePolicy { // if everything is allowed, then no need to carry on if (privilege.isAllAllowed()) - return; + return true; Certificate cert = (Certificate) object; String privilegeValue = cert.getUsername(); - PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue); + return checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue, assertHasPrivilege); } } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UsernameFromCertificateWithSameOrganisationPrivilege.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UsernameFromCertificateWithSameOrganisationPrivilege.java index 5a76963fb..137742b1d 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UsernameFromCertificateWithSameOrganisationPrivilege.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/policy/UsernameFromCertificateWithSameOrganisationPrivilege.java @@ -15,6 +15,9 @@ */ package li.strolch.privilege.policy; +import static li.strolch.privilege.policy.PrivilegePolicyHelper.preValidate; +import static li.strolch.utils.helper.StringHelper.isEmpty; + import java.text.MessageFormat; import li.strolch.privilege.base.AccessDeniedException; @@ -24,7 +27,6 @@ import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.IPrivilege; import li.strolch.privilege.model.PrivilegeContext; import li.strolch.privilege.model.Restrictable; -import li.strolch.utils.helper.StringHelper; /** *

@@ -46,7 +48,19 @@ public class UsernameFromCertificateWithSameOrganisationPrivilege extends Userna @Override public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException { - PrivilegePolicyHelper.preValidate(privilege, restrictable); + validateAction(ctx, privilege, restrictable, true); + } + + @Override + public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws PrivilegeException { + return validateAction(ctx, privilege, restrictable, false); + } + + protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, + boolean assertHasPrivilege) throws AccessDeniedException { + + preValidate(privilege, restrictable); // get the value on which the action is to be performed Object object = restrictable.getPrivilegeValue(); @@ -64,18 +78,22 @@ public class UsernameFromCertificateWithSameOrganisationPrivilege extends Userna // get user organisation String userOrg = ctx.getCertificate().getProperty(PARAM_ORGANISATION); - if (StringHelper.isEmpty(userOrg)) { - throw new AccessDeniedException("No organisation configured for user " + ctx.getUsername()); - } + if (isEmpty(userOrg)) + throw new PrivilegeException("No organisation configured for user " + ctx.getUsername()); + // assert same organisation String org = cert.getProperty(PARAM_ORGANISATION); if (!userOrg.equals(org)) { - throw new AccessDeniedException( - "User " + ctx.getUsername() + " may not access users outside of their organisation: " + userOrg - + " / " + org); + + if (assertHasPrivilege) + throw new AccessDeniedException( + "User " + ctx.getUsername() + " may not access users outside of their organisation: " + userOrg + + " / " + org); + + return false; } // now delegate the rest of the validation to the super class - super.validateAction(ctx, privilege, restrictable); + return super.validateAction(ctx, privilege, restrictable, assertHasPrivilege); } }