def create(self, validated_data): request = self.context['request'] user = request.user if 'template_from' in validated_data: template_from = validated_data.pop('template_from') template_node = Node.load(key=template_from) if template_node is None: raise exceptions.NotFound if not template_node.has_permission(user, 'read', check_parent=False): raise exceptions.PermissionDenied validated_data.pop('creator') changed_data = {template_from: validated_data} node = template_node.use_as_template(auth=get_user_auth(request), changes=changed_data) else: node = Node(**validated_data) try: node.save() except ValidationValueError as e: raise InvalidModelValueError(detail=e.message) if is_truthy(request.GET.get('inherit_contributors')) and validated_data['parent'].has_permission(user, 'write'): auth = get_user_auth(request) parent = validated_data['parent'] contributors = [] for contributor in parent.contributors: if contributor is not user: contributors.append({ 'user': contributor, 'permissions': parent.get_permissions(contributor), 'visible': parent.get_visible(contributor) }) node.add_contributors(contributors, auth=auth, log=True, save=True) return node
def update(self, node, validated_data): """Update instance with the validated data. Requires the request to be in the serializer context. """ assert isinstance(node, AbstractNode), 'node must be a Node' auth = get_user_auth(self.context['request']) # Update tags if 'tags' in validated_data: new_tags = set(validated_data.pop('tags', [])) node.update_tags(new_tags, auth=auth) if validated_data: if 'license_type' in validated_data or 'license' in validated_data: license_details = get_license_details(node, validated_data) validated_data['node_license'] = license_details try: node.update(validated_data, auth=auth) except ValidationError as e: raise InvalidModelValueError(detail=e.message) except PermissionsError: raise exceptions.PermissionDenied except NodeUpdateError as e: raise exceptions.ValidationError(detail=e.reason) except NodeStateError as e: raise InvalidModelValueError(detail=e.message) return node
def create(self, validated_data): auth = get_user_auth(self.context['request']) if not auth.user: raise exceptions.PermissionDenied try: node = self.context['view'].get_node() except exceptions.PermissionDenied: node = self.context['view'].get_node(check_object_permissions=False) if auth.user in node.contributors: raise exceptions.PermissionDenied('You cannot request access to a node you contribute to.') raise comment = validated_data.pop('comment', '') request_type = validated_data.pop('request_type', None) if not request_type: raise exceptions.ValidationError('You must specify a valid request_type.') try: node_request = NodeRequest.objects.create( target=node, creator=auth.user, comment=comment, machine_state=DefaultStates.INITIAL.value, request_type=request_type ) node_request.save() except IntegrityError: raise Conflict('Users may not have more than one {} request per node.'.format(request_type)) node_request.run_submit(auth.user) return node_request
def get_queryset(self): # For bulk requests, queryset is formed from request body. if is_bulk_request(self.request): auth = get_user_auth(self.request) registrations = Registration.objects.filter(guids___id__in=[registration['id'] for registration in self.request.data]) # If skip_uneditable=True in query_params, skip nodes for which the user # does not have EDIT permissions. if is_truthy(self.request.query_params.get('skip_uneditable', False)): has_permission = registrations.filter(contributor__user_id=auth.user.id, contributor__write=True).values_list('guids___id', flat=True) return Registration.objects.filter(guids___id__in=has_permission) for registration in registrations: if not registration.can_edit(auth): raise PermissionDenied return registrations blacklisted = self.is_blacklisted() registrations = self.get_queryset_from_request() # If attempting to filter on a blacklisted field, exclude withdrawals. if blacklisted: registrations = registrations.exclude(retraction__isnull=False) return registrations.select_related( 'root', 'root__embargo', 'root__embargo_termination_approval', 'root__retraction', 'root__registration_approval', )
def has_object_permission(self, request, view, obj): if isinstance(obj, ChronosSubmission): submission = ChronosSubmission.objects.get(publication_id=view.kwargs.get('submission_id', None)) auth = get_user_auth(request) is_submission_accepted = submission.status == 3 is_submission_published = submission.status == 4 user_has_perm = False # If the request is a GET, then check whether the user is a CONTRIBUTOR # Because it is okay for us to show contributors detail of all submissions of this preprint if request.method == 'GET': is_preprint_contributor = obj.preprint.is_contributor(auth.user) user_has_perm = is_preprint_contributor or is_submission_published or is_submission_accepted if not user_has_perm: raise exceptions.NotFound # However if the request is a PATCH or PUT, check whether the user is an ADMIN of this preprint # Because only preprint admins can update a submission if request.method in ['PATCH', 'PUT']: is_preprint_admin = obj.preprint.has_permission(auth.user, osf_permissions.ADMIN) user_has_perm = is_preprint_admin if not user_has_perm: raise exceptions.PermissionDenied return user_has_perm
def has_object_permission(self, request, view, obj): assert isinstance(obj, NodeWikiPage), 'obj must be a NodeWikiPage, got {}'.format(obj) auth = get_user_auth(request) if request.method in permissions.SAFE_METHODS: return obj.node.is_public or obj.node.can_view(auth) else: return obj.node.can_edit(auth)
def update(self, node, validated_data): """Update instance with the validated data. Requires the request to be in the serializer context. """ assert isinstance(node, Node), 'node must be a Node' auth = get_user_auth(self.context['request']) old_tags = set([tag._id for tag in node.tags]) if 'tags' in validated_data: current_tags = set(validated_data.get('tags')) del validated_data['tags'] elif self.partial: current_tags = set(old_tags) else: current_tags = set() for new_tag in (current_tags - old_tags): node.add_tag(new_tag, auth=auth) for deleted_tag in (old_tags - current_tags): node.remove_tag(deleted_tag, auth=auth) if validated_data: try: node.update(validated_data, auth=auth) except ValidationValueError as e: raise InvalidModelValueError(detail=e.message) except PermissionsError: raise exceptions.PermissionDenied except NodeUpdateError as e: raise exceptions.ValidationError(detail=e.reason) return node
def get_unread_comments_count(self, obj): user = get_user_auth(self.context['request']).user node_comments = Comment.find_n_unread(user=user, node=obj, page='node') return { 'node': node_comments }
def has_object_permission(self, request, view, obj): assert_resource_type(obj, self.acceptable_models) auth = get_user_auth(request) if request.method in permissions.SAFE_METHODS: return obj.is_public or obj.can_view(auth) else: return obj.has_permission(auth.user, osf_permissions.ADMIN)
def get_queryset(self): log = self.get_log() auth_user = get_user_auth(self.request) return [ node for node in log.node__logged if node.can_view(auth_user) ]
def get_node_links_count(self, obj): count = 0 auth = get_user_auth(self.context['request']) for pointer in obj.linked_nodes.filter(is_deleted=False, type='osf.node'): if pointer.can_view(auth): count += 1 return count
def has_object_permission(self, request, view, obj): assert isinstance(obj, (Node, Pointer)), "obj must be a Node or Pointer, got {}".format(obj) auth = get_user_auth(request) if request.method in permissions.SAFE_METHODS: return obj.is_public or obj.can_view(auth) else: return obj.can_edit(auth)
def get_default_queryset(self): auth = get_user_auth(self.request) auth_user = getattr(auth, 'user', None) provider = get_object_or_error(PreprintProvider, self.kwargs['provider_id'], self.request, display_name='PreprintProvider') # Permissions on the list objects are handled by the query return self.preprints_queryset(provider.preprint_services.all(), auth_user)
def get_node_links_count(self, obj): count = 0 auth = get_user_auth(self.context['request']) for pointer in obj.nodes_pointer: if not pointer.node.is_deleted and not pointer.node.is_collection and pointer.node.can_view(auth): count += 1 return count
def create(self, validated_data): auth = get_user_auth(self.context['request']) draft = validated_data.pop('draft') registration_choice = validated_data.pop('registration_choice', 'immediate') embargo_lifted = validated_data.pop('lift_embargo', None) reviewer = is_prereg_admin_not_project_admin(self.context['request'], draft) try: draft.validate_metadata(metadata=draft.registration_metadata, reviewer=reviewer, required_fields=True) except ValidationValueError as e: raise exceptions.ValidationError(e.message) registration = draft.register(auth, save=True) if registration_choice == 'embargo': if not embargo_lifted: raise exceptions.ValidationError('lift_embargo must be specified.') embargo_end_date = embargo_lifted.replace(tzinfo=pytz.utc) try: registration.embargo_registration(auth.user, embargo_end_date) except ValidationError as err: raise exceptions.ValidationError(err.message) else: try: registration.require_approval(auth.user) except NodeStateError as err: raise exceptions.ValidationError(err) registration.save() return registration
def create(self, validated_data): node = validated_data.pop('node', {}) if isinstance(node, dict): node = Node.objects.create(creator=self.context['request'].user, **node) if node.is_deleted: raise exceptions.ValidationError('Cannot create a preprint from a deleted node.') auth = get_user_auth(self.context['request']) if not node.has_permission(auth.user, permissions.ADMIN): raise exceptions.PermissionDenied provider = validated_data.pop('provider', None) if not provider: raise exceptions.ValidationError(detail='You must specify a valid provider to create a preprint.') node_preprints = node.preprints.filter(provider=provider) if node_preprints.exists(): raise Conflict('Only one preprint per provider can be submitted for a node. Check `meta[existing_resource_id]`.', meta={'existing_resource_id': node_preprints.first()._id}) preprint = PreprintService(node=node, provider=provider) preprint.save() preprint.node._has_abandoned_preprint = True preprint.node.save() return self.update(preprint, validated_data)
def has_object_permission(self, request, view, obj): assert isinstance(obj, AbstractNode), 'obj must be an Node, got {}'.format(obj) auth = get_user_auth(request) if request.method in permissions.SAFE_METHODS: return obj.is_contributor(auth.user) else: return obj.has_permission(auth.user, 'write')
def perform_destroy(self, instance): auth = get_user_auth(self.request) try: instance.remove_node(auth=auth) except NodeStateError as err: raise ValidationError(err.message) instance.save()
def has_object_permission(self, request, view, obj): assert isinstance(obj, (AbstractNode, OSFUser, Institution, BaseAddonSettings, DraftRegistration, PrivateLink)), 'obj must be an Node, User, Institution, Draft Registration, PrivateLink, or AddonSettings; got {}'.format(obj) auth = get_user_auth(request) if request.method in permissions.SAFE_METHODS: return obj.is_public or obj.can_view(auth) else: return obj.has_permission(auth.user, osf_permissions.ADMIN)
def has_object_permission(self, request, view, obj): assert isinstance(obj, (Node, DraftRegistration, PrivateLink)), 'obj must be a Node, Draft Registration, or PrivateLink, got {}'.format(obj) auth = get_user_auth(request) node = Node.load(request.parser_context['kwargs']['node_id']) if request.method != 'DELETE' and is_prereg_admin(auth.user): return True return node.has_permission(auth.user, osf_permissions.ADMIN)
def has_object_permission(self, request, view, obj): assert isinstance(obj, dict) auth = get_user_auth(request) parent_node = obj['self'] if request.method in permissions.SAFE_METHODS: return parent_node.can_view(auth) elif request.method == 'DELETE': return parent_node.can_edit(auth) else: has_parent_auth = parent_node.can_edit(auth) if not has_parent_auth: return False pointer_nodes = [] for pointer in request.data.get('data', []): node = AbstractNode.load(pointer['id']) if not node or node.is_collection: raise exceptions.NotFound(detail='Node with id "{}" was not found'.format(pointer['id'])) pointer_nodes.append(node) has_pointer_auth = True for pointer in pointer_nodes: if not pointer.can_view(auth): has_pointer_auth = False break return has_pointer_auth
def create(self, validated_data): auth = get_user_auth(self.context['request']) if not auth.user: raise exceptions.PermissionDenied preprint = self.context['view'].get_target() if not preprint.has_permission(auth.user, osf_permissions.ADMIN): raise exceptions.PermissionDenied comment = validated_data.pop('comment', '') request_type = validated_data.pop('request_type', None) if PreprintRequest.objects.filter(target_id=preprint.id, creator_id=auth.user.id, request_type=request_type).exists(): raise Conflict('Users may not have more than one {} request per preprint.'.format(request_type)) if request_type != RequestTypes.WITHDRAWAL.value: raise exceptions.ValidationError('You must specify a valid request_type.') preprint_request = PreprintRequest.objects.create( target=preprint, creator=auth.user, comment=comment, machine_state=DefaultStates.INITIAL.value, request_type=request_type ) preprint_request.save() preprint_request.run_submit(auth.user) return preprint_request
def create(self, validated_data): node = Node.load(validated_data.pop('node', None)) if not node: raise exceptions.NotFound('Unable to find Node with specified id.') auth = get_user_auth(self.context['request']) if not node.has_permission(auth.user, permissions.ADMIN): raise exceptions.PermissionDenied primary_file = validated_data.pop('primary_file', None) if not primary_file: raise exceptions.ValidationError(detail='You must specify a valid primary_file to create a preprint.') provider = validated_data.pop('provider', None) if not provider: raise exceptions.ValidationError(detail='You must specify a valid provider to create a preprint.') if PreprintService.find(Q('node', 'eq', node) & Q('provider', 'eq', provider)).count(): conflict = PreprintService.find_one(Q('node', 'eq', node) & Q('provider', 'eq', provider)) raise Conflict('Only one preprint per provider can be submitted for a node. Check `meta[existing_resource_id]`.', meta={'existing_resource_id': conflict._id}) preprint = PreprintService(node=node, provider=provider) self.set_field(preprint.set_primary_file, primary_file, auth, save=True) preprint.node._has_abandoned_preprint = True preprint.node.save() return self.update(preprint, validated_data)
def perform_destroy(self, instance): auth = get_user_auth(self.request) wiki_page = self.get_object() try: wiki_page.delete(auth) except django_exceptions.ValidationError as err: raise ValidationError(err.message)
def update(self, instance, validated_data): addon_name = instance.config.short_name if addon_name not in ADDONS_FOLDER_CONFIGURABLE: raise EndpointNotImplementedError('Requested addon not currently configurable via API.') auth = get_user_auth(self.context['request']) set_account, external_account_id = self.get_account_info(validated_data) set_folder, folder_info = self.get_folder_info(validated_data, addon_name) # Maybe raise errors self.check_for_update_errors(instance, folder_info, external_account_id) if instance and instance.configured and set_folder and not folder_info: # Enabled and configured, user requesting folder unset instance.clear_settings() instance.save() if instance and instance.has_auth and set_account and not external_account_id: # Settings authorized, User requesting deauthorization instance.deauthorize(auth=auth) # clear_auth performs save elif external_account_id: # Settings may or may not be authorized, user requesting to set instance.external_account account = self.get_account_or_error(addon_name, external_account_id, auth) if instance.external_account and external_account_id != instance.external_account._id: # Ensure node settings are deauthorized first, logs instance.deauthorize(auth=auth) instance.set_auth(account, auth.user) if set_folder and self.should_call_set_folder(folder_info, instance, auth, instance): # Enabled, user requesting to set folder instance.set_folder(folder_info, auth) return instance
def make_instance_obj(self, obj): # Convenience method to format instance based on view's get_object return { 'data': list(self.context['view'].collection_preprints(obj, user=get_user_auth(self.context['request']).user)), 'self': obj, }
def has_object_permission(self, request, view, obj): assert isinstance(obj, dict) auth = get_user_auth(request) collection = obj['self'] has_collection_auth = auth.user and auth.user.has_perm('write_collection', collection) if request.method in permissions.SAFE_METHODS: if collection.is_public: return True elif request.method == 'DELETE': return has_collection_auth if not has_collection_auth: return False pointer_nodes = [] for pointer in request.data.get('data', []): node = AbstractNode.load(pointer['id']) if not node: raise NotFound(detail='Node with id "{}" was not found'.format(pointer['id'])) pointer_nodes.append(node) has_pointer_auth = True # TODO: is this necessary? get_object checks can_view for pointer in pointer_nodes: if not pointer.can_view(auth): has_pointer_auth = False break return has_pointer_auth
def get_registration_links_count(self, obj): count = 0 auth = get_user_auth(self.context['request']) for pointer in obj.linked_nodes.filter(is_deleted=False, type='osf.registration').exclude(type='osf.collection'): if pointer.can_view(auth): count += 1 return count
def get_meta_information(self, meta_data, value): """ For retrieving meta values, otherwise returns {} """ meta = {} for key in meta_data or {}: if key == 'count' or key == 'unread': show_related_counts = self.context['request'].query_params.get('related_counts', False) if self.context['request'].parser_context.get('kwargs'): if self.context['request'].parser_context['kwargs'].get('is_embedded'): show_related_counts = False field_counts_requested = self.process_related_counts_parameters(show_related_counts, value) if utils.is_truthy(show_related_counts): meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent) elif utils.is_falsy(show_related_counts): continue elif self.field_name in field_counts_requested: meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent) else: continue elif key == 'projects_in_common': if not get_user_auth(self.context['request']).user: continue if not self.context['request'].query_params.get('show_projects_in_common', False): continue meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent) else: meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent) return meta
def get_node_count(self, obj): auth = get_user_auth(self.context['request']) user_id = getattr(auth.user, 'id', None) with connection.cursor() as cursor: cursor.execute(''' WITH RECURSIVE parents AS ( SELECT parent_id, child_id FROM osf_noderelation WHERE child_id = %s AND is_node_link IS FALSE UNION ALL SELECT osf_noderelation.parent_id, parents.parent_id AS child_id FROM parents JOIN osf_noderelation ON parents.PARENT_ID = osf_noderelation.child_id WHERE osf_noderelation.is_node_link IS FALSE ), has_admin AS (SELECT * FROM osf_contributor WHERE (node_id IN (SELECT parent_id FROM parents) OR node_id = %s) AND user_id = %s AND admin IS TRUE LIMIT 1) SELECT DISTINCT COUNT(child_id) FROM osf_noderelation JOIN osf_abstractnode ON osf_noderelation.child_id = osf_abstractnode.id JOIN osf_contributor ON osf_abstractnode.id = osf_contributor.node_id LEFT JOIN osf_privatelink_nodes ON osf_abstractnode.id = osf_privatelink_nodes.abstractnode_id LEFT JOIN osf_privatelink ON osf_privatelink_nodes.privatelink_id = osf_privatelink.id WHERE parent_id = %s AND is_node_link IS FALSE AND osf_abstractnode.is_deleted IS FALSE AND ( osf_abstractnode.is_public OR (TRUE IN (SELECT TRUE FROM has_admin)) OR (osf_contributor.user_id = %s AND osf_contributor.read IS TRUE) OR (osf_privatelink.key = %s AND osf_privatelink.is_deleted = FALSE) ); ''', [obj.id, obj.id, user_id, obj.id, user_id, auth.private_key]) return int(cursor.fetchone()[0])
def has_permission(self, request, view): if request.method not in ['PATCH', 'PUT']: return True auth = get_user_auth(request) return auth.user.has_perm('update_moderator', view.get_provider())
def has_permission(self, request, view): if request.method != 'POST': return True auth = get_user_auth(request) return auth.user.has_perm('add_moderator', view.get_provider())
def has_object_permission(self, request, view, obj): assert_resource_type(obj, self.acceptable_models) auth = get_user_auth(request) return obj.has_permission(auth.user, 'admin')
def update(self, preprint, validated_data): assert isinstance( preprint, PreprintService), 'You must specify a valid preprint to be updated' assert isinstance( preprint.node, Node ), 'You must specify a preprint with a valid node to be updated.' auth = get_user_auth(self.context['request']) if not preprint.node.has_permission(auth.user, 'admin'): raise exceptions.PermissionDenied( detail='User must be an admin to update a preprint.') published = validated_data.pop('is_published', None) if published and preprint.provider.is_reviewed: raise Conflict( '{} uses a moderation workflow, so preprints must be submitted for review instead of published directly. Submit a preprint by creating a `submit` Action at {}' .format( preprint.provider.name, absolute_reverse( 'preprints:preprint-review-action-list', kwargs={ 'version': self.context['request'].parser_context['kwargs'] ['version'], 'preprint_id': preprint._id }))) save_node = False save_preprint = False recently_published = False primary_file = validated_data.pop('primary_file', None) if primary_file: self.set_field(preprint.set_primary_file, primary_file, auth) save_node = True old_tags = set(preprint.node.tags.values_list('name', flat=True)) if validated_data.get('node') and 'tags' in validated_data['node']: current_tags = set(validated_data['node'].pop('tags', [])) elif self.partial: current_tags = set(old_tags) else: current_tags = set() for new_tag in (current_tags - old_tags): preprint.node.add_tag(new_tag, auth=auth) for deleted_tag in (old_tags - current_tags): preprint.node.remove_tag(deleted_tag, auth=auth) if 'node' in validated_data: preprint.node.update(fields=validated_data.pop('node')) save_node = True if 'subjects' in validated_data: subjects = validated_data.pop('subjects', None) self.set_field(preprint.set_subjects, subjects, auth) save_preprint = True if 'article_doi' in validated_data: preprint.node.preprint_article_doi = validated_data['article_doi'] save_node = True if 'license_type' in validated_data or 'license' in validated_data: license_details = get_license_details(preprint, validated_data) self.set_field(preprint.set_preprint_license, license_details, auth) save_preprint = True if 'original_publication_date' in validated_data: preprint.original_publication_date = validated_data[ 'original_publication_date'] save_preprint = True if published is not None: if not preprint.primary_file: raise exceptions.ValidationError( detail= 'A valid primary_file must be set before publishing a preprint.' ) self.set_field(preprint.set_published, published, auth) save_preprint = True recently_published = published preprint.node.set_privacy('public') save_node = True if save_node: try: preprint.node.save() except ValidationError as e: # Raised from invalid DOI raise exceptions.ValidationError(detail=e.messages[0]) if save_preprint: preprint.save() # Send preprint confirmation email signal to new authors on preprint! -- only when published # TODO: Some more thought might be required on this; preprints made from existing # nodes will send emails making it seem like a new node. if recently_published: for author in preprint.node.contributors: if author != auth.user: project_signals.contributor_added.send( preprint.node, contributor=author, auth=auth, email_template='preprint') return preprint
def has_object_permission(self, request, view, obj): if request.method in drf_permissions.SAFE_METHODS: return True auth = get_user_auth(request) return auth.user.has_perm('set_up_moderation', obj)
def get_registration_count(self, obj): auth = get_user_auth(self.context['request']) user_registration = default_node_list_queryset(model_cls=Registration).filter(contributor__user__id=obj.id) return user_registration.can_view(user=auth.user, private_link=auth.private_link).count()
def get_registration_count(self, obj): auth = get_user_auth(self.context['request']) registrations = [ node for node in obj.registrations_all if node.can_view(auth) ] return len(registrations)
def update(self, instance, validated_data): auth = get_user_auth(self.context['request']) preprint = instance['self'] preprint.unset_supplemental_node(auth=auth) preprint.save() return self.make_instance_obj(preprint)
def update(self, preprint, validated_data): assert isinstance(preprint, Preprint), 'You must specify a valid preprint to be updated' auth = get_user_auth(self.context['request']) if not preprint.has_permission(auth.user, osf_permissions.WRITE): raise exceptions.PermissionDenied(detail='User must have admin or write permissions to update a preprint.') published = validated_data.pop('is_published', None) if published and preprint.provider.is_reviewed: raise Conflict('{} uses a moderation workflow, so preprints must be submitted for review instead of published directly. Submit a preprint by creating a `submit` Action at {}'.format( preprint.provider.name, absolute_reverse( 'preprints:preprint-review-action-list', kwargs={ 'version': self.context['request'].parser_context['kwargs']['version'], 'preprint_id': preprint._id, }, ), )) save_preprint = False recently_published = False primary_file = validated_data.pop('primary_file', None) if primary_file: self.set_field(preprint.set_primary_file, primary_file, auth) save_preprint = True old_tags = set(preprint.tags.values_list('name', flat=True)) if 'tags' in validated_data: current_tags = set(validated_data.pop('tags', [])) elif self.partial: current_tags = set(old_tags) else: current_tags = set() for new_tag in (current_tags - old_tags): preprint.add_tag(new_tag, auth=auth) for deleted_tag in (old_tags - current_tags): preprint.remove_tag(deleted_tag, auth=auth) if 'node' in validated_data: node = validated_data.pop('node', None) self.set_field(preprint.set_supplemental_node, node, auth) save_preprint = True if 'subjects' in validated_data: subjects = validated_data.pop('subjects', None) self.update_subjects(preprint, subjects, auth) save_preprint = True if 'title' in validated_data: title = validated_data['title'] self.set_field(preprint.set_title, title, auth) save_preprint = True if 'description' in validated_data: description = validated_data['description'] self.set_field(preprint.set_description, description, auth) save_preprint = True if 'article_doi' in validated_data: preprint.article_doi = validated_data['article_doi'] save_preprint = True if 'license_type' in validated_data or 'license' in validated_data: license_details = get_license_details(preprint, validated_data) self.set_field(preprint.set_preprint_license, license_details, auth) save_preprint = True if 'original_publication_date' in validated_data: preprint.original_publication_date = validated_data['original_publication_date'] or None save_preprint = True if 'has_coi' in validated_data: try: preprint.update_has_coi(auth, validated_data['has_coi']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if 'conflict_of_interest_statement' in validated_data: try: preprint.update_conflict_of_interest_statement(auth, validated_data['conflict_of_interest_statement']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if 'has_data_links' in validated_data: try: preprint.update_has_data_links(auth, validated_data['has_data_links']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if 'why_no_data' in validated_data: try: preprint.update_why_no_data(auth, validated_data['why_no_data']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if 'data_links' in validated_data: try: preprint.update_data_links(auth, validated_data['data_links']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if 'has_prereg_links' in validated_data: try: preprint.update_has_prereg_links(auth, validated_data['has_prereg_links']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if 'why_no_prereg' in validated_data: try: preprint.update_why_no_prereg(auth, validated_data['why_no_prereg']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if 'prereg_links' in validated_data: try: preprint.update_prereg_links(auth, validated_data['prereg_links']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if 'prereg_link_info' in validated_data: try: preprint.update_prereg_link_info(auth, validated_data['prereg_link_info']) except PreprintStateError as e: raise exceptions.ValidationError(detail=str(e)) if published is not None: if not preprint.primary_file: raise exceptions.ValidationError(detail='A valid primary_file must be set before publishing a preprint.') self.set_field(preprint.set_published, published, auth) save_preprint = True recently_published = published preprint.set_privacy('public', log=False, save=True) if save_preprint: preprint.save() if recently_published: for author in preprint.contributors: if author != auth.user: project_signals.contributor_added.send(preprint, contributor=author, auth=auth, email_template='preprint') return preprint
def get_preprint_count(self, obj): auth_user = get_user_auth(self.context['request']).user user_preprints_query = Preprint.objects.filter(_contributors__guids___id=obj._id).exclude(machine_state='initial') return Preprint.objects.can_view(user_preprints_query, auth_user, allow_contribs=False).count()
def get_projects_in_common(self, obj): user = get_user_auth(self.context['request']).user if obj == user: return user.contributor_to.count() return obj.n_projects_in_common(user)
def get_node_count(self, obj): auth = get_user_auth(self.context['request']) if obj != auth.user: return default_node_list_permission_queryset(user=auth.user, model_cls=Node).filter(contributor__user__id=obj.id).count() return default_node_list_queryset(model_cls=Node).filter(contributor__user__id=obj.id).count()
def has_object_permission(self, request, view, obj): assert isinstance( obj, AbstractNode), 'obj must be an Node, got {}'.format(obj) auth = get_user_auth(request) return obj.has_permission(auth.user, osf_permissions.ADMIN)
def get_default_queryset(self): auth = get_user_auth(self.request) auth_user = getattr(auth, 'user', None) # Permissions on the list objects are handled by the query return self.preprints_queryset(PreprintService.objects.all(), auth_user)
def has_permission(self, request, view): auth = get_user_auth(request) return bool(get_perms(auth.user, view.get_provider()))
def has_object_permission(self, request, view, obj): assert isinstance( obj, AbstractNode), 'obj must be an Node got {}'.format(obj) auth = get_user_auth(request) return obj.is_public or obj.can_view(auth)
def update(self, preprint, validated_data): assert isinstance( preprint, PreprintService), 'You must specify a valid preprint to be updated' assert isinstance( preprint.node, Node ), 'You must specify a preprint with a valid node to be updated.' auth = get_user_auth(self.context['request']) if not preprint.node.has_permission(auth.user, 'admin'): raise exceptions.PermissionDenied( detail='User must be an admin to update a preprint.') save_node = False save_preprint = False recently_published = False primary_file = validated_data.pop('primary_file', None) if primary_file: self.set_field(preprint.set_primary_file, primary_file, auth) save_node = True if 'subjects' in validated_data: subjects = validated_data.pop('subjects', None) self.set_field(preprint.set_subjects, subjects, auth) save_preprint = True if 'article_doi' in validated_data: preprint.node.preprint_article_doi = validated_data['article_doi'] save_node = True published = validated_data.pop('is_published', None) if published is not None: self.set_field(preprint.set_published, published, auth) save_preprint = True recently_published = published if 'license_type' in validated_data or 'license' in validated_data: license_details = get_license_details(preprint, validated_data) self.set_field(preprint.set_preprint_license, license_details, auth) save_preprint = True if save_node: try: preprint.node.save() except ValidationValueError as e: # Raised from invalid DOI raise exceptions.ValidationError(detail=e.message) if save_preprint: preprint.save() # Send preprint confirmation email signal to new authors on preprint! -- only when published # TODO: Some more thought might be required on this; preprints made from existing # nodes will send emails making it seem like a new node. if recently_published: for author in preprint.node.contributors: if author != auth.user: project_signals.contributor_added.send( preprint.node, contributor=author, auth=auth, email_template='preprint') return preprint
def has_object_permission(self, request, view, obj): assert_resource_type(obj, self.acceptable_models) if isinstance(obj, PrivateLink): obj = view.get_node() auth = get_user_auth(request) return obj.has_permission(auth.user, osf_permissions.ADMIN)
def create(self, validated_data): auth = get_user_auth(self.context['request']) user_id = validated_data.pop('_id', '') address = validated_data.pop('email', '') provider = self.context['provider'] context = { 'referrer': auth.user, } if user_id and address: raise ValidationError('Cannot specify both "id" and "email".') user = None if user_id: user = OSFUser.load(user_id) elif address: try: email = Email.objects.get(address=address.lower()) except Email.DoesNotExist: full_name = validated_data.pop('fullname', '') if not full_name: raise ValidationError( '"full_name" is required when adding a moderator via email.' ) user = OSFUser.create_unregistered(full_name, email=address) user.add_unclaimed_record( provider, referrer=auth.user, given_name=full_name, email=address, ) user.save() claim_url = user.get_claim_url(provider._id, external=True) context['claim_url'] = claim_url else: user = email.user else: raise ValidationError('Must specify either "id" or "email".') if not user: raise ValidationError('Unable to find specified user.') context['user'] = user context['provider'] = provider if bool(get_perms(user, provider)): raise ValidationError('Specified user is already a moderator.') if 'claim_url' in context: template = mails.CONFIRM_EMAIL_MODERATION(provider) else: template = mails.MODERATOR_ADDED(provider) perm_group = validated_data.pop('permission_group', '') if perm_group not in REVIEW_GROUPS: raise ValidationError('Unrecognized permission_group') context[ 'notification_settings_url'] = '{}reviews/preprints/{}/notifications'.format( DOMAIN, provider._id) context['provider_name'] = provider.name context['is_reviews_moderator_notification'] = True context['is_admin'] = perm_group == 'admin' provider.add_to_group(user, perm_group) setattr(user, 'permission_group', perm_group) # Allows reserialization mails.send_mail(user.username, template, mimetype='html', **context) return user
def get_permissions(self, obj): auth = get_user_auth(self.context['request']) if not auth.user: return [] return get_perms(auth.user, obj)
def has_object_permission(self, request, view, obj): auth = get_user_auth(request) return obj.can_edit(auth)
def get_projects_in_common(self, obj): user = get_user_auth(self.context['request']).user if obj == user: return len(user.contributor_to) return len(obj.get_projects_in_common(user, primary_keys=True))
def perform_destroy(self, instance): auth = get_user_auth(self.request) instance.remove_group(auth=auth)
def has_object_permission(self, request, view, obj): assert_resource_type(obj, self.acceptable_models) auth = get_user_auth(request) return obj.is_public or obj.can_view(auth)
def get_registration_links_count(self, obj): auth = get_user_auth(self.context['request']) return Registration.objects.filter( guids__in=obj.guid_links.all(), is_deleted=False).can_view(user=auth.user, private_link=auth.private_link).count()
def get_queryset(self): auth = get_user_auth(self.request) return self.collection_preprints(self.get_collection(), auth.user)
def get_queryset(self): auth = get_user_auth(self.request) return Registration.objects.filter(guids__in=self.get_collection().guid_links.all(), is_deleted=False).can_view(user=auth.user, private_link=auth.private_link).order_by('-modified')
def get_queryset(self): auth = get_user_auth(self.request) return self.get_node().linked_nodes.filter(is_deleted=False).exclude(type='osf.collection').can_view(user=auth.user, private_link=auth.private_link).order_by('-date_modified')
def get_unread_comments_count(self, obj): user = get_user_auth(self.context['request']).user node_comments = Comment.find_n_unread(user=user, node=obj, page='node') return {'node': node_comments}
def has_object_permission(self, request, view, obj): auth = get_user_auth(request) # If a user has perms on the provider, they must be a moderator or admin is_moderator = bool(get_perms(auth.user, obj.provider)) return obj.is_admin_contributor(auth.user) or is_moderator