Users can create Features and FeatureCollections, perform analyses on them, etc. But the ability for the user to share these ideas to various groups is where the true collaborative value lies.
The most common use case would be: A user creates a Feature and wants others to comment on it. This user is a member of several groups. They can choose to share the Feature (i.e. to make the feature available read-only) to any one of the groups which has sharing permissions. If a user decides to organize their Features into FeatureCollections, those collections can be shared as well.
By default, new users are not assigned to any groups nor are groups assigned sharing permissions. Adding a user to a group is currently not automated and requests for group memebership must be made directly to the site administrator.
Groups can be given sharing permissions through the admin interface
- Navigate to Home › Auth › Groups
- Select the Group
- Add the ‘auth | group | Can Share Features’ permission
Or through python:
from madrona.common.utils import enable_sharing
from django.contrib.auth.models import Group
mygroup = Group.objects.get(name="My Group")
enable_sharing(mygroup)
Consider the following heirarchy of Features/FeatureCollections:
folder1
|-array1
|-pipeline
|-mpa1
If a user were to share folder1, array1, pipeline and mpa1 would all implicitly be shared as well. Even if mpa1 were explicitly unshared, it would still be viewable by group members by virtue of it’s belonging to array1 (which in turn belongs to folder1 which is shared).
The sharing app provides a form and views for editing an object’s sharing status. The url for a feature can be determined by:
url = Folder.get_options().get_share_form(folder1.pk)
# /features/folder/1/share/
A GET request to this URL will give access to this form (assuming that a user with the appropriate permissions is logged in), while a POST request to the same URL with the sharing_groups parameter specified will attempt to share the object with the specified groups. Appropriate error messages and status response codes are used and will hopefully be helpful and smooth things over in the case of errors.
This section describes the various components of the madrona API related to sharing.
First, there is the object manager which allows you to quickly obtain a queryset of all objects that have been shared with a user:
from myapp.models import MyFeature
features = MyFeature.objects.shared_with_user(user1)
The groups_users_sharing_with() utility function returns the groups and users which are currently sharing feature instances with a given user:
from madrona.features import groups_users_sharing_with
sharing_with_me = groups_users_sharing_with(user1)
To find out which groups a user can potentially share with, use the user_sharing_groups() utility function:
from madrona.features import user_sharing_groups
my_sharing_groups = user_sharing_groups(user1)
A common use case will be to determine if an object is readable by a user. In other words, is the object owned by OR shared with a given user. You can use the is_viewable() Feature method which returns two items: A boolean indicating if the user has read access and an appropriate HttpResponse object. It’s up to the implementation whether or not you return the HttpResponse or not but the common scenario would be to check if the object were readable by the user and, if not, return the HttpResponse. For example:
def some_view(request, pk):
feature1 = get_object_or_404(MyFeature, pk)
viewable, response = feature1.is_viewable(request.user)
if not viewable:
return response
else:
do_stuff()
In order to control sharing of an object with a given group using python code, you can use the share_with Feature method:
feature1 = MyFeature.objects.create(name="Feature 1")
# By default this overrides all previous sharing groups
feature1.share_with(mygroup)
# You can choose to append it
feature1.share_with(mygroup, append=True)
# You can also pass a list of groups
feature1.share_with([group1,group2])
# To remove all sharing groups, pass None
feature1.share_with()
Just like any other sharing group, these groups must exist and have the appropriate permissions. The only difference with normal bi-directional sharing is that the viewing of shared object is more tightly controlled (in the case of sharing to staff) or the viewing is made available to anyone (in the case of sharing to public). Other than that, they are shared to the specified groups in the exact same way.