Commit 767e8087 authored by Matija Obreza's avatar Matija Obreza
Browse files

ACL services and repositories cleaned up

- Removed unreferenced methods
- Using sensible method names
parent 9fc9a60e
......@@ -50,48 +50,17 @@ public interface AclEntryPersistence extends JpaRepository<AclEntry, Long> {
List<AclEntry> findBySidAndObjectIdentity(@Param("aclSid") AclSid sid, @Param("aclObjectIdentity") AclObjectIdentity objectIdentity);
/**
* Find by object identity and object class id and sid.
*
* @param objectIdentityId - id of domain object
* @param aclClass - domain class
* @param sid - user's email
* @return - returns lists of user's permissions
*/
@Query("select ae from AclEntry ae join ae.aclObjectIdentity aoi join aoi.aclClass ac join ae.aclSid sid where aoi.objectIdIdentity=?1 and ac.aclClass=?2 and sid.sid=?3")
List<AclEntry> findByObjectIdentityAndObjectClassIdAndSid(long objectIdentityId, String aclClass, String sid);
/**
* Find by sid and acl class.
*
* @param sid - user's email
* @param aclClass - class of domain object
* @return - returns lists of user's permissions on domain class
*/
@Query("select ae from AclEntry ae join ae.aclObjectIdentity aoi join aoi.aclClass ac join ae.aclSid sid where sid.sid=?1 and ac.aclClass=?2")
List<AclEntry> findBySidAndAclClass(String sid, String aclClass);
/**
* Find by sid and object identity and mask.
* Find IDs of object of aclClass for sid with specified permissions.
*
* @param sid - user's email
* @param objectIdIdentity - id of domain object
* @param mask - mask for permissions
* @param className - class name
* @return - returns lists of user's permissions on domain class
*/
@Query("select count(ae) from AclEntry ae join ae.aclObjectIdentity aoi join aoi.aclClass ac join ae.aclSid sid where sid.sid=?1 and aoi.objectIdIdentity=?2 and ae.mask=?3 and ac.aclClass=?4")
Long findBySidAndObjectIdentityAndMask(String sid, long objectIdIdentity, long mask, String className);
/**
* Find object identities by sid and acl class and mask.
*
* @param sid - user's email
* @param sid - SID
* @param aclClass - class of domain object
* @param mask - mask for permissions
* @param mask - permissions
* @return - returns lists of user's permissions on domain class
*/
@Query("select aoi.objectIdIdentity from AclEntry ae join ae.aclObjectIdentity aoi join aoi.aclClass ac join ae.aclSid sid where sid.sid=?1 and ac.aclClass=?2 and ae.mask=?3")
List<Long> findObjectIdentitiesBySidAndAclClassAndMask(String sid, String aclClass, long mask);
@Query("select ae.aclObjectIdentity.objectIdIdentity from AclEntry ae where ae.aclSid=?1 and ae.aclObjectIdentity.aclClass.aclClass=?2 and ae.mask=?3 and ae.granting=true")
List<Long> findObjectIdentitiesForSidAndAclClassAndMask(AclSid sid, String aclClass, long mask);
/**
* Calculates max. ace_order for acl_object_identity to avoid DuplicateIndex
......@@ -106,12 +75,11 @@ public interface AclEntryPersistence extends JpaRepository<AclEntry, Long> {
/**
* Gets the sids.
*
* @param objectIdIdentity the object id identity
* @param aclClass the acl class
* @param objectIdentity the object identity
* @return the sids
*/
@Query("select distinct ae.aclSid from AclEntry ae join ae.aclObjectIdentity aoi join aoi.aclClass ac where aoi.objectIdIdentity = :objectIdIdentity and ac.aclClass = :aclClass")
List<AclSid> getSids(@Param("objectIdIdentity") long objectIdIdentity, @Param("aclClass") String aclClass);
@Query("select distinct ae.aclSid from AclEntry ae where ae.aclObjectIdentity = :objectIdentity")
List<AclSid> getSids(@Param("objectIdentity") AclObjectIdentity objectIdentity);
/**
* Delete AclEntries for a SID
......@@ -121,4 +89,5 @@ public interface AclEntryPersistence extends JpaRepository<AclEntry, Long> {
@Query("delete from AclEntry ae where ae.aclSid = :sid")
<T extends AclSid> int deleteForSid(@Param("sid") T sid);
}
......@@ -33,5 +33,5 @@ public interface AclObjectIdentityPersistence extends JpaRepository<AclObjectIde
* @return the acl object identity
*/
@Query("select aoi from AclObjectIdentity aoi where aoi.objectIdIdentity = :objectIdIdentity and aoi.aclClass.aclClass = :aclClass")
AclObjectIdentity findByObjectIdIdentityAndClassName(@Param("objectIdIdentity") long objectIdentityId, @Param("aclClass") String aclClass);
AclObjectIdentity findByIdAndClassname(@Param("objectIdIdentity") long objectIdentityId, @Param("aclClass") String aclClass);
}
......@@ -44,4 +44,5 @@ public interface AclSidPersistence extends JpaRepository<AclSid, Long> {
*/
@Query("select distinct sid from AclSid sid where sid.id in :ids")
List<AclSid> listById(@Param("ids") Iterable<Long> ids);
}
......@@ -23,13 +23,28 @@ import org.genesys.blocks.security.model.AclEntry;
import org.genesys.blocks.security.model.AclObjectIdentity;
import org.genesys.blocks.security.model.AclSid;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.core.userdetails.UserDetails;
/**
* The Interface CustomAclService.
*/
public interface CustomAclService {
/**
* Get SID by ID
*
* @param id -- ID of an AclSid entity
* @return
*/
AclSid getSid(Long id);
/**
* Gets the sid of the specified authority
*
* @param authority the authority
* @return the authority sid
*/
AclSid getAuthoritySid(String authority);
/**
* Adds the creator permissions.
*
......@@ -60,14 +75,6 @@ public interface CustomAclService {
*/
AclObjectIdentity getObjectIdentity(String clazz, long id);
/**
* Gets the object identity.
*
* @param id the id
* @return the object identity
*/
AclObjectIdentity getObjectIdentity(long id);
/**
* Gets the object identity.
*
......@@ -109,15 +116,6 @@ public interface CustomAclService {
*/
List<AclEntry> getAclEntries(AclObjectIdentity objectIdentity);
/**
* Update permission.
*
* @param entity the entity
* @param sid the sid
* @param permissionMap the permission map
*/
void updatePermission(AclObjectIdentity entity, String sid, Map<Integer, Boolean> permissionMap);
/**
* Update permissions.
*
......@@ -125,7 +123,9 @@ public interface CustomAclService {
* @param sid the sid
* @param permissionMap the permission map
*/
void updatePermission(AclAwareModel entity, AclSid sid, Map<Integer, Boolean> permissionMap);
void updatePermissions(AclAwareModel entity, AclSid sid, Map<Integer, Boolean> permissionMap);
void updatePermissions(AclObjectIdentity objectIdentity, AclSid sid, Map<Integer, Boolean> permissionMap);
/**
* Gets the acl entries.
......@@ -152,13 +152,6 @@ public interface CustomAclService {
*/
List<AclSid> getSids(AclAwareModel entity);
/**
* Gets the all sids.
*
* @return the all sids
*/
List<AclSid> getAllSids();
/**
* Adds the permissions.
*
......@@ -170,7 +163,6 @@ public interface CustomAclService {
*/
boolean addPermissions(long objectIdIdentity, String className, AclSid sid, Map<Integer, Boolean> permissions);
/**
* Adds the permissions.
*
......@@ -181,7 +173,6 @@ public interface CustomAclService {
*/
boolean addPermissions(AclAwareModel entity, AclSid sid, Map<Integer, Boolean> permissionMap);
/**
* Ensure object identity.
*
......@@ -192,24 +183,14 @@ public interface CustomAclService {
AclObjectIdentity ensureObjectIdentity(String className, long objectIdIdentity);
/**
* Permissions by sid.
*
* @param className the class name
* @param id the id
* @param sid the sid
* @return the list
*/
List<Integer> permissionsBySid(String className, Long id, String sid);
/**
* List identities for sid.
* List IDs of the specified class for the SID with specified permissions.
*
* @param clazz the clazz
* @param authUser the auth user
* @param sid the sid
* @param permission the permission
* @return the list
*/
List<Long> listIdentitiesForSid(Class<? extends AclAwareModel> clazz, UserDetails authUser, Permission permission);
List<Long> listObjectIdentityIdsForSid(Class<? extends AclAwareModel> clazz, AclSid sid, Permission permission);
/**
* Utility method that creates a non-granting permission map
......@@ -218,5 +199,4 @@ public interface CustomAclService {
*/
Map<Integer, Boolean> blankPermissionsMap();
}
......@@ -15,7 +15,6 @@
*/
package org.genesys.blocks.security.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -39,7 +38,6 @@ import org.springframework.cache.CacheManager;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
......@@ -58,10 +56,6 @@ public class CustomAclServiceImpl implements CustomAclService {
@Autowired
private AclObjectIdentityPersistence aclObjectIdentityPersistence;
/** The acl sid persistence. */
@Autowired
private AclSidPersistence aclSidPersistence;
/** The acl class persistence. */
@Autowired
private AclClassPersistence aclClassPersistence;
......@@ -74,6 +68,10 @@ public class CustomAclServiceImpl implements CustomAclService {
@Autowired
private CacheManager cacheManager;
/** The acl sid persistence. */
@Autowired
private AclSidPersistence aclSidPersistence;
static {
basePermissions = new Permission[] { BasePermission.CREATE, BasePermission.READ, BasePermission.WRITE, BasePermission.DELETE, BasePermission.ADMINISTRATION };
}
......@@ -94,7 +92,18 @@ public class CustomAclServiceImpl implements CustomAclService {
}
return map;
}
@Override
@Transactional(readOnly=true)
public AclSid getSid(Long id) {
return aclSidPersistence.findOne(id);
}
@Override
public AclSid getAuthoritySid(String authority) {
return ensureSidForAuthority(authority);
}
/*
* (non-Javadoc)
* @see
......@@ -128,8 +137,7 @@ public class CustomAclServiceImpl implements CustomAclService {
objectIdentity.setEntriesInheriting(false);
// save object identity
AclObjectIdentity savedAclObjectIdentity = aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(objectIdentity.getObjectIdIdentity(), objectIdentity.getAclClass()
.getAclClass());
AclObjectIdentity savedAclObjectIdentity = aclObjectIdentityPersistence.findByIdAndClassname(objectIdentity.getObjectIdIdentity(), objectIdentity.getAclClass().getAclClass());
if (savedAclObjectIdentity == null) {
savedAclObjectIdentity = aclObjectIdentityPersistence.save(objectIdentity);
final Map<Integer, Boolean> permissionsMap = new HashMap<>();
......@@ -184,7 +192,7 @@ public class CustomAclServiceImpl implements CustomAclService {
* @param sid the sid
* @param objectIdentity the object identity
* @param permissions the permissions
* @return
* @return
*/
private boolean addPermissions(final AclSid sid, final AclObjectIdentity objectIdentity, final Map<Integer, Boolean> permissions) {
// create Acl Entry
......@@ -254,18 +262,7 @@ public class CustomAclServiceImpl implements CustomAclService {
@Override
@Transactional(readOnly = true)
public AclObjectIdentity getObjectIdentity(final String className, final long id) {
return aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(id, className);
}
/*
* (non-Javadoc)
* @see
* org.genesys.blocks.security.service.CustomAclService#getObjectIdentity(long)
*/
@Override
@Transactional(readOnly = true)
public AclObjectIdentity getObjectIdentity(final long id) {
return aclObjectIdentityPersistence.findOne(id);
return aclObjectIdentityPersistence.findByIdAndClassname(id, className);
}
/*
......@@ -280,7 +277,7 @@ public class CustomAclServiceImpl implements CustomAclService {
if (entity == null) {
LOG.error("getObjectIdentity: Entity is null");
}
final AclObjectIdentity oid = aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(entity.getId(), entity.getClass().getName());
final AclObjectIdentity oid = aclObjectIdentityPersistence.findByIdAndClassname(entity.getId(), entity.getClass().getName());
if (oid == null) {
LOG.warn("ACL object identity not found for class={} id={}", entity.getClass().getName(), entity.getId());
}
......@@ -339,12 +336,12 @@ public class CustomAclServiceImpl implements CustomAclService {
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity, 'ADMINISTRATION')")
public void updatePermission(final AclAwareModel entity, final AclSid sid, final Map<Integer, Boolean> permissionMap) {
public void updatePermissions(final AclAwareModel entity, final AclSid sid, final Map<Integer, Boolean> permissions) {
boolean oneGranting = false;
final AclObjectIdentity objectIdentity = getObjectIdentity(entity);
final List<AclEntry> aclEntries = aclEntryPersistence.findBySidAndObjectIdentity(sid, objectIdentity);
for (final AclEntry aclEntry : aclEntries) {
aclEntry.setGranting(permissionMap.get((int) aclEntry.getMask()));
aclEntry.setGranting(permissions.get((int) aclEntry.getMask()));
oneGranting |= aclEntry.isGranting();
}
if (oneGranting) {
......@@ -354,35 +351,14 @@ public class CustomAclServiceImpl implements CustomAclService {
LOG.info("Deleting " + aclEntries);
aclEntryPersistence.delete(aclEntries);
}
clearAclCache();
}
/*
* (non-Javadoc)
* @see
* org.genesys.blocks.security.service.CustomAclService#updatePermission(org.
* genesys.blocks.security.model.AclObjectIdentity, java.lang.String,
* java.util.Map)
*/
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity.aclClass.id, #entity.aclClass.aclClass, 'ADMINISTRATION')")
public void updatePermission(final AclObjectIdentity entity, final String sid, final Map<Integer, Boolean> permissionMap) {
boolean oneGranting = false;
final List<AclEntry> aclEntries = aclEntryPersistence.findBySidAndAclClass(sid, entity.getAclClass().getAclClass());
for (final AclEntry aclEntry : aclEntries) {
aclEntry.setGranting(permissionMap.get((int) aclEntry.getMask()));
oneGranting |= aclEntry.isGranting();
}
if (oneGranting) {
LOG.info("Saving " + aclEntries);
aclEntryPersistence.save(aclEntries);
} else {
LOG.info("Deleting " + aclEntries);
aclEntryPersistence.delete(aclEntries);
}
clearAclCache();
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#objectIdentity.objectIdIdentity, #objectIdentity.aclClass.aclClass, 'ADMINISTRATION')")
public void updatePermissions(AclObjectIdentity objectIdentity, AclSid sid, Map<Integer, Boolean> permissions) {
updatePermissions(objectIdentity, sid, permissions);
}
/*
......@@ -415,7 +391,7 @@ public class CustomAclServiceImpl implements CustomAclService {
@Override
@Transactional(readOnly = true)
public List<AclSid> getSids(final long id, final String className) {
return aclEntryPersistence.getSids(id, className);
return aclEntryPersistence.getSids(getObjectIdentity(className, id));
}
/*
......@@ -428,24 +404,14 @@ public class CustomAclServiceImpl implements CustomAclService {
@Transactional(readOnly = true)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity, 'ADMINISTRATION')")
public List<AclSid> getSids(final AclAwareModel entity) {
return aclEntryPersistence.getSids(entity.getId(), entity.getClass().getName());
return aclEntryPersistence.getSids(getObjectIdentity(entity));
}
/*
* (non-Javadoc)
* @see org.genesys.blocks.security.service.CustomAclService#getAllSids()
*/
@Override
@Transactional(readOnly = true)
public List<AclSid> getAllSids() {
return aclSidPersistence.findAll();
public boolean addPermissions(AclAwareModel entity, AclSid sid, Map<Integer, Boolean> permissions) {
return addPermissions(sid, getObjectIdentity(entity), permissions);
}
@Override
public boolean addPermissions(AclAwareModel entity, AclSid sid, Map<Integer, Boolean> permissionMap) {
return addPermissions(sid, getObjectIdentity(entity), permissionMap);
}
/*
* (non-Javadoc)
* @see
......@@ -460,6 +426,23 @@ public class CustomAclServiceImpl implements CustomAclService {
return addPermissions(sid, oid, permissions);
}
/**
* Ensure ACL SID entry for the specified authority name (role)
*/
private AclSid ensureSidForAuthority(String authority) {
AclSid roleSid = aclSidPersistence.findBySidAndPrincipal(authority, false);
if (roleSid == null) {
LOG.warn("Creating AclSid for role '{}'", authority);
roleSid = new AclSid();
roleSid.setPrincipal(false);
roleSid.setSid(authority);
return aclSidPersistence.save(roleSid);
}
return roleSid;
}
/*
* (non-Javadoc)
* @see
......@@ -469,7 +452,7 @@ public class CustomAclServiceImpl implements CustomAclService {
@Override
@Transactional
public AclObjectIdentity ensureObjectIdentity(final String className, final long objectIdIdentity) {
AclObjectIdentity aoi = aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(objectIdIdentity, className);
AclObjectIdentity aoi = aclObjectIdentityPersistence.findByIdAndClassname(objectIdIdentity, className);
if (aoi == null) {
aoi = new AclObjectIdentity();
aoi.setObjectIdIdentity(objectIdIdentity);
......@@ -481,29 +464,6 @@ public class CustomAclServiceImpl implements CustomAclService {
return aoi;
}
/*
* (non-Javadoc)
* @see
* org.genesys.blocks.security.service.CustomAclService#permissionsBySid(java.
* lang.String, java.lang.Long, java.lang.String)
*/
@Override
public List<Integer> permissionsBySid(final String className, final Long id, final String sid) {
final Map<String, Map<Integer, Boolean>> map = getPermissions(id, className);
final Map<Integer, Boolean> permissionMap = map.get(sid);
final List<Integer> list = new ArrayList<>();
for (final Map.Entry<Integer, Boolean> e : permissionMap.entrySet()) {
final Integer key = e.getKey();
final Boolean value = e.getValue();
if (value) {
list.add(key);
}
}
return list;
}
/*
* (non-Javadoc)
* @see
......@@ -513,8 +473,8 @@ public class CustomAclServiceImpl implements CustomAclService {
*/
@Override
@Transactional(readOnly = true)
public List<Long> listIdentitiesForSid(final Class<? extends AclAwareModel> clazz, final UserDetails authUser, final Permission permission) {
return aclEntryPersistence.findObjectIdentitiesBySidAndAclClassAndMask(authUser.getUsername(), clazz.getName(), permission.getMask());
public List<Long> listObjectIdentityIdsForSid(final Class<? extends AclAwareModel> clazz, final AclSid sid, final Permission permission) {
return aclEntryPersistence.findObjectIdentitiesForSidAndAclClassAndMask(sid, clazz.getName(), permission.getMask());
}
}
......@@ -16,6 +16,7 @@
package org.genesys.blocks.security.tests;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
......@@ -100,6 +101,12 @@ public class PermissionsTest extends ServiceTest {
for (AclEntry entry : entries) {
assertThat(entry.getAclSid().getId(), equalTo(user.getId()));
}
// Test listObjectIdentityIdsForSid
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user, BasePermission.ADMINISTRATION), contains(acl1.getId()));
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user, BasePermission.CREATE), contains(acl1.getId()));
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user, BasePermission.DELETE), contains(acl1.getId()));
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user, BasePermission.READ), contains(acl1.getId()));
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user, BasePermission.WRITE), contains(acl1.getId()));
LOG.info("Removing user");
try {
......@@ -130,6 +137,13 @@ public class PermissionsTest extends ServiceTest {
aclService.addPermissions(acl1, user2, permissionMap);
assertThat("ACL entries should be doubled!", aclService.getAclEntries(acl1), hasSize(entryCount * 2));
// Test listObjectIdentityIdsForSid
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user2, BasePermission.CREATE), contains(acl1.getId()));
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user2, BasePermission.WRITE), hasSize(0));
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user2, BasePermission.READ), hasSize(0));
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user2, BasePermission.DELETE), hasSize(0));
assertThat(aclService.listObjectIdentityIdsForSid(AclEntity.class, user2, BasePermission.ADMINISTRATION), hasSize(0));
// LOG.info("Removing user");
testUserService.deleteUser(user2);
// LOG.info("User removed, ACL Entriess should be gone");
......
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