def test_get_data_curation_users(self): depadmin = core_factories.User(name='depadmin') curator1 = core_factories.User(name='curator1') curator2 = core_factories.User(name='curator2') deposit = factories.DataContainer( name='data-deposit', users=[ { 'name': 'depadmin', 'capacity': 'admin' }, { 'name': 'curator1', 'capacity': 'editor' }, { 'name': 'curator2', 'capacity': 'editor' }, ], ) curators = helpers.get_data_curation_users( context={'user': '******'}) curator_names = sorted([ curator['name'] for curator in curators # Added to org by ckan if not curator['sysadmin'] ]) assert_equals(len(curator_names), 3) assert_equals(curator_names[0], 'curator1') assert_equals(curator_names[1], 'curator2') assert_equals(curator_names[2], 'depadmin')
def withdraw(self, dataset_id): user_id = getattr(toolkit.c.userobj, 'id', None) # Get curation data try: context, dataset, curation = _get_curation_data( dataset_id, user_id) except (toolkit.ObjectNotFound, toolkit.NotAuthorized): message = 'Not authorized to read dataset "%s"' return toolkit.abort(403, message % dataset_id) # Authorize context if 'withdraw' not in curation['actions']: message = 'This action is not available for the dataset "%s"' toolkit.h.flash_error(message % dataset['title']) toolkit.redirect_to('deposited-dataset_read', id=dataset['name']) context['ignore_auth'] = True # Delete withdrawn dataset, but first update its name so it can be reused new_name = _get_withdrawn_dataset_name(dataset['name']) toolkit.get_action('package_patch')(context, { 'id': dataset_id, 'name': new_name }) toolkit.get_action('package_delete')(context, {'id': dataset_id}) # Update activity stream message = toolkit.request.params.get('message') helpers.create_curation_activity('dataset_withdrawn', dataset['id'], dataset['name'], user_id, message=message) # Send notification email message = toolkit.request.params.get('message') for user in helpers.get_data_curation_users(): subj = mailer.compose_curation_email_subj(dataset) body = mailer.compose_curation_email_body(dataset, curation, user['display_name'], 'withdraw', message=message) mailer.mail_user_by_id(user['id'], subj, body) # Show flash message and redirect message = 'Dataset "%s" withdrawn' toolkit.h.flash_error(message % dataset['title']) toolkit.redirect_to('data-container_read', id='data-deposit')
def submit(self, dataset_id): user_id = getattr(toolkit.c.userobj, 'id', None) # Get curation data try: context, dataset, curation = _get_curation_data( dataset_id, user_id) except (toolkit.ObjectNotFound, toolkit.NotAuthorized): message = 'Not authorized to read dataset "%s"' return toolkit.abort(403, message % dataset_id) # Authorize context if 'submit' not in curation['actions']: message = 'This action is not available for the dataset "%s"' toolkit.h.flash_error(message % dataset['title']) toolkit.redirect_to('deposited-dataset_read', id=dataset['name']) context['ignore_auth'] = True # Update dataset dataset['curation_state'] = 'submitted' dataset = toolkit.get_action('package_update')(context, dataset) # Update activity stream message = toolkit.request.params.get('message') helpers.create_curation_activity('dataset_submitted', dataset['id'], dataset['name'], user_id, message=message) # Send notification email message = toolkit.request.params.get('message') curator = curation['contacts']['curator'] # We don't bother all curators if someone is already assigned users = [curator] if curator else helpers.get_data_curation_users() for user in users: subj = mailer.compose_curation_email_subj(dataset) body = mailer.compose_curation_email_body(dataset, curation, user['display_name'], 'submit', message=message) mailer.mail_user_by_id(user['id'], subj, body) # Show flash message and redirect message = 'Dataset "%s" submitted' toolkit.h.flash_success(message % dataset['title']) toolkit.redirect_to('deposited-dataset_read', id=dataset['name'])
def resource_download(context, data_dict): ''' This is a new auth function that specifically controls access to the download of a resource file, as opposed to seeing the metadata of a resource (handled by `resource_show` If this resource is marked as public or private in the custom visibility field, the authorization check is deferred to `resource_show` as the standard logic applies (we assume that the necessary validators are applied to keep `visibility` and `private` fields in sync). If this resource is marked as `restricted` then only users belonging to the dataset organization can download the file. ''' # Prepare all the parts context['model'] = context.get('model') or model user = context.get('user') resource = get_resource_object(context, data_dict) dataset = toolkit.get_action('package_show')({ 'ignore_auth': True }, { 'id': resource.package_id }) visibility = resource.extras.get('visibility') # Use default check user_id = getattr(context.get('auth_user_obj'), 'id', None) is_deposit = dataset.get('type') == 'deposited-dataset' if is_deposit: is_depositor = dataset.get('creator_user_id') == user_id curators = [u['id'] for u in helpers.get_data_curation_users(dataset)] is_curator = user_id in curators else: is_depositor = False is_curator = False if not user or is_depositor or is_curator or not visibility or visibility != 'restricted': try: toolkit.check_access('resource_show', context, data_dict) return {'success': True} except toolkit.NotAuthorized: return {'success': False} # Restricted visibility (public metadata but private downloads) if dataset.get('owner_org'): user_orgs = toolkit.get_action('organization_list_for_user')( { 'ignore_auth': True }, { 'id': user }) user_in_owner_org = any(org['id'] == dataset['owner_org'] for org in user_orgs) if user_in_owner_org: return {'success': True} # Check if the user is a dataset collaborator action = toolkit.get_action('package_collaborator_list_for_user') if user and action: datasets = action(context, {'id': user}) return { 'success': resource.package_id in [d['package_id'] for d in datasets] } return {'success': False}