ckanext-privatedatasets/ckanext/privatedatasets/controllers.py

137 lines
6.2 KiB
Python

import ckan.lib.base as base
import ckan.lib.helpers as helpers
import ckan.plugins as plugins
import ckan.model as model
import importlib
import logging
import pylons.config as config
from ckan.common import response, _
log = logging.getLogger(__name__)
PARSER_CONFIG_PROP = 'ckan.privatedatasets.parser'
######################################################################
############################ API CONTROLLER ##########################
######################################################################
class AdquiredDatasetsControllerAPI(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_users(self):
log.info('Notification Request received')
# 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': [type(e).__name__ + ': ' + 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 or dataset['allowed_users'] is None:
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})
######################################################################
############################ UI CONTROLLER ###########################
######################################################################
class AdquiredDatasetsControllerUI(base.BaseController):
def user_adquired_datasets(self):
c = plugins.toolkit.c
context = {
'model': model,
'session': model.Session,
'user': plugins.toolkit.c.user
}
# Get user information
try:
c.user_dict = plugins.toolkit.get_action('user_show')(context, {'user_obj': c.userobj})
c.user_dict['adquired_datasets'] = []
except plugins.toolkit.ObjectNotFound:
plugins.toolkit.abort(404, _('User not found'))
except plugins.toolkit.NotAuthorized:
plugins.toolkit.abort(401, _('Not authorized to see this page'))
# Get the datasets adquired by the user
query = model.Session.query(model.PackageExtra).filter(
# Select only the allowed_users key
'package_extra.key=\'%s\' AND package_extra.value!=\'\' ' % 'allowed_users' +
# Selec only when the state is 'active'
'AND package_extra.state=\'%s\' ' % 'active' +
# The user name should be contained in the list
'AND regexp_split_to_array(package_extra.value,\',\') @> ARRAY[\'%s\']' % context['user'])
# Get full information about the datasets
for dataset in query:
try:
dataset_dict = plugins.toolkit.get_action('package_show')(context, {'id': dataset.package_id})
c.user_dict['adquired_datasets'].append(dataset_dict)
except Exception:
continue
return plugins.toolkit.render('user/dashboard_adquired.html')