Omeka Levels of Access

In the interest of privacy, we are trying to tie whether a record is visible to a field that contains whether we have permission to display the image. So if that field is yes, we want the record to display, and if it’s no, we don’t want it to display. I think I can envision how that would work. We could create a .csv file for the initial upload that contained cells that would reflect that information, and then manually change the public/private setting if we received new consent forms.

However, we also we want some records to be available only to graduates of our institution. Would there be a way to create a third level of access between public and private that would require a login? I'm sure it could be done, but it might be beyond my php skills.

Another thought I had was to have records display, but not the image if the image has not been approved. So in the item record, we could have an if/then conditional statement based on the approval field that would determine whether the picture would display. Also this conditional statement could check to see if the user is logged in. We could even display a message instead of the picture, saying the image needs approval or have a link to get a username and password. Would this be possible?

So, you're looking to have three different groups of items?

  • Items that anybody can view (public)
  • Items that only site admins can view (private)
  • Items that graduates can view (something in between)

If I'm understanding this correctly, Omeka almost, but doesn't quite, support this out of the box. You can create users and give them access to see all items, public and non-public (this would be the "researcher" role), but there is no "third" access level (researchers can see all the items).

A plugin should be able to handle this, depending on how you want your "third level" to work and how an item will be marked as "semi-private."

Thanks. Any tips on where to get started? I was looking on the Omeka GitHub site to see how the public and private settings work, thinking that would be a logical place to start. However, I'm not really finding anything, is there a way to search the Omeka GitHub pages?

You mention that Omeka almost supports this out of the box. Would there be a way to modify the acl.php file to make this work? I guess I'm thinking of modifying the researcher role, so they can't view all items, just public and semi-private.

Currently the researcher group is allowed access to items and collections that are both public and private.

array('researcher',array('Items', 'Collections'),array('showNotPublic')),

The showNotPublic is part of
'Items' => array('add', 'batch-edit', 'batch-edit-save', 'edit', 'editSelf', 'editAll', 'delete', 'deleteSelf', 'deleteAll', 'tag', 'showNotPublic', 'showSelfNotPublic', 'untagOthers', 'makePublic', 'makeFeatured', 'modifyPerPage', 'browse'),

Would I be able to add a new term like "showSemiPrivate" to this list? And then set the researchers role to:

array('researcher',array('Items', 'Collections'),array('showSemiPrivate')),

Hi,

Sorry I can't help with this, Andy, but I just want to say that I'm very interested by this topic about the "intermediate" level of access. I also know another organisation in France wanting this kind of access level. I think it would be very appreciated if you can discuss that for a next version of Omeka because it would be particularly great for small organisation working in the same field who wants to collaborate on a same site.

I’ll take my situation as an example. At the origin of the project, we wanted a level private to every organisation collaborating to the project (they are contributors). We also wanted a level public like it is intended in Omeka. We also wanted a level where all the organisations participating to the project will share items between themselves. In other words, to have a level of sharing items between the contributors only. But, without financial resources, we decided to put on the side this level and the result is that fewer items are shared.

Thank you for considering this,

You can easily add permissions to the various roles. You can do this, as you suggested, in the acl.php file directly, but it's likely a better idea to do this kind of thing with a plugin, since we update acl.php from time to time.

This is what the define_acl hook in a plugin is for, it lets you modify the ACL rules before any of the permissions checks actually happen.

The bigger part of this is coming up with a way to store or decide which Items are "semi-private," and then checking against the appropriate permission.

I think I know how to add permissions to the roles, and I'd use a plugin with the define_acl hook, but I'm not sure how to define semi-private as a permission. So I had another idea to use a modified contributor role.

Contributors are allowed to view private items that they have added to the collection with showSelfNotPublic. They can't view other private items. So I'm thinking of adding a new role that would have that feature, but not all the editing features of the contributor.

array('alumni', 'Items', array('showSelfNotPublic')),

After creating this new role, I'd like to go back through my collection as a superuser and find items that will be semi-private, and attribute them to the alumni user. However, once again I'm not sure if that is possible. I can't seem to figure out where this information is stored on the admin site. It's stored somewhere because you can use the advanced search to filter by user. This will be a general login account for a group of users.

You're sure you don't want the editing permissions contributors currently have? They can only edit items they "own," no others.

Regardless of the specific permissions you want, adding a role is a reasonable option (again, this can be done in a plugin or by editing the ACL directly).

As for defining permissions, they're just names. The system only treats a few as "special" (the names of actions within a controller, for example). Anything else is being controlled by some specific check against that particular string.

Currently, the linkages between Items and their owners are stored in the entities_relations table. The linkage is somewhat overcomplicated: A User is associated with a particular Entity (you can look up the entity ID in the User table), and EntitiesRelations links entities to other Omeka objects. Relationship ID 1 is the "added" relationship.

So, in the end: the ownership data is a row in entities_relations where entity_id is the user's entity, relation_id is the item id, relationship_id is 1, and type is "Item". (We're working on simplifying this significantly).

Fortunately, for most in-Omeka usages you can ignore this under-the-hood complexity, you can call the wasAddedBy(User), setAddedBy(User), or getUserWhoAdded() methods on the Item model.

Above you mentioned that the bigger part is how to store which items are semi-private. I'm now thinking that we could store these items in a collection called "Alumni" which would be private, and none of the items in this collection would be public. This would prevent most people from accessing these items. Then I'd create a role that would have access to these non-public items in this collection.

Since, I'm not great at coding, I usually try to tweak existing code to suit my purposes. I'm thinking I could use part of function.php from the exhibit builder plugin.

function alumni_acl($acl)
{
    $resourceList = array('Collection_Alumni' => array(
        ('showNotPublic', 'browse')
    );
    $acl->loadResourceList($resourceList);

    $acl->allow(Alumni, 'Collection_Alumni',
        array('showNotPublic', 'browse'));

$acl->addRole(new Zend_Acl_Role('Alumni'));

   }

I'm not really sure if I'm on the right track. The documentation around the zend_acl is fairly limited. Although it does mention Writing Conditional ACL Rules with Assertions. Perhaps that is what I need to do. Also I still haven't found an example of how a permission like showNotPublic is defined. All I have found is information on creating new roles or resources. If you have any suggestions, I would greatly appreciate it. Thanks.

I've taken a break from this issue, and worked on some other things that I was able to successfully accomplish. I was hoping to come back to this, and be able to figure it out. Unfortunately that hasn't happened. So I have some questions about wasAddedBy(User), setAddedBy(User), and getUserWhoAdded() methods that you mentioned earlier.

I found a forum thread that explains how to use the getUserWhoAdded() (http://omeka.org/forums/topic/add-user-who-created-item-to-detailed-viewphp) So I added the following line to my show.php file: <?php echo $item->getUserWhoCreated()->username; ?> and it displays the username of the person who created the record.

Now I want to change the username of the creator of an item record. So could I use setAddedby(user) method to accomplish this change? I'm thinking of making this based on whether an item belongs to a certain collection. Here's an example of what I've tried:

<?php $mycollection=get_collection_for_item();
$name .= $mycollection->name;
if ($name=='Alumni Collection'){
$item->setAddedBy('alumni');
echo $item->getUserWhoCreated()->username;} ?>

Would something like this work and if so how do you use the setAddedBy method?

Thanks.

Well, getUserWhoCreated and setAddedBy and the related methods operate on Users. In your example, you're trying to do $item->setAddedBy('alumni'), where 'alumni' is presumably a role.

These methods get and set information about specific users, not roles or classes of users. You can say a particular user has the "alumni" role, but you can't say a particular item was added by "alumni." An Item can only be owned by one user.

Omeka uses (somewhat recently) a conditional ACL rule to determine if a User can view a particular item. The assertion checks against several permissions and against the "public" column to see if the user can view the item. Again, the main issue is coming up with the other piece of data that you need to check against for this "intermediate" level.

Ok, so let's say I am trying to use setAddedBy on a User. So instead of $item->setAddedBy('alumni') I had something like $item->setAddedBy{'andy'). Would that allow me to change who created an item? Or can you not change who created an item?

Basically I'm trying to change all the items in a certain collection to have been created by one user. This user would then allow alumni to view private items in this collection, since it could be set to showselfnotpublic.

Yes, you can change who created an item.

setAddedBy is going to want to take a User object as its parameter though, not a username or any other string.

Would User object be the number associated with a specific username? When I run an advanced search in our omeka admin that narrows it to items created by myself, part of the query string reads "&user=4". So would my code look like:

<?php $mycollection=get_collection_for_item();
$name .= $mycollection->name;
if ($name=='Alumni Collection'){
$item->setAddedBy(4);
echo $item->getUserWhoCreated()->username;} ?>

Or would I have to do something like:

<?php $mycollection=get_collection_for_item();
$name .= $mycollection->name;
$user = current_user();
$firstname .=$user->first_name;
if ($name=='Alumni Collection' && firstname=='andy'){
$item->setAddedBy($user);
echo $item->getUserWhoCreated()->username;} ?>

This is what I'm working with now:

<?php $mycollection=get_collection_for_item();
$name .= $mycollection->name;
$current = Omeka_Context::getInstance()->getCurrentUser();
$firstname .=$current->first_name;
echo $firstname;
if ($name=='Alumni Collection' && $firstname=='andy'){
$item->setAddedBy($current);
echo $item->getUserWhoCreated()->username;} ?>

This generates the word andy and then the username of the person who created the record. It still doesn't seem to be changing who created the item.

I still haven't figured this out. What do you mean when you said, "setAddedBy is going to want to take a User object as its parameter"?

It seems that $current = Omeka_Context::getInstance()->getCurrentUser(); gets the user object for the current user. I've placed print_r($current) in the code, and it prints all the information associated with the current user object. I've tried many variations on the code $item->setAddedBy($current); but haven't figured it out. What's the correct syntax for this? Or is the problem because I'm trying to do this in the show.php file?