Ejemplo n.º 1
0
def serialize_comment(comment):
    reports = [
        serialize_report(user, report)
        for user, report in comment.reports.iteritems()
    ]
    author_abs_url = furl(OSF_DOMAIN)
    author_abs_url.path.add(comment.user.url)

    return {
        'id': comment._id,
        'author': OSFUser.load(comment.user._id),
        'author_id': comment.user._id,
        'author_path': author_abs_url.url,
        'date_created': comment.created,
        'date_modified': comment.modified,
        'content': comment.content,
        'has_children': bool(getattr(comment, 'commented', [])),
        'modified': comment.edited,
        'is_deleted': comment.is_deleted,
        'spam_status': comment.spam_status,
        'reports': reports,
        'node': comment.node,
        'category': reports[0]['category'],
        'osf_support_email': OSF_SUPPORT_EMAIL,
    }
Ejemplo n.º 2
0
def send_users_email(send_type):
    """Find pending Emails and amalgamates them into a single Email.

    :param send_type
    :return:
    """
    grouped_emails = get_users_emails(send_type)
    for group in grouped_emails:
        user = OSFUser.load(group['user_id'])
        if not user:
            log_exception()
            continue
        info = group['info']
        notification_ids = [message['_id'] for message in info]
        sorted_messages = group_by_node(info)
        if sorted_messages:
            if not user.is_disabled:
                # If there's only one node in digest we can show it's preferences link in the template.
                notification_nodes = sorted_messages['children'].keys()
                node = AbstractNode.load(notification_nodes[0]) if len(
                    notification_nodes) == 1 else None
                mails.send_mail(
                    to_addr=user.username,
                    mimetype='html',
                    can_change_node_preferences=bool(node),
                    node=node,
                    mail=mails.DIGEST,
                    name=user.fullname,
                    message=sorted_messages,
                )
            remove_notifications(email_notification_ids=notification_ids)
Ejemplo n.º 3
0
def get_user_from_cas_resp(cas_resp):
    """
    Given a CAS service validation response, attempt to retrieve user information and next action.
    The `user` in `cas_resp` is the unique GUID of the user. Please do not use the primary key `id`
    or the email `username`. This holds except for the first step of ORCiD login.

    :param cas_resp: the cas service validation response
    :return: the user, the external_credential, and the next action
    """
    from osf.models import OSFUser
    if cas_resp.user:
        user = OSFUser.load(cas_resp.user)
        # cas returns a valid OSF user id
        if user:
            return user, None, 'authenticate'
        # cas does not return a valid OSF user id
        else:
            external_credential = validate_external_credential(cas_resp.user)
            # invalid cas response
            if not external_credential:
                return None, None, None
            # cas returns a valid external credential
            user = get_user(
                external_id_provider=external_credential['provider'],
                external_id=external_credential['id'])
            # existing user found
            if user:
                return user, external_credential, 'authenticate'
            # user first time login through external identity provider
            else:
                return None, external_credential, 'external_first_login'
Ejemplo n.º 4
0
    def form_valid(self, form):
        user_id = form.cleaned_data.get('user_id')
        osf_user = OSFUser.load(user_id)

        if not osf_user:
            raise Http404(
                'OSF user with id "{}" not found. Please double check.'.format(
                    user_id))

        for group in form.cleaned_data.get('group_perms'):
            osf_user.groups.add(group)
            split = group.name.split('_')
            group_type = split[0]
            if group_type == 'reviews':
                provider_id = split[2]
                provider = PreprintProvider.objects.get(id=provider_id)
                provider.notification_subscriptions.get(
                    event_name='new_pending_submissions'
                ).add_user_to_subscription(osf_user, 'email_transactional')

        osf_user.save()
        messages.success(
            self.request,
            'Permissions update successful for OSF User {}!'.format(
                osf_user.username))
        return super(PreprintProviderRegisterModeratorOrAdmin,
                     self).form_valid(form)
Ejemplo n.º 5
0
def reset_password_get(auth, uid=None, token=None):
    """
    View for user to land on the reset password page.
    HTTp Method: GET

    :param auth: the authentication state
    :param uid: the user id
    :param token: the token in verification key
    :return
    :raises: HTTPError(http.BAD_REQUEST) if verification key for the user is invalid, has expired or was used
    """

    # if users are logged in, log them out and redirect back to this page
    if auth.logged_in:
        return auth_logout(redirect_url=request.url)

    # Check if request bears a valid pair of `uid` and `token`
    user_obj = OSFUser.load(uid)
    if not (user_obj and user_obj.verify_password_token(token=token)):
        error_data = {
            'message_short': 'Invalid Request.',
            'message_long': 'The requested URL is invalid, has expired, or was already used',
        }
        raise HTTPError(http.BAD_REQUEST, data=error_data)

    # refresh the verification key (v2)
    user_obj.verification_key_v2 = generate_verification_key(verification_type='password')
    user_obj.save()

    return {
        'uid': user_obj._id,
        'token': user_obj.verification_key_v2['token'],
    }
Ejemplo n.º 6
0
def _get_current_user():
    from osf.models import OSFUser
    current_user_id = get_current_user_id()
    if current_user_id:
        return OSFUser.load(current_user_id, select_for_update=check_select_for_update(request))
    else:
        return None
Ejemplo n.º 7
0
def osfstorage_delete(file_node, payload, target, **kwargs):
    user = OSFUser.load(payload['user'])
    auth = Auth(user)

    #TODO Auth check?
    if not auth:
        raise HTTPError(httplib.BAD_REQUEST)
    if file_node == OsfStorageFolder.objects.get_root(target=target):
        raise HTTPError(httplib.BAD_REQUEST)

    try:
        file_node.delete(user=user)

    except exceptions.FileNodeCheckedOutError:
        raise HTTPError(httplib.FORBIDDEN)
    except exceptions.FileNodeIsPrimaryFile:
        raise HTTPError(
            httplib.FORBIDDEN,
            data={
                'message_long':
                'Cannot delete file as it is the primary file of preprint.'
            })

    update_storage_usage(file_node.target)
    return {'status': 'success'}
Ejemplo n.º 8
0
    def test_make_child_embargoed_registration_public_asks_all_admins_in_tree(
            self, mock_ask):
        # Initiate and approve embargo
        node = NodeFactory(creator=self.user)
        c1 = AuthUserFactory()
        child = NodeFactory(parent=node, creator=c1)
        c2 = AuthUserFactory()
        NodeFactory(parent=child, creator=c2)
        registration = RegistrationFactory(project=node)

        registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10))
        for user_id, embargo_tokens in registration.embargo.approval_state.iteritems(
        ):
            approval_token = embargo_tokens['approval_token']
            registration.embargo.approve_embargo(OSFUser.load(user_id),
                                                 approval_token)
        self.registration.save()

        registration.set_privacy('public', Auth(self.registration.creator))
        asked_admins = [(admin._id, n._id)
                        for admin, n in mock_ask.call_args[0][0]]
        for admin, node in registration.get_admin_contributors_recursive():
            assert_in((admin._id, node._id), asked_admins)
Ejemplo n.º 9
0
    def post(self, request, *args, **kwargs):
        registration_provider = RegistrationProvider.objects.get(
            id=self.kwargs['registration_provider_id'])
        data = dict(request.POST)
        del data[
            'csrfmiddlewaretoken']  # just to remove the key from the form dict

        moderator = OSFUser.load(data['add-moderators-form'][0])
        if moderator is None:
            messages.error(
                request,
                f'User for guid: {data["add-moderators-form"][0]} could not be found'
            )
            return redirect('registration_providers:add_moderators',
                            registration_provider_id=registration_provider.id)

        registration_provider.add_to_group(moderator, 'moderator')

        messages.success(
            request,
            f'The following moderator was successfully added: {moderator.fullname} ({moderator.username})'
        )

        return redirect('registration_providers:add_moderators',
                        registration_provider_id=registration_provider.id)
Ejemplo n.º 10
0
    def test_embargoed_registration_set_privacy_sends_mail(
            self, mock_send_mail):
        """
        Integration test for https://github.com/CenterForOpenScience/osf.io/pull/5294#issuecomment-212613668
        """
        # Initiate and approve embargo
        for i in range(3):
            c = AuthUserFactory()
            self.registration.add_contributor(c, [permissions.ADMIN],
                                              auth=Auth(self.user))
        self.registration.save()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10))
        for user_id, embargo_tokens in self.registration.embargo.approval_state.iteritems(
        ):
            approval_token = embargo_tokens['approval_token']
            self.registration.embargo.approve_embargo(OSFUser.load(user_id),
                                                      approval_token)
        self.registration.save()

        self.registration.set_privacy('public',
                                      Auth(self.registration.creator))
        for admin in self.registration.admin_contributors:
            assert_true(
                any([
                    each[0][0] == admin.username
                    for each in mock_send_mail.call_args_list
                ]))
Ejemplo n.º 11
0
    def test_embargoed_registration_set_privacy_requests_embargo_termination(
            self, mock_ask):
        # Initiate and approve embargo
        for i in range(3):
            c = AuthUserFactory()
            self.registration.add_contributor(c, [permissions.ADMIN],
                                              auth=Auth(self.user))
        self.registration.save()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10))
        for user_id, embargo_tokens in self.registration.embargo.approval_state.iteritems(
        ):
            approval_token = embargo_tokens['approval_token']
            self.registration.embargo.approve_embargo(OSFUser.load(user_id),
                                                      approval_token)
        self.registration.save()

        self.registration.set_privacy('public',
                                      Auth(self.registration.creator))
        for reg in self.registration.node_and_primary_descendants():
            reg.reload()
            assert_false(reg.is_public)
        assert_true(reg.embargo_termination_approval)
        assert_true(reg.embargo_termination_approval.is_pending_approval)
Ejemplo n.º 12
0
    def authenticate(self, request):
        """
        Check whether the request provides a valid OAuth2 bearer token.
        The `user` in `cas_auth_response` is the unique GUID of the user. Please do not use
        the primary key `id` or the email `username`.

        :param request: the request
        :return: the user who owns the bear token and the cas repsonse
        """

        client = cas.get_client()
        try:
            auth_header_field = request.META['HTTP_AUTHORIZATION']
            auth_token = cas.parse_auth_header(auth_header_field)
        except (cas.CasTokenError, KeyError):
            return None

        try:
            cas_auth_response = client.profile(auth_token)
        except cas.CasHTTPError:
            raise exceptions.NotAuthenticated(_('User provided an invalid OAuth2 access token'))

        if cas_auth_response.authenticated is False:
            raise exceptions.NotAuthenticated(_('CAS server failed to authenticate this token'))

        user = OSFUser.load(cas_auth_response.user)
        if not user:
            raise exceptions.AuthenticationFailed(_('Could not find the user associated with this token'))

        check_user(user)
        return user, cas_auth_response
Ejemplo n.º 13
0
def get_user_from_cas_resp(cas_resp):
    """
    Given a CAS service validation response, attempt to retrieve user information and next action.
    The `user` in `cas_resp` is the unique GUID of the user. Please do not use the primary key `id`
    or the email `username`. This holds except for the first step of ORCiD login.

    :param cas_resp: the cas service validation response
    :return: the user, the external_credential, and the next action
    """
    from osf.models import OSFUser
    if cas_resp.user:
        user = OSFUser.load(cas_resp.user)
        # cas returns a valid OSF user id
        if user:
            return user, None, 'authenticate'
        # cas does not return a valid OSF user id
        else:
            external_credential = validate_external_credential(cas_resp.user)
            # invalid cas response
            if not external_credential:
                return None, None, None
            # cas returns a valid external credential
            user = get_user(external_id_provider=external_credential['provider'],
                            external_id=external_credential['id'])
            # existing user found
            if user:
                return user, external_credential, 'authenticate'
            # user first time login through external identity provider
            else:
                return None, external_credential, 'external_first_login'
Ejemplo n.º 14
0
def _get_current_user():
    from osf.models import OSFUser
    current_user_id = get_current_user_id()
    if current_user_id:
        return OSFUser.load(current_user_id, select_for_update=check_select_for_update(request))
    else:
        return None
Ejemplo n.º 15
0
def send_users_email(send_type):
    """Find pending Emails and amalgamates them into a single Email.

    :param send_type
    :return:
    """
    grouped_emails = get_users_emails(send_type)
    if not grouped_emails:
        return
    for group in grouped_emails:
        user = User.load(group['user_id'])
        if not user:
            log_exception()
            continue
        info = group['info']
        notification_ids = [message['_id'] for message in info]
        sorted_messages = group_by_node(info)
        if sorted_messages:
            mails.send_mail(to_addr=user.username,
                            mimetype='html',
                            mail=mails.DIGEST,
                            name=user.fullname,
                            message=sorted_messages,
                            callback=remove_notifications(
                                email_notification_ids=notification_ids))
Ejemplo n.º 16
0
def send_users_email(send_type):
    """Find pending Emails and amalgamates them into a single Email.

    :param send_type
    :return:
    """
    grouped_emails = get_users_emails(send_type)
    for group in grouped_emails:
        user = OSFUser.load(group['user_id'])
        if not user:
            log_exception()
            continue
        info = group['info']
        notification_ids = [message['_id'] for message in info]
        sorted_messages = group_by_node(info)
        if sorted_messages:
            if not user.is_disabled:
                mails.send_mail(
                    to_addr=user.username,
                    mimetype='html',
                    mail=mails.DIGEST,
                    name=user.fullname,
                    message=sorted_messages,
                )
            remove_notifications(email_notification_ids=notification_ids)
Ejemplo n.º 17
0
def process_project_search_results(results, **kwargs):
    """
    :param results: list of projects from the modular ODM search
    :return: we return the entire search result, which is a list of
    dictionaries. This includes the list of contributors.
    """
    user = kwargs['auth'].user

    ret = []

    for project in results:
        authors = get_node_contributors_abbrev(project=project,
                                               auth=kwargs['auth'])
        authors_html = ''
        for author in authors['contributors']:
            a = OSFUser.load(author['user_id'])
            authors_html += '<a href="%s">%s</a>' % (a.url, a.fullname)
            authors_html += author['separator'] + ' '
        authors_html += ' ' + authors['others_count']

        ret.append({
            'id':
            project._id,
            'label':
            project.title,
            'value':
            project.title,
            'category':
            'My Projects'
            if user in project.contributors else 'Public Projects',
            'authors':
            authors_html,
        })

    return ret
Ejemplo n.º 18
0
def get_public_components(uid=None, user=None):
    user = user or User.load(uid)

    rel_child_ids = (
        NodeRelation.objects.filter(
            child__is_public=True,
            child__type='osf.node',  # nodes only (not collections or registration)
            child___contributors=user,  # user is a contributor
            is_node_link=False  # exclude childs by node linkage
        )
        .exclude(parent__type='osf.collection')
        .exclude(child__is_deleted=True)
        .values_list('child_id', flat=True)
    )

    nodes = (Node.objects.filter(id__in=rel_child_ids)
    .include('contributor__user__guids', 'guids', '_parents__parent__guids')
    # Defer some fields that we don't use for rendering node lists
    .defer('child_node_subscriptions', 'date_created', 'deleted_date', 'description',
           'file_guid_to_share_uuids')
        .order_by('-date_modified'))

    return [
        serialize_node_summary(node=node, auth=Auth(user), show_path=True)
        for node in nodes
    ]
Ejemplo n.º 19
0
def deserialize_contributors(node, user_dicts, auth, validate=False):
    """View helper that returns a list of User objects from a list of
    serialized users (dicts). The users in the list may be registered or
    unregistered users.

    e.g. ``[{'id': 'abc123', 'registered': True, 'fullname': ..},
            {'id': None, 'registered': False, 'fullname'...},
            {'id': '123ab', 'registered': False, 'fullname': ...}]

    If a dict represents an unregistered user without an ID, creates a new
    unregistered User record.

    :param Node node: The node to add contributors to
    :param list(dict) user_dicts: List of serialized users in the format above.
    :param Auth auth:
    :param bool validate: Whether to validate and sanitize fields (if necessary)
    """

    # Add the registered contributors
    contribs = []
    for contrib_dict in user_dicts:
        fullname = contrib_dict['fullname']
        visible = contrib_dict['visible']
        email = contrib_dict.get('email')

        if validate is True:
            # Validate and sanitize inputs as needed. Email will raise error if invalid.
            # TODO Edge case bug: validation and saving are performed in same loop, so all in list
            # up to the invalid entry will be saved. (communicate to the user what needs to be retried)
            fullname = sanitize.strip_html(fullname)
            if not fullname:
                raise ValidationError('Full name field cannot be empty')
            if email:
                validate_email(email)  # Will raise a ValidationError if email invalid

        if contrib_dict['id']:
            contributor = OSFUser.load(contrib_dict['id'])
        else:
            try:
                contributor = OSFUser.create_unregistered(
                    fullname=fullname,
                    email=email)
                contributor.save()
            except ValidationError:
                ## FIXME: This suppresses an exception if ID not found & new validation fails; get_user will return None
                contributor = get_user(email=email)

        # Add unclaimed record if necessary
        if not contributor.is_registered:
            contributor.add_unclaimed_record(node, referrer=auth.user,
                given_name=fullname,
                email=email)
            contributor.save()

        contribs.append({
            'user': contributor,
            'visible': visible,
            'permissions': expand_permissions(contrib_dict.get('permission'))
        })
    return contribs
Ejemplo n.º 20
0
def _get_current_user():
    from osf.models import OSFUser
    current_user_id = get_current_user_id()
    if current_user_id:
        return OSFUser.load(current_user_id)
    else:
        return None
Ejemplo n.º 21
0
def _send_global_and_node_emails(send_type):
    """
    Called by `send_users_email`. Send all global and node-related notification emails.
    """
    grouped_emails = get_users_emails(send_type)
    for group in grouped_emails:
        user = OSFUser.load(group['user_id'])
        if not user:
            log_exception()
            continue
        info = group['info']
        notification_ids = [message['_id'] for message in info]
        sorted_messages = group_by_node(info)
        if sorted_messages:
            if not user.is_disabled:
                # If there's only one node in digest we can show it's preferences link in the template.
                notification_nodes = sorted_messages['children'].keys()
                node = AbstractNode.load(notification_nodes[0]) if len(
                    notification_nodes) == 1 else None
                mails.send_mail(
                    to_addr=user.username,
                    mimetype='html',
                    can_change_node_preferences=bool(node),
                    node=node,
                    mail=mails.DIGEST,
                    name=user.fullname,
                    message=sorted_messages,
                )
            remove_notifications(email_notification_ids=notification_ids)
Ejemplo n.º 22
0
    def get_contributors(self, obj):

        contributor_info = []

        if is_anonymized(self.context['request']):
            return contributor_info

        contributor_ids = obj.get('contributors', None)
        params_node = obj.get('node', None)

        if contributor_ids:
            for contrib_id in contributor_ids:
                user = OSFUser.load(contrib_id)
                unregistered_name = None
                if user.unclaimed_records.get(params_node):
                    unregistered_name = user.unclaimed_records[params_node].get('name', None)

                contributor_info.append({
                    'id': contrib_id,
                    'full_name': user.fullname,
                    'given_name': user.given_name,
                    'middle_names': user.middle_names,
                    'family_name': user.family_name,
                    'unregistered_name': unregistered_name,
                    'active': user.is_active
                })
        return contributor_info
Ejemplo n.º 23
0
    def save(self, *args, **kwargs):
        first_save = not bool(self.pk)
        saved_fields = self.get_dirty_fields() or []
        old_subjects = kwargs.pop('old_subjects', [])
        if saved_fields:
            request, user_id = get_request_and_user_id()
            request_headers = {}
            if not isinstance(request, DummyRequest):
                request_headers = {
                    k: v
                    for k, v in get_headers_from_request(request).items()
                    if isinstance(v, basestring)
                }
            user = OSFUser.load(user_id)
            if user:
                self.check_spam(user, saved_fields, request_headers)

        if not first_save and ('ever_public' in saved_fields and saved_fields['ever_public']):
            raise ValidationError('Cannot set "ever_public" to False')

        ret = super(Preprint, self).save(*args, **kwargs)

        if first_save:
            self._set_default_region()
            self.update_group_permissions()
            self._add_creator_as_contributor()

        if (not first_save and 'is_published' in saved_fields) or self.is_published:
            update_or_enqueue_on_preprint_updated(preprint_id=self._id, old_subjects=old_subjects, saved_fields=saved_fields)
        return ret
Ejemplo n.º 24
0
    def check_spam(self):
        request, user_id = get_request_and_user_id()
        user = OSFUser.load(user_id)
        if not isinstance(request, DummyRequest):
            request_headers = {
                k: v
                for k, v in get_headers_from_request(request).items()
                if isinstance(v, basestring)
            }

        node = self.wiki_page.node

        if not settings.SPAM_CHECK_ENABLED:
            return False
        if settings.SPAM_CHECK_PUBLIC_ONLY and not node.is_public:
            return False
        if 'ham_confirmed' in user.system_tags:
            return False

        content = self._get_spam_content(node)
        if not content:
            return
        is_spam = node.do_check_spam(
            user.fullname,
            user.username,
            content,
            request_headers
        )

        logger.info("Node ({}) '{}' smells like {} (tip: {})".format(
            node._id, node.title.encode('utf-8'), 'SPAM' if is_spam else 'HAM', node.spam_pro_tip
        ))
        if is_spam:
            node._check_spam_user(user)
        return is_spam
Ejemplo n.º 25
0
def process_project_search_results(results, **kwargs):
    """
    :param results: list of projects from the modular ODM search
    :return: we return the entire search result, which is a list of
    dictionaries. This includes the list of contributors.
    """
    user = kwargs['auth'].user

    ret = []

    for project in results:
        authors = get_node_contributors_abbrev(project=project, auth=kwargs['auth'])
        authors_html = ''
        for author in authors['contributors']:
            a = OSFUser.load(author['user_id'])
            authors_html += '<a href="%s">%s</a>' % (a.url, a.fullname)
            authors_html += author['separator'] + ' '
        authors_html += ' ' + authors['others_count']

        ret.append({
            'id': project._id,
            'label': project.title,
            'value': project.title,
            'category': 'My Projects' if user in project.contributors else 'Public Projects',
            'authors': authors_html,
        })

    return ret
Ejemplo n.º 26
0
def reset_password_get(auth, uid=None, token=None):
    """
    View for user to land on the reset password page.
    HTTp Method: GET

    :param auth: the authentication state
    :param uid: the user id
    :param token: the token in verification key
    :return
    :raises: HTTPError(http.BAD_REQUEST) if verification key for the user is invalid, has expired or was used
    """

    # if users are logged in, log them out and redirect back to this page
    if auth.logged_in:
        return auth_logout(redirect_url=request.url)

    # Check if request bears a valid pair of `uid` and `token`
    user_obj = OSFUser.load(uid)
    if not (user_obj and user_obj.verify_password_token(token=token)):
        error_data = {
            'message_short': 'Invalid Request.',
            'message_long': 'The requested URL is invalid, has expired, or was already used',
        }
        raise HTTPError(http.BAD_REQUEST, data=error_data)

    # refresh the verification key (v2)
    user_obj.verification_key_v2 = generate_verification_key(verification_type='password')
    user_obj.save()

    return {
        'uid': user_obj._id,
        'token': user_obj.verification_key_v2['token'],
    }
Ejemplo n.º 27
0
    def authenticate(self, request):
        """
        Check whether the request provides a valid OAuth2 bearer token.
        The `user` in `cas_auth_response` is the unique GUID of the user. Please do not use
        the primary key `id` or the email `username`.

        :param request: the request
        :return: the user who owns the bear token and the cas repsonse
        """

        client = cas.get_client()
        try:
            auth_header_field = request.META['HTTP_AUTHORIZATION']
            auth_token = cas.parse_auth_header(auth_header_field)
        except (cas.CasTokenError, KeyError):
            return None

        try:
            cas_auth_response = client.profile(auth_token)
        except cas.CasHTTPError:
            raise exceptions.NotAuthenticated(_('User provided an invalid OAuth2 access token'))

        if cas_auth_response.authenticated is False:
            raise exceptions.NotAuthenticated(_('CAS server failed to authenticate this token'))

        user = OSFUser.load(cas_auth_response.user)
        if not user:
            raise exceptions.AuthenticationFailed(_('Could not find the user associated with this token'))

        check_user(user)
        return user, cas_auth_response
Ejemplo n.º 28
0
def subscribe_mailchimp(list_name, user_id):
    user = User.load(user_id)
    m = get_mailchimp_api()
    list_id = get_list_id_from_name(list_name=list_name)

    if user.mailchimp_mailing_lists is None:
        user.mailchimp_mailing_lists = {}

    try:
        m.lists.subscribe(
            id=list_id,
            email={'email': user.username},
            merge_vars={
                'fname': user.given_name,
                'lname': user.family_name,
            },
            double_optin=False,
            update_existing=True,
        )

    except (mailchimp.ValidationError, mailchimp.ListInvalidBounceMemberError) as error:
        sentry.log_exception()
        sentry.log_message(error.message)
        user.mailchimp_mailing_lists[list_name] = False
    else:
        user.mailchimp_mailing_lists[list_name] = True
    finally:
        user.save()
Ejemplo n.º 29
0
def osfstorage_create_child(file_node, payload, node_addon, **kwargs):
    parent = file_node  # Just for clarity
    name = payload.get('name')
    user = OSFUser.load(payload.get('user'))
    is_folder = payload.get('kind') == 'folder'

    if not (name or user) or '/' in name:
        raise HTTPError(httplib.BAD_REQUEST)

    try:
        # Create a save point so that we can rollback and unlock
        # the parent record
        with transaction.atomic():
            if is_folder:
                created, file_node = True, parent.append_folder(name)
            else:
                created, file_node = True, parent.append_file(name)
    except (ValidationError, IntegrityError):
        created, file_node = False, parent.find_child_by_name(name, kind=int(not is_folder))

    if not created and is_folder:
        raise HTTPError(httplib.CONFLICT, data={
            'message': 'Cannot create folder "{name}" because a file or folder already exists at path "{path}"'.format(
                name=file_node.name,
                path=file_node.materialized_path,
            )
        })

    if not is_folder:
        try:
            if file_node.checkout is None or file_node.checkout._id == user._id:
                version = file_node.create_version(
                    user,
                    dict(payload['settings'], **dict(
                        payload['worker'], **{
                            'object': payload['metadata']['name'],
                            'service': payload['metadata']['provider'],
                        })
                    ),
                    dict(payload['metadata'], **payload['hashes'])
                )
                version_id = version._id
                archive_exists = version.archive is not None
            else:
                raise HTTPError(httplib.FORBIDDEN, data={
                    'message_long': 'File cannot be updated due to checkout status.'
                })
        except KeyError:
            raise HTTPError(httplib.BAD_REQUEST)
    else:
        version_id = None
        archive_exists = False

    return {
        'status': 'success',
        'archive': not archive_exists,  # Should waterbutler also archive this file
        'data': file_node.serialize(),
        'version': version_id,
    }, httplib.CREATED if created else httplib.OK
Ejemplo n.º 30
0
def send_claim_registered_email(claimer, unclaimed_user, node, throttle=24 * 3600):
    """
    A registered user claiming the unclaimed user account as an contributor to a project.
    Send an email for claiming the account to the referrer and notify the claimer.

    :param claimer: the claimer
    :param unclaimed_user: the user account to claim
    :param node: the project node where the user account is claimed
    :param throttle: the time period in seconds before another claim for the account can be made
    :return:
    :raise: http.BAD_REQUEST
    """

    unclaimed_record = unclaimed_user.get_unclaimed_record(node._primary_key)

    # check throttle
    timestamp = unclaimed_record.get('last_sent')
    if not throttle_period_expired(timestamp, throttle):
        raise HTTPError(http.BAD_REQUEST, data=dict(
            message_long='User account can only be claimed with an existing user once every 24 hours'
        ))

    # roll the valid token for each email, thus user cannot change email and approve a different email address
    verification_key = generate_verification_key(verification_type='claim')
    unclaimed_record['token'] = verification_key['token']
    unclaimed_record['expires'] = verification_key['expires']
    unclaimed_record['claimer_email'] = claimer.username
    unclaimed_user.save()

    referrer = User.load(unclaimed_record['referrer_id'])
    claim_url = web_url_for(
        'claim_user_registered',
        uid=unclaimed_user._primary_key,
        pid=node._primary_key,
        token=unclaimed_record['token'],
        _external=True,
    )

    # Send mail to referrer, telling them to forward verification link to claimer
    mails.send_mail(
        referrer.username,
        mails.FORWARD_INVITE_REGISTERED,
        user=unclaimed_user,
        referrer=referrer,
        node=node,
        claim_url=claim_url,
        fullname=unclaimed_record['name'],
    )
    unclaimed_record['last_sent'] = get_timestamp()
    unclaimed_user.save()

    # Send mail to claimer, telling them to wait for referrer
    mails.send_mail(
        claimer.username,
        mails.PENDING_VERIFICATION_REGISTERED,
        fullname=claimer.fullname,
        referrer=referrer,
        node=node,
    )
Ejemplo n.º 31
0
 def wrapper(node):
     from osf.models import OSFUser
     if node._id not in cache:
         osf_storage = node.get_addon('osfstorage')
         file_tree = osf_storage._get_file_tree(user=OSFUser.load(
             list(node.admin_contributor_or_group_member_ids)[0]))
         cache[node._id] = _do_get_file_map(file_tree)
     return func(node, cache[node._id])
Ejemplo n.º 32
0
def profile_view_id(uid, auth):
    user = OSFUser.load(uid)
    is_profile = auth and auth.user == user
    # Embed node data, so profile node lists can be rendered
    return _profile_view(user,
                         is_profile,
                         embed_nodes=False,
                         include_node_counts=True)
Ejemplo n.º 33
0
def reset_password_post(uid=None, token=None):
    """
    View for user to submit reset password form.
    HTTP Method: POST

    :param uid: the user id
    :param token: the token in verification key
    :return:
    :raises: HTTPError(http.BAD_REQUEST) if verification key for the user is invalid, has expired or was used
    """

    form = ResetPasswordForm(request.form)

    # Check if request bears a valid pair of `uid` and `token`
    user_obj = OSFUser.load(uid)
    if not (user_obj and user_obj.verify_password_token(token=token)):
        error_data = {
            'message_short':
            'Invalid Request.',
            'message_long':
            'The requested URL is invalid, has expired, or was already used',
        }
        raise HTTPError(http.BAD_REQUEST, data=error_data)

    if not form.validate():
        # Don't go anywhere
        forms.push_errors_to_status(form.errors)
    else:
        # clear verification key (v2)
        user_obj.verification_key_v2 = {}
        # new verification key (v1) for CAS
        user_obj.verification_key = generate_verification_key(
            verification_type=None)
        try:
            user_obj.set_password(form.password.data)
            user_obj.save()
        except exceptions.ChangePasswordError as error:
            for message in error.messages:
                status.push_status_message(message,
                                           kind='warning',
                                           trust=False)
        else:
            status.push_status_message('Password reset',
                                       kind='success',
                                       trust=False)
            # redirect to CAS and authenticate the user automatically with one-time verification key.
            return redirect(
                cas.get_login_url(web_url_for('user_account', _absolute=True),
                                  username=user_obj.username,
                                  verification_key=user_obj.verification_key))

    return {
        'uid': user_obj._id,
        'token': user_obj.verification_key_v2['token'],
    }
Ejemplo n.º 34
0
def project_remove_contributor(auth, **kwargs):
    """Remove a contributor from a list of nodes.

    :param Auth auth: Consolidated authorization
    :raises: HTTPError(400) if contributors to be removed are not in list
        or if no admin users would remain after changes were applied

    """
    contributor_id = request.get_json()['contributorID']
    node_ids = request.get_json()['nodeIDs']
    contributor = OSFUser.load(contributor_id)
    if contributor is None:
        raise HTTPError(http_status.HTTP_400_BAD_REQUEST,
                        data={'message_long': 'Contributor not found.'})
    redirect_url = {}
    parent_id = node_ids[0]
    for node_id in node_ids:
        # Update permissions and order
        node = AbstractNode.load(node_id)

        # Forbidden unless user is removing herself
        if not node.has_permission(auth.user, ADMIN):
            if auth.user != contributor:
                raise HTTPError(http_status.HTTP_403_FORBIDDEN)

        if node.visible_contributors.count() == 1 \
                and node.visible_contributors[0] == contributor:
            raise HTTPError(
                http_status.HTTP_403_FORBIDDEN,
                data={
                    'message_long':
                    'Must have at least one bibliographic contributor'
                })

        nodes_removed = node.remove_contributor(contributor, auth=auth)
        # remove_contributor returns false if there is not one admin or visible contributor left after the move.
        if not nodes_removed:
            raise HTTPError(
                http_status.HTTP_400_BAD_REQUEST,
                data={'message_long': 'Could not remove contributor.'})

        # On parent node, if user has removed herself from project, alert; redirect to
        # node summary if node is public, else to user's dashboard page
        if not node.is_contributor_or_group_member(
                auth.user) and node_id == parent_id:
            status.push_status_message(
                'You have removed yourself as a contributor from this project',
                kind='success',
                trust=False,
                id='remove_self_contrib')
            if node.is_public:
                redirect_url = {'redirectUrl': node.url}
            else:
                redirect_url = {'redirectUrl': web_url_for('dashboard')}
    return redirect_url
 def get_user_object(self, user_id, group):
     if user_id:
         user = OSFUser.load(user_id)
         if not user:
             raise exceptions.NotFound(
                 detail='User with id {} not found.'.format(user_id))
         if group.has_permission(user, 'member'):
             raise exceptions.ValidationError(
                 detail='User is already a member of this group.')
         return user
     return user_id
Ejemplo n.º 36
0
 def has_object_permission(self, request, view, obj):
     assert isinstance(obj, (AbstractNode, OSFUser, Contributor)), 'obj must be User, Contributor, or Node, got {}'.format(obj)
     auth = get_user_auth(request)
     context = request.parser_context['kwargs']
     node = AbstractNode.load(context[view.node_lookup_url_kwarg])
     user = OSFUser.load(context['user_id'])
     if request.method in permissions.SAFE_METHODS:
         return node.is_public or node.can_view(auth)
     elif request.method == 'DELETE':
         return node.has_permission(auth.user, osf_permissions.ADMIN) or auth.user == user
     else:
         return node.has_permission(auth.user, osf_permissions.ADMIN)
Ejemplo n.º 37
0
 def has_object_permission(self, request, view, obj):
     assert_resource_type(obj, self.acceptable_models)
     auth = get_user_auth(request)
     context = request.parser_context['kwargs']
     node = self.load_resource(context, view)
     user = OSFUser.load(context['user_id'])
     if request.method in permissions.SAFE_METHODS:
         return node.is_public or node.can_view(auth)
     elif request.method == 'DELETE':
         return node.has_permission(auth.user, osf_permissions.ADMIN) or auth.user == user
     else:
         return node.has_permission(auth.user, osf_permissions.ADMIN)
Ejemplo n.º 38
0
    def save(self, request=None, *args, **kwargs):
        super(NodeSettings, self).save(*args, **kwargs)
        if request:
            if not hasattr(request,
                           'user'):  # TODO: remove when Flask is removed
                _, user_id = get_request_and_user_id()
                user = OSFUser.load(user_id)
            else:
                user = request.user

            self.owner.check_spam(user, {'addons_forward_node_settings__url'},
                                  get_headers_from_request(request))
Ejemplo n.º 39
0
def _validate_reports(value, *args, **kwargs):
    from osf.models import OSFUser
    for key, val in value.items():
        if not OSFUser.load(key):
            raise ValidationValueError('Keys must be user IDs')
        if not isinstance(val, dict):
            raise ValidationTypeError('Values must be dictionaries')
        if ('category' not in val or 'text' not in val or 'date' not in val or 'retracted' not in val):
            raise ValidationValueError(
                ('Values must include `date`, `category`, ',
                 '`text`, `retracted` keys')
            )
Ejemplo n.º 40
0
def _validate_reports(value, *args, **kwargs):
    from osf.models import OSFUser
    for key, val in value.iteritems():
        if not OSFUser.load(key):
            raise ValidationValueError('Keys must be user IDs')
        if not isinstance(val, dict):
            raise ValidationTypeError('Values must be dictionaries')
        if ('category' not in val or 'text' not in val or 'date' not in val or 'retracted' not in val):
            raise ValidationValueError(
                ('Values must include `date`, `category`, ',
                 '`text`, `retracted` keys')
            )
Ejemplo n.º 41
0
 def has_object_permission(self, request, view, obj):
     assert isinstance(obj, (AbstractNode, User, Contributor)), 'obj must be User, Contributor, or Node, got {}'.format(obj)
     auth = get_user_auth(request)
     context = request.parser_context['kwargs']
     node = AbstractNode.load(context[view.node_lookup_url_kwarg])
     user = User.load(context['user_id'])
     if request.method in permissions.SAFE_METHODS:
         return node.is_public or node.can_view(auth)
     elif request.method == 'DELETE':
         return node.has_permission(auth.user, osf_permissions.ADMIN) or auth.user == user
     else:
         return node.has_permission(auth.user, osf_permissions.ADMIN)
Ejemplo n.º 42
0
    def has_object_permission(self, request, view, obj):
        assert_resource_type(obj, self.acceptable_models)
        context = request.parser_context['kwargs']
        preprint = self.load_resource(context, view)
        auth = get_user_auth(request)
        user = OSFUser.load(context['user_id'])

        if request.method in permissions.SAFE_METHODS:
            return super(ContributorDetailPermissions, self).has_object_permission(request, view, preprint)
        elif request.method == 'DELETE':
            return preprint.has_permission(auth.user, osf_permissions.ADMIN) or auth.user == user
        else:
            return preprint.has_permission(auth.user, osf_permissions.ADMIN)
Ejemplo n.º 43
0
def find_inactive_users_with_no_inactivity_email_sent_or_queued():
    inactive_users = User.find(
        (Q('date_last_login', 'lt', timezone.now() - settings.NO_LOGIN_WAIT_TIME) & Q('tags__name', 'ne', 'osf4m')) |
        (Q('date_last_login', 'lt', timezone.now() - settings.NO_LOGIN_OSF4M_WAIT_TIME) & Q('tags__name', 'eq', 'osf4m'))
    )
    inactive_emails = QueuedMail.find(Q('email_type', 'eq', NO_LOGIN_TYPE))

    #This is done to prevent User query returns comparison to User, as equality fails
    #on datetime fields due to pymongo rounding. Instead here _id is compared.
    users_sent_id = [email.user._id for email in inactive_emails]
    inactive_ids = [user._id for user in inactive_users if user.is_active]
    users_to_send = [User.load(id) for id in (set(inactive_ids) - set(users_sent_id))]
    return users_to_send
Ejemplo n.º 44
0
def reviews_submit_notification(self, context):
    event_type = utils.find_subscription_type('global_reviews')
    for user_id in context['email_recipients']:
        user = OSFUser.load(user_id)
        user_subscriptions = get_user_subscriptions(user, event_type)
        context['no_future_emails'] = user_subscriptions['none']
        context['is_creator'] = user == context['reviewable'].node.creator
        context['provider_name'] = context['reviewable'].provider.name
        mails.send_mail(user.username,
                        mails.REVIEWS_SUBMISSION_CONFIRMATION,
                        mimetype='html',
                        user=user,
                        **context)
Ejemplo n.º 45
0
def claim_user_post(node, **kwargs):
    """
    View for claiming a user from the X-editable form on a project page.

    :param node: the project node
    :return:
    """

    request_data = request.json

    # The unclaimed user
    unclaimed_user = OSFUser.load(request_data['pk'])
    unclaimed_data = unclaimed_user.get_unclaimed_record(node._primary_key)

    # Claimer is not logged in and submit her/his email through X-editable, stored in `request_data['value']`
    if 'value' in request_data:
        email = request_data['value'].lower().strip()
        claimer = get_user(email=email)
        # registered user
        if claimer and claimer.is_registered:
            send_claim_registered_email(claimer, unclaimed_user, node)
        # unregistered user
        else:
            send_claim_email(email, unclaimed_user, node, notify=True)
    # Claimer is logged in with confirmed identity stored in `request_data['claimerId']`
    elif 'claimerId' in request_data:
        claimer_id = request_data['claimerId']
        claimer = OSFUser.load(claimer_id)
        send_claim_registered_email(claimer, unclaimed_user, node)
        email = claimer.username
    else:
        raise HTTPError(http_status.HTTP_400_BAD_REQUEST)

    return {
        'status': 'success',
        'email': email,
        'fullname': unclaimed_data['name']
    }
Ejemplo n.º 46
0
def claim_user_post(node, **kwargs):
    """
    View for claiming a user from the X-editable form on a project page.

    :param node: the project node
    :return:
    """

    request_data = request.json

    # The unclaimed user
    unclaimed_user = OSFUser.load(request_data['pk'])
    unclaimed_data = unclaimed_user.get_unclaimed_record(node._primary_key)

    # Claimer is not logged in and submit her/his email through X-editable, stored in `request_data['value']`
    if 'value' in request_data:
        email = request_data['value'].lower().strip()
        claimer = get_user(email=email)
        # registered user
        if claimer and claimer.is_registered:
            send_claim_registered_email(claimer, unclaimed_user, node)
        # unregistered user
        else:
            send_claim_email(email, unclaimed_user, node, notify=True)
    # Claimer is logged in with confirmed identity stored in `request_data['claimerId']`
    elif 'claimerId' in request_data:
        claimer_id = request_data['claimerId']
        claimer = OSFUser.load(claimer_id)
        send_claim_registered_email(claimer, unclaimed_user, node)
        email = claimer.username
    else:
        raise HTTPError(http.BAD_REQUEST)

    return {
        'status': 'success',
        'email': email,
        'fullname': unclaimed_data['name']
    }
Ejemplo n.º 47
0
 def has_object_permission(self, request, view, obj):
     if not isinstance(obj, OSFGroup):
         obj = OSFGroup.load(request.parser_context['kwargs']['group_id'])
     assert_resource_type(obj, self.acceptable_models)
     auth = get_user_auth(request)
     if request.method in permissions.SAFE_METHODS:
         return True
     elif request.method == 'DELETE':
         user = OSFUser.load(request.parser_context['kwargs']['user_id'])
         # You must have manage permissions on the OSFGroup to remove a member,
         # unless you are removing yourself
         return obj.has_permission(auth.user, MANAGE) or auth.user == user
     else:
         return auth.user and obj.has_permission(auth.user, MANAGE)
Ejemplo n.º 48
0
    def wrapped(*args, **kwargs):
        from osf.models import OSFUser

        user = OSFUser.load(kwargs['uid'])
        if user is not None:
            if user.is_confirmed:
                return func(*args, **kwargs)
            else:
                raise HTTPError(httplib.BAD_REQUEST, data={
                    'message_short': 'Account not yet confirmed',
                    'message_long': 'The profile page could not be displayed as the user has not confirmed the account.'
                })
        else:
            raise HTTPError(httplib.NOT_FOUND)
Ejemplo n.º 49
0
    def wrapped(*args, **kwargs):
        from osf.models import OSFUser

        user = OSFUser.load(kwargs['uid'])
        if user is not None:
            if user.is_confirmed:
                return func(*args, **kwargs)
            else:
                raise HTTPError(httplib.BAD_REQUEST, data={
                    'message_short': 'Account not yet confirmed',
                    'message_long': 'The profile page could not be displayed as the user has not confirmed the account.'
                })
        else:
            raise HTTPError(httplib.NOT_FOUND)
Ejemplo n.º 50
0
def project_remove_contributor(auth, **kwargs):
    """Remove a contributor from a list of nodes.

    :param Auth auth: Consolidated authorization
    :raises: HTTPError(400) if contributors to be removed are not in list
        or if no admin users would remain after changes were applied

    """
    contributor_id = request.get_json()['contributorID']
    node_ids = request.get_json()['nodeIDs']
    contributor = OSFUser.load(contributor_id)
    if contributor is None:
        raise HTTPError(http.BAD_REQUEST, data={'message_long': 'Contributor not found.'})
    redirect_url = {}
    parent_id = node_ids[0]
    for node_id in node_ids:
        # Update permissions and order
        node = AbstractNode.load(node_id)

        # Forbidden unless user is removing herself
        if not node.has_permission(auth.user, 'admin'):
            if auth.user != contributor:
                raise HTTPError(http.FORBIDDEN)

        if node.visible_contributors.count() == 1 \
                and node.visible_contributors[0] == contributor:
            raise HTTPError(http.FORBIDDEN, data={
                'message_long': 'Must have at least one bibliographic contributor'
            })

        nodes_removed = node.remove_contributor(contributor, auth=auth)
        # remove_contributor returns false if there is not one admin or visible contributor left after the move.
        if not nodes_removed:
            raise HTTPError(http.BAD_REQUEST, data={
                'message_long': 'Could not remove contributor.'})

        # On parent node, if user has removed herself from project, alert; redirect to
        # node summary if node is public, else to user's dashboard page
        if not node.is_contributor(auth.user) and node_id == parent_id:
            status.push_status_message(
                'You have removed yourself as a contributor from this project',
                kind='success',
                trust=False,
                id='remove_self_contrib'
            )
            if node.is_public:
                redirect_url = {'redirectUrl': node.url}
            else:
                redirect_url = {'redirectUrl': web_url_for('dashboard')}
    return redirect_url
Ejemplo n.º 51
0
def reset_password_post(uid=None, token=None):
    """
    View for user to submit reset password form.
    HTTP Method: POST

    :param uid: the user id
    :param token: the token in verification key
    :return:
    :raises: HTTPError(http.BAD_REQUEST) if verification key for the user is invalid, has expired or was used
    """

    form = ResetPasswordForm(request.form)

    # Check if request bears a valid pair of `uid` and `token`
    user_obj = OSFUser.load(uid)
    if not (user_obj and user_obj.verify_password_token(token=token)):
        error_data = {
            'message_short': 'Invalid Request.',
            'message_long': 'The requested URL is invalid, has expired, or was already used',
        }
        raise HTTPError(http.BAD_REQUEST, data=error_data)

    if not form.validate():
        # Don't go anywhere
        forms.push_errors_to_status(form.errors)
    else:
        # clear verification key (v2)
        user_obj.verification_key_v2 = {}
        # new verification key (v1) for CAS
        user_obj.verification_key = generate_verification_key(verification_type=None)
        try:
            user_obj.set_password(form.password.data)
            user_obj.save()
        except exceptions.ChangePasswordError as error:
            for message in error.messages:
                status.push_status_message(message, kind='warning', trust=False)
        else:
            status.push_status_message('Password reset', kind='success', trust=False)
            # redirect to CAS and authenticate the user automatically with one-time verification key.
            return redirect(cas.get_login_url(
                web_url_for('user_account', _absolute=True),
                username=user_obj.username,
                verification_key=user_obj.verification_key
            ))

    return {
        'uid': user_obj._id,
        'token': user_obj.verification_key_v2['token'],
    }
Ejemplo n.º 52
0
def store_emails(recipient_ids,
                 notification_type,
                 event,
                 user,
                 node,
                 timestamp,
                 abstract_provider=None,
                 template=None,
                 **context):
    """Store notification emails

    Emails are sent via celery beat as digests
    :param recipient_ids: List of user ids to send mail to.
    :param notification_type: from constants.Notification_types
    :param event: event that triggered notification
    :param user: user who triggered the notification
    :param node: instance of Node
    :param timestamp: time event happened
    :param context:
    :return: --
    """
    if notification_type == 'none':
        return

    # If `template` is not specified, default to using a template with name `event`
    template = '{template}.html.mako'.format(template=template or event)

    # user whose action triggered email sending
    context['user'] = user
    node_lineage_ids = get_node_lineage(node) if node else []

    for recipient_id in recipient_ids:
        if recipient_id == user._id:
            continue
        recipient = OSFUser.load(recipient_id)
        if recipient.is_disabled:
            continue
        context['localized_timestamp'] = localize_timestamp(
            timestamp, recipient)
        context['recipient'] = recipient
        message = mails.render_message(template, **context)
        digest = NotificationDigest(timestamp=timestamp,
                                    send_type=notification_type,
                                    event=event,
                                    user=recipient,
                                    message=message,
                                    node_lineage=node_lineage_ids,
                                    provider=abstract_provider)
        digest.save()
Ejemplo n.º 53
0
def _get_current_user():
    from osf.models import OSFUser
    from framework.auth import cas
    current_user_id = get_current_user_id()
    header_token = request.headers.get('Authorization', None)
    if current_user_id:
        return OSFUser.load(current_user_id,
                            select_for_update=check_select_for_update(request))
    elif header_token and 'bearer' in header_token.lower():
        # instead of querying directly here, let CAS deal with the authentication
        client = cas.get_client()
        auth_token = cas.parse_auth_header(header_token)

        try:
            cas_auth_response = client.profile(auth_token)
        except cas.CasHTTPError:
            return None

        return OSFUser.load(cas_auth_response.user,
                            select_for_update=check_select_for_update(request)
                            ) if cas_auth_response.authenticated else None

    else:
        return None
Ejemplo n.º 54
0
 def spam_check(self):
     # Since wiki_pages_current will be removed from Node model, when a new WikiVersion is saved, trigger a spam check.
     request, user_id = get_request_and_user_id()
     request_headers = {}
     if not isinstance(request, DummyRequest):
         request_headers = {
             k: v
             for k, v in get_headers_from_request(request).items()
             if isinstance(v, basestring)
         }
     user = OSFUser.load(user_id)
     if user:
         return self.wiki_page.node.check_spam(user, ['wiki_pages_latest'], request_headers)
     else:
         return False
Ejemplo n.º 55
0
def notify_mentions(event, user, node, timestamp, **context):
    event_type = utils.find_subscription_type(event)
    sent_users = []
    new_mentions = context.get('new_mentions', [])
    for m in new_mentions:
        mentioned_user = OSFUser.load(m)
        subscriptions = get_user_subscriptions(mentioned_user, event_type)
        for notification_type in subscriptions:
            if (notification_type != 'none'
                    and subscriptions[notification_type]
                    and m in subscriptions[notification_type]):
                store_emails([m], notification_type, 'mentions', user, node,
                             timestamp, **context)
                sent_users.extend([m])
    return sent_users
Ejemplo n.º 56
0
def replace_unclaimed_user_with_registered(user):
    """Listens for the user_registered signal. If unreg_user is stored in the
    session, then the current user is trying to claim themselves as a contributor.
    Replaces the old, unregistered contributor with the newly registered
    account.

    """
    unreg_user_info = session.data.get('unreg_user')
    if unreg_user_info:
        unreg_user = OSFUser.load(unreg_user_info['uid'])
        pid = unreg_user_info['pid']
        node = AbstractNode.load(pid)
        node.replace_contributor(old=unreg_user, new=user)
        node.save()
        status.push_status_message(
            'Successfully claimed contributor.', kind='success', trust=False)
Ejemplo n.º 57
0
    def wrapped(payload, *args, **kwargs):
        try:
            user = OSFUser.load(payload['user'])
            dest_node = AbstractNode.load(payload['destination']['node'])
            source = OsfStorageFileNode.get(payload['source'], kwargs['node'])
            dest_parent = OsfStorageFolder.get(payload['destination']['parent'], dest_node)

            kwargs.update({
                'user': user,
                'source': source,
                'destination': dest_parent,
                'name': payload['destination']['name'],
            })
        except KeyError:
            raise HTTPError(httplib.BAD_REQUEST)

        return func(*args, **kwargs)
def verify_merge(merged_list):
    """
    Expecting merged list in format [{"user_id": "abcde", "preprints": ["12345"]}]
    """
    for user_dict in merged_list:
        user = OSFUser.load(user_dict['user_id'])
        merged_by = user.merged_by
        for preprint_id in user_dict['preprints']:
            preprint = Preprint.load(preprint_id)
            user_contrib = _get_preprint_contributor(preprint, user)
            merged_by_contrib = _get_preprint_contributor(preprint, merged_by)
            print 'Preprint: {}'.format(preprint._id)
            print '    User: {}, Merged by: {}'.format(user._id, merged_by._id)
            print '   Perms: {}, {}'.format(user_contrib.permission if user_contrib else None, merged_by_contrib.permission if merged_by_contrib else None)
            print '     Bib: {}, {}'.format(user_contrib.visible if user_contrib else None, merged_by_contrib.visible if merged_by_contrib else None)
            print ' Creator: {}, {}'.format(preprint.creator == user, preprint.creator == merged_by)
            print '_______________________________________'