diff --git a/config/PrivilegeContainer.xml b/config/PrivilegeContainer.xml index 0c64f7a94..e87acad3c 100644 --- a/config/PrivilegeContainer.xml +++ b/config/PrivilegeContainer.xml @@ -17,7 +17,7 @@ - + diff --git a/config/PrivilegePolicies.xml b/config/PrivilegePolicies.xml new file mode 100644 index 000000000..2b2c6f486 --- /dev/null +++ b/config/PrivilegePolicies.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/config/PrivilegeRoles.xml b/config/PrivilegeRoles.xml index a09f1a393..89724934b 100644 --- a/config/PrivilegeRoles.xml +++ b/config/PrivilegeRoles.xml @@ -3,8 +3,11 @@ - + + + + \ No newline at end of file diff --git a/config/PrivilegeUsers.xml b/config/PrivilegeUsers.xml index cc8867f25..f03340020 100644 --- a/config/PrivilegeUsers.xml +++ b/config/PrivilegeUsers.xml @@ -7,8 +7,9 @@ ENABLED en_GB - admin PrivilegeAdmin + admin + serviceExecutor diff --git a/config/Privileges.xml b/config/Privileges.xml index e1fb1de4e..baec28f6c 100644 --- a/config/Privileges.xml +++ b/config/Privileges.xml @@ -1,10 +1,16 @@ - + true + + + false + + ch.eitchnet.privilege.test.TestRestrictable + \ No newline at end of file diff --git a/config/RestrictionPolicies.xml b/config/RestrictionPolicies.xml deleted file mode 100644 index acda375fe..000000000 --- a/config/RestrictionPolicies.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/docs/PrivilegeHandlers.dia b/docs/PrivilegeHandlers.dia new file mode 100644 index 000000000..4f8da83b7 Binary files /dev/null and b/docs/PrivilegeHandlers.dia differ diff --git a/docs/PrivilegeModelPrivilege.dia b/docs/PrivilegeModelPrivilege.dia new file mode 100644 index 000000000..f46a49ea6 Binary files /dev/null and b/docs/PrivilegeModelPrivilege.dia differ diff --git a/docs/PrivilegeModelUser.dia b/docs/PrivilegeModelUser.dia new file mode 100644 index 000000000..86d5b1149 Binary files /dev/null and b/docs/PrivilegeModelUser.dia differ diff --git a/src/ch/eitchnet/privilege/base/PrivilegeContainer.java b/src/ch/eitchnet/privilege/base/PrivilegeContainer.java index 1ffc36d3b..acd6ee315 100644 --- a/src/ch/eitchnet/privilege/base/PrivilegeContainer.java +++ b/src/ch/eitchnet/privilege/base/PrivilegeContainer.java @@ -130,10 +130,10 @@ public class PrivilegeContainer { String policyHandlerClassName = policyHandlerElement.attributeValue(XmlConstants.XML_ATTR_CLASS); PolicyHandler policyHandler = ClassHelper.instantiateClass(policyHandlerClassName); - // instantiate modification handler - Element modificationHandlerElement = containerRootElement.element(XmlConstants.XML_HANDLER_MODEL); - String modificationHandlerClassName = modificationHandlerElement.attributeValue(XmlConstants.XML_ATTR_CLASS); - ModelHandler modelHandler = ClassHelper.instantiateClass(modificationHandlerClassName); + // instantiate model handler + Element modelHandlerElement = containerRootElement.element(XmlConstants.XML_HANDLER_MODEL); + String modelHandlerClassName = modelHandlerElement.attributeValue(XmlConstants.XML_ATTR_CLASS); + ModelHandler modelHandler = ClassHelper.instantiateClass(modelHandlerClassName); try { persistenceHandler.initialize(persistenceHandlerElement); @@ -162,11 +162,11 @@ public class PrivilegeContainer { throw new PrivilegeException("PolicyHandler " + policyHandlerClassName + " could not be initialized"); } try { - modelHandler.initialize(modificationHandlerElement); + modelHandler.initialize(modelHandlerElement); modelHandler.setPersistenceHandler(persistenceHandler); } catch (Exception e) { logger.error(e, e); - throw new PrivilegeException("ModificationHandler " + modificationHandlerClassName + throw new PrivilegeException("ModificationHandler " + modelHandlerClassName + " could not be initialized"); } diff --git a/src/ch/eitchnet/privilege/base/XmlConstants.java b/src/ch/eitchnet/privilege/base/XmlConstants.java index 727841b53..d2c7400e4 100644 --- a/src/ch/eitchnet/privilege/base/XmlConstants.java +++ b/src/ch/eitchnet/privilege/base/XmlConstants.java @@ -19,7 +19,7 @@ public class XmlConstants { public static final String XML_ROOT_PRIVILEGE_ROLES = "PrivilegeRoles"; public static final String XML_ROOT_PRIVILEGES = "Privileges"; public static final String XML_ROOT_PRIVILEGE_USERS = "PrivilegesUsers"; - public static final String XML_ROOT_RESTRICTION_POLICIES = "RestrictionPolicies"; + public static final String XML_ROOT_PRIVILEGE_POLICIES = "PrivilegePolicies"; public static final String XML_HANDLER_PERSISTENCE = "PersistenceHandler"; public static final String XML_HANDLER_ENCRYPTION = "EncryptionHandler"; diff --git a/src/ch/eitchnet/privilege/handler/DefaultPolicyHandler.java b/src/ch/eitchnet/privilege/handler/DefaultPolicyHandler.java index a72f5c996..27dff956d 100644 --- a/src/ch/eitchnet/privilege/handler/DefaultPolicyHandler.java +++ b/src/ch/eitchnet/privilege/handler/DefaultPolicyHandler.java @@ -24,8 +24,9 @@ import ch.eitchnet.privilege.helper.ConfigurationHelper; import ch.eitchnet.privilege.helper.XmlHelper; import ch.eitchnet.privilege.i18n.PrivilegeException; import ch.eitchnet.privilege.model.Restrictable; +import ch.eitchnet.privilege.model.internal.Privilege; import ch.eitchnet.privilege.model.internal.Role; -import ch.eitchnet.privilege.policy.RestrictionPolicy; +import ch.eitchnet.privilege.policy.PrivilegePolicy; /** * @author rvonburg @@ -33,7 +34,7 @@ import ch.eitchnet.privilege.policy.RestrictionPolicy; */ public class DefaultPolicyHandler implements PolicyHandler { - private Map> policyMap; + private Map> policyMap; /** * @see ch.eitchnet.privilege.handler.PolicyHandler#actionAllowed(ch.eitchnet.privilege.model.internal.Role, @@ -48,26 +49,38 @@ public class DefaultPolicyHandler implements PolicyHandler { else if (restrictable == null) throw new PrivilegeException("Restrictable may not be null!"); - // validate restriction key for this restrictable - String restrictionKey = restrictable.getRestrictionKey(); - if (restrictionKey == null || restrictionKey.length() < 3) { + // validate PrivilegeName for this restrictable + String privilegeName = restrictable.getPrivilegeName(); + if (privilegeName == null || privilegeName.length() < 3) { throw new PrivilegeException( - "The RestrictionKey may not be shorter than 3 characters. Invalid Restrictable " + "The PrivilegeName may not be shorter than 3 characters. Invalid Restrictable " + restrictable.getClass().getName()); } - // get restriction policy class - Class policyClazz = policyMap.get(restrictionKey); - if (policyClazz == null) { - throw new PrivilegeException("No RestrictionPolicy exists for the RestrictionKey " + restrictionKey - + " for Restrictable " + restrictable.getClass().getName()); + // If the role does not have this privilege, then stop as another role might have this privilege + if (!role.hasPrivilege(privilegeName)) { + return false; } - // instantiate policy - RestrictionPolicy policy = ClassHelper.instantiateClass(policyClazz); + // get the privilege for this restrictable + Privilege privilege = PrivilegeContainer.getInstance().getModelHandler().getPrivilege(privilegeName); + if (privilege == null) { + throw new PrivilegeException("No Privilege exists with the name " + privilegeName + " for Restrictable " + + restrictable.getClass().getName()); + } - // delegate checking to restriction policy - return policy.actionAllowed(role, restrictable); + // get the policy class configured for this privilege + Class policyClazz = policyMap.get(privilege.getPolicy()); + if (policyClazz == null) { + throw new PrivilegeException("PrivilegePolicy " + privilege.getPolicy() + " does not exist for Privilege " + + privilegeName); + } + + // instantiate the policy + PrivilegePolicy policy = ClassHelper.instantiateClass(policyClazz); + + // delegate checking to privilege policy + return policy.actionAllowed(role, privilege, restrictable); } /** @@ -95,7 +108,7 @@ public class DefaultPolicyHandler implements PolicyHandler { + policyFile.getAbsolutePath()); } - policyMap = new HashMap>(); + policyMap = new HashMap>(); // parse policy xml file to XML document Element containerRootElement = XmlHelper.parseDocument(policyFile).getRootElement(); @@ -105,7 +118,7 @@ public class DefaultPolicyHandler implements PolicyHandler { String policyName = policyElement.attributeValue(XmlConstants.XML_ATTR_NAME); String policyClass = policyElement.attributeValue(XmlConstants.XML_ATTR_CLASS); - Class clazz = ClassHelper.loadClass(policyClass); + Class clazz = ClassHelper.loadClass(policyClass); policyMap.put(policyName, clazz); } diff --git a/src/ch/eitchnet/privilege/handler/SessionHandler.java b/src/ch/eitchnet/privilege/handler/SessionHandler.java index d019d0dbe..10e0b4fa4 100644 --- a/src/ch/eitchnet/privilege/handler/SessionHandler.java +++ b/src/ch/eitchnet/privilege/handler/SessionHandler.java @@ -49,7 +49,7 @@ public interface SessionHandler extends PrivilegeContainerObject { public boolean isCertificateValid(Certificate certificate); /** - * @param user + * @param username * @param password * * @return @@ -57,5 +57,5 @@ public interface SessionHandler extends PrivilegeContainerObject { * @throws AccessDeniedException * if the user credentials are not valid */ - public Certificate authenticate(String user, String password); + public Certificate authenticate(String username, String password); } diff --git a/src/ch/eitchnet/privilege/helper/BootstrapConfigurationHelper.java b/src/ch/eitchnet/privilege/helper/BootstrapConfigurationHelper.java index 14001dc08..db99ea0be 100644 --- a/src/ch/eitchnet/privilege/helper/BootstrapConfigurationHelper.java +++ b/src/ch/eitchnet/privilege/helper/BootstrapConfigurationHelper.java @@ -49,7 +49,7 @@ public class BootstrapConfigurationHelper { private static String hashAlgorithm = "SHA-256"; - private static String policyXmlFile = "RestrictionPolicies.xml"; + private static String policyXmlFile = "PrivilegePolicies.xml"; private static String defaultPersistenceHandler = "ch.eitchnet.privilege.handler.DefaultPersistenceHandler"; private static String defaultSessionHandler = "ch.eitchnet.privilege.handler.DefaultSessionHandler"; diff --git a/src/ch/eitchnet/privilege/model/Restrictable.java b/src/ch/eitchnet/privilege/model/Restrictable.java index 9a2952fac..155876e23 100644 --- a/src/ch/eitchnet/privilege/model/Restrictable.java +++ b/src/ch/eitchnet/privilege/model/Restrictable.java @@ -16,7 +16,7 @@ package ch.eitchnet.privilege.model; */ public interface Restrictable { - public String getRestrictionKey(); + public String getPrivilegeName(); - public Object getRestrictionValue(); + public Object getPrivilegeValue(); } diff --git a/src/ch/eitchnet/privilege/policy/DefaultPrivilege.java b/src/ch/eitchnet/privilege/policy/DefaultPrivilege.java new file mode 100644 index 000000000..097214169 --- /dev/null +++ b/src/ch/eitchnet/privilege/policy/DefaultPrivilege.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 + * + * Robert von Burg + * eitch@eitchnet.ch + * + * All rights reserved. + * + */ + +package ch.eitchnet.privilege.policy; + +import ch.eitchnet.privilege.i18n.PrivilegeException; +import ch.eitchnet.privilege.model.Restrictable; +import ch.eitchnet.privilege.model.internal.Privilege; +import ch.eitchnet.privilege.model.internal.Role; + +/** + * @author rvonburg + * + */ +public class DefaultPrivilege implements PrivilegePolicy { + + /** + * @see ch.eitchnet.privilege.policy.PrivilegePolicy#actionAllowed(ch.eitchnet.privilege.model.internal.Role, + * ch.eitchnet.privilege.model.internal.Privilege, ch.eitchnet.privilege.model.Restrictable) + */ + @Override + public boolean actionAllowed(Role role, Privilege privilege, Restrictable restrictable) { + + // validate user is not null + if (role == null) + throw new PrivilegeException("Role may not be null!"); + + // get the PrivilegeName + String privilegeName = restrictable.getPrivilegeName(); + if (privilegeName == null || privilegeName.isEmpty()) { + throw new PrivilegeException("The PrivilegeName for the Restrictable is null or empty: " + restrictable); + } + + // does this role have privilege for any values? + if (privilege.isAllAllowed()) + return true; + + // 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 String)) { + throw new PrivilegeException(Restrictable.class.getName() + " " + restrictable.getClass().getSimpleName() + + " has returned a non-string privilege value!"); + } + + String privilegeValue = (String) object; + + // first check values not allowed + for (String denied : privilege.getDenyList()) { + if (denied.equals(privilegeValue)) + return false; + } + + // now check values allowed + for (String allowed : privilege.getAllowList()) { + if (allowed.equals(privilegeValue)) + return true; + } + + // default is not allowed + return false; + } +} diff --git a/src/ch/eitchnet/privilege/policy/DefaultRestriction.java b/src/ch/eitchnet/privilege/policy/DefaultRestriction.java deleted file mode 100644 index d0d27d1e8..000000000 --- a/src/ch/eitchnet/privilege/policy/DefaultRestriction.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2010 - * - * Robert von Burg - * eitch@eitchnet.ch - * - * All rights reserved. - * - */ - -package ch.eitchnet.privilege.policy; - -import ch.eitchnet.privilege.base.PrivilegeContainer; -import ch.eitchnet.privilege.i18n.PrivilegeException; -import ch.eitchnet.privilege.model.Restrictable; -import ch.eitchnet.privilege.model.internal.Privilege; -import ch.eitchnet.privilege.model.internal.Role; - -/** - * @author rvonburg - * - */ -public class DefaultRestriction implements RestrictionPolicy { - - /** - * @see ch.eitchnet.privilege.policy.RestrictionPolicy#actionAllowed(java.lang.String, - * ch.eitchnet.privilege.model.internal.Role, ch.eitchnet.privilege.model.Restrictable) - */ - @Override - public boolean actionAllowed(Role role, Restrictable restrictable) { - - // validate user is not null - if (role == null) - throw new PrivilegeException("Role may not be null!"); - - // get the restriction key - String restrictionKey = restrictable.getRestrictionKey(); - if (restrictionKey == null || restrictionKey.isEmpty()) { - throw new PrivilegeException("The restriction key for the Restrictable is null or empty: " + restrictable); - } - - // get restriction object for users role - Privilege privilege = PrivilegeContainer.getInstance().getModelHandler().getPrivilege(restrictionKey); - - // no restriction object means no privilege - // TODO should default deny/allow policy be configurable? - if (privilege == null) - return false; - - // does this role have privilege for any values? - if (privilege.isAllAllowed()) - return true; - - // get the value on which the action is to be performed - Object object = restrictable.getRestrictionValue(); - - // DefaultRestriction policy expects the restriction value to be a string - if (!(object instanceof String)) { - throw new PrivilegeException(Restrictable.class.getName() + " " + restrictable.getClass().getSimpleName() - + " has returned a non-string restriction value!"); - } - - String restrictionValue = (String) object; - - // first check values not allowed - for (String denied : privilege.getDenyList()) { - if (denied.equals(restrictionValue)) - return false; - } - - // now check values allowed - for (String allowed : privilege.getAllowList()) { - if (allowed.equals(restrictionValue)) - return true; - } - - // default is not allowed - return false; - } -} diff --git a/src/ch/eitchnet/privilege/policy/RestrictionPolicy.java b/src/ch/eitchnet/privilege/policy/PrivilegePolicy.java similarity index 60% rename from src/ch/eitchnet/privilege/policy/RestrictionPolicy.java rename to src/ch/eitchnet/privilege/policy/PrivilegePolicy.java index 093ca1468..44c679e5b 100644 --- a/src/ch/eitchnet/privilege/policy/RestrictionPolicy.java +++ b/src/ch/eitchnet/privilege/policy/PrivilegePolicy.java @@ -11,13 +11,14 @@ package ch.eitchnet.privilege.policy; import ch.eitchnet.privilege.model.Restrictable; +import ch.eitchnet.privilege.model.internal.Privilege; import ch.eitchnet.privilege.model.internal.Role; /** * @author rvonburg * */ -public interface RestrictionPolicy { +public interface PrivilegePolicy { - public boolean actionAllowed(Role role, Restrictable restrictable); + public boolean actionAllowed(Role role, Privilege privilege, Restrictable restrictable); } diff --git a/test/ch/eitchnet/privilege/test/PrivilegeTest.java b/test/ch/eitchnet/privilege/test/PrivilegeTest.java index d7a6e748f..bfa8a7beb 100644 --- a/test/ch/eitchnet/privilege/test/PrivilegeTest.java +++ b/test/ch/eitchnet/privilege/test/PrivilegeTest.java @@ -26,6 +26,7 @@ import ch.eitchnet.privilege.handler.ModelHandler; import ch.eitchnet.privilege.i18n.AccessDeniedException; import ch.eitchnet.privilege.i18n.PrivilegeException; import ch.eitchnet.privilege.model.Certificate; +import ch.eitchnet.privilege.model.Restrictable; import ch.eitchnet.privilege.model.UserRep; import ch.eitchnet.privilege.model.UserState; @@ -185,4 +186,18 @@ public class PrivilegeTest { PrivilegeContainer.getInstance().getModelHandler().addOrReplaceUser(certificate, userRep, null); logger.info("Added user bob"); } + + @Test + public void testPerformRestrictable() throws Exception { + + Certificate certificate = PrivilegeContainer.getInstance().getSessionHandler().authenticate("eitch", + "1234567890"); + org.junit.Assert.assertTrue("Certificate is null!", certificate != null); + + // see if eitch can perform restrictable + Restrictable restrictable = new TestRestrictable(); + boolean actionAllowed = PrivilegeContainer.getInstance().getSessionHandler().actionAllowed(certificate, + restrictable); + org.junit.Assert.assertTrue("eitch may not perform restrictable!", actionAllowed); + } } diff --git a/test/ch/eitchnet/privilege/test/TestRestrictable.java b/test/ch/eitchnet/privilege/test/TestRestrictable.java new file mode 100644 index 000000000..1f65beef6 --- /dev/null +++ b/test/ch/eitchnet/privilege/test/TestRestrictable.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010 + * + * Robert von Burg + * eitch@eitchnet.ch + * + * All rights reserved. + * + */ + +package ch.eitchnet.privilege.test; + +import ch.eitchnet.privilege.model.Restrictable; + +/** + * @author rvonburg + * + */ +public class TestRestrictable implements Restrictable { + + /**@see ch.eitchnet.privilege.model.Restrictable#getPrivilegeName() + */ + @Override + public String getPrivilegeName() { + return "Service"; + } + + /**@see ch.eitchnet.privilege.model.Restrictable#getPrivilegeValue() + */ + @Override + public Object getPrivilegeValue() { + return TestRestrictable.class.getName(); + } + +}