Commit 26c64dc0 authored by Matija Obreza's avatar Matija Obreza

Merge branch 'acl-updates' into 'master'

Acl updates

See merge request genesys-pgr/application-blocks!41
parents a3588258 ce45ba76
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package org.genesys.blocks.security.persistence; package org.genesys.blocks.security.persistence;
import java.util.List;
import org.genesys.blocks.security.model.AclObjectIdentity; import org.genesys.blocks.security.model.AclObjectIdentity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
...@@ -45,4 +47,6 @@ public interface AclObjectIdentityPersistence extends JpaRepository<AclObjectIde ...@@ -45,4 +47,6 @@ public interface AclObjectIdentityPersistence extends JpaRepository<AclObjectIde
@Modifying @Modifying
@Query("update AclObjectIdentity aoi set aoi.parentObject = null where aoi.parentObject = ?1") @Query("update AclObjectIdentity aoi set aoi.parentObject = null where aoi.parentObject = ?1")
void resetChildrenOfOID(AclObjectIdentity oID); void resetChildrenOfOID(AclObjectIdentity oID);
List<AclObjectIdentity> findByParentObject(AclObjectIdentity parentObject);
} }
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package org.genesys.blocks.security.service; package org.genesys.blocks.security.service;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.genesys.blocks.util.JsonSidConverter; import org.genesys.blocks.util.JsonSidConverter;
...@@ -23,10 +24,14 @@ import org.genesys.blocks.security.model.AclClass; ...@@ -23,10 +24,14 @@ import org.genesys.blocks.security.model.AclClass;
import org.genesys.blocks.security.model.AclEntry; import org.genesys.blocks.security.model.AclEntry;
import org.genesys.blocks.security.model.AclObjectIdentity; import org.genesys.blocks.security.model.AclObjectIdentity;
import org.genesys.blocks.security.model.AclSid; 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.Permissions;
import org.genesys.blocks.security.serialization.SidPermissions; import org.genesys.blocks.security.serialization.SidPermissions;
import org.springframework.security.acls.model.Permission; import org.springframework.security.acls.model.Permission;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
/** /**
* The Interface CustomAclService. * The Interface CustomAclService.
*/ */
...@@ -170,6 +175,15 @@ public interface CustomAclService extends JsonSidConverter.SidProvider { ...@@ -170,6 +175,15 @@ public interface CustomAclService extends JsonSidConverter.SidProvider {
*/ */
AclObjectIdentity setPermissions(AclObjectIdentity objectIdentity, AclSid sid, final Permissions permissions); AclObjectIdentity setPermissions(AclObjectIdentity objectIdentity, AclSid sid, final Permissions permissions);
/**
* Removes the permissions for SID on ACL OID
*
* @param objectIdentity the object identity
* @param aclSid the acl sid
* @return the acl object identity
*/
AclObjectIdentity removePermissions(AclObjectIdentity objectIdentity, AclSid aclSid);
/** /**
* Gets the acl entries. * Gets the acl entries.
* *
...@@ -245,4 +259,26 @@ public interface CustomAclService extends JsonSidConverter.SidProvider { ...@@ -245,4 +259,26 @@ public interface CustomAclService extends JsonSidConverter.SidProvider {
* @return the sid name * @return the sid name
*/ */
String getSidName(long id); 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<AclEntry> inherited = new ArrayList<>();
public AclObjectIdentityExt(AclObjectIdentity source) {
this.original = source;
}
}
} }
...@@ -16,7 +16,9 @@ ...@@ -16,7 +16,9 @@
package org.genesys.blocks.security.service.impl; package org.genesys.blocks.security.service.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
...@@ -261,10 +263,10 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -261,10 +263,10 @@ public class CustomAclServiceImpl implements CustomAclService {
* permissions granted to the SID are removed. * permissions granted to the SID are removed.
*/ */
@Override @Override
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
public void removeAclAwareModel(final AclAwareModel target) { public void removeAclAwareModel(final AclAwareModel target) {
LOG.debug("Deleting ACL data for {}", target); LOG.debug("Deleting ACL data for {}", target);
if (target instanceof AclSid) { if (target instanceof AclSid) {
LOG.info("Deleting permissions for {}", target); LOG.info("Deleting permissions for {}", target);
removePermissionsFor((AclSid) target); removePermissionsFor((AclSid) target);
...@@ -272,6 +274,11 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -272,6 +274,11 @@ public class CustomAclServiceImpl implements CustomAclService {
final AclObjectIdentity aclObjectIdentity = getObjectIdentity(target); final AclObjectIdentity aclObjectIdentity = getObjectIdentity(target);
if (aclObjectIdentity != null) { if (aclObjectIdentity != null) {
LOG.debug("OID {}#{} of {}", aclObjectIdentity.getAclClass().getAclClass(), aclObjectIdentity.getObjectIdIdentity(), target);
for (AclObjectIdentity child : aclObjectIdentityPersistence.findByParentObject(aclObjectIdentity)) {
LOG.debug("Has child {}#{}", child.getAclClass().getAclClass(), child.getObjectIdIdentity());
}
LOG.info("Deleting ACL data of {}", target); LOG.info("Deleting ACL data of {}", target);
final List<AclEntry> aclEntries = aclEntryPersistence.findByObjectIdentity(aclObjectIdentity); final List<AclEntry> aclEntries = aclEntryPersistence.findByObjectIdentity(aclObjectIdentity);
if (aclEntries != null) { if (aclEntries != null) {
...@@ -341,7 +348,7 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -341,7 +348,7 @@ public class CustomAclServiceImpl implements CustomAclService {
clearAclCache(); clearAclCache();
} }
} }
private void clearAclCache() { private void clearAclCache() {
if (cacheManager!=null) { if (cacheManager!=null) {
final Cache aclCache = cacheManager.getCache("aclCache"); final Cache aclCache = cacheManager.getCache("aclCache");
...@@ -380,6 +387,38 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -380,6 +387,38 @@ public class CustomAclServiceImpl implements CustomAclService {
return aclClass; 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<AclEntry> 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<AclEntry> inherited(AclObjectIdentity objectIdentity, List<AclEntry> aclEntries, Set<AclObjectIdentity> 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) * (non-Javadoc)
...@@ -487,8 +526,13 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -487,8 +526,13 @@ public class CustomAclServiceImpl implements CustomAclService {
if (permissions == null) { if (permissions == null) {
throw new NullPointerException("Permissions must be provided, was null."); throw new NullPointerException("Permissions must be provided, was null.");
} }
String className = entity.getClass().getName();
if (entity instanceof ClassAclOid<?>) {
className = ((ClassAclOid<?>) entity).getClassName();
}
final AclObjectIdentity objectIdentity = getObjectIdentity(entity); final AclObjectIdentity objectIdentity = ensureObjectIdentity(entity.getId(), className);
return setPermissions(objectIdentity, sid, permissions); return setPermissions(objectIdentity, sid, permissions);
} }
...@@ -544,6 +588,32 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -544,6 +588,32 @@ public class CustomAclServiceImpl implements CustomAclService {
} }
} }
/* (non-Javadoc)
* @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.");
}
if (sid == null) {
throw new NullPointerException("AclSid must be provided, was null.");
}
try {
final List<AclEntry> 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());
} finally {
clearAclCache();
}
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.genesys.blocks.security.service.CustomAclService#getAclEntries(org. * @see org.genesys.blocks.security.service.CustomAclService#getAclEntries(org.
...@@ -627,7 +697,7 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -627,7 +697,7 @@ public class CustomAclServiceImpl implements CustomAclService {
* java.lang.String, long) * java.lang.String, long)
*/ */
@Override @Override
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
public AclObjectIdentity ensureObjectIdentity(final long objectIdIdentity, final String className) { public AclObjectIdentity ensureObjectIdentity(final long objectIdIdentity, final String className) {
AclObjectIdentity aoi = aclObjectIdentityPersistence.findByObjectIdAndClassname(objectIdIdentity, className); AclObjectIdentity aoi = aclObjectIdentityPersistence.findByObjectIdAndClassname(objectIdIdentity, className);
if (aoi == null) { if (aoi == null) {
...@@ -661,7 +731,7 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -661,7 +731,7 @@ public class CustomAclServiceImpl implements CustomAclService {
* .genesys.blocks.security.model.AclAwareModel, boolean) * .genesys.blocks.security.model.AclAwareModel, boolean)
*/ */
@Override @Override
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity, 'ADMINISTRATION')") @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity, 'ADMINISTRATION')")
public void makePubliclyReadable(AclAwareModel entity, boolean publiclyReadable) { public void makePubliclyReadable(AclAwareModel entity, boolean publiclyReadable) {
AclSid roleEveryone = getAuthoritySid("ROLE_EVERYONE"); AclSid roleEveryone = getAuthoritySid("ROLE_EVERYONE");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment