コード例 #1
0
def _send_reviews_moderator_emails(send_type):
    """
    Called by `send_users_email`. Send all reviews triggered emails.
    """
    grouped_emails = get_moderators_emails(send_type)
    for group in grouped_emails:
        user = OSFUser.load(group['user_id'])
        info = group['info']
        notification_ids = [message['_id'] for message in info]
        if not user.is_disabled:
            provider = AbstractProvider.objects.get(id=group['provider_id'])
            mails.send_mail(
                to_addr=user.username,
                mimetype='html',
                mail=mails.DIGEST_REVIEWS_MODERATORS,
                name=user.fullname,
                message=info,
                provider_name=provider.name,
                reviews_submissions_url='{}reviews/preprints/{}'.format(
                    settings.DOMAIN, provider._id),
                notification_settings_url='{}reviews/preprints/{}/notifications'
                .format(settings.DOMAIN, provider._id),
                is_reviews_moderator_notification=True,
                is_admin=GroupHelper(provider).get_group(
                    'admin').user_set.filter(id=user.id).exists())
        remove_notifications(email_notification_ids=notification_ids)
コード例 #2
0
def update_group_auth(apps, schema):
    emit_post_migrate_signal(2, False, 'default')
    PreprintProvider = apps.get_model('osf', 'preprintprovider')
    [
        GroupHelper(each).update_provider_auth_groups()
        for each in PreprintProvider.objects.all()
    ]
コード例 #3
0
 def get_default_queryset(self):
     provider = self.get_provider()
     group_helper = GroupHelper(provider)
     admin_group = group_helper.get_group('admin')
     mod_group = group_helper.get_group('moderator')
     return (admin_group.user_set.all()
             | mod_group.user_set.all()).annotate(permission_group=Case(
                 When(groups=admin_group, then=Value('admin')),
                 default=Value('moderator'),
                 output_field=CharField())).order_by('fullname')
コード例 #4
0
    def handle(self, *args, **options):
        dry = options.get('dry_run')

        # Start a transaction that will be rolled back if any exceptions are raised
        with transaction.atomic():
            for cls in ReviewProviderMixin.__subclasses__():
                for provider in cls.objects.all():
                    logger.info('Updating auth groups for review provider %s',
                                provider)
                    GroupHelper(provider).update_provider_auth_groups()
            if dry:
                # When running in dry mode force the transaction to rollback
                raise Exception('Abort Transaction - Dry Run')
コード例 #5
0
 def test_list_moderators_alphabetically(self, app, url, admin, moderator,
                                         provider):
     admin.fullname = 'Alice Alisdottir'
     moderator.fullname = 'Bob Bobsson'
     new_mod = AuthUserFactory(fullname='Cheryl Cherylsdottir')
     GroupHelper(provider).get_group('moderator').user_set.add(new_mod)
     admin.save()
     moderator.save()
     res = app.get(url, auth=admin.auth)
     assert len(res.json['data']) == 3
     assert res.json['data'][0]['id'] == admin._id
     assert res.json['data'][1]['id'] == moderator._id
     assert res.json['data'][2]['id'] == new_mod._id
コード例 #6
0
 def user(self, request, preprint):
     user = AuthUserFactory()
     if request.param:
         user.groups.add(
             GroupHelper(preprint.provider).get_group('moderator'))
     else:
         preprint.node.add_contributor(user,
                                       permissions=[
                                           osf_permissions.READ,
                                           osf_permissions.WRITE,
                                           osf_permissions.ADMIN
                                       ])
     return user
コード例 #7
0
 def add_to_group(self, user, group):
     from api.providers.permissions import GroupHelper
     # Add default notification subscription
     notification = self.notification_subscriptions.get(
         _id='{}_new_pending_submissions'.format(self._id))
     user_id = user.id
     is_subscriber = notification.none.filter(id=user_id).exists() \
                     or notification.email_digest.filter(id=user_id).exists() \
                     or notification.email_transactional.filter(id=user_id).exists()
     if not is_subscriber:
         notification.add_user_to_subscription(user,
                                               'email_transactional',
                                               save=True)
     return GroupHelper(self).get_group(group).user_set.add(user)
コード例 #8
0
    def remove_from_group(self, user, group, unsubscribe=True):
        from api.providers.permissions import GroupHelper
        _group = GroupHelper(self).get_group(group)
        if group == 'admin':
            if _group.user_set.filter(
                    id=user.id).exists() and not _group.user_set.exclude(
                        id=user.id).exists():
                raise ValueError('Cannot remove last admin.')
        if unsubscribe:
            # remove notification subscription
            notification = self.notification_subscriptions.get(
                _id='{}_new_pending_submissions'.format(self._id))
            notification.remove_user_from_subscription(user, save=True)

        return _group.user_set.remove(user)
コード例 #9
0
def populate_provider_notification_subscriptions(apps, schema_editor):
    NotificationSubscription = apps.get_model('osf',
                                              'NotificationSubscription')
    PreprintProvider = apps.get_model('osf', 'PreprintProvider')
    for provider in PreprintProvider.objects.all():
        helper = GroupHelper(provider)
        try:
            provider_admins = helper.get_group('admin').user_set.all()
            provider_moderators = helper.get_group('moderator').user_set.all()
        except Group.DoesNotExist:
            logger.warn(
                'Unable to find groups for provider "{}", assuming there are no subscriptions to create.'
                .format(provider._id))
            continue
        instance, created = NotificationSubscription.objects.get_or_create(
            _id='{provider_id}_new_pending_submissions'.format(
                provider_id=provider._id),
            event_name='new_pending_submissions',
            provider=provider)
        for user in provider_admins | provider_moderators:
            # add user to subscription list but set their notification to none by default
            instance.add_user_to_subscription(user,
                                              'email_transactional',
                                              save=True)
コード例 #10
0
ファイル: test_filters.py プロジェクト: summerdefalut/osf.io
    def test_permissions(self, app, url, preprint_one, preprint_two,
                         preprint_three, group_name):
        another_user = AuthUserFactory()
        preprints = (preprint_one, preprint_two, preprint_three)

        for preprint in preprints:
            preprint.is_published = False
            preprint.save()

        def actual():
            res = app.get(url, auth=another_user.auth)
            return set([preprint['id'] for preprint in res.json['data']])

        expected = set()
        assert expected == actual()

        for preprint in preprints:
            another_user.groups.add(
                GroupHelper(preprint.provider).get_group(group_name))
            expected.update([
                p._id for p in preprints
                if p.provider_id == preprint.provider_id
            ])
            assert expected == actual()
コード例 #11
0
 def provider_admin(self, provider):
     user = AuthUserFactory()
     user.groups.add(GroupHelper(provider).get_group('admin'))
     return user
コード例 #12
0
ファイル: provider.py プロジェクト: GigaElk/osf.io
def create_provider_auth_groups(sender, instance, created, **kwargs):
    if created:
        GroupHelper(instance).update_provider_auth_groups()
コード例 #13
0
 def moderator(self, provider):
     user = AuthUserFactory()
     GroupHelper(provider).get_group('moderator').user_set.add(user)
     return user
コード例 #14
0
 def admin(self, provider):
     user = AuthUserFactory()
     GroupHelper(provider).get_group('admin').user_set.add(user)
     return user
コード例 #15
0
ファイル: filter_mixins.py プロジェクト: summerdefalut/osf.io
 def admin_pair(self, expected_providers):
     user = AuthUserFactory()
     provider = expected_providers[1]
     user.groups.add(GroupHelper(provider).get_group('admin'))
     return (user, provider)
コード例 #16
0
    def test_create_permissions(self, app, url, preprint, node_admin,
                                moderator):
        assert preprint.machine_state == 'initial'

        submit_payload = self.create_payload(preprint._id, trigger='submit')

        # Unauthorized user can't submit
        res = app.post_json_api(url, submit_payload, expect_errors=True)
        assert res.status_code == 401

        # A random user can't submit
        some_rando = AuthUserFactory()
        res = app.post_json_api(url,
                                submit_payload,
                                auth=some_rando.auth,
                                expect_errors=True)
        assert res.status_code == 403

        # Node admin can submit
        res = app.post_json_api(url, submit_payload, auth=node_admin.auth)
        assert res.status_code == 201
        preprint.refresh_from_db()
        assert preprint.machine_state == 'pending'
        assert not preprint.is_published

        accept_payload = self.create_payload(preprint._id,
                                             trigger='accept',
                                             comment='This is good.')

        # Unauthorized user can't accept
        res = app.post_json_api(url, accept_payload, expect_errors=True)
        assert res.status_code == 401

        # A random user can't accept
        res = app.post_json_api(url,
                                accept_payload,
                                auth=some_rando.auth,
                                expect_errors=True)
        assert res.status_code == 403

        # Moderator from another provider can't accept
        another_moderator = AuthUserFactory()
        another_moderator.groups.add(
            GroupHelper(PreprintProviderFactory()).get_group('moderator'))
        res = app.post_json_api(url,
                                accept_payload,
                                auth=another_moderator.auth,
                                expect_errors=True)
        assert res.status_code == 403

        # Node admin can't accept
        res = app.post_json_api(url,
                                accept_payload,
                                auth=node_admin.auth,
                                expect_errors=True)
        assert res.status_code == 403

        # Still unchanged after all those tries
        preprint.refresh_from_db()
        assert preprint.machine_state == 'pending'
        assert not preprint.is_published

        # Moderator can accept
        res = app.post_json_api(url, accept_payload, auth=moderator.auth)
        assert res.status_code == 201
        preprint.refresh_from_db()
        assert preprint.machine_state == 'accepted'
        assert preprint.is_published
コード例 #17
0
ファイル: 0060_reviews.py プロジェクト: summerdefalut/osf.io
def create_provider_auth_groups(apps, schema_editor):
    # this is to make sure that the permissions created in an earlier migration exist!
    emit_post_migrate_signal(2, False, 'default')
    PreprintProvider = apps.get_model('osf', 'PreprintProvider')
    for provider in PreprintProvider.objects.all():
        GroupHelper(provider).update_provider_auth_groups()
コード例 #18
0
 def post_mod_provider(self, moderator):
     ppp = PreprintProviderFactory(reviews_workflow='post-moderation')
     GroupHelper(ppp).get_group('moderator').user_set.add(moderator)
     return ppp
コード例 #19
0
ファイル: filter_mixins.py プロジェクト: summerdefalut/osf.io
 def user(self, allowed_providers):
     user = AuthUserFactory()
     for provider in allowed_providers:
         user.groups.add(GroupHelper(provider).get_group('moderator'))
     return user
コード例 #20
0
 def provider_moderator(self, provider):
     user = AuthUserFactory()
     user.groups.add(GroupHelper(provider).get_group('moderator'))
     return user
コード例 #21
0
 def moderator(self, provider):
     moderator = AuthUserFactory()
     moderator.groups.add(GroupHelper(provider).get_group('moderator'))
     return moderator
コード例 #22
0
 def provider(self):
     pp = PreprintProviderFactory(name='ModArxiv')
     GroupHelper(pp).update_provider_auth_groups()
     return pp
コード例 #23
0
def resolve_guid(guid, suffix=None):
    """Load GUID by primary key, look up the corresponding view function in the
    routing table, and return the return value of the view function without
    changing the URL.

    :param str guid: GUID primary key
    :param str suffix: Remainder of URL after the GUID
    :return: Return value of proxied view function
    """
    try:
        # Look up
        guid_object = Guid.load(guid)
    except KeyError as e:
        if e.message == 'osfstorageguidfile':  # Used when an old detached OsfStorageGuidFile object is accessed
            raise HTTPError(http.NOT_FOUND)
        else:
            raise e
    if guid_object:
        # verify that the object implements a GuidStoredObject-like interface. If a model
        #   was once GuidStoredObject-like but that relationship has changed, it's
        #   possible to have referents that are instances of classes that don't
        #   have a deep_url attribute or otherwise don't behave as
        #   expected.
        if not hasattr(guid_object.referent, 'deep_url'):
            sentry.log_message('Guid resolved to an object with no deep_url',
                               dict(guid=guid))
            raise HTTPError(http.NOT_FOUND)
        referent = guid_object.referent
        if referent is None:
            logger.error('Referent of GUID {0} not found'.format(guid))
            raise HTTPError(http.NOT_FOUND)
        if not referent.deep_url:
            raise HTTPError(http.NOT_FOUND)

        # Handle file `/download` shortcut with supported types.
        if suffix and suffix.rstrip('/').lower() == 'download':
            file_referent = None
            if isinstance(referent, PreprintService) and referent.primary_file:
                if not referent.is_published:
                    # TODO: Ideally, permissions wouldn't be checked here.
                    # This is necessary to prevent a logical inconsistency with
                    # the routing scheme - if a preprint is not published, only
                    # admins and moderators should be able to know it exists.
                    auth = Auth.from_kwargs(request.args.to_dict(), {})
                    group_helper = GroupHelper(referent.provider)
                    admin_group = group_helper.get_group('admin')
                    mod_group = group_helper.get_group('moderator')
                    # Check if user isn't a nonetype or that the user has admin/moderator permissions
                    if auth.user is None or not (
                            referent.node.has_permission(
                                auth.user, permissions.ADMIN) or
                        (mod_group.user_set.all() | admin_group.user_set.all()
                         ).filter(id=auth.user.id).exists()):
                        raise HTTPError(http.NOT_FOUND)
                file_referent = referent.primary_file
            elif isinstance(referent, BaseFileNode) and referent.is_file:
                file_referent = referent

            if file_referent:
                # Extend `request.args` adding `action=download`.
                request.args = request.args.copy()
                request.args.update({'action': 'download'})
                # Do not include the `download` suffix in the url rebuild.
                url = _build_guid_url(urllib.unquote(file_referent.deep_url))
                return proxy_url(url)

        # Handle Ember Applications
        if isinstance(referent, PreprintService):
            if referent.provider.domain_redirect_enabled:
                # This route should always be intercepted by nginx for the branded domain,
                # w/ the exception of `<guid>/download` handled above.
                return redirect(referent.absolute_url, http.MOVED_PERMANENTLY)

            if PROXY_EMBER_APPS:
                resp = requests.get(EXTERNAL_EMBER_APPS['preprints']['server'],
                                    stream=True,
                                    timeout=EXTERNAL_EMBER_SERVER_TIMEOUT)
                return Response(stream_with_context(resp.iter_content()),
                                resp.status_code)

            return send_from_directory(preprints_dir, 'index.html')

        if isinstance(referent, BaseFileNode
                      ) and referent.is_file and referent.node.is_quickfiles:
            if referent.is_deleted:
                raise HTTPError(http.GONE)
            if PROXY_EMBER_APPS:
                resp = requests.get(
                    EXTERNAL_EMBER_APPS['ember_osf_web']['server'],
                    stream=True,
                    timeout=EXTERNAL_EMBER_SERVER_TIMEOUT)
                return Response(stream_with_context(resp.iter_content()),
                                resp.status_code)

            return send_from_directory(ember_osf_web_dir, 'index.html')

        if isinstance(referent,
                      Node) and not referent.is_registration and suffix:
            page = suffix.strip('/').split('/')[0]
            flag_name = 'ember_project_{}_page'.format(page)
            request.user = _get_current_user() or MockUser()

            if waffle.flag_is_active(request, flag_name):
                use_ember_app()

        url = _build_guid_url(urllib.unquote(referent.deep_url), suffix)
        return proxy_url(url)

    # GUID not found; try lower-cased and redirect if exists
    guid_object_lower = Guid.load(guid.lower())
    if guid_object_lower:
        return redirect(_build_guid_url(guid.lower(), suffix))

    # GUID not found
    raise HTTPError(http.NOT_FOUND)
コード例 #24
0
ファイル: filter_mixins.py プロジェクト: summerdefalut/osf.io
 def moderator_pair(self, expected_providers):
     user = AuthUserFactory()
     provider = expected_providers[0]
     user.groups.add(GroupHelper(provider).get_group('moderator'))
     return (user, provider)