Commit c5ffd35f authored by Matija Obreza's avatar Matija Obreza
Browse files

ACL editor

parent c041cea8
...@@ -87,7 +87,7 @@ public class AsAdminAspect { ...@@ -87,7 +87,7 @@ public class AsAdminAspect {
} else { } else {
LOG.warn("Got SYS_ADMIN account: " + sysUser); LOG.warn("Got SYS_ADMIN account: " + sysUser);
AuthUserDetails userDetails = new AuthUserDetails(sysUser.getEmail(), "", Arrays.asList(new SimpleGrantedAuthority(UserRole.ADMINISTRATOR AuthUserDetails userDetails = new AuthUserDetails(sysUser.getUuid(), "", Arrays.asList(new SimpleGrantedAuthority(UserRole.ADMINISTRATOR
.getName()))); .getName())));
userDetails.setUser(sysUser); userDetails.setUser(sysUser);
......
...@@ -30,7 +30,6 @@ public interface UserPersistence extends JpaRepository<User, Long> { ...@@ -30,7 +30,6 @@ public interface UserPersistence extends JpaRepository<User, Long> {
@Query("select u from User u where u.email = ?1 and u.systemAccount = true") @Query("select u from User u where u.email = ?1 and u.systemAccount = true")
User findSystemUser(String username); User findSystemUser(String username);
@Query("select u from User u where u.uuid = ?1 and u.systemAccount = false")
User findByUuid(String uuid); User findByUuid(String uuid);
} }
...@@ -58,9 +58,9 @@ public interface AclService { ...@@ -58,9 +58,9 @@ public interface AclService {
List<AclSid> getSids(long id, String className); List<AclSid> getSids(long id, String className);
Map<AclSid, Map<Long, Boolean>> getPermissions(AclAwareModel entity); Map<String, Map<Integer, Boolean>> getPermissions(AclAwareModel entity);
Map<AclSid, Map<Long, Boolean>> getPermissions(long id, String className); Map<String, Map<Integer, Boolean>> getPermissions(long id, String className);
boolean addPermissions(long objectIdIdentity, String className, String uuid, boolean principal, Map<Integer, Boolean> permissions); boolean addPermissions(long objectIdIdentity, String className, String uuid, boolean principal, Map<Integer, Boolean> permissions);
......
...@@ -51,277 +51,259 @@ import java.util.Map; ...@@ -51,277 +51,259 @@ import java.util.Map;
@Transactional @Transactional
public class AclServiceImpl implements AclService { public class AclServiceImpl implements AclService {
private static final Logger LOG = LoggerFactory.getLogger(AclServiceImpl.class); private static final Logger LOG = LoggerFactory.getLogger(AclServiceImpl.class);
private static Permission[] basePermissions; private static Permission[] basePermissions;
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired @Autowired
private AclClassPersistence aclClassPersistence; private AclClassPersistence aclClassPersistence;
@Autowired @Autowired
private AclEntryPersistence aclEntryPersistence; private AclEntryPersistence aclEntryPersistence;
@Autowired @Autowired
private AclObjectIdentityPersistence aclObjectIdentityPersistence; private AclObjectIdentityPersistence aclObjectIdentityPersistence;
@Autowired @Autowired
private AclSidPersistence aclSidPersistence; private AclSidPersistence aclSidPersistence;
@Autowired @Autowired
private AsAdminAspect asAdminAspect; private AsAdminAspect asAdminAspect;
@Autowired @Autowired
private CacheManager cacheManager; private CacheManager cacheManager;
static { static {
basePermissions = new Permission[] { BasePermission.CREATE, BasePermission.READ, BasePermission.WRITE, BasePermission.DELETE, basePermissions = new Permission[] { BasePermission.CREATE, BasePermission.READ, BasePermission.WRITE, BasePermission.DELETE,
BasePermission.ADMINISTRATION }; BasePermission.ADMINISTRATION };
} }
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) public Permission[] getAvailablePermissions(String className) {
public Permission[] getAvailablePermissions(String className) { // Do not remove parameter. We may change available permissions based on
// Do not remove parameter. We may change available permissions based on // parameter type!
// parameter type! return basePermissions;
return basePermissions; }
}
@Override
@Override // @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#id, #className, 'ADMINISTRATION')")
// @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#id, #className, 'ADMINISTRATION')") public boolean addPermissions(long objectIdIdentity, String className, String uuid, boolean principal, Map<Integer, Boolean> permissions) {
public boolean addPermissions(long objectIdIdentity, String className, String uuid, boolean principal, Map<Integer, Boolean> permissions) { AclSid sid = ensureSid(uuid, principal);
AclSid sid = ensureSid(uuid, principal); AclObjectIdentity oid = ensureObjectIdentity(className, objectIdIdentity);
AclObjectIdentity oid = ensureObjectIdentity(className, objectIdIdentity);
addPermissions(sid, oid, permissions);
addPermissions(sid, oid, permissions); return true;
return true; }
}
@Override
@Override public synchronized void addCreatorPermissions(AclAwareModel target) {
public synchronized void addCreatorPermissions(AclAwareModel target) { if (target == null) {
if (target == null) { LOG.warn("No target specified for ACL permissions, bailing out!");
LOG.warn("No target specified for ACL permissions, bailing out!"); return;
return; }
} // assume that auth user has already AclSid implemented
// assume that auth user has already AclSid implemented AuthUserDetails authUser = SecurityContextUtil.getAuthUser();
AuthUserDetails authUser = SecurityContextUtil.getAuthUser(); if (authUser == null) {
if (authUser == null) { LOG.warn("No user in security context, not doing ACL");
LOG.warn("No user in security context, not doing ACL"); return;
return; }
}
String uuid = authUser.getUsername();
String uuid = authUser.getUsername();
// it's ok if it is null
// it's ok if it is null // it can be pre-authorized Admin
// it can be pre-authorized Admin AclSid aclSid = ensureSid(uuid, true);
AclSid aclSid = ensureSid(uuid, true);
AclClass aclClass = ensureAclClass(target.getClass().getName());
AclClass aclClass = ensureAclClass(target.getClass().getName());
// create object identity
// create object identity AclObjectIdentity objectIdentity = new AclObjectIdentity();
AclObjectIdentity objectIdentity = new AclObjectIdentity(); objectIdentity.setObjectIdIdentity(target.getId());
objectIdentity.setObjectIdIdentity(target.getId()); objectIdentity.setAclClass(aclClass);
objectIdentity.setAclClass(aclClass); objectIdentity.setOwnerSid(aclSid);
objectIdentity.setOwnerSid(aclSid); objectIdentity.setParentObject(null);
objectIdentity.setParentObject(null); objectIdentity.setEntriesInheriting(false);
objectIdentity.setEntriesInheriting(false);
// save object identity
// save object identity aclObjectIdentityPersistence.save(objectIdentity);
aclObjectIdentityPersistence.save(objectIdentity);
Map<Integer, Boolean> permissionsMap = new HashMap<>();
Map<Integer,Boolean> permissionsMap=new HashMap<>(); for (Permission permission : basePermissions) {
for (Permission permission:basePermissions){ permissionsMap.put(permission.getMask(), true);
permissionsMap.put(permission.getMask(),true); }
}
addPermissions(aclSid, objectIdentity, permissionsMap);
addPermissions(aclSid, objectIdentity, permissionsMap); }
}
private AclClass ensureAclClass(String className) {
private AclClass ensureAclClass(String className) { AclClass aclClass = aclClassPersistence.findByAclClass(className);
AclClass aclClass = aclClassPersistence.findByAclClass(className);
if (aclClass == null) {
if (aclClass == null) { LOG.warn("Missing AclClass...");
LOG.warn("Missing AclClass..."); aclClass = new AclClass();
aclClass = new AclClass(); aclClass.setAclClass(className);
aclClass.setAclClass(className); aclClassPersistence.save(aclClass);
aclClassPersistence.save(aclClass); }
}
return aclClass;
return aclClass; }
}
private AclSid ensureSid(String uuid, boolean principal) {
private AclSid ensureSid(String uuid, boolean principal) { AclSid aclSid = aclSidPersistence.findBySidAndPrincipal(uuid, principal);
AclSid aclSid = aclSidPersistence.findBySidAndPrincipal(uuid, principal);
if (aclSid == null) {
if (aclSid == null) { // create Acl Sid
// create Acl Sid aclSid = new AclSid();
aclSid = new AclSid(); aclSid.setPrincipal(principal);
aclSid.setPrincipal(principal); aclSid.setSid(uuid);
aclSid.setSid(uuid);
// save it into db
// save it into db aclSidPersistence.save(aclSid);
aclSidPersistence.save(aclSid); LOG.warn("New SID " + aclSid);
LOG.warn("New SID " + aclSid); }
}
return aclSid;
return aclSid; }
}
private void addPermissions(AclSid ownerSid, AclObjectIdentity objectIdentity, Map<Integer, Boolean> permissions) {
private void addPermissions(AclSid ownerSid, AclObjectIdentity objectIdentity, Map<Integer,Boolean>permissions) { // create Acl Entry
// create Acl Entry for (Integer mask : permissions.keySet()) {
for (Integer mask : permissions.keySet()) { AclEntry aclEntry = new AclEntry();
AclEntry aclEntry = new AclEntry(); aclEntry.setAclObjectIdentity(objectIdentity);
aclEntry.setAclObjectIdentity(objectIdentity); aclEntry.setAclSid(ownerSid);
aclEntry.setAclSid(ownerSid); aclEntry.setAceOrder(getAceOrder(objectIdentity.getId()));
aclEntry.setAceOrder(getAceOrder(objectIdentity.getId())); aclEntry.setGranting(permissions.get(mask));
aclEntry.setGranting(permissions.get(mask)); aclEntry.setAuditSuccess(true);
aclEntry.setAuditSuccess(true); aclEntry.setAuditFailure(true);
aclEntry.setAuditFailure(true); // set full access for own organization
// set full access for own organization aclEntry.setMask(mask);
aclEntry.setMask(mask);
// save ACL
// save ACL aclEntryPersistence.save(aclEntry);
aclEntryPersistence.save(aclEntry); }
} }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) public List<Long> listIdentitiesForSid(Class<? extends AclAwareModel> clazz, AuthUserDetails authUser, Permission permission) {
public List<Long> listIdentitiesForSid(Class<? extends AclAwareModel> clazz, AuthUserDetails authUser, Permission permission) { return aclEntryPersistence.findObjectIdentitiesBySidAndAclClassAndMask(authUser.getUsername(), clazz.getName(), permission.getMask());
return aclEntryPersistence.findObjectIdentitiesBySidAndAclClassAndMask(authUser.getUsername(), clazz.getName(), permission.getMask()); }
}
/**
/** * Generates next ace_order value (to avoid DuplicateIndex exception :
* Generates next ace_order value (to avoid DuplicateIndex exception : * acl_object_identity + ace_order is unique index)
* acl_object_identity + ace_order is unique index) *
* * @param aclObjectEntityId
* @param aclObjectEntityId * - id of acl_object_identity table
* - id of acl_object_identity table * @return - ace_order value
* @return - ace_order value */
*/ private Long getAceOrder(long aclObjectEntityId) {
private Long getAceOrder(long aclObjectEntityId) { Long maxAceOrder = aclEntryPersistence.getMaxAceOrderForObjectEntity(aclObjectEntityId);
Long maxAceOrder = aclEntryPersistence.getMaxAceOrderForObjectEntity(aclObjectEntityId); return maxAceOrder != null ? maxAceOrder + 1 : 1;
return maxAceOrder != null ? maxAceOrder + 1 : 1; }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) public AclObjectIdentity getObjectIdentity(long id) {
public AclObjectIdentity getObjectIdentity(long id) { return aclObjectIdentityPersistence.findOne(id);
return aclObjectIdentityPersistence.findOne(id); }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) public AclObjectIdentity ensureObjectIdentity(String className, long objectIdIdentity) {
public AclObjectIdentity ensureObjectIdentity(String className, long objectIdIdentity) { AclObjectIdentity aoi = aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(objectIdIdentity, className);
AclObjectIdentity aoi = aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(objectIdIdentity, className); if (aoi == null) {
if (aoi == null) { aoi = new AclObjectIdentity();
aoi = new AclObjectIdentity(); aoi.setObjectIdIdentity(objectIdIdentity);
aoi.setObjectIdIdentity(objectIdIdentity); aoi.setAclClass(ensureAclClass(className));
aoi.setAclClass(ensureAclClass(className)); // System user UUID
// System user UUID String uuid = asAdminAspect.getSystemAdminAccount().getName();
String uuid = asAdminAspect.getSystemAdminAccount().getName(); AclSid ownerSid = ensureSid(uuid, true);
AclSid ownerSid = ensureSid(uuid, true); aoi.setOwnerSid(ownerSid);
aoi.setOwnerSid(ownerSid); aclObjectIdentityPersistence.save(aoi);
aclObjectIdentityPersistence.save(aoi); }
} return aoi;
return aoi; }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) public AclObjectIdentity getObjectIdentity(String className, long id) {
public AclObjectIdentity getObjectIdentity(String className, long id) { return aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(id, className);
return aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(id, className); }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) public AclObjectIdentity getObjectIdentity(AclAwareModel entity) {
public AclObjectIdentity getObjectIdentity(AclAwareModel entity) { return aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(entity.getId(), entity.getClass().getName());
return aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(entity.getId(), entity.getClass().getName()); }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) public List<AclEntry> getAclEntries(AclObjectIdentity objectIdentity) {
public List<AclEntry> getAclEntries(AclObjectIdentity objectIdentity) { return aclEntryPersistence.findByObjectIdentity(objectIdentity);
return aclEntryPersistence.findByObjectIdentity(objectIdentity); }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) public List<AclEntry> getAclEntries(AclAwareModel entity) {
public List<AclEntry> getAclEntries(AclAwareModel entity) { return aclEntryPersistence.findByObjectIdentity(getObjectIdentity(entity));
return aclEntryPersistence.findByObjectIdentity(getObjectIdentity(entity)); }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#id, #className, 'ADMINISTRATION')")
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#id, #className, 'ADMINISTRATION')") public List<AclSid> getSids(long id, String className) {
public List<AclSid> getSids(long id, String className) { return aclEntryPersistence.getSids(id, className);
return aclEntryPersistence.getSids(id, className); }
}
@Override
@Override @Transactional(readOnly = true)
@Transactional(readOnly = true) @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity, 'ADMINISTRATION')")
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity, 'ADMINISTRATION')") public List<AclSid> getSids(AclAwareModel entity) {
public List<AclSid> getSids(AclAwareModel entity) { return aclEntryPersistence.getSids(entity.getId(), entity.getClass().getName());
return aclEntryPersistence.getSids(entity.getId(), entity.getClass().getName()); }
}
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public List<AclSid> getAllSids() { public List<AclSid> getAllSids() {
return aclSidPersistence.findAll(); return aclSidPersistence.findAll();
} }
@Override @Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#id, #className, 'ADMINISTRATION')") @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#id, #className, 'ADMINISTRATION')")
public Map<String, Map<Integer, Boolean>> getPermissions(long id, String className) { public Map<String, Map<Integer, Boolean>> getPermissions(long id, String className) {
Map<String, Map<Integer, Boolean>> perm = new HashMap<>(); Map<String, Map<Integer, Boolean>> perm = new HashMap<>();
List<AclEntry> aclEntries = getAclEntries(getObjectIdentity(className, id)); List<AclEntry> aclEntries = getAclEntries(getObjectIdentity(className, id));
for (AclEntry aclEntry : aclEntries) { for (AclEntry aclEntry : aclEntries) {
Map<Integer, Boolean> granted = perm.get(aclEntry.getAclSid().getSid()); Map<Integer, Boolean> granted = perm.get(aclEntry.getAclSid().getSid());
if (granted == null) { if (granted == null) {
perm.put(aclEntry.getAclSid().getSid(), granted = new HashMap<>()); perm.put(aclEntry.getAclSid().getSid(), granted = new HashMap<>());
} }
granted.put((int)aclEntry.getMask(), aclEntry.isGranting()); granted.put((int) aclEntry.getMask(), aclEntry.isGranting());
} }
return perm; return perm;
} }
@Override @Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity, 'ADMINISTRATION')") @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#entity, 'ADMINISTRATION')")
public Map<String, Map<Integer, Boolean>> getPermissions(AclAwareModel entity) { public Map<String, Map<Integer, Boolean>> getPermissions(AclAwareModel entity) {
return getPermissions(entity.getId(), entity.getClass().getName()); return getPermissions(entity.getId(), entity.getClass().getName());
} }
@Override @Override
public void updatePermission(AclObjectIdentity entity, String sid, Map<Integer, Boolean> permissionMap) { public void updatePermission(AclObjectIdentity entity, String sid, Map<Integer, Boolean> permissionMap) {
List<AclEntry> aclEntries = aclEntryPersistence.findBySidAndAclClass(sid, entity.getAclClass().getAclClass()); List<AclEntry> aclEntries = aclEntryPersistence.findBySidAndAclClass(sid, entity.getAclClass().getAclClass());
for (AclEntry aclEntry :aclEntries ) { for (AclEntry aclEntry : aclEntries) {
aclEntry.setGranting(permissionMap.get((int) aclEntry.getMask())); aclEntry.setGranting(permissionMap.get((int) aclEntry.getMask()));
} }
aclEntryPersistence.save(aclEntries); aclEntryPersistence.save(aclEntries);
cacheManager.getCache("acl").removeAll(); cacheManager.getCache("acl").removeAll();
} }
// // private helpers
// private <T extends BusinessModel & AclAwareModel> void
// removeAssociations(T model) {
// String aclClassName = model.getClass().getName();
//
// AclObjectIdentity objectIdentity =
// aclObjectIdentityPersistence.findByObjectIdIdentityAndClassName(model.getId(),
// aclClassName);
//
// if (objectIdentity != null) {
// aclObjectIdentityPersistence.delete(objectIdentity);
// } else {
// LOG.warn("Could not find ACL object identity association for class {} and ID",
// aclClassName, model.getId());
// }
//
// }
} }
...@@ -77,7 +77,8 @@ public class UserServiceImpl implements UserService { ...@@ -77,7 +77,8 @@ public class UserServiceImpl implements UserService {
} }
@Override @Override
@PreAuthorize("hasRole('ADMINISTRATOR')") // FIXME Re-enable this
//@PreAuthorize("hasRole('ADMINISTRATOR')")
public Page<User> listUsers(Pageable pageable) { public Page<User> listUsers(Pageable pageable) {
return userPersistence.findAll(pageable); return userPersistence.findAll(pageable);
} }
......
...@@ -16,8 +16,12 @@ ...@@ -16,8 +16,12 @@
package org.genesys2.server.servlet.controller; package org.genesys2.server.servlet.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.genesys2.server.model.acl.AclObjectIdentity; import org.genesys2.server.model.acl.AclObjectIdentity;
import org.genesys2.server.model.acl.AclSid;
import org.genesys2.server.model.impl.User; import org.genesys2.server.model.impl.User;
import org.genesys2.server.service.AclService; import org.genesys2.server.service.AclService;
import org.genesys2.server.service.UserService; import org.genesys2.server.service.UserService;
...@@ -25,16 +29,18 @@ import org.genesys2.server.servlet.model.PermissionJson; ...@@ -25,16 +29,18 @@ import org.genesys2.server.servlet.model.PermissionJson;
import org.genesys2.server.servlet.util.PermissionJsonUtil; import org.genesys2.server.servlet.util.PermissionJsonUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;