Exemplo n.º 1
0
 def test_group_management(self):
     x = UserProfile.objects.get(pk=10968)
     assert not action_allowed_user(x, 'Admin', '%')
     do_adduser('10968', '1')
     assert action_allowed_user(x, 'Admin', '%')
     do_removeuser('10968', '1')
     assert not action_allowed_user(x, 'Admin', '%')
Exemplo n.º 2
0
    def test_group_management(self):
        user = UserProfile.objects.get(pk=10968)
        assert not action_allowed_user(user, amo.permissions.ADMIN_TOOLS)

        management.call_command('addusertogroup', '10968', '1')
        del user.groups_list
        assert action_allowed_user(user, amo.permissions.ADMIN_TOOLS)

        management.call_command('removeuserfromgroup', '10968', '1')
        del user.groups_list
        assert not action_allowed_user(user, amo.permissions.ADMIN_TOOLS)
Exemplo n.º 3
0
        def inner(view, request, guid=None, **kwargs):
            try:
                addon = Addon.unfiltered.get(guid=guid)
            except Addon.DoesNotExist:
                if allow_missing:
                    addon = None
                else:
                    return Response({'error': _('Could not find add-on with '
                                                'id "{}".').format(guid)},
                                    status=status.HTTP_404_NOT_FOUND)
            # Call the view if there is no add-on, the current user is an
            # auther of the add-on or the current user is an admin and the
            # request is a GET.
            has_perm = (
                addon is None or
                (addon.has_author(request.user) or
                    (request.method == 'GET' and
                        acl.action_allowed_user(
                            request.user, 'Addons', 'Edit'))))

            if has_perm:
                return fn(view, request, addon=addon, **kwargs)
            else:
                return Response(
                    {'error': _('You do not own this addon.')},
                    status=status.HTTP_403_FORBIDDEN)
Exemplo n.º 4
0
        def inner(view, request, **kwargs):
            guid = kwargs.get('guid', None)
            try:
                if guid is None:
                    raise Addon.DoesNotExist('No GUID')
                addon = Addon.unfiltered.get(guid=guid)
            except Addon.DoesNotExist:
                if allow_missing:
                    addon = None
                else:
                    msg = ugettext(
                        'Could not find add-on with id "{}".').format(guid)
                    return Response(
                        {'error': msg},
                        status=status.HTTP_404_NOT_FOUND)
            # Call the view if there is no add-on, the current user is an
            # auther of the add-on or the current user is an admin and the
            # request is a GET.
            has_perm = (
                addon is None or
                (addon.has_author(request.user) or
                    (request.method == 'GET' and
                        acl.action_allowed_user(
                            request.user, amo.permissions.ADDONS_EDIT))))

            if has_perm:
                return fn(view, request, addon=addon, **kwargs)
            else:
                return Response(
                    {'error': ugettext('You do not own this addon.')},
                    status=status.HTTP_403_FORBIDDEN)
Exemplo n.º 5
0
def action_from_user(user, version):
    review_perm = ('Review' if version.channel == amo.RELEASE_CHANNEL_LISTED
                   else 'ReviewUnlisted')
    if version.addon.authors.filter(pk=user.pk).exists():
        return amo.LOG.DEVELOPER_REPLY_VERSION
    elif acl.action_allowed_user(user, 'Addons', review_perm):
        return amo.LOG.REVIEWER_REPLY_VERSION
Exemplo n.º 6
0
 def is_staff(self):
     """Property indicating whether the user should be able to log in to
     the django admin tools. Does not guarantee that the user will then
     be able to do anything, as each module can have its own permission
     checks. (see has_module_perms() and has_perm())"""
     from olympia.access import acl
     return acl.action_allowed_user(self, amo.permissions.ANY_ADMIN)
Exemplo n.º 7
0
def log_and_notify(action, comments, note_creator, version):
    log_kwargs = {
        'user': note_creator,
        'created': datetime.datetime.now(),
    }
    if comments:
        log_kwargs['details'] = {
            'comments': comments,
            'version': version.version}
    else:
        # Just use the name of the action if no comments provided.  Alas we
        # can't know the locale of recipient, and our templates are English
        # only so prevent language jumble by forcing into en-US.
        with no_translation():
            comments = '%s' % action.short
    note = amo.log(action, version.addon, version, **log_kwargs)

    # Collect reviewers involved with this version.
    review_perm = ('Review' if version.channel == amo.RELEASE_CHANNEL_LISTED
                   else 'ReviewUnlisted')
    log_users = {
        alog.user for alog in ActivityLog.objects.for_version(version) if
        acl.action_allowed_user(alog.user, 'Addons', review_perm)}
    # Collect add-on authors (excl. the person who sent the email.)
    addon_authors = set(version.addon.authors.all()) - {note_creator}
    # Collect staff that want a copy of the email
    staff_cc = set(
        UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP))
    # If task_user doesn't exist that's no big issue (i.e. in tests)
    try:
        task_user = {get_task_user()}
    except UserProfile.DoesNotExist:
        task_user = set()
    # Collect reviewers on the thread (excl. the email sender and task user for
    # automated messages).
    reviewers = ((log_users | staff_cc) - addon_authors - task_user -
                 {note_creator})
    author_context_dict = {
        'name': version.addon.name,
        'number': version.version,
        'author': note_creator.name,
        'comments': comments,
        'url': absolutify(version.addon.get_dev_url('versions')),
        'SITE_URL': settings.SITE_URL,
    }
    reviewer_context_dict = author_context_dict.copy()
    reviewer_context_dict['url'] = absolutify(
        reverse('editors.review', args=[version.addon.pk], add_prefix=False))

    # Not being localised because we don't know the recipients locale.
    subject = 'Mozilla Add-ons: %s Updated' % version.addon.name
    template = loader.get_template('activity/emails/developer.txt')
    send_activity_mail(
        subject, template.render(Context(author_context_dict)), version,
        addon_authors, settings.EDITORS_EMAIL)
    send_activity_mail(
        subject, template.render(Context(reviewer_context_dict)), version,
        reviewers, settings.EDITORS_EMAIL)
    return note
Exemplo n.º 8
0
    def test_can_create_an_admin_user(self):
        group = Group.objects.create(rules='*:*', name='admin group')
        res = self.post(self.url, {'group': 'admin'})

        assert res.status_code == 201, res.content
        user = UserProfile.objects.get(pk=res.data['user_id'])
        assert action_allowed_user(user, 'Any', 'DamnThingTheyWant')
        assert res.data['groups'] == [(group.pk, group.name, group.rules)]
Exemplo n.º 9
0
    def has_perm(self, perm, obj=None):
        """Determine what the user can do in the django admin tools.

        perm is in the form "<app>.<action>_<model>".
        """
        from olympia.access import acl
        return acl.action_allowed_user(
            self, amo.permissions.DJANGO_PERMISSIONS_MAPPING[perm])
Exemplo n.º 10
0
    def test_can_create_an_admin_user(self):
        group = Group.objects.create(rules='*:*', name='admin group')
        res = self.post(self.url, {'group': 'admin'})

        assert res.status_code == 201, res.content
        user = UserProfile.objects.get(pk=res.data['user_id'])
        assert action_allowed_user(user, 'Any', 'DamnThingTheyWant')
        assert res.data['groups'] == [(group.pk, group.name, group.rules)]
Exemplo n.º 11
0
    def has_perm(self, perm, obj=None):
        """Determine what the user can do in the django admin tools.

        perm is in the form "<app>.<action>_<model>".
        """
        from olympia.access import acl
        return acl.action_allowed_user(
            self, amo.permissions.DJANGO_PERMISSIONS_MAPPING[perm])
Exemplo n.º 12
0
def action_from_user(user, version):
    review_perm = (amo.permissions.ADDONS_REVIEW
                   if version.channel == amo.RELEASE_CHANNEL_LISTED
                   else amo.permissions.ADDONS_REVIEW_UNLISTED)
    if version.addon.authors.filter(pk=user.pk).exists():
        return amo.LOG.DEVELOPER_REPLY_VERSION
    elif acl.action_allowed_user(user, review_perm):
        return amo.LOG.REVIEWER_REPLY_VERSION
Exemplo n.º 13
0
def action_from_user(user, version):
    review_perm = (amo.permissions.ADDONS_REVIEW
                   if version.channel == amo.RELEASE_CHANNEL_LISTED
                   else amo.permissions.ADDONS_REVIEW_UNLISTED)
    if version.addon.authors.filter(pk=user.pk).exists():
        return amo.LOG.DEVELOPER_REPLY_VERSION
    elif acl.action_allowed_user(user, review_perm):
        return amo.LOG.REVIEWER_REPLY_VERSION
Exemplo n.º 14
0
def template_from_user(user, version):
    review_perm = (amo.permissions.ADDONS_REVIEW
                   if version.channel == amo.RELEASE_CHANNEL_LISTED else
                   amo.permissions.ADDONS_REVIEW_UNLISTED)
    template = 'activity/emails/developer.txt'
    if (not version.addon.authors.filter(pk=user.pk).exists()
            and acl.action_allowed_user(user, review_perm)):
        template = 'activity/emails/from_reviewer.txt'
    return loader.get_template(template)
Exemplo n.º 15
0
    def __init__(self, *args, **kw):
        self.helper = kw.pop('helper')
        super(ReviewForm, self).__init__(*args, **kw)

        # Info request deadline needs to be readonly unless we're an admin.
        user = self.helper.handler.user
        deadline_widget_attributes = {}
        info_request_deadline = self.fields['info_request_deadline']
        if not acl.action_allowed_user(user, amo.permissions.REVIEWS_ADMIN):
            info_request_deadline.min_value = info_request_deadline.initial
            info_request_deadline.max_value = info_request_deadline.initial
            deadline_widget_attributes['readonly'] = 'readonly'
        deadline_widget_attributes.update({
            'min': info_request_deadline.min_value,
            'max': info_request_deadline.max_value,
        })
        info_request_deadline.widget.attrs.update(deadline_widget_attributes)

        # With the helper, we now have the add-on and can set queryset on the
        # versions field correctly. Small optimization: we only need to do this
        # if the reject_multiple_versions action is available, otherwise we
        # don't really care about this field.
        if 'reject_multiple_versions' in self.helper.actions:
            self.fields['versions'].queryset = (
                self.helper.addon.versions.distinct().filter(
                    channel=amo.RELEASE_CHANNEL_LISTED,
                    files__status__in=(amo.STATUS_PUBLIC,
                                       amo.STATUS_AWAITING_REVIEW)).
                order_by('created'))

        # For the canned responses, we're starting with an empty one, which
        # will be hidden via CSS.
        canned_choices = [
            ['', [('', ugettext('Choose a canned response...'))]]]

        canned_type = (
            amo.CANNED_RESPONSE_THEME
            if self.helper.addon.type == amo.ADDON_STATICTHEME
            else amo.CANNED_RESPONSE_ADDON)
        responses = CannedResponse.objects.filter(type=canned_type)

        # Loop through the actions (public, etc).
        for k, action in self.helper.actions.iteritems():
            action_choices = [[c.response, c.name] for c in responses
                              if c.sort_group and k in c.sort_group.split(',')]

            # Add the group of responses to the canned_choices array.
            if action_choices:
                canned_choices.append([action['label'], action_choices])

        # Now, add everything not in a group.
        for r in responses:
            if not r.sort_group:
                canned_choices.append([r.response, r.name])
        self.fields['canned_response'].choices = canned_choices
        self.fields['action'].choices = [
            (k, v['label']) for k, v in self.helper.actions.items()]
Exemplo n.º 16
0
    def __init__(self, *args, **kw):
        self.helper = kw.pop('helper')
        super(ReviewForm, self).__init__(*args, **kw)

        # Info request deadline needs to be readonly unless we're an admin.
        user = self.helper.handler.user
        deadline_widget_attributes = {}
        info_request_deadline = self.fields['info_request_deadline']
        if not acl.action_allowed_user(user, amo.permissions.REVIEWS_ADMIN):
            info_request_deadline.min_value = info_request_deadline.initial
            info_request_deadline.max_value = info_request_deadline.initial
            deadline_widget_attributes['readonly'] = 'readonly'
        deadline_widget_attributes.update({
            'min': info_request_deadline.min_value,
            'max': info_request_deadline.max_value,
        })
        info_request_deadline.widget.attrs.update(deadline_widget_attributes)

        # With the helper, we now have the add-on and can set queryset on the
        # versions field correctly. Small optimization: we only need to do this
        # if the reject_multiple_versions action is available, otherwise we
        # don't really care about this field.
        if 'reject_multiple_versions' in self.helper.actions:
            self.fields['versions'].queryset = (
                self.helper.addon.versions.distinct().filter(
                    channel=amo.RELEASE_CHANNEL_LISTED,
                    files__status__in=(amo.STATUS_PUBLIC,
                                       amo.STATUS_AWAITING_REVIEW)).
                order_by('created'))

        # For the canned responses, we're starting with an empty one, which
        # will be hidden via CSS.
        canned_choices = [
            ['', [('', ugettext('Choose a canned response...'))]]]

        canned_type = (
            amo.CANNED_RESPONSE_THEME
            if self.helper.addon.type == amo.ADDON_STATICTHEME
            else amo.CANNED_RESPONSE_ADDON)
        responses = CannedResponse.objects.filter(type=canned_type)

        # Loop through the actions (public, etc).
        for k, action in self.helper.actions.iteritems():
            action_choices = [[c.response, c.name] for c in responses
                              if c.sort_group and k in c.sort_group.split(',')]

            # Add the group of responses to the canned_choices array.
            if action_choices:
                canned_choices.append([action['label'], action_choices])

        # Now, add everything not in a group.
        for r in responses:
            if not r.sort_group:
                canned_choices.append([r.response, r.name])
        self.fields['canned_response'].choices = canned_choices
        self.fields['action'].choices = [
            (k, v['label']) for k, v in self.helper.actions.items()]
Exemplo n.º 17
0
def template_from_user(user, version):
    review_perm = (amo.permissions.ADDONS_REVIEW
                   if version.channel == amo.RELEASE_CHANNEL_LISTED
                   else amo.permissions.ADDONS_REVIEW_UNLISTED)
    template = 'activity/emails/developer.txt'
    if (not version.addon.authors.filter(pk=user.pk).exists() and
            acl.action_allowed_user(user, review_perm)):
        template = 'activity/emails/from_reviewer.txt'
    return loader.get_template(template)
Exemplo n.º 18
0
def log_and_notify(action, comments, note_creator, version):
    log_kwargs = {
        'user': note_creator,
        'created': datetime.datetime.now(),
        'details': {
            'comments': comments,
            'version': version.version
        }
    }
    note = amo.log(action, version.addon, version, **log_kwargs)

    # Collect reviewers involved with this version.
    review_perm = ('Review' if version.channel == amo.RELEASE_CHANNEL_LISTED
                   else 'ReviewUnlisted')
    log_users = {
        alog.user
        for alog in ActivityLog.objects.for_version(version)
        if acl.action_allowed_user(alog.user, 'Addons', review_perm)
    }
    # Collect add-on authors (excl. the person who sent the email.)
    addon_authors = set(version.addon.authors.all()) - {note_creator}
    # Collect staff that want a copy of the email
    staff_cc = set(
        UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP))
    # If task_user doesn't exist that's no big issue (i.e. in tests)
    try:
        task_user = {get_task_user()}
    except UserProfile.DoesNotExist:
        task_user = set()
    # Collect reviewers on the thread (excl. the email sender and task user for
    # automated messages).
    reviewers = ((log_users | staff_cc) - addon_authors - task_user -
                 {note_creator})
    author_context_dict = {
        'name': version.addon.name,
        'number': version.version,
        'author': note_creator.name,
        'comments': comments,
        'url': version.addon.get_dev_url('versions'),
        'SITE_URL': settings.SITE_URL,
    }
    reviewer_context_dict = author_context_dict.copy()
    reviewer_context_dict['url'] = absolutify(
        reverse('editors.review', args=[version.addon.pk], add_prefix=False))

    # Not being localised because we don't know the recipients locale.
    subject = 'Mozilla Add-ons: %s Updated' % version.addon.name
    template = loader.get_template('activity/emails/developer.txt')
    send_activity_mail(subject, template.render(Context(author_context_dict)),
                       version, addon_authors, settings.EDITORS_EMAIL)
    send_activity_mail(subject,
                       template.render(Context(reviewer_context_dict)),
                       version, reviewers, settings.EDITORS_EMAIL)
    return note
Exemplo n.º 19
0
 def needs_tougher_password(user):
     from olympia.access import acl
     return (acl.action_allowed_user(user, 'Admin', '%') or
             acl.action_allowed_user(user, 'Addons', 'Edit') or
             acl.action_allowed_user(user, 'Addons', 'Review') or
             acl.action_allowed_user(user, 'Apps', 'Review') or
             acl.action_allowed_user(user, 'Personas', 'Review') or
             acl.action_allowed_user(user, 'Users', 'Edit'))
Exemplo n.º 20
0
 def needs_tougher_password(user):
     from olympia.access import acl
     return (acl.action_allowed_user(user, 'Admin', '%')
             or acl.action_allowed_user(user, 'Addons', 'Edit')
             or acl.action_allowed_user(user, 'Addons', 'Review')
             or acl.action_allowed_user(user, 'Apps', 'Review')
             or acl.action_allowed_user(user, 'Personas', 'Review')
             or acl.action_allowed_user(user, 'Users', 'Edit'))
Exemplo n.º 21
0
def send_notifications(signal=None, sender=None, **kw):
    if sender.is_beta or sender.channel != amo.RELEASE_CHANNEL_LISTED:
        return

    subscribers = sender.addon.reviewersubscription_set.all()

    if not subscribers:
        return

    for subscriber in subscribers:
        user = subscriber.user
        is_reviewer = (user and not user.deleted and user.email
                       and acl.action_allowed_user(
                           user, amo.permissions.ADDONS_REVIEW))
        if is_reviewer:
            subscriber.send_notification(sender)
Exemplo n.º 22
0
    def needs_tougher_password(user):
        from olympia.access import acl

        return (
            acl.action_allowed_user(user, "Admin", "%")
            or acl.action_allowed_user(user, "Addons", "Edit")
            or acl.action_allowed_user(user, "Addons", "Review")
            or acl.action_allowed_user(user, "Apps", "Review")
            or acl.action_allowed_user(user, "Personas", "Review")
            or acl.action_allowed_user(user, "Users", "Edit")
        )
Exemplo n.º 23
0
def send_notifications(signal=None, sender=None, **kw):
    if sender.is_beta:
        return

    subscribers = sender.addon.reviewersubscription_set.all()

    if not subscribers:
        return

    for subscriber in subscribers:
        user = subscriber.user
        is_reviewer = (
            user and not user.deleted and user.email and
            acl.action_allowed_user(user, amo.permissions.ADDONS_REVIEW))
        if is_reviewer:
            subscriber.send_notification(sender)
        subscriber.delete()
Exemplo n.º 24
0
def verify_mozilla_trademark(name, user, form=None):
    skip_trademark_check = (
        user
        and user.is_authenticated
        and action_allowed_user(user, amo.permissions.TRADEMARK_BYPASS)
    )

    def _check(name):
        name = normalize_string(name, strip_punctuation=True).lower()

        for symbol in amo.MOZILLA_TRADEMARK_SYMBOLS:
            violates_trademark = name.count(symbol) > 1 or (
                name.count(symbol) >= 1 and not name.endswith(' for {}'.format(symbol))
            )

            if violates_trademark:
                raise forms.ValidationError(
                    gettext(
                        'Add-on names cannot contain the Mozilla or '
                        'Firefox trademarks.'
                    )
                )

    if not skip_trademark_check:
        if not isinstance(name, dict):
            _check(name)
        else:
            for locale, localized_name in name.items():
                try:
                    _check(localized_name)
                except forms.ValidationError as exc:
                    if form is not None:
                        for message in exc.messages:
                            error_message = LocaleErrorMessage(
                                message=message, locale=locale
                            )
                            form.add_error('name', error_message)
                    else:
                        raise
    return name
Exemplo n.º 25
0
 def is_staff(self):
     from olympia.access import acl
     return acl.action_allowed_user(self, 'Admin', '%')
Exemplo n.º 26
0
 def is_staff(self):
     from olympia.access import acl
     return acl.action_allowed_user(self, 'Admin', '%')
Exemplo n.º 27
0
def log_and_notify(action,
                   comments,
                   note_creator,
                   version,
                   perm_setting=None,
                   detail_kwargs=None):
    log_kwargs = {
        'user': note_creator,
        'created': datetime.datetime.now(),
    }
    if detail_kwargs is None:
        detail_kwargs = {}
    if comments:
        detail_kwargs['version'] = version.version
        detail_kwargs['comments'] = comments
    else:
        # Just use the name of the action if no comments provided.  Alas we
        # can't know the locale of recipient, and our templates are English
        # only so prevent language jumble by forcing into en-US.
        with no_translation():
            comments = '%s' % action.short
    if detail_kwargs:
        log_kwargs['details'] = detail_kwargs

    note = ActivityLog.create(action, version.addon, version, **log_kwargs)
    if not note:
        return

    # Collect reviewers involved with this version.
    review_perm = (amo.permissions.ADDONS_REVIEW
                   if version.channel == amo.RELEASE_CHANNEL_LISTED else
                   amo.permissions.ADDONS_REVIEW_UNLISTED)
    log_users = {
        alog.user
        for alog in ActivityLog.objects.for_version(version)
        if acl.action_allowed_user(alog.user, review_perm)
    }
    # Collect add-on authors (excl. the person who sent the email.)
    addon_authors = set(version.addon.authors.all()) - {note_creator}
    # Collect staff that want a copy of the email
    staff = set(UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP))
    # If task_user doesn't exist that's no big issue (i.e. in tests)
    try:
        task_user = {get_task_user()}
    except UserProfile.DoesNotExist:
        task_user = set()
    # Collect reviewers on the thread (excl. the email sender and task user for
    # automated messages).
    reviewers = log_users - addon_authors - task_user - {note_creator}
    staff_cc = staff - reviewers - addon_authors - task_user - {note_creator}
    author_context_dict = {
        'name': version.addon.name,
        'number': version.version,
        'author': note_creator.name,
        'comments': comments,
        'url': absolutify(version.addon.get_dev_url('versions')),
        'SITE_URL': settings.SITE_URL,
        'email_reason': 'you are an author of this add-on'
    }

    reviewer_context_dict = author_context_dict.copy()
    reviewer_context_dict['url'] = absolutify(
        reverse('editors.review',
                kwargs={
                    'addon_id': version.addon.pk,
                    'channel': amo.CHANNEL_CHOICES_API[version.channel]
                },
                add_prefix=False))
    reviewer_context_dict['email_reason'] = 'you reviewed this add-on'

    staff_cc_context_dict = reviewer_context_dict.copy()
    staff_cc_context_dict['email_reason'] = (
        'you are member of the activity email cc group')

    # Not being localised because we don't know the recipients locale.
    with translation.override('en-US'):
        subject = u'Mozilla Add-ons: %s %s' % (version.addon.name,
                                               version.version)
    template = template_from_user(note_creator, version)
    from_email = formataddr((note_creator.name, NOTIFICATIONS_FROM_EMAIL))
    send_activity_mail(subject, template.render(author_context_dict), version,
                       addon_authors, from_email, note.id, perm_setting)

    send_activity_mail(subject, template.render(reviewer_context_dict),
                       version, reviewers, from_email, note.id, perm_setting)

    send_activity_mail(subject, template.render(staff_cc_context_dict),
                       version, staff_cc, from_email, note.id, perm_setting)

    if action == amo.LOG.DEVELOPER_REPLY_VERSION:
        version.update(has_info_request=False)

    return note
Exemplo n.º 28
0
    def get_actions(self, request):
        actions = OrderedDict()
        if request is None:
            # If request is not set, it means we are just (ab)using the
            # ReviewHelper for its `handler` attribute and we don't care about
            # the actions.
            return actions

        # 2 kind of checks are made for the review page.
        # - Base permission checks to access the review page itself, done in
        #   the review() view
        # - A more specific check for each action, done below, restricting
        #   their availability while not affecting whether the user can see
        #   the review page or not.
        permission = None
        version_is_unlisted = (self.version and self.version.channel
                               == amo.RELEASE_CHANNEL_UNLISTED)
        try:
            is_recommendable = self.addon.discoveryitem.recommendable
        except DiscoveryItem.DoesNotExist:
            is_recommendable = False
        current_version_is_listed_and_auto_approved = (
            self.version and self.version.channel == amo.RELEASE_CHANNEL_LISTED
            and self.addon.current_version
            and self.addon.current_version.was_auto_approved)

        if is_recommendable:
            is_admin_needed = (self.addon.needs_admin_content_review
                               or self.addon.needs_admin_code_review)
            permission = amo.permissions.ADDONS_RECOMMENDED_REVIEW
        elif self.content_review:
            is_admin_needed = self.addon.needs_admin_content_review
            permission = amo.permissions.ADDONS_CONTENT_REVIEW
        elif version_is_unlisted:
            is_admin_needed = self.addon.needs_admin_code_review
            permission = amo.permissions.ADDONS_REVIEW_UNLISTED
        elif self.addon.type == amo.ADDON_STATICTHEME:
            is_admin_needed = self.addon.needs_admin_theme_review
            permission = amo.permissions.STATIC_THEMES_REVIEW
        elif current_version_is_listed_and_auto_approved:
            is_admin_needed = (self.addon.needs_admin_content_review
                               or self.addon.needs_admin_code_review)
            permission = amo.permissions.ADDONS_POST_REVIEW
        else:
            is_admin_needed = (self.addon.needs_admin_content_review
                               or self.addon.needs_admin_code_review)
            permission = amo.permissions.ADDONS_REVIEW

        assert permission is not None

        if is_admin_needed:
            permission = amo.permissions.REVIEWS_ADMIN

        # Is the current user a reviewer for this kind of add-on ?
        is_reviewer = acl.is_reviewer(request, self.addon)

        # Is the current user an appropriate reviewer, noy only for this kind
        # of add-on, but also for the state the add-on is in ? (Allows more
        # impactful actions).
        is_appropriate_reviewer = acl.action_allowed_user(
            request.user, permission)

        # Special logic for availability of reject multiple action:
        if (self.content_review or is_recommendable
                or self.addon.type == amo.ADDON_STATICTHEME):
            can_reject_multiple = is_appropriate_reviewer
        else:
            # When doing a code review, this action is also available to
            # users with Addons:PostReview even if the current version hasn't
            # been auto-approved, provided that the add-on isn't marked as
            # needing admin review.
            can_reject_multiple = (
                is_appropriate_reviewer or (acl.action_allowed_user(
                    request.user, amo.permissions.ADDONS_POST_REVIEW)
                                            and not is_admin_needed))

        addon_is_complete = self.addon.status not in (amo.STATUS_NULL,
                                                      amo.STATUS_DELETED)
        version_is_unreviewed = self.version and self.version.is_unreviewed
        addon_is_valid = self.addon.is_public() or self.addon.is_unreviewed()
        addon_is_valid_and_version_is_listed = (addon_is_valid and self.version
                                                and self.version.channel
                                                == amo.RELEASE_CHANNEL_LISTED)

        # Definitions for all actions.
        actions['public'] = {
            'method':
            self.handler.process_public,
            'minimal':
            False,
            'details':
            _('This will approve, sign, and publish this '
              'version. The comments will be sent to the '
              'developer.'),
            'label':
            _('Approve'),
            'available':
            (not self.content_review and addon_is_complete
             and version_is_unreviewed and is_appropriate_reviewer)
        }
        actions['reject'] = {
            'method':
            self.handler.process_sandbox,
            'label':
            _('Reject'),
            'details':
            _('This will reject this version and remove it '
              'from the queue. The comments will be sent '
              'to the developer.'),
            'minimal':
            False,
            'available':
            (not self.content_review and addon_is_complete
             and version_is_unreviewed and is_appropriate_reviewer)
        }
        actions['approve_content'] = {
            'method':
            self.handler.approve_content,
            'label':
            _('Approve Content'),
            'details':
            _('This records your approbation of the '
              'content of the latest public version, '
              'without notifying the developer.'),
            'minimal':
            False,
            'comments':
            False,
            'available':
            (self.content_review and addon_is_valid_and_version_is_listed
             and is_appropriate_reviewer),
        }
        actions['confirm_auto_approved'] = {
            'method':
            self.handler.confirm_auto_approved,
            'label':
            _('Confirm Approval'),
            'details':
            _('The latest public version of this add-on was '
              'automatically approved. This records your '
              'confirmation of the approval of that version, '
              'without notifying the developer.'),
            'minimal':
            True,
            'comments':
            False,
            'available':
            (not self.content_review and addon_is_valid_and_version_is_listed
             and current_version_is_listed_and_auto_approved
             and is_appropriate_reviewer),
        }
        actions['reject_multiple_versions'] = {
            'method':
            self.handler.reject_multiple_versions,
            'label':
            _('Reject Multiple Versions'),
            'minimal':
            True,
            'versions':
            True,
            'details':
            _('This will reject the selected public '
              'versions. The comments will be sent to the '
              'developer.'),
            'available': (addon_is_valid_and_version_is_listed
                          and can_reject_multiple),
        }
        actions['block_multiple_versions'] = {
            'method':
            self.handler.reject_multiple_versions,
            'label':
            _('Block Multiple Versions'),
            'minimal':
            True,
            'versions':
            True,
            'comments':
            False,
            'details':
            _('This will disable the selected approved '
              'versions silently, and open up the block creation '
              'admin page.'),
            'available': (self.addon.type != amo.ADDON_STATICTHEME
                          and version_is_unlisted and is_appropriate_reviewer),
        }
        actions['confirm_multiple_versions'] = {
            'method':
            self.handler.confirm_multiple_versions,
            'label':
            _('Confirm Multiple Versions'),
            'minimal':
            True,
            'versions':
            True,
            'details':
            _('This will confirm approval of the selected '
              'versions without notifying the developer.'),
            'comments':
            False,
            'available': (self.addon.type != amo.ADDON_STATICTHEME
                          and version_is_unlisted and is_appropriate_reviewer),
        }
        actions['reply'] = {
            'method':
            self.handler.reviewer_reply,
            'label':
            _('Reviewer reply'),
            'details':
            _('This will send a message to the developer. '
              'You will be notified when they reply.'),
            'minimal':
            True,
            'available': (self.version is not None and is_reviewer)
        }
        actions['super'] = {
            'method':
            self.handler.process_super_review,
            'label':
            _('Request super-review'),
            'details':
            _('If you have concerns about this add-on that '
              'an admin reviewer should look into, enter '
              'your comments in the area below. They will '
              'not be sent to the developer.'),
            'minimal':
            True,
            'available': (self.version is not None and is_reviewer)
        }
        actions['comment'] = {
            'method':
            self.handler.process_comment,
            'label':
            _('Comment'),
            'details':
            _('Make a comment on this version. The developer '
              'won\'t be able to see this.'),
            'minimal':
            True,
            'available': (is_reviewer)
        }

        return OrderedDict(((key, action) for key, action in actions.items()
                            if action['available']))
Exemplo n.º 29
0
    def get_actions(self, request):
        actions = OrderedDict()
        if request is None:
            # If request is not set, it means we are just (ab)using the
            # ReviewHelper for its `handler` attribute and we don't care about
            # the actions.
            return actions

        # 2 kind of checks are made for the review page.
        # - Base permission checks to access the review page itself, done in
        #   the review() view
        # - A more specific check for each action, done below, restricting
        #   their availability while not affecting whether the user can see
        #   the review page or not.
        version_is_unlisted = (self.version and self.version.channel
                               == amo.RELEASE_CHANNEL_UNLISTED)
        promoted_group = self.addon.promoted_group(currently_approved=False)

        # Default permissions / admin needed values if it's just a regular
        # code review, nothing fancy.
        permission = amo.permissions.ADDONS_REVIEW
        permission_post_review = amo.permissions.ADDONS_REVIEW
        is_admin_needed = (self.addon.needs_admin_content_review
                           or self.addon.needs_admin_code_review)
        is_admin_needed_post_review = is_admin_needed

        # More complex/specific cases.
        if promoted_group == RECOMMENDED:
            permission = amo.permissions.ADDONS_RECOMMENDED_REVIEW
            permission_post_review = permission
        elif version_is_unlisted:
            is_admin_needed = self.addon.needs_admin_code_review
            permission = amo.permissions.ADDONS_REVIEW_UNLISTED
            permission_post_review = permission
        elif promoted_group.admin_review:
            is_admin_needed = is_admin_needed_post_review = True
        elif self.content_review:
            is_admin_needed = self.addon.needs_admin_content_review
            permission = amo.permissions.ADDONS_CONTENT_REVIEW
        elif self.addon.type == amo.ADDON_STATICTHEME:
            is_admin_needed = self.addon.needs_admin_theme_review
            permission = amo.permissions.STATIC_THEMES_REVIEW
            permission_post_review = permission

        # In addition, if the latest (or current for post-review) version is
        # pending rejection, an admin is needed.
        if self.version and self.version.pending_rejection:
            is_admin_needed = True
        if (self.addon.current_version
                and self.addon.current_version.pending_rejection):
            is_admin_needed_post_review = True

        # Whatever permission values we set, we override if an admin is needed.
        if is_admin_needed:
            permission = amo.permissions.REVIEWS_ADMIN
        if is_admin_needed_post_review:
            permission_post_review = amo.permissions.REVIEWS_ADMIN

        # Is the current user a reviewer for this kind of add-on ?
        is_reviewer = acl.is_reviewer(request, self.addon)

        # Is the current user an appropriate reviewer, not only for this kind
        # of add-on, but also for the state the add-on is in ? (Allows more
        # impactful actions).
        is_appropriate_reviewer = acl.action_allowed_user(
            request.user, permission)
        is_appropriate_reviewer_post_review = acl.action_allowed_user(
            request.user, permission_post_review)

        addon_is_complete = self.addon.status not in (amo.STATUS_NULL,
                                                      amo.STATUS_DELETED)
        addon_is_incomplete_and_version_is_unlisted = (self.addon.status
                                                       == amo.STATUS_NULL
                                                       and version_is_unlisted)
        addon_is_reviewable = (addon_is_complete
                               or addon_is_incomplete_and_version_is_unlisted)
        version_is_unreviewed = self.version and self.version.is_unreviewed
        addon_is_valid = self.addon.is_public() or self.addon.is_unreviewed()
        addon_is_valid_and_version_is_listed = (addon_is_valid and self.version
                                                and self.version.channel
                                                == amo.RELEASE_CHANNEL_LISTED)
        current_version_is_listed_and_auto_approved = (
            self.version and self.version.channel == amo.RELEASE_CHANNEL_LISTED
            and self.addon.current_version
            and self.addon.current_version.was_auto_approved)
        version_is_blocked = self.version and self.version.is_blocked

        promoted_subscription_okay = (
            not promoted_group
            or not self.addon.promotedaddon.has_pending_subscription)

        # Special logic for availability of reject multiple action:
        if version_is_unlisted:
            can_reject_multiple = is_appropriate_reviewer
        elif (self.content_review or promoted_group.pre_review
              or self.addon.type == amo.ADDON_STATICTHEME):
            can_reject_multiple = (addon_is_valid_and_version_is_listed
                                   and is_appropriate_reviewer)
        else:
            # When doing a code review, this action is also available to
            # users with Addons:PostReview even if the current version hasn't
            # been auto-approved, provided that the add-on isn't marked as
            # needing admin review.
            can_reject_multiple = addon_is_valid_and_version_is_listed and (
                is_appropriate_reviewer or is_appropriate_reviewer_post_review)

        # Definitions for all actions.
        actions['public'] = {
            'method':
            self.handler.approve_latest_version,
            'minimal':
            False,
            'details':
            _('This will approve, sign, and publish this '
              'version. The comments will be sent to the '
              'developer.'),
            'label':
            _('Approve'),
            'available':
            (not self.content_review and addon_is_reviewable
             and version_is_unreviewed and is_appropriate_reviewer
             and not version_is_blocked and promoted_subscription_okay)
        }
        actions['reject'] = {
            'method':
            self.handler.reject_latest_version,
            'label':
            _('Reject'),
            'details':
            _('This will reject this version and remove it '
              'from the queue. The comments will be sent '
              'to the developer.'),
            'minimal':
            False,
            'available': (
                not self.content_review and
                # We specifically don't let the individual reject action be
                # available for unlisted review. `reject_latest_version` isn't
                # currently implemented for unlisted.
                addon_is_valid_and_version_is_listed and
                version_is_unreviewed and is_appropriate_reviewer)
        }
        actions['approve_content'] = {
            'method':
            self.handler.approve_content,
            'label':
            _('Approve Content'),
            'details':
            _('This records your approbation of the '
              'content of the latest public version, '
              'without notifying the developer.'),
            'minimal':
            False,
            'comments':
            False,
            'available':
            (self.content_review and addon_is_valid_and_version_is_listed
             and is_appropriate_reviewer),
        }
        actions['confirm_auto_approved'] = {
            'method':
            self.handler.confirm_auto_approved,
            'label':
            _('Confirm Approval'),
            'details':
            _('The latest public version of this add-on was '
              'automatically approved. This records your '
              'confirmation of the approval of that version, '
              'without notifying the developer.'),
            'minimal':
            True,
            'comments':
            False,
            'available':
            (not self.content_review and addon_is_valid_and_version_is_listed
             and current_version_is_listed_and_auto_approved
             and is_appropriate_reviewer_post_review),
        }
        actions['reject_multiple_versions'] = {
            'method':
            self.handler.reject_multiple_versions,
            'label':
            _('Reject Multiple Versions'),
            'minimal':
            True,
            'delayable':
            not version_is_unlisted,
            'versions':
            True,
            'details':
            _('This will reject the selected versions. '
              'The comments will be sent to the developer.'),
            'available': (can_reject_multiple),
        }
        actions['block_multiple_versions'] = {
            'method':
            self.handler.block_multiple_versions,
            'label':
            _('Block Multiple Versions'),
            'minimal':
            True,
            'versions':
            True,
            'comments':
            False,
            'details':
            _('This will disable the selected approved '
              'versions silently, and open up the block creation '
              'admin page.'),
            'available': (self.addon.type != amo.ADDON_STATICTHEME
                          and version_is_unlisted and is_appropriate_reviewer),
        }
        actions['confirm_multiple_versions'] = {
            'method':
            self.handler.confirm_multiple_versions,
            'label':
            _('Confirm Multiple Versions'),
            'minimal':
            True,
            'versions':
            True,
            'details':
            _('This will confirm approval of the selected '
              'versions without notifying the developer.'),
            'comments':
            False,
            'available': (self.addon.type != amo.ADDON_STATICTHEME
                          and version_is_unlisted and is_appropriate_reviewer),
        }
        actions['reply'] = {
            'method':
            self.handler.reviewer_reply,
            'label':
            _('Reviewer reply'),
            'details':
            _('This will send a message to the developer. '
              'You will be notified when they reply.'),
            'minimal':
            True,
            'available':
            (self.version is not None and is_reviewer
             and (not promoted_group.admin_review or is_appropriate_reviewer))
        }
        actions['super'] = {
            'method':
            self.handler.process_super_review,
            'label':
            _('Request super-review'),
            'details':
            _('If you have concerns about this add-on that '
              'an admin reviewer should look into, enter '
              'your comments in the area below. They will '
              'not be sent to the developer.'),
            'minimal':
            True,
            'available': (self.version is not None and is_reviewer)
        }
        actions['comment'] = {
            'method':
            self.handler.process_comment,
            'label':
            _('Comment'),
            'details':
            _('Make a comment on this version. The developer '
              'won\'t be able to see this.'),
            'minimal':
            True,
            'available': (is_reviewer)
        }

        return OrderedDict(((key, action) for key, action in actions.items()
                            if action['available']))
Exemplo n.º 30
0
 def is_adminish(user):
     return (user and
             acl.action_allowed_user(user, amo.permissions.USERS_EDIT))
Exemplo n.º 31
0
 def get_serializer_class(self):
     if (self.self_view or acl.action_allowed_user(
             self.request.user, amo.permissions.USERS_EDIT)):
         return UserProfileSerializer
     else:
         return PublicUserProfileSerializer
Exemplo n.º 32
0
 def admin_viewing(self):
     return acl.action_allowed_user(
         self.request.user, amo.permissions.USERS_EDIT)
Exemplo n.º 33
0
def log_and_notify(action, comments, note_creator, version, perm_setting=None,
                   detail_kwargs=None):
    log_kwargs = {
        'user': note_creator,
        'created': datetime.datetime.now(),
    }
    if detail_kwargs is None:
        detail_kwargs = {}
    if comments:
        detail_kwargs['version'] = version.version
        detail_kwargs['comments'] = comments
    else:
        # Just use the name of the action if no comments provided.  Alas we
        # can't know the locale of recipient, and our templates are English
        # only so prevent language jumble by forcing into en-US.
        with no_translation():
            comments = '%s' % action.short
    if detail_kwargs:
        log_kwargs['details'] = detail_kwargs

    note = ActivityLog.create(action, version.addon, version, **log_kwargs)

    # Collect reviewers involved with this version.
    review_perm = (amo.permissions.ADDONS_REVIEW
                   if version.channel == amo.RELEASE_CHANNEL_LISTED
                   else amo.permissions.ADDONS_REVIEW_UNLISTED)
    log_users = {
        alog.user for alog in ActivityLog.objects.for_version(version) if
        acl.action_allowed_user(alog.user, review_perm)}
    # Collect add-on authors (excl. the person who sent the email.)
    addon_authors = set(version.addon.authors.all()) - {note_creator}
    # Collect staff that want a copy of the email
    staff_cc = set(
        UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP))
    # If task_user doesn't exist that's no big issue (i.e. in tests)
    try:
        task_user = {get_task_user()}
    except UserProfile.DoesNotExist:
        task_user = set()
    # Collect reviewers on the thread (excl. the email sender and task user for
    # automated messages).
    reviewers = ((log_users | staff_cc) - addon_authors - task_user -
                 {note_creator})
    author_context_dict = {
        'name': version.addon.name,
        'number': version.version,
        'author': note_creator.name,
        'comments': comments,
        'url': absolutify(version.addon.get_dev_url('versions')),
        'SITE_URL': settings.SITE_URL,
    }
    reviewer_context_dict = author_context_dict.copy()
    reviewer_context_dict['url'] = absolutify(
        reverse('editors.review', args=[version.addon.pk], add_prefix=False))

    # Not being localised because we don't know the recipients locale.
    with translation.override('en-US'):
        subject = u'Mozilla Add-ons: %s %s %s' % (
            version.addon.name, version.version, action.short)
    template = template_from_user(note_creator, version)
    send_activity_mail(
        subject, template.render(Context(author_context_dict)), version,
        addon_authors, settings.EDITORS_EMAIL, perm_setting)
    send_activity_mail(
        subject, template.render(Context(reviewer_context_dict)), version,
        reviewers, settings.EDITORS_EMAIL, perm_setting)
    return note
Exemplo n.º 34
0
def action_from_user(user, version):
    review_perm = 'Review' if version.addon.is_listed else 'ReviewUnlisted'
    if version.addon.authors.filter(pk=user.pk).exists():
        return amo.LOG.DEVELOPER_REPLY_VERSION
    elif acl.action_allowed_user(user, 'Addons', review_perm):
        return amo.LOG.REVIEWER_REPLY_VERSION
Exemplo n.º 35
0
def log_and_notify(action, comments, note_creator, version, perm_setting=None,
                   detail_kwargs=None):
    log_kwargs = {
        'user': note_creator,
        'created': datetime.datetime.now(),
    }
    if detail_kwargs is None:
        detail_kwargs = {}
    if comments:
        detail_kwargs['version'] = version.version
        detail_kwargs['comments'] = comments
    else:
        # Just use the name of the action if no comments provided.  Alas we
        # can't know the locale of recipient, and our templates are English
        # only so prevent language jumble by forcing into en-US.
        with no_translation():
            comments = '%s' % action.short
    if detail_kwargs:
        log_kwargs['details'] = detail_kwargs

    note = ActivityLog.create(action, version.addon, version, **log_kwargs)
    if not note:
        return

    # Collect reviewers involved with this version.
    review_perm = (amo.permissions.ADDONS_REVIEW
                   if version.channel == amo.RELEASE_CHANNEL_LISTED
                   else amo.permissions.ADDONS_REVIEW_UNLISTED)
    log_users = {
        alog.user for alog in ActivityLog.objects.for_version(version) if
        acl.action_allowed_user(alog.user, review_perm)}
    # Collect add-on authors (excl. the person who sent the email.)
    addon_authors = set(version.addon.authors.all()) - {note_creator}
    # Collect staff that want a copy of the email
    staff = set(
        UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP))
    # If task_user doesn't exist that's no big issue (i.e. in tests)
    try:
        task_user = {get_task_user()}
    except UserProfile.DoesNotExist:
        task_user = set()
    # Collect reviewers on the thread (excl. the email sender and task user for
    # automated messages).
    reviewers = log_users - addon_authors - task_user - {note_creator}
    staff_cc = staff - reviewers - addon_authors - task_user - {note_creator}
    author_context_dict = {
        'name': version.addon.name,
        'number': version.version,
        'author': note_creator.name,
        'comments': comments,
        'url': absolutify(version.addon.get_dev_url('versions')),
        'SITE_URL': settings.SITE_URL,
        'email_reason': 'you are an author of this add-on'
    }

    reviewer_context_dict = author_context_dict.copy()
    reviewer_context_dict['url'] = absolutify(
        reverse('reviewers.review',
                kwargs={'addon_id': version.addon.pk,
                        'channel': amo.CHANNEL_CHOICES_API[version.channel]},
                add_prefix=False))
    reviewer_context_dict['email_reason'] = 'you reviewed this add-on'

    staff_cc_context_dict = reviewer_context_dict.copy()
    staff_cc_context_dict['email_reason'] = (
        'you are member of the activity email cc group')

    # Not being localised because we don't know the recipients locale.
    with translation.override('en-US'):
        subject = u'Mozilla Add-ons: %s %s' % (
            version.addon.name, version.version)
    template = template_from_user(note_creator, version)
    from_email = formataddr((note_creator.name, NOTIFICATIONS_FROM_EMAIL))
    send_activity_mail(
        subject, template.render(author_context_dict),
        version, addon_authors, from_email, note.id, perm_setting)

    send_activity_mail(
        subject, template.render(reviewer_context_dict),
        version, reviewers, from_email, note.id, perm_setting)

    send_activity_mail(
        subject, template.render(staff_cc_context_dict),
        version, staff_cc, from_email, note.id, perm_setting)

    if action == amo.LOG.DEVELOPER_REPLY_VERSION:
        version.update(has_info_request=False)

    return note
Exemplo n.º 36
0
 def is_adminish(user):
     return (user and acl.action_allowed_user(
         user, amo.permissions.USERS_EDIT))
Exemplo n.º 37
0
def action_from_user(user, version):
    review_perm = 'Review' if version.addon.is_listed else 'ReviewUnlisted'
    if version.addon.authors.filter(pk=user.pk).exists():
        return amo.LOG.DEVELOPER_REPLY_VERSION
    elif acl.action_allowed_user(user, 'Addons', review_perm):
        return amo.LOG.REVIEWER_REPLY_VERSION
Exemplo n.º 38
0
 def test_can_create_a_reviewer_user(self):
     Group.objects.create(rules='Addons:Review', name='reviewer group')
     res = self.post(self.url, {'group': 'reviewer'})
     assert res.status_code == 201, res.content
     user = UserProfile.objects.get(pk=res.data['user_id'])
     assert action_allowed_user(user, 'Addons', 'Review')
Exemplo n.º 39
0
    def __init__(self, *args, **kw):
        self.helper = kw.pop('helper')
        super(ReviewForm, self).__init__(*args, **kw)

        # Delayed rejection period needs to be readonly unless we're an admin.
        user = self.helper.handler.user
        rejection_period_widget_attributes = {}
        rejection_period = self.fields['delayed_rejection_days']
        if not acl.action_allowed_user(user, amo.permissions.REVIEWS_ADMIN):
            rejection_period.min_value = rejection_period.initial
            rejection_period.max_value = rejection_period.initial
            rejection_period_widget_attributes['readonly'] = 'readonly'
        rejection_period_widget_attributes['min'] = rejection_period.min_value
        rejection_period_widget_attributes['max'] = rejection_period.max_value
        rejection_period.widget.attrs.update(
            rejection_period_widget_attributes)

        # With the helper, we now have the add-on and can set queryset on the
        # versions field correctly. Small optimization: we only need to do this
        # if the relevant actions are available, otherwise we don't really care
        # about this field.
        versions_actions = [
            k for k in self.helper.actions
            if self.helper.actions[k].get('versions')
        ]
        if versions_actions:
            if self.helper.version:
                channel = self.helper.version.channel
            else:
                channel = amo.RELEASE_CHANNEL_LISTED
            statuses = (amo.STATUS_APPROVED, amo.STATUS_AWAITING_REVIEW)
            self.fields['versions'].widget.versions_actions = versions_actions
            self.fields['versions'].queryset = (self.helper.addon.versions(
                manager='unfiltered_for_relations').filter(
                    channel=channel, files__status__in=statuses).no_transforms(
                    ).prefetch_related('files').distinct().order_by('created'))
            # Reset data-value depending on widget depending on actions
            # available ([''] added to get an extra '|' at the end).
            self.fields['versions'].widget.attrs['data-value'] = '|'.join(
                versions_actions + [''])
        # For the canned responses, we're starting with an empty one, which
        # will be hidden via CSS.
        canned_choices = [['', [('', gettext('Choose a canned response...'))]]]

        canned_type = (amo.CANNED_RESPONSE_TYPE_THEME
                       if self.helper.addon.type == amo.ADDON_STATICTHEME else
                       amo.CANNED_RESPONSE_TYPE_ADDON)
        responses = CannedResponse.objects.filter(type=canned_type)

        # Loop through the actions (public, etc).
        for k, action in self.helper.actions.items():
            action_choices = [[c.response, c.name] for c in responses
                              if c.sort_group and k in c.sort_group.split(',')]

            # Add the group of responses to the canned_choices array.
            if action_choices:
                canned_choices.append([action['label'], action_choices])

        # Now, add everything not in a group.
        for canned_response in responses:
            if not canned_response.sort_group:
                canned_choices.append(
                    [canned_response.response, canned_response.name])
        self.fields['canned_response'].choices = canned_choices

        # Set choices on the action field dynamically to raise an error when
        # someone tries to use an action they don't have access to.
        self.fields['action'].choices = [
            (k, v['label']) for k, v in self.helper.actions.items()
        ]
Exemplo n.º 40
0
 def admin_viewing(self):
     return acl.action_allowed_user(self.request.user,
                                    amo.permissions.USERS_EDIT)
Exemplo n.º 41
0
 def is_staff(self):
     from olympia.access import acl
     return acl.action_allowed_user(self, amo.permissions.ADMIN)
Exemplo n.º 42
0
 def has_permission(self, request, view):
     if not request.user.is_authenticated():
         return False
     return acl.action_allowed_user(request.user, self.app, self.action)
Exemplo n.º 43
0
 def test_can_create_a_reviewer_user(self):
     Group.objects.create(rules='Addons:Review', name='reviewer group')
     res = self.post(self.url, {'group': 'reviewer'})
     assert res.status_code == 201, res.content
     user = UserProfile.objects.get(pk=res.data['user_id'])
     assert action_allowed_user(user, 'Addons', 'Review')
Exemplo n.º 44
0
 def has_permission(self, request, view):
     if not request.user.is_authenticated():
         return False
     return acl.action_allowed_user(request.user, self.app, self.action)
Exemplo n.º 45
0
 def is_staff(self):
     from olympia.access import acl
     return acl.action_allowed_user(self, amo.permissions.ADMIN)