137 lines
6.2 KiB
Python
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')
|