I am trying to make a proof of concept application that allows the user with administration permission to grant and revoke permissions of other users. While granting and revoking works with only username (unique identifier) getting the permission to display in the UI proves to be out of my reach. Is it possible to get a list of other user's permissions from within a service method?
I've tried to search the web but I couldn't find any solution that would apply to my problem. I have tried using SwitchUserAuthorityChanger, RunAsManager and aclService.readAclsById. None of those worked.
I am using Grails 3.3.2 with Spring-Security 3.2.0 and ACL 3.2.0.
Cheers folks!
I ended up solving this myself. I'll post the answer here in case some poor soul would run into a similar problem.
After digging a bit in the ACL database tables, I created a separate service in which I get AclObjectIdentity
by its id, I get users sid. Using these variables I find all related variables from AclEntry
. After that its just a matter of getting permissions by their mask.
Here is the method in case it might help anyone:
def getPermissions(Object domainObject, String sid) {
Map<String, String> returnValue = [
"status": "success"
]
def aclObject = AclObjectIdentity.findByObjectId(domainObject.id)
def userAclSid = AclSid.findBySid(sid)
if (null == userAclSid || null == aclObject) {
returnValue["status"] = "failed"
return returnValue
}
def aclEntries = AclEntry.findAllBySidAndAclObjectIdentity(userAclSid, aclObject)
returnValue["permissions"] = []
def tempMap = [:]
if (null == aclEntries) {
returnValue["permissions"] = "null"
return returnValue
}
def counter = 0
for (entry in aclEntries) {
int mask = entry.mask
BasePermission permission
for (BasePermission perm in PermissionEnum.toList()) {
int test = 1 << mask
if (perm.getMask() == test) {
permission = perm
break;
}
}
def permString = PermissionEnum.getPermission(permission)
tempMap["$counter"] = permString
counter++
}
returnValue["permissions"] = tempMap
return returnValue
}