Skip to content

Commit

Permalink
[!Not backwards compatible!] remove dependency on ckanext-scheming an…
Browse files Browse the repository at this point in the history
…d ckanext-composite

we get a more self-contained plugin that may work without additionnaly fiddling

fixes EnviDat#15
  • Loading branch information
olivierdalang committed May 13, 2020
1 parent 065a336 commit 89693f5
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 90 deletions.
61 changes: 0 additions & 61 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,71 +77,10 @@ Requirements

This extension has been oruginally developed for CKAN version 2.5.2 and is compatible up to 2.8.x.

Recommends the following extensions (otherwise the configuration is more complicated):
* ckanext-scheming
* ckanext-repeating
* ckanext-composite

The resource access restriction level can be individualy defined for every package. This requires adding an extra field to package metadata with (some of) the possible values: "public", "registered", "any_organization", "same_organization" (as the package).

The allowed user list is also defined in an additional field that includes autocomplete.

If you use ckanext-scheming and ckanext-composite, this is the field definition in JSON:
::
{
"scheming_version": 1,
"dataset_type": "dataset",
"about": "",
"about_url": "http://github.com/ckan/ckanext-scheming",
"dataset_fields": [...],
"resource_fields": [
[...]
{
"field_name": "restricted",
"label": "Access Restriction",
"preset": "composite",
"subfields":
[
{
"field_name": "level",
"label": "Level",
"preset": "select",
"form_include_blank_choice": false,
"required": true,
"choices": [
{
"value": "public",
"label": "Public"
},
{
"value": "registered",
"label": "Registered Users"
},
{
"value": "any_organization",
"label": "Any Organization Members (Trusted Users)"
},
{
"value": "same_organization",
"label": "Same Organization Members"
},
{
"value": "only_allowed_users",
"label": "Allowed Users Only"
}
]
},
{
"field_name": "allowed_users",
"label": "Allowed Users",
"preset": "tag_string_autocomplete",
"data-module-source":"/api/2/util/user/autocomplete?q=?"
}
]
}
]
}

The usage of this extension, regarding the level "any_organization", makes more sense if the CKAN administrator sets some users as members of an organization. In our case we created an organization called "trusted_users" where the mail accounts have been double checked. Therefore this extension sends a mail to the defined 'mail_to' in the CKAN config file at every new user registration. To switch off this functionality, just comment out the code at:
https://github.com/espona/ckanext-restricted/blob/master/ckanext/restricted/plugin.py#L14

Expand Down
36 changes: 7 additions & 29 deletions ckanext/restricted/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,35 +34,13 @@ def restricted_get_username_from_context(context):


def restricted_get_restricted_dict(resource_dict):
restricted_dict = {'level': 'public', 'allowed_users': []}

# the ckan plugins ckanext-scheming and ckanext-composite
# change the structure of the resource dict and the nature of how
# to access our restricted field values
if resource_dict:
# the dict might exist as a child inside the extras dict
extras = resource_dict.get('extras', {})
# or the dict might exist as a direct descendant of the resource dict
restricted = resource_dict.get('restricted', extras.get('restricted', {}))
if not isinstance(restricted, dict):
# if the restricted property does exist, but not as a dict,
# we may need to parse it as a JSON string to gain access to the values.
# as is the case when making composite fields
try:
restricted = json.loads(restricted)
except ValueError:
restricted = {}

if restricted:
restricted_level = restricted.get('level', 'public')
allowed_users = restricted.get('allowed_users', '')
if not isinstance(allowed_users, list):
allowed_users = allowed_users.split(',')
restricted_dict = {
'level': restricted_level,
'allowed_users': allowed_users}

return restricted_dict
restricted_level = resource_dict.get('restricted_level', 'public')
allowed_users = resource_dict.get('restricted_allowed_users', '')
if not isinstance(allowed_users, list):
allowed_users = allowed_users.split(',')
return {
'level': restricted_level,
'allowed_users': allowed_users}


def restricted_check_user_resource_access(user, resource_dict, package_dict):
Expand Down
31 changes: 31 additions & 0 deletions ckanext/restricted/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class RestrictedPlugin(plugins.SingletonPlugin, DefaultTranslation):
plugins.implements(plugins.IAuthFunctions)
plugins.implements(plugins.IRoutes, inherit=True)
plugins.implements(plugins.IResourceController, inherit=True)
plugins.implements(plugins.IDatasetForm, inherit=False)

# IConfigurer
def update_config(self, config_):
Expand Down Expand Up @@ -67,3 +68,33 @@ def after_update(self, context, resource):
previous_value = context.get('__restricted_previous_value')
logic.restricted_notify_allowed_users(previous_value, resource)

# IDatasetForm
def is_fallback(self):
return False

def package_types(self):
return []

def _modify_package_schema(self, schema):
# Add our custom document_type metadata field to the schema.
schema['resources'].update({
'restricted_level': [toolkit.get_validator('ignore_missing'),],
'restricted_allowed_users': [toolkit.get_validator('ignore_missing'),],
})
return schema

def create_package_schema(self):
schema = super(RestrictedPlugin, self).create_package_schema()
schema = self._modify_package_schema(schema)
return schema

def update_package_schema(self):
schema = super(RestrictedPlugin, self).update_package_schema()
schema = self._modify_package_schema(schema)
return schema

def show_package_schema(self):
schema = super(RestrictedPlugin, self).show_package_schema()
schema = self._modify_package_schema(schema)
return schema

22 changes: 22 additions & 0 deletions ckanext/restricted/templates/package/snippets/resource_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{% ckan_extends %}

{% block metadata_fields %}

{{ super() }}

<div class="form-group control-full">
<label class="control-label" for="field-document_type">{{ _("Restriction") }}</label>
<div class="controls">
<select id="field-restricted_level" name="restricted_level" class="form-control">
<option value="public"{% if data.get('restricted_level') == 'public' %} selected="selected"{% endif %}>public</option>
<option value="registered"{% if data.get('restricted_level') == 'registered' %} selected="selected"{% endif %}>membre enregistrés</option>
<option value="same_organization"{% if data.get('restricted_level') == 'same_organization' %} selected="selected"{% endif %}>membre de l'organisation</option>
<option value="only_allowed_users"{% if data.get('restricted_level') == 'only_allowed_users' %} selected="selected"{% endif %}>personnes authorisées</option>
</select>
</div>
</div>

{% set tag_attrs = {'data-module': 'autocomplete', 'data-module-tags': '', 'data-module-source': '/api/2/util/user/autocomplete?q=?'} %}
{{ form.input('restricted_allowed_users', id='field-restricted_allowed_users', label=_('Allowed users'), placeholder=_('Specific users who can access resources'), value=data.get('restricted_allowed_users'), error=errors.tags, classes=['control-full'], attrs=tag_attrs) }}

{% endblock %}

0 comments on commit 89693f5

Please sign in to comment.