Skip to content

Commit

Permalink
[#3192] implement package_show auth with permission labels
Browse files Browse the repository at this point in the history
  • Loading branch information
wardi committed Aug 21, 2016
1 parent 8ff3f1f commit c766440
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 30 deletions.
25 changes: 16 additions & 9 deletions ckan/lib/plugins.py
Expand Up @@ -243,6 +243,13 @@ def plugin_validate(plugin, context, data_dict, schema, action):
return toolkit.navl_validate(data_dict, schema, context)


def get_permission_labels():
'''Return the permission label plugin (or default implementation)'''
for plugin in plugins.PluginImplementations(plugins.IPermissionLabels):
return plugin
return DefaultPermissionLabels()


class DefaultDatasetForm(object):
'''The default implementation of
:py:class:`~ckan.plugins.interfaces.IDatasetForm`.
Expand Down Expand Up @@ -583,23 +590,23 @@ class DefaultPermissionLabels(object):
- users can read their own drafts "creator-(user id)"
- users can read datasets belonging to their orgs "member-(org id)"
'''
def get_dataset_labels(self, dataset):
if dataset['state'] == 'active' and not dataset['private']:
def get_dataset_labels(self, dataset_obj):
if dataset_obj.state == 'active' and not dataset_obj.private:
return [u'public']

if dataset['private']:
return [u'member-%s' % dataset['owner_org']]
if dataset_obj.owner_org:
return [u'member-%s' % dataset_obj.owner_org]

return [u'creator-%s' % dataset['creator_user_id']]
return [u'creator-%s' % dataset_obj.creator_user_id]

def get_user_dataset_labels(self, user):
def get_user_dataset_labels(self, user_obj):
labels = [u'public']
if not user:
if not user_obj:
return labels

labels.append(u'creator-%s' % user['id'])
labels.append(u'creator-%s' % user_obj.id)

orgs = logic.get_action('organization_list_for_user')(
{'user': user['id']}, {'permission': 'read'})
{'user': user_obj.id}, {'permission': 'read'})
labels.extend(u'member-%s' % o['id'] for o in orgs)
return labels
24 changes: 9 additions & 15 deletions ckan/logic/auth/get.py
Expand Up @@ -5,6 +5,7 @@
from ckan.lib.base import _
from ckan.logic.auth import (get_package_object, get_group_object,
get_resource_object)
from ckan.lib.plugins import get_permission_labels


def sysadmin(context, data_dict):
Expand Down Expand Up @@ -112,22 +113,15 @@ def package_relationships_list(context, data_dict):
def package_show(context, data_dict):
user = context.get('user')
package = get_package_object(context, data_dict)
# draft state indicates package is still in the creation process
# so we need to check we have creation rights.
if package.state.startswith('draft'):
auth = authz.is_authorized('package_update',
context, data_dict)
authorized = auth.get('success')
elif package.owner_org is None and package.state == 'active':
return {'success': True}
else:
# anyone can see a public package
if not package.private and package.state == 'active':
return {'success': True}
authorized = authz.has_user_permission_for_group_or_org(
package.owner_org, user, 'read')
labels = get_permission_labels()
user_labels = labels.get_user_dataset_labels(context['auth_user_obj'])
authorized = any(
dl in user_labels for dl in labels.get_dataset_labels(package))

if not authorized:
return {'success': False, 'msg': _('User %s not authorized to read package %s') % (user, package.id)}
return {
'success': False,
'msg': _('User %s not authorized to read package %s') % (user, package.id)}
else:
return {'success': True}

Expand Down
12 changes: 6 additions & 6 deletions ckan/plugins/interfaces.py
Expand Up @@ -1582,27 +1582,27 @@ class IPermissionLabels(Interface):
default behaviours for these methods.
'''

def get_dataset_labels(self, dataset):
def get_dataset_labels(self, dataset_obj):
'''
Return a list of unicode strings to be stored in the search index
as the permission lables for a dataset dict.
:param dataset: dataset fields
:type dataset: dict
:param dataset_obj: dataset details
:type dataset_obj: Package model object
:returns: permission labels
:rtype: list of unicode strings
'''

def get_user_dataset_labels(self, user):
def get_user_dataset_labels(self, user_obj):
'''
Return the permission labels that give a user permission to view
a dataset. If any of the labels returned from this method match
any of the labels returned from :py:meth:`.get_dataset_labels`
then this user is permitted to view that dataset.
:param user: user fields
:type user: dict
:param user_obj: user details
:type user_obj: User model object or None
:returns: permission labels
:rtype: list of unicode strings
Expand Down

0 comments on commit c766440

Please sign in to comment.