Example #1
0
def acquire_refund_permission(request, addon_id, addon, webapp=False):
    """This is the callback from Paypal."""
    # Set up our redirects.
    if request.GET.get('dest', '') == 'submission':
        on_good = reverse('submit.app.payments.confirm', args=[addon.app_slug])
        on_error = reverse('submit.app.payments.paypal', args=[addon.app_slug])
        show_good_msgs = False
    else:
        # The management pages are the default.
        on_good = addon.get_dev_url('paypal_setup_confirm')
        on_error = addon.get_dev_url('paypal_setup_bounce')
        show_good_msgs = True

    if 'request_token' not in request.GET:
        paypal_log.debug('User did not approve permissions for'
                         ' addon: %s' % addon_id)
        messages.error(
            request, 'You will need to accept the permissions '
            'to continue.')
        return redirect(on_error)

    paypal_log.debug('User approved permissions for addon: %s' % addon_id)
    token = paypal.get_permissions_token(request.GET['request_token'],
                                         request.GET['verification_code'])

    paypal_log.debug('Getting personal data for token: %s' % addon_id)
    data = paypal.get_personal_data(token)
    email = data.get('email')

    # If the email from paypal is different, something has gone wrong.
    if email != addon.paypal_id:
        paypal_log.debug('Addon paypal_id and personal data differ: '
                         '%s vs %s' % (email, addon.paypal_id))
        messages.warning(
            request,
            _('The email returned by Paypal, '
              'did not match the PayPal email you '
              'entered. Please login using %s.') % email)
        return redirect(on_error)

    # Set the permissions token that we have just successfully used
    # in get_personal_data.
    addonpremium, created = (AddonPremium.objects.safer_get_or_create(
        addon=addon))
    addonpremium.update(paypal_permissions_token=token)

    # Finally update the data returned from PayPal for this addon.
    paypal_log.debug('Updating personal data for: %s' % addon_id)
    apd, created = AddonPaymentData.objects.safer_get_or_create(addon=addon)
    apd.update(**data)
    amo.log(amo.LOG.EDIT_PROPERTIES, addon)

    if show_good_msgs:
        messages.success(request, 'Please confirm the data we '
                         'received from PayPal.')
    return redirect(on_good)
Example #2
0
def acquire_refund_permission(request, addon_id, addon, webapp=False):
    """This is the callback from Paypal."""
    # Set up our redirects.
    if request.GET.get('dest', '') == 'submission':
        on_good = reverse('submit.app.payments.confirm', args=[addon.app_slug])
        on_error = reverse('submit.app.payments.paypal', args=[addon.app_slug])
        show_good_msgs = False
    else:
        # The management pages are the default.
        on_good = addon.get_dev_url('paypal_setup_confirm')
        on_error = addon.get_dev_url('paypal_setup_bounce')
        show_good_msgs = True

    if 'request_token' not in request.GET:
        paypal_log.debug('User did not approve permissions for'
                         ' addon: %s' % addon_id)
        messages.error(request, 'You will need to accept the permissions '
                                'to continue.')
        return redirect(on_error)

    paypal_log.debug('User approved permissions for addon: %s' % addon_id)
    token = paypal.get_permissions_token(request.GET['request_token'],
                                         request.GET['verification_code'])

    paypal_log.debug('Getting personal data for token: %s' % addon_id)
    data = paypal.get_personal_data(token)
    email = data.get('email')

    # If the email from paypal is different, something has gone wrong.
    if email != addon.paypal_id:
        paypal_log.debug('Addon paypal_id and personal data differ: '
                         '%s vs %s' % (email, addon.paypal_id))
        messages.warning(request, _('The email returned by Paypal, '
                                    'did not match the PayPal email you '
                                    'entered. Please login using %s.')
                         % email)
        return redirect(on_error)

    # Set the permissions token that we have just successfully used
    # in get_personal_data.
    addonpremium, created = (AddonPremium.objects
                                         .safer_get_or_create(addon=addon))
    addonpremium.update(paypal_permissions_token=token)

    # Finally update the data returned from PayPal for this addon.
    paypal_log.debug('Updating personal data for: %s' % addon_id)
    apd, created = AddonPaymentData.objects.safer_get_or_create(addon=addon)
    apd.update(**data)
    amo.log(amo.LOG.EDIT_PROPERTIES, addon)

    if show_good_msgs:
        messages.success(request, 'Please confirm the data we '
                                  'received from PayPal.')
    return redirect(on_good)
Example #3
0
def acquire_refund_permission(request, addon_id, addon, webapp=False):
    """This is the callback from Paypal."""
    # Set up our redirects.
    if request.GET.get("dest", "") == "submission":
        on_good = reverse("submit.app.payments.confirm", args=[addon.app_slug])
        on_error = reverse("submit.app.payments.paypal", args=[addon.app_slug])
        show_good_msgs = False
    else:
        # The management pages are the default.
        on_good = addon.get_dev_url("paypal_setup_confirm")
        on_error = addon.get_dev_url("paypal_setup_bounce")
        show_good_msgs = True

    if "request_token" not in request.GET:
        paypal_log.debug("User did not approve permissions for" " addon: %s" % addon_id)
        messages.error(request, "You will need to accept the permissions " "to continue.")
        return redirect(on_error)

    paypal_log.debug("User approved permissions for addon: %s" % addon_id)
    token = paypal.get_permissions_token(request.GET["request_token"], request.GET["verification_code"])

    paypal_log.debug("Getting personal data for token: %s" % addon_id)
    data = paypal.get_personal_data(token)
    email = data.get("email")

    # If the email from paypal is different, something has gone wrong.
    if email != addon.paypal_id:
        paypal_log.debug("Addon paypal_id and personal data differ: " "%s vs %s" % (email, addon.paypal_id))
        messages.warning(
            request,
            _("The email returned by Paypal, " "did not match the PayPal email you " "entered. Please login using %s.")
            % email,
        )
        return redirect(on_error)

    # Set the permissions token that we have just successfully used
    # in get_personal_data.
    addonpremium, created = AddonPremium.objects.safer_get_or_create(addon=addon)
    addonpremium.update(paypal_permissions_token=token)

    # Finally update the data returned from PayPal for this addon.
    paypal_log.debug("Updating personal data for: %s" % addon_id)
    apd, created = AddonPaymentData.objects.safer_get_or_create(addon=addon)
    apd.update(**data)
    amo.log(amo.LOG.EDIT_PROPERTIES, addon)

    if show_good_msgs:
        messages.success(request, "Please confirm the data we " "received from PayPal.")
    return redirect(on_good)
Example #4
0
def _review(request, addon):
    version = addon.latest_version

    if not settings.ALLOW_SELF_REVIEWS and addon.has_author(request.amo_user):
        messages.warning(request, _('Self-reviews are not allowed.'))
        return redirect(reverse('reviewers.home'))

    form = forms.get_review_form(request.POST or None,
                                 request=request,
                                 addon=addon,
                                 version=version)
    queue_type = form.helper.review_type
    redirect_url = reverse('reviewers.apps.queue_%s' % queue_type)
    is_admin = acl.action_allowed(request, 'Addons', 'Edit')

    if request.method == 'POST' and form.is_valid():
        form.helper.process()
        if form.cleaned_data.get('notify'):
            EditorSubscription.objects.get_or_create(user=request.amo_user,
                                                     addon=addon)
        if form.cleaned_data.get('adminflag') and is_admin:
            addon.update(admin_review=False)
        messages.success(request, _('Review successfully processed.'))
        return redirect(redirect_url)

    canned = AppCannedResponse.objects.all()
    actions = form.helper.actions.items()

    statuses = [
        amo.STATUS_PUBLIC, amo.STATUS_LITE, amo.STATUS_LITE_AND_NOMINATED
    ]

    try:
        show_diff = (addon.versions.exclude(id=version.id).filter(
            files__isnull=False,
            created__lt=version.created,
            files__status__in=statuses).latest())
    except Version.DoesNotExist:
        show_diff = None

    # The actions we should show a minimal form from.
    actions_minimal = [k for (k, a) in actions if not a.get('minimal')]

    # We only allow the user to check/uncheck files for "pending"
    allow_unchecking_files = form.helper.review_type == "pending"

    versions = (Version.objects.filter(addon=addon).exclude(
        files__status=amo.STATUS_BETA).order_by('-created').transform(
            Version.transformer_activity).transform(Version.transformer))

    product_attrs = {
        'product':
        json.dumps(product_as_dict(request, addon, False, 'developer'),
                   cls=JSONEncoder),
        'manifest_url':
        addon.manifest_url,
    }

    pager = paginate(request, versions, 10)

    num_pages = pager.paginator.num_pages
    count = pager.paginator.count

    ctx = context(version=version,
                  product=addon,
                  pager=pager,
                  num_pages=num_pages,
                  count=count,
                  flags=Review.objects.filter(addon=addon, flag=True),
                  form=form,
                  canned=canned,
                  is_admin=is_admin,
                  status_types=amo.STATUS_CHOICES,
                  show_diff=show_diff,
                  allow_unchecking_files=allow_unchecking_files,
                  actions=actions,
                  actions_minimal=actions_minimal,
                  tab=queue_type,
                  product_attrs=product_attrs)

    return jingo.render(request, 'reviewers/review.html', ctx)
Example #5
0
def _review(request, addon, version):

    if (not settings.ALLOW_SELF_REVIEWS and
        not acl.action_allowed(request, 'Admin', '%') and
        addon.has_author(request.amo_user)):
        messages.warning(request, _('Self-reviews are not allowed.'))
        return redirect(reverse('reviewers.home'))

    if (addon.status == amo.STATUS_BLOCKED and
        not acl.action_allowed(request, 'Apps', 'ReviewEscalated')):
        messages.warning(
            request, _('Only senior reviewers can review blocklisted apps.'))
        return redirect(reverse('reviewers.home'))

    attachment_formset = forms.AttachmentFormSet(data=request.POST or None,
                                                 files=request.FILES or None,
                                                 prefix='attachment')
    form = forms.get_review_form(data=request.POST or None,
                                 files=request.FILES or None, request=request,
                                 addon=addon, version=version,
                                 attachment_formset=attachment_formset)
    postdata = request.POST if request.method == 'POST' else None
    all_forms = [form, attachment_formset]

    if waffle.switch_is_active('buchets'):
        features_list = [unicode(f) for f in version.features.to_list()]
        appfeatures_form = AppFeaturesForm(data=postdata,
                                           instance=version.features)
        all_forms.append(appfeatures_form)
    else:
        appfeatures_form = None

    queue_type = form.helper.review_type
    redirect_url = reverse('reviewers.apps.queue_%s' % queue_type)
    is_admin = acl.action_allowed(request, 'Addons', 'Edit')

    if request.method == 'POST' and all(f.is_valid() for f in all_forms):

        old_types = set(o.id for o in addon.device_types)
        new_types = set(form.cleaned_data.get('device_override'))

        if waffle.switch_is_active('buchets'):
            old_features = set(features_list)
            new_features = set(unicode(f) for f
                               in appfeatures_form.instance.to_list())

        if form.cleaned_data.get('action') == 'public':
            if old_types != new_types:
                # The reviewer overrode the device types. We need to not publish
                # this app immediately.
                if addon.make_public == amo.PUBLIC_IMMEDIATELY:
                    addon.update(make_public=amo.PUBLIC_WAIT)

                # And update the device types to what the reviewer set.
                AddonDeviceType.objects.filter(addon=addon).delete()
                for device in form.cleaned_data.get('device_override'):
                    addon.addondevicetype_set.create(device_type=device)

                # Log that the reviewer changed the device types.
                added_devices = new_types - old_types
                removed_devices = old_types - new_types
                msg = _(u'Device(s) changed by reviewer: {0}').format(', '.join(
                    [_(u'Added {0}').format(unicode(amo.DEVICE_TYPES[d].name))
                     for d in added_devices] +
                    [_(u'Removed {0}').format(unicode(amo.DEVICE_TYPES[d].name))
                     for d in removed_devices]))
                amo.log(amo.LOG.REVIEW_DEVICE_OVERRIDE, addon,
                        addon.current_version, details={'comments': msg})

            if (waffle.switch_is_active('buchets') and
                 old_features != new_features):
                # The reviewer overrode the requirements. We need to not publish
                # this app immediately.
                if addon.make_public == amo.PUBLIC_IMMEDIATELY:
                    addon.update(make_public=amo.PUBLIC_WAIT)

                appfeatures_form.save(mark_for_rereview=False)

                # Log that the reviewer changed the minimum requirements.
                added_features = new_features - old_features
                removed_features = old_features - new_features

                fmt = ', '.join(
                      [_(u'Added {0}').format(f) for f in added_features] +
                      [_(u'Removed {0}').format(f) for f in removed_features])
                # L10n: {0} is the list of requirements changes.
                msg = _(u'Requirements changed by reviewer: {0}').format(fmt)
                amo.log(amo.LOG.REVIEW_FEATURES_OVERRIDE, addon,
                        addon.current_version, details={'comments': msg})

        form.helper.process()

        if form.cleaned_data.get('notify'):
            EditorSubscription.objects.get_or_create(user=request.amo_user,
                                                     addon=addon)

        messages.success(request, _('Review successfully processed.'))
        return redirect(redirect_url)

    canned = AppCannedResponse.objects.all()
    actions = form.helper.actions.items()

    try:
        show_diff = (addon.versions.exclude(id=version.id)
                                   .filter(files__isnull=False,
                                           created__lt=version.created,
                                           files__status=amo.STATUS_PUBLIC)
                                   .latest())
    except Version.DoesNotExist:
        show_diff = None

    # The actions we should show a minimal form from.
    actions_minimal = [k for (k, a) in actions if not a.get('minimal')]

    # We only allow the user to check/uncheck files for "pending"
    allow_unchecking_files = form.helper.review_type == "pending"

    versions = (Version.with_deleted.filter(addon=addon)
                                    .order_by('-created')
                                    .transform(Version.transformer_activity)
                                    .transform(Version.transformer))

    product_attrs = {
        'product': json.dumps(
            product_as_dict(request, addon, False, 'reviewer'),
            cls=JSONEncoder),
        'manifest_url': addon.manifest_url,
    }

    pager = paginate(request, versions, 10)

    num_pages = pager.paginator.num_pages
    count = pager.paginator.count

    ctx = context(request, version=version, product=addon, pager=pager,
                  num_pages=num_pages, count=count,
                  flags=Review.objects.filter(addon=addon, flag=True),
                  form=form, canned=canned, is_admin=is_admin,
                  status_types=amo.STATUS_CHOICES, show_diff=show_diff,
                  allow_unchecking_files=allow_unchecking_files,
                  actions=actions, actions_minimal=actions_minimal,
                  tab=queue_type, product_attrs=product_attrs,
                  attachment_formset=attachment_formset,
                  appfeatures_form=appfeatures_form)

    if waffle.switch_is_active('buchets'):
        ctx['feature_list'] = features_list

    return jingo.render(request, 'reviewers/review.html', ctx)
Example #6
0
def _review(request, addon, version):

    if (not settings.ALLOW_SELF_REVIEWS
            and not acl.action_allowed(request, 'Admin', '%')
            and addon.has_author(request.amo_user)):
        messages.warning(request, _('Self-reviews are not allowed.'))
        return redirect(reverse('reviewers.home'))

    if (addon.status == amo.STATUS_BLOCKED
            and not acl.action_allowed(request, 'Apps', 'ReviewEscalated')):
        messages.warning(
            request, _('Only senior reviewers can review blocklisted apps.'))
        return redirect(reverse('reviewers.home'))

    attachment_formset = forms.AttachmentFormSet(data=request.POST or None,
                                                 files=request.FILES or None,
                                                 prefix='attachment')
    form = forms.get_review_form(data=request.POST or None,
                                 files=request.FILES or None,
                                 request=request,
                                 addon=addon,
                                 version=version,
                                 attachment_formset=attachment_formset)
    queue_type = form.helper.review_type
    redirect_url = reverse('reviewers.apps.queue_%s' % queue_type)
    is_admin = acl.action_allowed(request, 'Addons', 'Edit')

    forms_valid = lambda: form.is_valid() and attachment_formset.is_valid()
    if request.method == 'POST' and forms_valid():

        old_types = set(o.id for o in addon.device_types)
        new_types = set(form.cleaned_data.get('device_override'))

        if (form.cleaned_data.get('action') == 'public'
                and old_types != new_types):

            # The reviewer overrode the device types. We need to not publish
            # this app immediately.
            if addon.make_public == amo.PUBLIC_IMMEDIATELY:
                addon.update(make_public=amo.PUBLIC_WAIT)

            # And update the device types to what the reviewer set.
            AddonDeviceType.objects.filter(addon=addon).delete()
            for device in form.cleaned_data.get('device_override'):
                addon.addondevicetype_set.create(device_type=device)

            # Log that the reviewer changed the device types.
            added_devices = new_types - old_types
            removed_devices = old_types - new_types
            msg = _(u'Device(s) changed by reviewer: {0}').format(', '.join([
                _(u'Added {0}').format(unicode(amo.DEVICE_TYPES[d].name))
                for d in added_devices
            ] + [
                _(u'Removed {0}').format(unicode(amo.DEVICE_TYPES[d].name))
                for d in removed_devices
            ]))
            amo.log(amo.LOG.REVIEW_DEVICE_OVERRIDE,
                    addon,
                    addon.current_version,
                    details={'comments': msg})

        form.helper.process()

        if form.cleaned_data.get('notify'):
            EditorSubscription.objects.get_or_create(user=request.amo_user,
                                                     addon=addon)

        messages.success(request, _('Review successfully processed.'))
        return redirect(redirect_url)

    canned = AppCannedResponse.objects.all()
    actions = form.helper.actions.items()

    try:
        show_diff = (addon.versions.exclude(id=version.id).filter(
            files__isnull=False,
            created__lt=version.created,
            files__status=amo.STATUS_PUBLIC).latest())
    except Version.DoesNotExist:
        show_diff = None

    # The actions we should show a minimal form from.
    actions_minimal = [k for (k, a) in actions if not a.get('minimal')]

    # We only allow the user to check/uncheck files for "pending"
    allow_unchecking_files = form.helper.review_type == "pending"

    versions = (Version.with_deleted.filter(
        addon=addon).order_by('-created').transform(
            Version.transformer_activity).transform(Version.transformer))

    product_attrs = {
        'product':
        json.dumps(product_as_dict(request, addon, False, 'reviewer'),
                   cls=JSONEncoder),
        'manifest_url':
        addon.manifest_url,
    }

    pager = paginate(request, versions, 10)

    num_pages = pager.paginator.num_pages
    count = pager.paginator.count

    ctx = context(version=version,
                  product=addon,
                  pager=pager,
                  num_pages=num_pages,
                  count=count,
                  flags=Review.objects.filter(addon=addon, flag=True),
                  form=form,
                  canned=canned,
                  is_admin=is_admin,
                  status_types=amo.STATUS_CHOICES,
                  show_diff=show_diff,
                  allow_unchecking_files=allow_unchecking_files,
                  actions=actions,
                  actions_minimal=actions_minimal,
                  tab=queue_type,
                  product_attrs=product_attrs,
                  attachment_formset=attachment_formset)

    return jingo.render(request, 'reviewers/review.html', ctx)
Example #7
0
def _review(request, addon):
    version = addon.latest_version

    if (not settings.DEBUG and
        addon.authors.filter(user=request.user).exists()):
        messages.warning(request, _('Self-reviews are not allowed.'))
        return redirect(reverse('reviewers.home'))

    form = forms.get_review_form(request.POST or None, request=request,
                                 addon=addon, version=version)
    queue_type = form.helper.review_type
    redirect_url = reverse('reviewers.apps.queue_%s' % queue_type)
    is_admin = acl.action_allowed(request, 'Addons', 'Edit')

    if request.method == 'POST' and form.is_valid():
        form.helper.process()
        if form.cleaned_data.get('notify'):
            EditorSubscription.objects.get_or_create(user=request.amo_user,
                                                     addon=addon)
        if form.cleaned_data.get('adminflag') and is_admin:
            addon.update(admin_review=False)
        messages.success(request, _('Review successfully processed.'))
        return redirect(redirect_url)

    canned = AppCannedResponse.objects.all()
    actions = form.helper.actions.items()

    statuses = [amo.STATUS_PUBLIC, amo.STATUS_LITE,
                amo.STATUS_LITE_AND_NOMINATED]

    try:
        show_diff = (addon.versions.exclude(id=version.id)
                                   .filter(files__isnull=False,
                                       created__lt=version.created,
                                       files__status__in=statuses)
                                   .latest())
    except Version.DoesNotExist:
        show_diff = None

    # The actions we should show a minimal form from.
    actions_minimal = [k for (k, a) in actions if not a.get('minimal')]

    # We only allow the user to check/uncheck files for "pending"
    allow_unchecking_files = form.helper.review_type == "pending"

    versions = (Version.objects.filter(addon=addon)
                               .exclude(files__status=amo.STATUS_BETA)
                               .order_by('-created')
                               .transform(Version.transformer_activity)
                               .transform(Version.transformer))

    pager = paginate(request, versions, 10)

    num_pages = pager.paginator.num_pages
    count = pager.paginator.count

    ctx = context(version=version, product=addon, pager=pager,
                  num_pages=num_pages, count=count,
                  flags=Review.objects.filter(addon=addon, flag=True),
                  form=form, canned=canned, is_admin=is_admin,
                  status_types=amo.STATUS_CHOICES, show_diff=show_diff,
                  allow_unchecking_files=allow_unchecking_files,
                  actions=actions, actions_minimal=actions_minimal,
                  tab=queue_type)

    return jingo.render(request, 'reviewers/review.html', ctx)
Example #8
0
def _review(request, addon):
    version = addon.latest_version

    if (not settings.DEBUG
            and addon.authors.filter(user=request.user).exists()):
        messages.warning(request, _('Self-reviews are not allowed.'))
        return redirect(reverse('reviewers.home'))

    form = forms.get_review_form(request.POST or None,
                                 request=request,
                                 addon=addon,
                                 version=version)

    queue_type = (form.helper.review_type
                  if form.helper.review_type != 'preliminary' else 'prelim')
    redirect_url = reverse('reviewers.apps.queue_%s' % queue_type)

    num = request.GET.get('num')
    paging = {}
    if num:
        try:
            num = int(num)
        except (ValueError, TypeError):
            raise http.Http404
        total = queue_counts(queue_type)
        paging = {
            'current': num,
            'total': total,
            'prev': num > 1,
            'next': num < total,
            'prev_url': '%s?num=%s' % (redirect_url, num - 1),
            'next_url': '%s?num=%s' % (redirect_url, num + 1)
        }

    is_admin = acl.action_allowed(request, 'Addons', 'Edit')

    if request.method == 'POST' and form.is_valid():
        form.helper.process()
        if form.cleaned_data.get('notify'):
            EditorSubscription.objects.get_or_create(user=request.amo_user,
                                                     addon=addon)
        if form.cleaned_data.get('adminflag') and is_admin:
            addon.update(admin_review=False)
        messages.success(request, _('Review successfully processed.'))
        return redirect(redirect_url)

    canned = AppCannedResponse.objects.all()
    actions = form.helper.actions.items()

    statuses = [
        amo.STATUS_PUBLIC, amo.STATUS_LITE, amo.STATUS_LITE_AND_NOMINATED
    ]

    try:
        show_diff = (addon.versions.exclude(id=version.id).filter(
            files__isnull=False,
            created__lt=version.created,
            files__status__in=statuses).latest())
    except Version.DoesNotExist:
        show_diff = None

    # The actions we should show a minimal form from.
    actions_minimal = [k for (k, a) in actions if not a.get('minimal')]

    # We only allow the user to check/uncheck files for "pending"
    allow_unchecking_files = form.helper.review_type == "pending"

    versions = (Version.objects.filter(addon=addon).exclude(
        files__status=amo.STATUS_BETA).order_by('-created').transform(
            Version.transformer_activity).transform(Version.transformer))

    pager = paginate(request, versions, 10)

    num_pages = pager.paginator.num_pages
    count = pager.paginator.count

    ctx = context(version=version,
                  product=addon,
                  pager=pager,
                  num_pages=num_pages,
                  count=count,
                  flags=Review.objects.filter(addon=addon, flag=True),
                  form=form,
                  paging=paging,
                  canned=canned,
                  is_admin=is_admin,
                  status_types=amo.STATUS_CHOICES,
                  show_diff=show_diff,
                  allow_unchecking_files=allow_unchecking_files,
                  actions=actions,
                  actions_minimal=actions_minimal)

    return jingo.render(request, 'reviewers/review.html', ctx)
Example #9
0
def acquire_refund_permission(request, addon_id, addon, webapp=False):
    """This is the callback from Paypal."""
    # Set up our redirects.
    if request.GET.get('dest', '') == 'submission':
        on_good = reverse('submit.app.payments.confirm', args=[addon.app_slug])
        on_error = reverse('submit.app.payments.paypal', args=[addon.app_slug])
        show_good_msgs = False
    else:
        # The management pages are the default.
        on_good = addon.get_dev_url('paypal_setup_confirm')
        on_error = addon.get_dev_url('paypal_setup_bounce')
        show_good_msgs = True

    if 'request_token' not in request.GET:
        paypal_log.debug('User did not approve permissions for'
                         ' addon: %s' % addon_id)
        messages.error(request, 'You will need to accept the permissions '
                                'to continue.')
        return redirect(on_error)

    paypal_log.debug('User approved permissions for addon: %s' % addon_id)
    if waffle.flag_is_active(request, 'solitude-payments'):
        client.post_permission_token(data={
            'seller': addon, 'token': request.GET['request_token'],
            'verifier': request.GET['verification_code'],
        })
        try:
            data = client.post_personal_basic(data={'seller': addon})
        except client.Error as err:
            paypal_log.debug('%s for addon %s' % (err.message, addon.id))
            messages.warning(request, err.message)
            return redirect(on_error)

        data.update(client.post_personal_advanced(data={'seller': addon}))
    # TODO(solitude): remove these.
    else:
        token = paypal.get_permissions_token(request.GET['request_token'],
                                             request.GET['verification_code'])
        data = paypal.get_personal_data(token)

    # TODO(solitude): remove this.
    email = data.get('email')
    # If the email from paypal is different, something has gone wrong.
    if email != addon.paypal_id:
        paypal_log.debug('Addon paypal_id and personal data differ: '
                         '%s vs %s' % (email, addon.paypal_id))
        messages.warning(request, _('The email returned by Paypal, '
                                    'did not match the PayPal email you '
                                    'entered. Please login using %s.')
                         % email)
        return redirect(on_error)

    # TODO(solitude): remove this. Sadly because the permissions tokens
    # are never being traversed back we have a disconnect between what is
    # happening in solitude and here and this will not easily survive flipping
    # on and off the flag.
    if not waffle.flag_is_active(request, 'solitude-payments'):
        # Set the permissions token that we have just successfully used
        # in get_personal_data.
        addonpremium, created = (AddonPremium.objects
                                             .safer_get_or_create(addon=addon))
        addonpremium.update(paypal_permissions_token=token)

    # Finally update the data returned from PayPal for this addon.
    paypal_log.debug('Updating personal data for: %s' % addon_id)
    # TODO(solitude): delete this, as the data was pulled through solitude
    # it was saved.
    apd, created = AddonPaymentData.objects.safer_get_or_create(addon=addon)
    # This can be deleted with solitude, but this needs to change because
    # data will contain more than the fields on the object, this is a quick
    # workaround.
    for k, v in data.items():
        setattr(apd, k, v)
    apd.save()

    amo.log(amo.LOG.EDIT_PROPERTIES, addon)

    if show_good_msgs:
        messages.success(request, 'Please confirm the data we '
                                  'received from PayPal.')
    return redirect(on_good)
Example #10
0
def _review(request, addon):
    version = addon.latest_version

    if not settings.ALLOW_SELF_REVIEWS and addon.has_author(request.amo_user):
        messages.warning(request, _("Self-reviews are not allowed."))
        return redirect(reverse("reviewers.home"))

    if addon.status == amo.STATUS_BLOCKED and not acl.action_allowed(request, "Apps", "ReviewEscalated"):
        messages.warning(request, _("Only senior reviewers can review blocklisted apps."))
        return redirect(reverse("reviewers.home"))

    form = forms.get_review_form(request.POST or None, request=request, addon=addon, version=version)
    queue_type = form.helper.review_type
    redirect_url = reverse("reviewers.apps.queue_%s" % queue_type)
    is_admin = acl.action_allowed(request, "Addons", "Edit")

    if request.method == "POST" and form.is_valid():

        old_types = set(o.id for o in addon.device_types)
        new_types = set(form.cleaned_data.get("device_override"))

        if form.cleaned_data.get("action") == "public" and old_types != new_types:

            # The reviewer overrode the device types. We need to not publish
            # this app immediately.
            if addon.make_public == amo.PUBLIC_IMMEDIATELY:
                addon.update(make_public=amo.PUBLIC_WAIT)

            # And update the device types to what the reviewer set.
            AddonDeviceType.objects.filter(addon=addon).delete()
            for device in form.cleaned_data.get("device_override"):
                addon.addondevicetype_set.create(device_type=device)

            # Log that the reviewer changed the device types.
            added_devices = new_types - old_types
            removed_devices = old_types - new_types
            msg = _(u"Device(s) changed by reviewer: {0}").format(
                ", ".join(
                    [_(u"Added {0}").format(unicode(amo.DEVICE_TYPES[d].name)) for d in added_devices]
                    + [_(u"Removed {0}").format(unicode(amo.DEVICE_TYPES[d].name)) for d in removed_devices]
                )
            )
            amo.log(amo.LOG.REVIEW_DEVICE_OVERRIDE, addon, addon.current_version, details={"comments": msg})

        form.helper.process()

        if form.cleaned_data.get("notify"):
            EditorSubscription.objects.get_or_create(user=request.amo_user, addon=addon)

        messages.success(request, _("Review successfully processed."))
        return redirect(redirect_url)

    canned = AppCannedResponse.objects.all()
    actions = form.helper.actions.items()

    try:
        show_diff = (
            addon.versions.exclude(id=version.id)
            .filter(files__isnull=False, created__lt=version.created, files__status=amo.STATUS_PUBLIC)
            .latest()
        )
    except Version.DoesNotExist:
        show_diff = None

    # The actions we should show a minimal form from.
    actions_minimal = [k for (k, a) in actions if not a.get("minimal")]

    # We only allow the user to check/uncheck files for "pending"
    allow_unchecking_files = form.helper.review_type == "pending"

    versions = (
        Version.objects.filter(addon=addon)
        .order_by("-created")
        .transform(Version.transformer_activity)
        .transform(Version.transformer)
    )

    product_attrs = {
        "product": json.dumps(product_as_dict(request, addon, False, "reviewer"), cls=JSONEncoder),
        "manifest_url": addon.manifest_url,
    }

    pager = paginate(request, versions, 10)

    num_pages = pager.paginator.num_pages
    count = pager.paginator.count

    ctx = context(
        version=version,
        product=addon,
        pager=pager,
        num_pages=num_pages,
        count=count,
        flags=Review.objects.filter(addon=addon, flag=True),
        form=form,
        canned=canned,
        is_admin=is_admin,
        status_types=amo.STATUS_CHOICES,
        show_diff=show_diff,
        allow_unchecking_files=allow_unchecking_files,
        actions=actions,
        actions_minimal=actions_minimal,
        tab=queue_type,
        product_attrs=product_attrs,
    )

    return jingo.render(request, "reviewers/review.html", ctx)