Add notification URL to add allowed users programmatically
This commit is contained in:
parent
b945acc0a6
commit
acb304ae04
|
@ -0,0 +1,85 @@
|
|||
import ckan.lib.base as base
|
||||
import ckan.lib.helpers as helpers
|
||||
import ckan.plugins as plugins
|
||||
import importlib
|
||||
import logging
|
||||
import pylons.config as config
|
||||
|
||||
from ckan.common import response
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
PARSER_CONFIG_PROP = 'ckan.privatedatasets.parser'
|
||||
|
||||
|
||||
class AdquiredDatasetsController(base.BaseController):
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
# avoid status_code_redirect intercepting error responses
|
||||
environ['pylons.status_code_redirect'] = True
|
||||
return base.BaseController.__call__(self, environ, start_response)
|
||||
|
||||
def add_user(self):
|
||||
|
||||
# Get the parser from the configuration
|
||||
class_path = config.get(PARSER_CONFIG_PROP, '')
|
||||
|
||||
if class_path != '':
|
||||
try:
|
||||
class_package = class_path.split(':')[0]
|
||||
class_name = class_path.split(':')[1]
|
||||
parser = getattr(importlib.import_module(class_package), class_name)
|
||||
# Parse the result using the parser set in the configuration
|
||||
result = parser().parse_notification()
|
||||
except Exception as e:
|
||||
result = {'errors': [str(e)]}
|
||||
else:
|
||||
result = {'errors': ['%s not configured' % PARSER_CONFIG_PROP]}
|
||||
|
||||
# Introduce the users into the datasets
|
||||
# Expected result: {'errors': ["...", "...", ...]
|
||||
# 'users_datasets': [{'user': 'user_name', 'datasets': ['ds1', 'ds2', ...]}, ...]}
|
||||
warns = []
|
||||
|
||||
if 'errors' in result and len(result['errors']) > 0:
|
||||
log.warn('Errors arised parsing the request: ' + str(result['errors']))
|
||||
response.status_int = 400
|
||||
return helpers.json.dumps({'errors': result['errors']})
|
||||
elif 'users_datasets' in result:
|
||||
for user_info in result['users_datasets']:
|
||||
for dataset_id in user_info['datasets']:
|
||||
try:
|
||||
# Get dataset data
|
||||
dataset = plugins.toolkit.get_action('package_show')({'ignore_auth': True}, {'id': dataset_id})
|
||||
|
||||
# Generate default set of users if it does not exist
|
||||
if 'allowed_users' not in dataset:
|
||||
dataset['allowed_users'] = ''
|
||||
|
||||
# Only new users will be inserted
|
||||
allowed_users = dataset['allowed_users'].split(',')
|
||||
if user_info['user'] not in allowed_users:
|
||||
|
||||
# Comma is only introduced when there are more than one user in the list of allowed users
|
||||
separator = '' if dataset['allowed_users'] == '' else ','
|
||||
dataset['allowed_users'] += separator + user_info['user']
|
||||
|
||||
# Update dataset data
|
||||
plugins.toolkit.get_action('package_update')({'ignore_auth': True}, dataset)
|
||||
else:
|
||||
log.warn('The user %s is already allowed to access the %s dataset' % (user_info['user'], dataset_id))
|
||||
|
||||
except plugins.toolkit.ObjectNotFound:
|
||||
# If a dataset does not exist in the instance, an error message will be returned to the user.
|
||||
# However the process won't stop and the process will continue with the remaining datasets.
|
||||
log.warn('Dataset %s was not found in this instance' % dataset_id)
|
||||
warns.append('Dataset %s was not found in this instance' % dataset_id)
|
||||
except plugins.toolkit.ValidationError as e:
|
||||
# Some datasets does not allow to introduce the list of allowed users since this property is
|
||||
# only valid for private datasets outside an organization. In this case, a wanr will return
|
||||
# but the process will continue
|
||||
warns.append('Dataset %s: %s' % (dataset_id, e.error_dict['allowed_users'][0]))
|
||||
|
||||
# Return warnings that inform about non-existing datasets
|
||||
if len(warns) > 0:
|
||||
return helpers.json.dumps({'warns': warns})
|
|
@ -0,0 +1,34 @@
|
|||
import ckan.lib.helpers as helpers
|
||||
import re
|
||||
|
||||
from urlparse import urlparse
|
||||
from ckan.common import request
|
||||
|
||||
|
||||
class FiWareNotificationParser(object):
|
||||
|
||||
def parse_notification(self):
|
||||
|
||||
my_host = request.host
|
||||
|
||||
# Parse the body
|
||||
content = helpers.json.loads(request.body, encoding='utf-8')
|
||||
resources = content['resources']
|
||||
user_name = content['customer_name']
|
||||
datasets = []
|
||||
errors = []
|
||||
|
||||
for resource in resources:
|
||||
if 'url' in resource:
|
||||
parsed_url = urlparse(resource['url'])
|
||||
dataset_name = re.findall('^/dataset/(.+)$', parsed_url.path)
|
||||
|
||||
if len(dataset_name) == 1:
|
||||
if parsed_url.netloc == my_host:
|
||||
datasets.append(dataset_name[0])
|
||||
else:
|
||||
errors.append('Dataset %s is associated with the CKAN instance located at %s' % (dataset_name[0], parsed_url.netloc))
|
||||
|
||||
return {'errors': errors,
|
||||
'users_datasets': [{'user': user_name, 'datasets': datasets}]
|
||||
}
|
|
@ -64,6 +64,8 @@ def package_update(context, data_dict):
|
|||
|
||||
def allowed_users_not_valid_on_public_datasets_or_organizations(key, data, errors, context):
|
||||
|
||||
# TODO: In some cases, we will need to retireve all the dataset information if it isn't present...
|
||||
|
||||
private_val = data.get(('private',))
|
||||
owner_org = data.get(('owner_org',))
|
||||
private = private_val is True if isinstance(private_val, bool) else private_val == "True"
|
||||
|
@ -75,9 +77,11 @@ def allowed_users_not_valid_on_public_datasets_or_organizations(key, data, error
|
|||
|
||||
|
||||
class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm):
|
||||
|
||||
p.implements(p.IDatasetForm)
|
||||
p.implements(p.IAuthFunctions)
|
||||
p.implements(p.IConfigurer)
|
||||
p.implements(p.IRoutes, inherit=True)
|
||||
|
||||
######################################################################
|
||||
############################ DATASET FORM ############################
|
||||
|
@ -149,3 +153,15 @@ class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm):
|
|||
|
||||
# Register this plugin's fanstatic directory with CKAN.
|
||||
tk.add_resource('fanstatic', 'privatedatasets')
|
||||
|
||||
######################################################################
|
||||
############################### ROUTES ###############################
|
||||
######################################################################
|
||||
|
||||
def after_map(self, m):
|
||||
# DataSet adquired notification
|
||||
m.connect('/dataset_adquired',
|
||||
controller='ckanext.privatedatasets.controller:AdquiredDatasetsController',
|
||||
action='add_user', conditions=dict(method=['POST']))
|
||||
|
||||
return m
|
||||
|
|
Loading…
Reference in New Issue