diff --git a/security/src/main/java/org/genesys/blocks/security/service/CustomAclService.java b/security/src/main/java/org/genesys/blocks/security/service/CustomAclService.java index 77c90998164b3c0785944c08231b9412fc9c8a54..d104d0122c5cefff17792ff591d0ecf8921ed1f5 100644 --- a/security/src/main/java/org/genesys/blocks/security/service/CustomAclService.java +++ b/security/src/main/java/org/genesys/blocks/security/service/CustomAclService.java @@ -15,6 +15,7 @@ */ package org.genesys.blocks.security.service; +import java.util.ArrayList; import java.util.List; import org.genesys.blocks.util.JsonSidConverter; @@ -23,10 +24,14 @@ import org.genesys.blocks.security.model.AclClass; import org.genesys.blocks.security.model.AclEntry; import org.genesys.blocks.security.model.AclObjectIdentity; import org.genesys.blocks.security.model.AclSid; +import org.genesys.blocks.security.serialization.AclEntriesToPermissions; import org.genesys.blocks.security.serialization.Permissions; import org.genesys.blocks.security.serialization.SidPermissions; import org.springframework.security.acls.model.Permission; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + /** * The Interface CustomAclService. */ @@ -255,4 +260,25 @@ public interface CustomAclService extends JsonSidConverter.SidProvider { */ String getSidName(long id); + /** + * Load object identity extended information + * + * @param objectIdentity the object identity + * @return the acl object identity ext + */ + AclObjectIdentityExt loadObjectIdentityExt(AclObjectIdentity objectIdentity); + + /** + * Wraps {@link AclObjectIdentity} and adds list of inherited permissions. + */ + public static class AclObjectIdentityExt { + @JsonUnwrapped + public AclObjectIdentity original; + @JsonSerialize(converter = AclEntriesToPermissions.class) + public List inherited = new ArrayList<>(); + + public AclObjectIdentityExt(AclObjectIdentity source) { + this.original = source; + } + } } diff --git a/security/src/main/java/org/genesys/blocks/security/service/impl/CustomAclServiceImpl.java b/security/src/main/java/org/genesys/blocks/security/service/impl/CustomAclServiceImpl.java index 30cdbe570c8aa13d56f3b314e842fdda6c85533d..e063fd159511da5a84c69d8dca10ce80082387c7 100644 --- a/security/src/main/java/org/genesys/blocks/security/service/impl/CustomAclServiceImpl.java +++ b/security/src/main/java/org/genesys/blocks/security/service/impl/CustomAclServiceImpl.java @@ -16,7 +16,9 @@ package org.genesys.blocks.security.service.impl; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.persistence.EntityManager; @@ -385,6 +387,38 @@ public class CustomAclServiceImpl implements CustomAclService { return aclClass; } + + @Override + @Transactional(readOnly = true) + public AclObjectIdentityExt loadObjectIdentityExt(AclObjectIdentity objectIdentity) { + if (objectIdentity != null) { + objectIdentity = getObjectIdentity(objectIdentity.getId()); + AclObjectIdentityExt _aclObjectIdentity = new AclObjectIdentityExt(objectIdentity); + objectIdentity.getAclEntries().forEach(entry -> entry.getAclSid().getId()); + + List inheritedEntries = inherited(objectIdentity.getParentObject(), new ArrayList<>(), new HashSet<>()); + _aclObjectIdentity.inherited.addAll(inheritedEntries); + // lazy load for JSON + _aclObjectIdentity.inherited.forEach(entry -> entry.getAclSid().getId()); + return _aclObjectIdentity; + } + + return null; + } + + private List inherited(AclObjectIdentity objectIdentity, List aclEntries, Set handled) { + if (objectIdentity == null || handled.contains(objectIdentity)) { + return aclEntries; + } + aclEntries.addAll(objectIdentity.getAclEntries()); + handled.add(objectIdentity); + + if (objectIdentity.getParentObject() != null) { + inherited(objectIdentity.getParentObject(), aclEntries, handled); + } + + return aclEntries; + } /* * (non-Javadoc) @@ -558,6 +592,7 @@ public class CustomAclServiceImpl implements CustomAclService { * @see org.genesys.blocks.security.service.CustomAclService#removePermissions(org.genesys.blocks.security.model.AclObjectIdentity, org.genesys.blocks.security.model.AclSid) */ @Override + @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED) public AclObjectIdentity removePermissions(AclObjectIdentity objectIdentity, AclSid sid) { if (objectIdentity == null) { throw new NullPointerException("AclObjectIdentity must be provided, was null."); @@ -569,6 +604,7 @@ public class CustomAclServiceImpl implements CustomAclService { try { final List aclEntries = aclEntryPersistence.findBySidAndObjectIdentity(sid, objectIdentity); // delete ACL entries for sid + LOG.debug("Deleting {} AclEntries for {}", aclEntries.size(), sid); aclEntryPersistence.delete(aclEntries); return getObjectIdentity(objectIdentity.getId());