I have implemented a service where user can upload files (here referred to as services) to analyze them. Each registered user has only access to his uploaded files.
So, after uploading a file I grant the user a wildcard permission for that file:
def currentUser = SecurityUtils.subject
if (currentUser.isAuthenticated()) {
def user = User.findByUsername(currentUser.principal)
user.addToPermissions("service:*:$serviceId")
user.save()
}
When accessing a file, I check if the currently logged in user has the permission to open that file:
SecurityUtils.subject.checkPermission("service:*:$id")
This seems to work all fine but now I want to give the logged in user a way to list all his uploaded files. For that, I get the user, take all his permissions, extract the IDs and then search for the files:
def user = User.findByUsername(SecurityUtils.subject.principal)
def serviceIds = user.permissions.collect { it.split(':').last().toLong() }
[services: Service.findAllByIdInList(serviceIds)]
While this works, it seems horribly inefficient. What would be a better way to implement this? Maybe create a relation between the user and the files?
You could as you said create a relation between User
and Service
(1 -> M) making it easier to run a query for the Service
objects for that User
. My thinking of this is that it sounds like it fits within your domain model, after all, it sounds like there is a real relationship between the User
and the Service
as the Service
does in fact belong to the User
. Permissions are still helpful for controlling who has access to the Service
whilst that one User
remains the owner of the Service
[services: Service.findAllByUser(User.findByUsername(SecurityUtils.subject.principal))]
It might not make it any more efficient but it is a cleaner solution