Forum OpenACS Development: Permissions on categories

Collapse
Posted by Malte Sussdorff on
I have the following szenario.

Based on a type of file users should have access to the file or not. Therefore I need the permission on the file type and not on the file itself.

Here are some ideas which I tossed around to come up with a solution:

1) Use custom code for checking upon file delivery if the file might be of a certain type (extended table) and then check the permissions on that.

2) Use one folder per type and store the files into the folders, giving permission on the folder instead (and use a callback on folder name upon creation to automatically give a group of people permission to the folder). The drawback is that each new type triggers a new folder to be generated. That is fine in a flat szenario, but if you have one folder per project, then the number of folders just gets too big.

3) Use categories for the types and write some permission code based on categories that allows you to give the usual permissions based on the category. This has the benefit of allowing permissions based on category_id, so you can get the permission on all files you have direct permissions or on which you have permission on the mapped categories.

I am leaning towards approach 3) as it gives you the option to give permissions on types to anything you want. Give permissions on all sales projects, give permission on all review files, give permission on all accounting tasks....

But to be honest I hope someone has found a different solution which I could just reuse 😊. Or, alternatively, OCT has time to discuss this so we can figure out if and how to include this in the toolkit. The permissions per type thing is something which came up lately in two clients, thats why I have to start thinking about it.

Collapse
Posted by Dave Bauer on
Malte, what do you mean by "type"? Do you mean Word, PDF, XLS etc?

It seems somewhere you are going to have to add some custom UI to manage these type of permissions.

Collapse
Posted by Malte Sussdorff on
Nope, I do not mean the "mime type", but types like "Invitation Letter" or "Bill" or "Payment Request" or any arbitrarily defined type. So when going to file-storage folder view you will see all "Bills" if you have the permission to read files of the type "Bill". But as I mentioned this is not limited to files, it is also the permissions on types of projects and types of users (e.g. a student administrator can change student data but can not change data from a fellow administrator let alone a professor. Only the HR supervisor is allowed to change data on these).
Collapse
Posted by Dave Bauer on
Ah,

So for example, you could subtype cr_revision or whatever to determine the type. But of course, there are no permissions on object_types.

What I have done in the past is create a special object per "type" of thing I need to permission and check permissions on that object. of course that is a pain if you want to do that on top of file storage, which is not aware of these types.

Well then again, to define the type you'd need to map it somehow so you need a mapping table somewhere. This could be categories.

That seems like a good compromise, but you still have to check permissions on the category the object is mapped to.

I imagine you want custom package_id/type permission mappings, so that a user or group would have permission for certain types within an instance of file storage.

Even if you make object types objects and applied permissions on those, it would apply overall, not within a certain package instance.

Collapse
Posted by Gustaf Neumann on
xowiki does already something what you describe. xowiki's page types are subtypes of cr_revision. via policies, it is possible to base the access rights (a) on arbitrary attributes of the object and (b) to differentiate the access rights on the class of the object (also an acs_type). xowiki does not have a file-store like interface and has no folders (yet). however, the access right policies seem well suited for this task and can be easily set differently per instance. See also http://alice.wu-wien.ac.at:8000/xowiki-faq/#policies
Collapse
Posted by Malte Sussdorff on
I have thought about making xofs or something like that copying the code from xowiki, but what stopped me was the fact that I would need to create a subtype of xofs::file on the fly as the adding of file or project "types" needs to be something the end user should be able to configure. Which would mean to create the subtype on the fly (no problem) and keep it persistent, and here I am not sure if I can just create the subtype in the DB and it will work or do I need to write this into the filesystem as well as I need to do with classes?

On a related note: Excellent that you work on the xowiki-faq. This will help a lot of users!

Collapse
Posted by Gustaf Neumann on
malte, there is no need to copy code from xowiki, one can use xowiki and reuse it like e.g. in the s5 package. There is also no need to create a high number of subtypes. Here are two approaches, the second one requires no new subtype at all.

1) One can subclass xowiki::File to e.g. XFile, add an "security label" as in mandatory access control systems as an additional attribute (security_label). If this label is an acs-object, one can define a policy rule like

Class XFile -array set require_permission {
  download {{security_label read}}
}
one can define as security labels acs-objects "public", "internal use", "confidential", "top secret" and give the users rights to these (acs) objects (e.g. via groups). When an XFile is created, the security labels are associated with the files. With the policy definition above, you should be done.

2) maybe less efficient, but less programming work, using categories as security labels.

xotcl-core defines a couple of "privileges" such as "swa", "login", "creator" which are not necessarily based on acs_permissions. These privileges are defined as single words in the policy rules. One can define custom privileges as well, which are methods with names like "privilege=SOMETHING".

You can define a category tree named "security labels", map the tree to the instance, require the user to provide categories like "public" .. "top secret" for the files.
You can define such a privilege method (e.g. privilege=label), and check in this method, whether the object has such a label. Finally check, if the user has clearance for this label. Since categories are already acs-objcets, rights could be provided for the category objects.

There is an example for a custom privilege rule in generic-procs (privilege=creator, which we used for the conference registration).

Collapse
Posted by Ryan Gallimore on
Hi Gustaf,

Thanks for the instructions. Is it possible to take an existing category tree, like:

Release Notes
Documentation
Support

and grant read/write/admin on any xowiki pages inside each?

For instance I may have a user, Joe, and I want him to be able read-only the pages in Release Notes, edit the Documentation pages, but not even see the Support category.

Thanks.

Collapse
Posted by Malte Sussdorff on
"I imagine you want custom package_id/type permission mappings, so that a user or group would have permission for certain types within an instance of file storage."

Yes. I thought about that. But then I figured: Too much hassle. If I go with categories, I could map a different category tree to the "other" file-storage instance and then give the permissions on those other categories as my assumption is that you will not have a situation where every file storage instance has the same file "types" and if it does, then the likelyhood that a different role of users has access to those file types is even more limited.

That is also one of the reasons why the idea of making object types objects was not so appealing because it kindoff "forced" the permissions on everything, whereas with categories you could turn it on and off and assign multiple categories (e.g. this file is a "Bill" but should also be readable by everyone who can read "Paychecks" as it is a provider bill and the HR department should be able to read it as well). But to be honest, I did not think about making the object_types objects for that purpose (though I thought about making object types objects a couple of times already 😊).