diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingActivityMap.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingActivityMap.java index 4174d3874..d3e76ee57 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingActivityMap.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingActivityMap.java @@ -25,7 +25,6 @@ import li.strolch.model.activity.Activity; import li.strolch.model.query.ActivityQuery; import li.strolch.model.visitor.ActivityVisitor; import li.strolch.persistence.api.StrolchTransaction; -import li.strolch.runtime.privilege.PrivilegeHandler; import li.strolch.utils.dbc.DBC; /** @@ -37,9 +36,8 @@ import li.strolch.utils.dbc.DBC; */ public class AuditingActivityMap extends AuditingElementMapFacade implements ActivityMap { - public AuditingActivityMap(PrivilegeHandler privilegeHandler, ElementMap elementMap, - boolean observeAccessReads) { - super(privilegeHandler, elementMap, observeAccessReads); + public AuditingActivityMap(ElementMap elementMap, boolean observeAccessReads) { + super(elementMap, observeAccessReads); } @Override diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingElementMapFacade.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingElementMapFacade.java index 4b64bbb10..b817e7823 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingElementMapFacade.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingElementMapFacade.java @@ -15,8 +15,6 @@ */ package li.strolch.agent.impl; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_GET_PREFIX; - import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -30,8 +28,6 @@ import li.strolch.model.StrolchRootElement; import li.strolch.model.parameter.StringListParameter; import li.strolch.model.parameter.StringParameter; import li.strolch.persistence.api.StrolchTransaction; -import li.strolch.runtime.privilege.PrivilegeHandler; -import li.strolch.runtime.privilege.TransactedRestrictable; import li.strolch.utils.dbc.DBC; /** @@ -53,7 +49,6 @@ import li.strolch.utils.dbc.DBC; */ public abstract class AuditingElementMapFacade implements ElementMap { - private PrivilegeHandler privilegeHandler; protected ElementMap elementMap; protected Set read; @@ -65,11 +60,8 @@ public abstract class AuditingElementMapFacade imp protected boolean observeAccessReads; - public AuditingElementMapFacade(PrivilegeHandler privilegeHandler, ElementMap elementMap, - boolean observeAccessReads) { - DBC.PRE.assertNotNull("PrivilegeHandler must be set!", privilegeHandler); //$NON-NLS-1$ + public AuditingElementMapFacade(ElementMap elementMap, boolean observeAccessReads) { DBC.PRE.assertNotNull("ElementMap must be set!", elementMap); //$NON-NLS-1$ - this.privilegeHandler = privilegeHandler; this.elementMap = elementMap; this.observeAccessReads = observeAccessReads; @@ -165,11 +157,6 @@ public abstract class AuditingElementMapFacade imp @Override public T getBy(StrolchTransaction tx, String type, String id) { T element = this.elementMap.getBy(tx, type, id); - - if (element != null) - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()) - .validateAction(new TransactedRestrictable(tx, PRIVILEGE_GET_PREFIX + getElementType(), element)); - if (this.observeAccessReads && element != null) this.read.add(element); return element; @@ -180,11 +167,6 @@ public abstract class AuditingElementMapFacade imp @Override public T getBy(StrolchTransaction tx, String type, String id, boolean assertExists) throws StrolchException { T element = this.elementMap.getBy(tx, type, id, assertExists); - - if (element != null) - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()) - .validateAction(new TransactedRestrictable(tx, PRIVILEGE_GET_PREFIX + getElementType(), element)); - if (this.observeAccessReads && element != null) this.read.add(element); return element; @@ -193,11 +175,6 @@ public abstract class AuditingElementMapFacade imp @Override public T getBy(StrolchTransaction tx, String type, String id, int version) { T element = this.elementMap.getBy(tx, type, id, version); - - if (element != null) - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()) - .validateAction(new TransactedRestrictable(tx, PRIVILEGE_GET_PREFIX + getElementType(), element)); - if (this.observeAccessReads && element != null) this.read.add(element); return element; @@ -207,11 +184,6 @@ public abstract class AuditingElementMapFacade imp public T getBy(StrolchTransaction tx, String type, String id, int version, boolean assertExists) throws StrolchException { T element = this.elementMap.getBy(tx, type, id, version, assertExists); - - if (element != null) - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()) - .validateAction(new TransactedRestrictable(tx, PRIVILEGE_GET_PREFIX + getElementType(), element)); - if (this.observeAccessReads && element != null) this.read.add(element); return element; @@ -220,11 +192,6 @@ public abstract class AuditingElementMapFacade imp @Override public T getBy(StrolchTransaction tx, StringParameter refP, boolean assertExists) throws StrolchException { T element = this.elementMap.getBy(tx, refP, assertExists); - - if (element != null) - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()) - .validateAction(new TransactedRestrictable(tx, PRIVILEGE_GET_PREFIX + getElementType(), element)); - if (this.observeAccessReads && element != null) this.read.add(element); return element; @@ -234,12 +201,6 @@ public abstract class AuditingElementMapFacade imp public List getBy(StrolchTransaction tx, StringListParameter refP, boolean assertExists) throws StrolchException { List elements = this.elementMap.getBy(tx, refP, assertExists); - - for (T element : elements) { - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()) - .validateAction(new TransactedRestrictable(tx, PRIVILEGE_GET_PREFIX + getElementType(), element)); - } - if (this.observeAccessReads && !elements.isEmpty()) this.read.addAll(elements); return elements; @@ -248,11 +209,6 @@ public abstract class AuditingElementMapFacade imp @Override public List getVersionsFor(StrolchTransaction tx, String type, String id) { List versions = this.elementMap.getVersionsFor(tx, type, id); - - if (!versions.isEmpty()) - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()).validateAction(new TransactedRestrictable(tx, - PRIVILEGE_GET_PREFIX + getElementType(), versions.get(versions.size() - 1))); - if (this.observeAccessReads && !versions.isEmpty()) this.read.add(versions.get(versions.size() - 1)); return versions; @@ -261,12 +217,6 @@ public abstract class AuditingElementMapFacade imp @Override public List getAllElements(StrolchTransaction tx) { List elements = this.elementMap.getAllElements(tx); - - for (T element : elements) { - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()) - .validateAction(new TransactedRestrictable(tx, PRIVILEGE_GET_PREFIX + getElementType(), element)); - } - if (this.observeAccessReads && !elements.isEmpty()) this.read.addAll(elements); return elements; @@ -275,12 +225,6 @@ public abstract class AuditingElementMapFacade imp @Override public List getElementsBy(StrolchTransaction tx, String type) { List elements = this.elementMap.getElementsBy(tx, type); - - for (T element : elements) { - this.privilegeHandler.getPrivilegeContext(tx.getCertificate()) - .validateAction(new TransactedRestrictable(tx, PRIVILEGE_GET_PREFIX + getElementType(), element)); - } - if (this.observeAccessReads && !elements.isEmpty()) this.read.addAll(elements); return elements; diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingOrderMap.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingOrderMap.java index e7e90c55e..8c9410a54 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingOrderMap.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingOrderMap.java @@ -25,7 +25,6 @@ import li.strolch.model.Tags; import li.strolch.model.query.OrderQuery; import li.strolch.model.visitor.OrderVisitor; import li.strolch.persistence.api.StrolchTransaction; -import li.strolch.runtime.privilege.PrivilegeHandler; import li.strolch.utils.dbc.DBC; /** @@ -37,9 +36,8 @@ import li.strolch.utils.dbc.DBC; */ public class AuditingOrderMap extends AuditingElementMapFacade implements OrderMap { - public AuditingOrderMap(PrivilegeHandler privilegeHandler, ElementMap elementMap, - boolean observeAccessReads) { - super(privilegeHandler, elementMap, observeAccessReads); + public AuditingOrderMap(ElementMap elementMap, boolean observeAccessReads) { + super(elementMap, observeAccessReads); } @Override diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingResourceMap.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingResourceMap.java index 7685c5854..e1002e01a 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingResourceMap.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/AuditingResourceMap.java @@ -25,7 +25,6 @@ import li.strolch.model.Tags; import li.strolch.model.query.ResourceQuery; import li.strolch.model.visitor.StrolchElementVisitor; import li.strolch.persistence.api.StrolchTransaction; -import li.strolch.runtime.privilege.PrivilegeHandler; import li.strolch.utils.dbc.DBC; /** @@ -37,9 +36,8 @@ import li.strolch.utils.dbc.DBC; */ public class AuditingResourceMap extends AuditingElementMapFacade implements ResourceMap { - public AuditingResourceMap(PrivilegeHandler privilegeHandler, ElementMap elementMap, - boolean observeAccessReads) { - super(privilegeHandler, elementMap, observeAccessReads); + public AuditingResourceMap(ElementMap elementMap, boolean observeAccessReads) { + super(elementMap, observeAccessReads); } @Override diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java index 0d0678067..b5505af9b 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java @@ -16,15 +16,6 @@ package li.strolch.persistence.api; import static li.strolch.model.Tags.AGENT; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_ADD_ACTIVITY; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_ADD_ORDER; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_ADD_RESOURCE; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_REMOVE_ACTIVITY; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_REMOVE_ORDER; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_REMOVE_RESOURCE; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_UPDATE_ACTIVITY; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_UPDATE_ORDER; -import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_UPDATE_RESOURCE; import java.text.MessageFormat; import java.util.ArrayList; @@ -83,6 +74,7 @@ import li.strolch.model.query.StrolchQuery; import li.strolch.model.timedstate.StrolchTimedState; import li.strolch.model.timevalue.IValue; import li.strolch.model.visitor.ElementTypeVisitor; +import li.strolch.privilege.base.AccessDeniedException; import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.PrivilegeContext; @@ -324,7 +316,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { @Override public ResourceMap getResourceMap() { if (this.resourceMap == null) { - this.resourceMap = new AuditingResourceMap(this.privilegeHandler, this.realm.getResourceMap(), + this.resourceMap = new AuditingResourceMap(this.realm.getResourceMap(), this.realm.isAuditTrailEnabledForRead()); } return this.resourceMap; @@ -333,8 +325,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { @Override public OrderMap getOrderMap() { if (this.orderMap == null) { - this.orderMap = new AuditingOrderMap(this.privilegeHandler, this.realm.getOrderMap(), - this.realm.isAuditTrailEnabledForRead()); + this.orderMap = new AuditingOrderMap(this.realm.getOrderMap(), this.realm.isAuditTrailEnabledForRead()); } return this.orderMap; } @@ -342,7 +333,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { @Override public ActivityMap getActivityMap() { if (this.activityMap == null) { - this.activityMap = new AuditingActivityMap(this.privilegeHandler, this.realm.getActivityMap(), + this.activityMap = new AuditingActivityMap(this.realm.getActivityMap(), this.realm.isAuditTrailEnabledForRead()); } return this.activityMap; @@ -666,102 +657,71 @@ public abstract class AbstractTransaction implements StrolchTransaction { return this.objectFilter; } + @Override + public void assertHasPrivilege(Operation operation, StrolchRootElement element) throws AccessDeniedException { + DBC.PRE.assertNotNull("operation must not be null", operation); + DBC.PRE.assertNotNull("element must not be null", element); + this.privilegeHandler.getPrivilegeContext(this.certificate) + .validateAction(new TransactedRestrictable(this, operation.getPrivilegeName(element), element)); + } + @Override public void addResource(Resource resource) throws StrolchModelException { DBC.PRE.assertNotNull("resource must not be null", resource); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_ADD_RESOURCE, resource)); - DBC.PRE.assertFalse("resource already exists with id " + resource.getId(), getResourceMap().hasElement(this, resource.getType(), resource.getId())); - getObjectFilter().add(Tags.RESOURCE, resource); } @Override public void addOrder(Order order) throws StrolchException { DBC.PRE.assertNotNull("order must not be null", order); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_ADD_ORDER, order)); - DBC.PRE.assertFalse("order already exists with id " + order.getId(), getOrderMap().hasElement(this, order.getType(), order.getId())); - getObjectFilter().add(Tags.ORDER, order); } @Override public void addActivity(Activity activity) throws StrolchException { DBC.PRE.assertNotNull("activity must not be null", activity); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_ADD_ACTIVITY, activity)); - DBC.PRE.assertFalse("activity already exists with id " + activity.getId(), getActivityMap().hasElement(this, activity.getType(), activity.getId())); - getObjectFilter().add(Tags.ACTIVITY, activity); } @Override public void updateResource(Resource resource) throws StrolchException { DBC.PRE.assertNotNull("resource must not be null", resource); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_UPDATE_RESOURCE, resource)); - getObjectFilter().update(Tags.RESOURCE, resource); } @Override public void updateOrder(Order order) { DBC.PRE.assertNotNull("order must not be null", order); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_UPDATE_ORDER, order)); - getObjectFilter().update(Tags.ORDER, order); } @Override public void updateActivity(Activity activity) throws StrolchException { DBC.PRE.assertNotNull("activity must not be null", activity); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_UPDATE_ACTIVITY, activity)); - getObjectFilter().update(Tags.ACTIVITY, activity); } @Override public void removeResource(Resource resource) throws StrolchException { DBC.PRE.assertNotNull("resource must not be null", resource); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_REMOVE_RESOURCE, resource)); - getObjectFilter().remove(Tags.RESOURCE, resource); } @Override public void removeOrder(Order order) throws StrolchException { DBC.PRE.assertNotNull("order must not be null", order); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_REMOVE_ORDER, order)); - getObjectFilter().remove(Tags.ORDER, order); } @Override public void removeActivity(Activity activity) throws StrolchException { DBC.PRE.assertNotNull("activity must not be null", activity); - - this.privilegeHandler.getPrivilegeContext(this.certificate) - .validateAction(new TransactedRestrictable(this, PRIVILEGE_REMOVE_ACTIVITY, activity)); - getObjectFilter().remove(Tags.ACTIVITY, activity); } diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/Operation.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/Operation.java new file mode 100644 index 000000000..246aa0fad --- /dev/null +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/Operation.java @@ -0,0 +1,26 @@ +package li.strolch.persistence.api; + +import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_ADD_PREFIX; +import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_GET_PREFIX; +import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_REMOVE_PREFIX; +import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_UPDATE_PREFIX; + +import li.strolch.model.StrolchRootElement; + +public enum Operation { + GET(PRIVILEGE_GET_PREFIX), // + ADD(PRIVILEGE_ADD_PREFIX), // + UPDATE(PRIVILEGE_UPDATE_PREFIX), // + REMOVE(PRIVILEGE_REMOVE_PREFIX); + + private String privilegePrefix; + + public String getPrivilegeName(StrolchRootElement element) { + return this.privilegePrefix + element.getObjectType(); + } + + private Operation(String privilegePrefix) { + this.privilegePrefix = privilegePrefix; + + } +} diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java index d72a5da76..2321e8a1e 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java @@ -49,6 +49,7 @@ import li.strolch.model.query.ResourceQuery; import li.strolch.model.visitor.ActivityVisitor; import li.strolch.model.visitor.OrderVisitor; import li.strolch.model.visitor.ResourceVisitor; +import li.strolch.privilege.base.AccessDeniedException; import li.strolch.privilege.model.Certificate; import li.strolch.runtime.StrolchConstants; import li.strolch.service.api.Command; @@ -1056,4 +1057,16 @@ public interface StrolchTransaction extends AutoCloseable { * if the activity is null */ public void removeActivity(Activity activity) throws StrolchException; + + /** + * Asserts that the current {@link Certificate} has access to the given element with the given operation + * + * @param operation + * the operation to be performed + * @param element + * the element on which the operation is performed + * + * @throws AccessDeniedException + */ + public void assertHasPrivilege(Operation operation, StrolchRootElement element) throws AccessDeniedException; } diff --git a/li.strolch.agent/src/main/java/li/strolch/runtime/StrolchConstants.java b/li.strolch.agent/src/main/java/li/strolch/runtime/StrolchConstants.java index be937cf7c..183cde0c3 100644 --- a/li.strolch.agent/src/main/java/li/strolch/runtime/StrolchConstants.java +++ b/li.strolch.agent/src/main/java/li/strolch/runtime/StrolchConstants.java @@ -101,18 +101,9 @@ public class StrolchConstants { public static final String PRIVILEGE_INVALIDATE_SESSION = "InvalidateSession"; public static final String PRIVILEGE_GET_SESSION = "GetSession"; - public static final String PRIVILEGE_ADD_RESOURCE = "AddResource"; - public static final String PRIVILEGE_UPDATE_RESOURCE = "UpdateResource"; - public static final String PRIVILEGE_REMOVE_RESOURCE = "RemoveResource"; - - public static final String PRIVILEGE_ADD_ORDER = "AddOrder"; - public static final String PRIVILEGE_UPDATE_ORDER = "UpdateOrder"; - public static final String PRIVILEGE_REMOVE_ORDER = "RemoveOrder"; - - public static final String PRIVILEGE_ADD_ACTIVITY = "AddActivity"; - public static final String PRIVILEGE_UPDATE_ACTIVITY = "UpdateActivity"; - public static final String PRIVILEGE_REMOVE_ACTIVITY = "RemoveActivity"; - + public static final String PRIVILEGE_ADD_PREFIX= "Add"; + public static final String PRIVILEGE_UPDATE_PREFIX= "Update"; + public static final String PRIVILEGE_REMOVE_PREFIX= "Remove"; public static final String PRIVILEGE_GET_PREFIX= "Get"; public static final String INTERNAL = StrolchModelConstants.INTERNAL; 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 67de8c556..a381502d4 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 @@ -3,6 +3,7 @@ package li.strolch.runtime.privilege; import java.text.MessageFormat; import li.strolch.model.StrolchRootElement; +import li.strolch.privilege.base.AccessDeniedException; import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.i18n.PrivilegeMessages; import li.strolch.privilege.model.IPrivilege; @@ -20,7 +21,8 @@ public class ModelPrivilege implements PrivilegePolicy { * @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(IPrivilege, Restrictable) */ @Override - public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws AccessDeniedException { PrivilegePolicyHelper.preValidate(privilege, restrictable); // get the value on which the action is to be performed diff --git a/li.strolch.model/src/main/java/li/strolch/model/Order.java b/li.strolch.model/src/main/java/li/strolch/model/Order.java index 2971e1b27..8205106a3 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/Order.java +++ b/li.strolch.model/src/main/java/li/strolch/model/Order.java @@ -81,6 +81,11 @@ public class Order extends AbstractStrolchRootElement implements StrolchRootElem setDate(date); } + @Override + public String getObjectType() { + return Tags.ORDER; + } + @Override public boolean hasVersion() { return this.version != null; diff --git a/li.strolch.model/src/main/java/li/strolch/model/Resource.java b/li.strolch.model/src/main/java/li/strolch/model/Resource.java index 5db1d3efa..b6c78bfd9 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/Resource.java +++ b/li.strolch.model/src/main/java/li/strolch/model/Resource.java @@ -62,6 +62,11 @@ public class Resource extends AbstractStrolchRootElement implements StrolchRootE super(id, name, type); } + @Override + public String getObjectType() { + return Tags.RESOURCE; + } + @Override public boolean hasVersion() { return this.version != null; diff --git a/li.strolch.model/src/main/java/li/strolch/model/StrolchRootElement.java b/li.strolch.model/src/main/java/li/strolch/model/StrolchRootElement.java index 5a774a112..63a9d9831 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/StrolchRootElement.java +++ b/li.strolch.model/src/main/java/li/strolch/model/StrolchRootElement.java @@ -26,6 +26,13 @@ import li.strolch.model.visitor.StrolchRootElementVisitor; */ public interface StrolchRootElement extends StrolchElement, PolicyContainer, ParameterBagContainer { + /** + * Returns the object type + * + * @return the object type + */ + public String getObjectType(); + /** * Set the type of this {@link StrolchRootElement}. Not that this method should only be called for new elements, not * if this element has already been persisted! diff --git a/li.strolch.model/src/main/java/li/strolch/model/activity/Activity.java b/li.strolch.model/src/main/java/li/strolch/model/activity/Activity.java index 43721ef45..345be8ae4 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/activity/Activity.java +++ b/li.strolch.model/src/main/java/li/strolch/model/activity/Activity.java @@ -83,6 +83,11 @@ public class Activity extends AbstractStrolchRootElement this.timeOrdering = timeOrdering; } + @Override + public String getObjectType() { + return Tags.ACTIVITY; + } + public TimeOrdering getTimeOrdering() { return this.timeOrdering; } 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 69c6bea21..363cbefe2 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 @@ -17,6 +17,7 @@ package li.strolch.privilege.policy; import java.text.MessageFormat; +import li.strolch.privilege.base.AccessDeniedException; import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.i18n.PrivilegeMessages; import li.strolch.privilege.model.IPrivilege; @@ -38,7 +39,8 @@ public class DefaultPrivilege implements PrivilegePolicy { * @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(IPrivilege, Restrictable) */ @Override - public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws AccessDeniedException { PrivilegePolicyHelper.preValidate(privilege, restrictable); // get the value on which the action is to be performed 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 fe6daff9e..20b0f2e2c 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 @@ -49,6 +49,6 @@ public interface PrivilegePolicy { * @throws AccessDeniedException * if action not allowed */ - public abstract void validateAction(PrivilegeContext context, IPrivilege privilege, Restrictable restrictable) + public void validateAction(PrivilegeContext context, IPrivilege privilege, Restrictable restrictable) throws AccessDeniedException; } 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 d8540b339..53b637de3 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 @@ -30,7 +30,20 @@ import li.strolch.utils.helper.StringHelper; */ public class PrivilegePolicyHelper { - public static String preValidate(IPrivilege privilege, Restrictable restrictable) { + /** + * Validates the given values and returns the privilege name + * + * @param privilege + * the {@link IPrivilege} + * @param restrictable + * the {@link Restrictable} + * + * @return the privilege name + * + * @throws PrivilegeException + * if something is wrong + */ + public static String preValidate(IPrivilege privilege, Restrictable restrictable) throws PrivilegeException { if (privilege == null) throw new PrivilegeException(PrivilegeMessages.getString("Privilege.privilegeNull")); //$NON-NLS-1$ if (restrictable == null) @@ -54,27 +67,42 @@ public class PrivilegePolicyHelper { } /** + * Validates privilege is granted by checking first if all is allows, then the deny values, then the allow values. + * If the privilegeValue is in the deny list or not in the allow list, then access is denied and the + * {@link AccessDeniedException} is thrown + * + * @param ctx + * the context * @param privilege + * the privielge + * @param restrictable + * the restrictable * @param privilegeValue + * the privilege value + * + * @throws AccessDeniedException + * if access is denied */ public static void checkByAllowDenyValues(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable, - String privilegeValue) { + String privilegeValue) throws AccessDeniedException { + + // now check values allowed + if (privilege.isAllowed(privilegeValue)) + return; // first check values not allowed if (privilege.isDenied(privilegeValue)) { + // then throw access denied 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); } - // now check values allowed - if (privilege.isAllowed(privilegeValue)) - return; - // 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); } } 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 e0dfb4676..73d7a13ac 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 @@ -17,6 +17,7 @@ package li.strolch.privilege.policy; import java.text.MessageFormat; +import li.strolch.privilege.base.AccessDeniedException; import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.handler.PrivilegeHandler; import li.strolch.privilege.i18n.PrivilegeMessages; @@ -38,7 +39,8 @@ import li.strolch.utils.dbc.DBC; public class RoleAccessPrivilege implements PrivilegePolicy { @Override - public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws AccessDeniedException { String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable); // get the value on which the action is to be performed 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 ca46ec55e..9d2e9f36c 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 @@ -17,6 +17,7 @@ package li.strolch.privilege.policy; import java.text.MessageFormat; +import li.strolch.privilege.base.AccessDeniedException; import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.handler.PrivilegeHandler; import li.strolch.privilege.i18n.PrivilegeMessages; @@ -37,7 +38,8 @@ import li.strolch.utils.dbc.DBC; public class UserAccessPrivilege implements PrivilegePolicy { @Override - public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws AccessDeniedException { String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable); // get the value on which the action is to be performed 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 5f02ae266..60f25e27d 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 @@ -39,7 +39,8 @@ public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege private static final String PARAM_ORGANISATION = "organisation"; @Override - public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws AccessDeniedException { String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable); // get the value on which the action is to be performed 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 a95d2d11e..3596c9461 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 @@ -17,6 +17,7 @@ package li.strolch.privilege.policy; import java.text.MessageFormat; +import li.strolch.privilege.base.AccessDeniedException; import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.i18n.PrivilegeMessages; import li.strolch.privilege.model.Certificate; @@ -40,7 +41,8 @@ import li.strolch.privilege.model.Restrictable; public class UsernameFromCertificatePrivilege implements PrivilegePolicy { @Override - public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws AccessDeniedException { PrivilegePolicyHelper.preValidate(privilege, restrictable); // get the value on which the action is to be performed 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 79ceb086d..46b4ba080 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 @@ -44,7 +44,8 @@ public class UsernameFromCertificateWithSameOrganisationPrivilege extends Userna private static final String PARAM_ORGANISATION = "organisation"; @Override - public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) + throws AccessDeniedException { PrivilegePolicyHelper.preValidate(privilege, restrictable); // get the value on which the action is to be performed diff --git a/li.strolch.service/src/test/java/li/strolch/command/InMemoryTransactionTest.java b/li.strolch.service/src/test/java/li/strolch/command/InMemoryTransactionTest.java index e1f28dc05..1a49dd34b 100644 --- a/li.strolch.service/src/test/java/li/strolch/command/InMemoryTransactionTest.java +++ b/li.strolch.service/src/test/java/li/strolch/command/InMemoryTransactionTest.java @@ -7,6 +7,7 @@ import static li.strolch.service.test.AbstractRealmServiceTest.dropSchema; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.junit.BeforeClass; import org.junit.Test; @@ -16,7 +17,9 @@ import li.strolch.model.Order; import li.strolch.model.Resource; import li.strolch.model.activity.Activity; import li.strolch.model.activity.TimeOrdering; +import li.strolch.persistence.api.Operation; import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.privilege.base.AccessDeniedException; import li.strolch.privilege.model.Certificate; import li.strolch.testbase.runtime.RuntimeMock; @@ -31,7 +34,6 @@ public class InMemoryTransactionTest { public static void beforeClass() throws Exception { dropSchema("jdbc:postgresql://localhost/cacheduserdb", "cacheduser", "test"); - dropSchema("jdbc:postgresql://localhost/transactionaluserdb", "transactionaluser", "test"); runtimeMock = new RuntimeMock().mockRuntime(TARGET_RUNTIME, CONFIG_SRC); runtimeMock.startContainer(); @@ -44,15 +46,15 @@ public class InMemoryTransactionTest { @Test public void runTransient() { - shouldRunAll(REALM_TRANSIENT); + runAll(REALM_TRANSIENT); } @Test public void runCached() { - shouldRunAll(REALM_CACHED); + runAll(REALM_CACHED); } - private void shouldRunAll(String realmName) { + private void runAll(String realmName) { shouldCrudResource(realmName); shouldCrudResource1(realmName); @@ -65,6 +67,136 @@ public class InMemoryTransactionTest { shouldCrudActivity(realmName); shouldCrudActivity1(realmName); shouldCrudActivity2(realmName); + + shouldAssertPrivilegeResource(realmName); + shouldAssertPrivilegeOrder(realmName); + shouldAssertPrivilegeActivity(realmName); + } + + private void shouldAssertPrivilegeResource(String realmName) { + String id = "@203"; + String type = "Car"; + + // create + Resource newRes = ModelGenerator.createResource(id, "200", type); + try (StrolchTransaction tx = openTx(realmName)) { + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.GET, newRes); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.ADD, newRes); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.UPDATE, newRes); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.REMOVE, newRes); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + } + } + + private void shouldAssertPrivilegeOrder(String realmName) { + String id = "@203"; + String type = "Car"; + + // create + Order newOrder = ModelGenerator.createOrder(id, "200", type); + try (StrolchTransaction tx = openTx(realmName)) { + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.GET, newOrder); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.ADD, newOrder); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.UPDATE, newOrder); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.REMOVE, newOrder); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + } + } + + private void shouldAssertPrivilegeActivity(String realmName) { + String id = "@203"; + String type = "Car"; + + // create + Activity newActivity = ModelGenerator.createActivity(id, "200", type, TimeOrdering.SERIES); + try (StrolchTransaction tx = openTx(realmName)) { + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.GET, newActivity); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.ADD, newActivity); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.UPDATE, newActivity); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + + // privilege assertion + try { + tx.assertHasPrivilege(Operation.REMOVE, newActivity); + fail(); + } catch (AccessDeniedException e) { + // as expected + } + } } public void shouldCrudResource(String realmName) { @@ -74,6 +206,10 @@ public class InMemoryTransactionTest { // create Resource newRes = ModelGenerator.createResource(id, "200", type); try (StrolchTransaction tx = openTx(realmName)) { + + // privilege assertion + tx.assertHasPrivilege(Operation.ADD, newRes); + tx.addResource(newRes); tx.commitOnClose(); } @@ -86,6 +222,11 @@ public class InMemoryTransactionTest { // update try (StrolchTransaction tx = openTx(realmName)) { Resource res = tx.getResourceBy(type, id); + + // privilege assertion + tx.assertHasPrivilege(Operation.GET, res); + tx.assertHasPrivilege(Operation.UPDATE, res); + res.setName("Foo foo"); tx.updateResource(res); tx.commitOnClose(); @@ -100,6 +241,10 @@ public class InMemoryTransactionTest { // remove try (StrolchTransaction tx = openTx(realmName)) { Resource res = tx.getResourceBy(type, id); + + // privilege assertion + tx.assertHasPrivilege(Operation.REMOVE, res); + tx.removeResource(res); tx.commitOnClose(); } @@ -129,6 +274,10 @@ public class InMemoryTransactionTest { // create Order newOrder = ModelGenerator.createOrder(id, "200", type); try (StrolchTransaction tx = openTx(realmName)) { + + // privilege assertion + tx.assertHasPrivilege(Operation.ADD, newOrder); + tx.addOrder(newOrder); tx.commitOnClose(); } @@ -141,6 +290,11 @@ public class InMemoryTransactionTest { // update try (StrolchTransaction tx = openTx(realmName)) { Order order = tx.getOrderBy(type, id); + + // privilege assertion + tx.assertHasPrivilege(Operation.GET, order); + tx.assertHasPrivilege(Operation.UPDATE, order); + order.setName("Foo foo"); tx.updateOrder(order); tx.commitOnClose(); @@ -155,6 +309,10 @@ public class InMemoryTransactionTest { // remove try (StrolchTransaction tx = openTx(realmName)) { Order order = tx.getOrderBy(type, id); + + // privilege assertion + tx.assertHasPrivilege(Operation.REMOVE, order); + tx.removeOrder(order); tx.commitOnClose(); } @@ -184,6 +342,10 @@ public class InMemoryTransactionTest { // create Activity newActivity = ModelGenerator.createActivity(id, "200", type, TimeOrdering.SERIES); try (StrolchTransaction tx = openTx(realmName)) { + + // privilege assertion + tx.assertHasPrivilege(Operation.ADD, newActivity); + tx.addActivity(newActivity); tx.commitOnClose(); } @@ -196,6 +358,11 @@ public class InMemoryTransactionTest { // update try (StrolchTransaction tx = openTx(realmName)) { Activity activity = tx.getActivityBy(type, id); + + // privilege assertion + tx.assertHasPrivilege(Operation.GET, activity); + tx.assertHasPrivilege(Operation.UPDATE, activity); + activity.setName("Foo foo"); tx.updateActivity(activity); tx.commitOnClose(); @@ -210,6 +377,10 @@ public class InMemoryTransactionTest { // remove try (StrolchTransaction tx = openTx(realmName)) { Activity activity = tx.getActivityBy(type, id); + + // privilege assertion + tx.assertHasPrivilege(Operation.REMOVE, activity); + tx.removeActivity(activity); tx.commitOnClose(); } @@ -255,7 +426,7 @@ public class InMemoryTransactionTest { String id = "@202"; String type = "Bike"; - // create and update + // create, update and remove Resource newRes = ModelGenerator.createResource(id, "200", type); try (StrolchTransaction tx = openTx(realmName)) { tx.addResource(newRes); @@ -304,7 +475,7 @@ public class InMemoryTransactionTest { tx.commitOnClose(); } - // should not exist + // create, update and remove try (StrolchTransaction tx = openTx(realmName)) { assertFalse("Order should not exist!", tx.getOrderMap().hasElement(tx, type, id)); } @@ -333,7 +504,7 @@ public class InMemoryTransactionTest { String id = "@202"; String type = "Bike"; - // create and update + // create, update and remove Activity newActivity = ModelGenerator.createActivity(id, "200", type, TimeOrdering.SERIES); try (StrolchTransaction tx = openTx(realmName)) { tx.addActivity(newActivity); diff --git a/li.strolch.service/src/test/resources/svctest/config/PrivilegeRoles.xml b/li.strolch.service/src/test/resources/svctest/config/PrivilegeRoles.xml index 0efa7b233..98277681a 100644 --- a/li.strolch.service/src/test/resources/svctest/config/PrivilegeRoles.xml +++ b/li.strolch.service/src/test/resources/svctest/config/PrivilegeRoles.xml @@ -60,40 +60,40 @@ - true + Bike - true + Bike - true + Bike - true + Bike - true + Bike - true + Bike - true + Bike - true + Bike - true + Bike - true + Bike - true + Bike - true + Bike