diff --git a/src/main/java/org/caosdb/server/permissions/AbstractEntityACLFactory.java b/src/main/java/org/caosdb/server/permissions/AbstractEntityACLFactory.java index 7d7120ebd65dc5a21c9e76271aede9e58aa05f95..88247950fa8497973fd682da9fdedf612a091d6d 100644 --- a/src/main/java/org/caosdb/server/permissions/AbstractEntityACLFactory.java +++ b/src/main/java/org/caosdb/server/permissions/AbstractEntityACLFactory.java @@ -169,7 +169,17 @@ public abstract class AbstractEntityACLFactory<T extends EntityACL> { return create(acis); } + /** + * Normalize the permission rules. + * + * <p>This means that rules which are overriden by other rules are removed. E.g. a granting rule + * for the permission X and the agent P would be removed if there is a denial of X (for P) with + * the same or a higher priority. Likewise, A denial of Y for agent Q would be removed if there is + * a granting rule of Y (for Q) with a higher priority. + */ private void normalize() { + // 1. run through all prioritized denials and remove overriden rules + // (priority grants, normal grants and normal denials) Iterator<Entry<ResponsibleAgent, Long>> iterator = this.priorityDenials.entrySet().iterator(); while (iterator.hasNext()) { Entry<ResponsibleAgent, Long> next = iterator.next(); @@ -189,6 +199,8 @@ public abstract class AbstractEntityACLFactory<T extends EntityACL> { this.normalGrants.put(agent, this.normalGrants.get(agent) & ~bitset); } } + // 2. run through all prioritized grants and remove overriden rules (normal + // denials and grants) iterator = this.priorityGrants.entrySet().iterator(); while (iterator.hasNext()) { Entry<ResponsibleAgent, Long> next = iterator.next(); @@ -205,6 +217,7 @@ public abstract class AbstractEntityACLFactory<T extends EntityACL> { this.normalGrants.put(agent, this.normalGrants.get(agent) & ~bitset); } } + // 3. run through all normal denials and remove overriden rules (normal grants) iterator = this.normalDenials.entrySet().iterator(); while (iterator.hasNext()) { Entry<ResponsibleAgent, Long> next = iterator.next(); @@ -218,6 +231,7 @@ public abstract class AbstractEntityACLFactory<T extends EntityACL> { this.normalGrants.put(agent, this.normalGrants.get(agent) & ~bitset); } } + // finally, remove all remaining empty grants iterator = this.normalGrants.entrySet().iterator(); while (iterator.hasNext()) { Entry<ResponsibleAgent, Long> next = iterator.next(); @@ -237,9 +251,18 @@ public abstract class AbstractEntityACLFactory<T extends EntityACL> { protected abstract T create(Collection<EntityACI> acis); - public AbstractEntityACLFactory<T> remove(EntityACL permissions) { - if (permissions != null) { - for (EntityACI aci : permissions.getRules()) { + /** + * Remove all rules of the `other` EntityACL from this factory. + * + * <p>This is mainly used for removing all rules which belong to the global entity ACL from this + * ACL before storing it to the backend. + * + * @param other + * @return the same object with changed rule set. + */ + public AbstractEntityACLFactory<T> remove(EntityACL other) { + if (other != null) { + for (EntityACI aci : other.getRules()) { if (EntityACL.isAllowance(aci.getBitSet())) { if (EntityACL.isPriorityBitSet(aci.getBitSet())) { Long bitset = this.priorityGrants.get(aci.getResponsibleAgent());