Пример #1
0
def setup_viewer(request, file_obj):
    data = {'file': file_obj,
            'version': file_obj.version,
            'addon': file_obj.version.addon,
            'status': False,
            'selected': {},
            'validate_url': ''}

    if (acl.check_reviewer(request) or
        acl.check_addon_ownership(request, file_obj.version.addon,
                                  viewer=True, ignore_disabled=True)):
        data['validate_url'] = reverse(
            'mkt.developers.apps.json_file_validation',
            args=[file_obj.version.addon.app_slug, file_obj.id])

    if acl.check_reviewer(request):
        data['file_link'] = {'text': _('Back to review'),
                             'url': reverse('reviewers.apps.review',
                                            args=[data['addon'].app_slug])}
    else:
        data['file_link'] = {
            'text': _('Back to app'),
            'url': reverse('detail', args=[data['addon'].pk])
        }
    return data
Пример #2
0
def setup_viewer(request, file_obj):
    data = {
        'file': file_obj,
        'version': file_obj.version,
        'addon': file_obj.version.addon,
        'status': False,
        'selected': {},
        'validate_url': ''
    }

    if (acl.check_reviewer(request) or acl.check_addon_ownership(
            request, file_obj.version.addon, viewer=True,
            ignore_disabled=True)):
        data['validate_url'] = reverse(
            'mkt.developers.apps.json_file_validation',
            args=[file_obj.version.addon.app_slug, file_obj.id])

    if acl.check_reviewer(request):
        data['file_link'] = {
            'text': _('Back to review'),
            'url': reverse('reviewers.apps.review',
                           args=[data['addon'].app_slug])
        }
    else:
        data['file_link'] = {
            'text': _('Back to app'),
            'url': reverse('detail', args=[data['addon'].pk])
        }
    return data
Пример #3
0
def setup_viewer(request, file_obj):
    data = {
        "file": file_obj,
        "version": file_obj.version,
        "addon": file_obj.version.addon,
        "status": False,
        "selected": {},
        "validate_url": "",
    }

    if acl.check_reviewer(request) or acl.check_addon_ownership(
        request, file_obj.version.addon, viewer=True, ignore_disabled=True
    ):
        data["validate_url"] = reverse(
            "mkt.developers.apps.json_file_validation", args=[file_obj.version.addon.app_slug, file_obj.id]
        )

    if acl.check_reviewer(request):
        data["file_link"] = {
            "text": _("Back to review"),
            "url": reverse("reviewers.apps.review", args=[data["addon"].app_slug]),
        }
    else:
        data["file_link"] = {"text": _("Back to app"), "url": reverse("detail", args=[data["addon"].pk])}
    return data
Пример #4
0
def manifest(request, addon):
    """
    Returns the "mini" manifest for packaged apps.

    If not a packaged app, returns an empty JSON doc.

    """
    is_reviewer = acl.check_reviewer(request)
    is_dev = addon.has_author(request.amo_user)
    is_public = addon.status == amo.STATUS_PUBLIC

    if (not addon.is_packaged or addon.disabled_by_user
            or (not is_public and not (is_reviewer or is_dev))):
        raise http.Http404

    manifest_content = addon.get_cached_manifest()
    manifest_etag = hashlib.md5(manifest_content).hexdigest()

    @etag(lambda r, a: manifest_etag)
    def _inner_view(request, addon):
        response = http.HttpResponse(
            manifest_content,
            content_type='application/x-web-app-manifest+json')
        response['ETag'] = manifest_etag
        return response

    return _inner_view(request, addon)
Пример #5
0
def global_settings(request):
    """
    Storing standard AMO-wide information used in global headers, such as
    account links and settings.
    """
    account_links = []
    tools_links = []
    context = {}

    tools_title = _('Tools')
    is_reviewer = False

    if request.user.is_authenticated():
        amo_user = request.amo_user
        profile = request.user
        is_reviewer = acl.check_reviewer(request)

        account_links.append({'text': _('My Profile'),
                              'href': profile.get_url_path()})

        if not settings.APP_PREVIEW:
            account_links.append({
                'text': _('My Collections'),
                'href': reverse('collections.user', args=[amo_user.username])})

        account_links.append({
            'text': _('Log out'),
            'href': remora_url('/users/logout?to=' + urlquote(request.path)),
        })

        if request.amo_user.is_developer:
            tools_links.append({'text': _('Manage My Submissions'),
                                'href': reverse('devhub.addons')})
        tools_links += [
            {'text': _('Submit a New Add-on'),
             'href': reverse('devhub.submit.1')},
            {'text': _('Developer Hub'),
             'href': reverse('devhub.index')},
        ]

        if is_reviewer:
            tools_links.append({'text': _('Editor Tools'),
                                'href': reverse('editors.home')})
        if (acl.action_allowed(request, 'Admin', '%') or
            acl.action_allowed(request, 'AdminTools', 'View')):
            tools_links.append({'text': _('Admin Tools'),
                                'href': reverse('zadmin.home')})

        context['amo_user'] = request.amo_user
    else:
        context['amo_user'] = AnonymousUser()

    context.update({'account_links': account_links,
                    'settings': settings, 'amo': amo,
                    'tools_links': tools_links,
                    'tools_title': tools_title,
                    'ADMIN_MESSAGE': get_config('site_notice'),
                    'collect_timings_percent': get_collect_timings(),
                    'is_reviewer': is_reviewer})
    return context
Пример #6
0
def review_list(request, addon, review_id=None, user_id=None, rating=None):
    qs = Review.objects.valid().filter(addon=addon).order_by('-created')

    ctx = {'product': addon, 'score': rating, 'review_perms': {}}

    if review_id is not None:
        qs = qs.filter(pk=review_id)
        ctx['page'] = 'detail'
        # If this is a dev reply, find the first msg for context.
        review = get_object_or_404(Review, pk=review_id)
        if review.reply_to_id:
            review_id = review.reply_to_id
            ctx['reply'] = review
    elif user_id is not None:
        qs = qs.filter(user=user_id)
        ctx['page'] = 'user'
        if not qs:
            raise http.Http404()
    else:
        ctx['page'] = 'list'
        qs = qs.filter(is_latest=True)

    ctx['ratings'] = ratings = amo.utils.paginate(request, qs, 20)
    if not ctx.get('reply'):
        ctx['replies'] = Review.get_replies(ratings.object_list)
    if request.user.is_authenticated():
        ctx['review_perms'] = {
            'is_admin': acl.action_allowed(request, 'Addons', 'Edit'),
            'is_editor': acl.check_reviewer(request),
            'is_author': acl.check_addon_ownership(request, addon, viewer=True,
                                                   dev=True, support=True),
        }
        ctx['flags'] = get_flags(request, ratings.object_list)
        ctx['has_review'] = addon.reviews.filter(user=request.user.id).exists()
    return jingo.render(request, 'ratings/listing.html', ctx)
Пример #7
0
        def wrapper(request, addon, *args, **kw):
            from mkt.submit.views import _resume

            if webapp:
                kw["webapp"] = addon.is_webapp()
            fun = lambda: f(request, addon_id=addon.id, addon=addon, *args, **kw)
            if allow_editors:
                if acl.check_reviewer(request):
                    return fun()
            # Require an owner or dev for POST requests.
            if request.method == "POST":
                if acl.check_addon_ownership(request, addon, dev=not owner_for_post):
                    return fun()
            # Ignore disabled so they can view their add-on.
            elif acl.check_addon_ownership(request, addon, viewer=True, ignore_disabled=True):
                if not skip_submit_check:
                    try:
                        # If it didn't go through the app submission
                        # checklist. Don't die. This will be useful for
                        # creating apps with an API later.
                        step = addon.appsubmissionchecklist.get_next()
                    except ObjectDoesNotExist:
                        step = None
                    # Redirect to the submit flow if they're not done.
                    if not getattr(f, "submitting", False) and step:
                        return _resume(addon, step)
                return fun()
            return http.HttpResponseForbidden()
Пример #8
0
    def is_visible(self, request):
        region = getattr(request, "REGION", mkt.regions.WORLDWIDE)

        # See if it's a game without a content rating.
        if (
            region == mkt.regions.BR
            and self.listed_in(category="games")
            and not self.content_ratings_in(mkt.regions.BR, "games")
        ):
            unrated_brazil_game = True
        else:
            unrated_brazil_game = False

        # Let developers see it always.
        can_see = self.has_author(request.amo_user) or action_allowed(request, "Apps", "Edit")

        # Let app reviewers see it only when it's pending.
        if check_reviewer(request, only="app") and self.is_pending():
            can_see = True

        visible = False

        if can_see:
            # Developers and reviewers should see it always.
            visible = True
        elif self.is_public() and not unrated_brazil_game:
            # Everyone else can see it only if it's public -
            # and if it's a game, it must have a content rating.
            visible = True

        return visible
Пример #9
0
def review_list(request, addon, review_id=None, user_id=None, rating=None):
    qs = Review.objects.valid().filter(addon=addon).order_by('-created')

    # Mature regions show only reviews from within that region.
    if not request.REGION.adolescent:
        qs = qs.filter(client_data__region=request.REGION.id)
    ctx = {'product': addon, 'score': rating, 'review_perms': {}}

    if review_id is not None:
        qs = qs.filter(pk=review_id)
        ctx['page'] = 'detail'
    elif user_id is not None:
        qs = qs.filter(user=user_id)
        ctx['page'] = 'user'
        if not qs:
            raise http.Http404()
    else:
        ctx['page'] = 'list'
        qs = qs.filter(is_latest=True)

    ctx['ratings'] = ratings = amo.utils.paginate(request, qs, 20)
    if request.user.is_authenticated():
        ctx['review_perms'] = {
            'is_admin': acl.action_allowed(request, 'Addons', 'Edit'),
            'is_editor': acl.check_reviewer(request),
            'is_author': acl.check_addon_ownership(request, addon, viewer=True,
                                                   dev=True, support=True),
        }
        ctx['flags'] = get_flags(request, ratings.object_list)
        ctx['has_review'] = addon.reviews.filter(user=request.user.id).exists()
    return jingo.render(request, 'ratings/listing.html', ctx)
Пример #10
0
 def wrapper(request, addon, *args, **kw):
     from devhub.views import _resume
     if webapp:
         kw['webapp'] = addon.is_webapp()
     fun = lambda: f(
         request, addon_id=addon.id, addon=addon, *args, **kw)
     if allow_editors:
         if acl.check_reviewer(request):
             return fun()
     # Require an owner or dev for POST requests.
     if request.method == 'POST':
         if acl.check_addon_ownership(request,
                                      addon,
                                      dev=not owner_for_post):
             return fun()
     # Ignore disabled so they can view their add-on.
     elif acl.check_addon_ownership(request,
                                    addon,
                                    viewer=True,
                                    ignore_disabled=True):
         step = SubmitStep.objects.filter(addon=addon)
         # Redirect to the submit flow if they're not done.
         if not getattr(f, 'submitting', False) and step:
             return _resume(addon, step)
         return fun()
     raise PermissionDenied
Пример #11
0
def manifest(request, addon):
    """
    Returns the "mini" manifest for packaged apps.

    If not a packaged app, returns an empty JSON doc.

    """
    is_reviewer = acl.check_reviewer(request)
    is_dev = addon.has_author(request.amo_user)
    is_public = addon.status == amo.STATUS_PUBLIC

    if (not addon.is_packaged or addon.disabled_by_user or (
            not is_public and not (is_reviewer or is_dev))):
        raise http.Http404

    manifest_content = addon.get_cached_manifest()
    manifest_etag = hashlib.md5(manifest_content).hexdigest()

    @etag(lambda r, a: manifest_etag)
    def _inner_view(request, addon):
        response = http.HttpResponse(manifest_content,
            content_type='application/x-web-app-manifest+json')
        response['ETag'] = manifest_etag
        return response

    return _inner_view(request, addon)
Пример #12
0
    def is_visible(self, request):
        region = getattr(request, 'REGION', mkt.regions.WORLDWIDE)

        # See if it's a game without a content rating.
        if (region == mkt.regions.BR and self.listed_in(category='games')
                and not self.content_ratings_in(mkt.regions.BR, 'games')):
            unrated_brazil_game = True
        else:
            unrated_brazil_game = False

        # Let developers see it always.
        can_see = (self.has_author(request.amo_user)
                   or action_allowed(request, 'Apps', 'Edit'))

        # Let app reviewers see it only when it's pending.
        if check_reviewer(request, only='app') and self.is_pending():
            can_see = True

        visible = False

        if can_see:
            # Developers and reviewers should see it always.
            visible = True
        elif self.is_public() and not unrated_brazil_game:
            # Everyone else can see it only if it's public -
            # and if it's a game, it must have a content rating.
            visible = True

        return visible
Пример #13
0
def record(request, addon):
    is_dev = request.check_ownership(addon, require_owner=False,
                                     ignore_disabled=True)
    if (not (addon.is_public() or acl.check_reviewer(request)
        or is_dev or not addon.is_webapp())):
        raise http.Http404

    if addon.is_premium() and not addon.has_purchased(request.amo_user):
        return http.HttpResponseForbidden()

    installed, c = Installed.objects.safer_get_or_create(addon=addon,
                                                         user=request.amo_user)
    send_request('install', request, {
                    'app-domain': addon.domain_from_url(addon.origin),
                    'app-id': addon.pk})

    # Look up to see if its in the receipt cache and log if we have
    # to recreate it.
    receipt = memoize_get('create-receipt', installed.pk)
    error = ''
    cef(request, addon, 'request', 'Receipt requested')
    if not receipt:
        cef(request, addon, 'sign', 'Receipt signing')
        try:
            receipt = create_receipt(installed.pk)
        except SigningError:
            error = _('There was a problem installing the app.')

    return {'addon': addon.pk, 'receipt': receipt, 'error': error}
Пример #14
0
def manifest(request, uuid):
    """Returns the "mini" manifest for packaged apps.

    If not a packaged app, returns a 404.

    """
    addon = get_object_or_404(Webapp, guid=uuid, is_packaged=True)

    is_reviewer = acl.check_reviewer(request)
    is_dev = addon.has_author(request.amo_user)
    is_avail = addon.status in [amo.STATUS_PUBLIC, amo.STATUS_BLOCKED]

    package_etag = hashlib.md5()

    if not addon.is_packaged or addon.disabled_by_user or not (is_avail or is_reviewer or is_dev):
        raise http.Http404

    else:
        manifest_content = addon.get_cached_manifest()
        package_etag.update(manifest_content)

        if addon.is_packaged:
            # Update the hash with the content of the package itself.
            package_file = addon.get_latest_file()
            if package_file:
                package_etag.update(package_file.hash)

    manifest_etag = package_etag.hexdigest()

    @etag(lambda r, a: manifest_etag)
    def _inner_view(request, addon):
        response = http.HttpResponse(manifest_content, content_type="application/x-web-app-manifest+json")
        return response

    return _inner_view(request, addon)
Пример #15
0
def privacy(request, addon):
    is_dev = request.check_ownership(addon, require_owner=False, ignore_disabled=True)
    if not (addon.is_public() or acl.check_reviewer(request) or is_dev):
        raise http.Http404
    if not addon.privacy_policy:
        return http.HttpResponseRedirect(addon.get_url_path())
    return jingo.render(request, "detail/privacy.html", {"product": addon})
Пример #16
0
def market_tile(context, product, link=True, src=""):
    request = context["request"]
    if product.is_webapp():
        classes = ["product", "mkt-tile"]
        purchased = request.amo_user and product.pk in request.amo_user.purchase_ids()

        is_dev = product.has_author(request.amo_user)
        is_reviewer = acl.check_reviewer(request)
        receipt_type = "developer" if is_dev or is_reviewer else None
        product_dict = product_as_dict(request, product, purchased=purchased, receipt_type=receipt_type)
        product_dict["prepareNavPay"] = reverse("bluevia.prepare_pay", args=[product.app_slug])

        data_attrs = {
            "product": json.dumps(product_dict, cls=JSONEncoder),
            "manifest_url": product.get_manifest_url(),
            "src": src,
        }
        if product.is_premium() and product.premium:
            classes.append("premium")
        c = dict(request=request, product=product, data_attrs=data_attrs, classes=" ".join(classes), link=link)
        t = env.get_template("site/tiles/app.html")
        return jinja2.Markup(t.render(c))

    elif product.is_persona():
        classes = ["product", "mkt-tile", "arrow"]
        product_dict = product_as_dict_theme(request, product)
        data_attrs = {"product": json.dumps(product_dict, cls=JSONEncoder), "src": src}
        c = dict(product=product, data_attrs=data_attrs, classes=" ".join(classes), link=link)
        t = env.get_template("site/tiles/theme.html")
        return jinja2.Markup(t.render(c))
Пример #17
0
 def wrapper(request, addon, *args, **kw):
     from devhub.views import _resume
     if theme:
         kw['theme'] = addon.is_persona()
     elif addon.is_persona():
         # Don't allow theme views if theme not passed in.
         raise http.Http404
     fun = lambda: f(request, addon_id=addon.id, addon=addon,
                     *args, **kw)
     if allow_editors:
         if acl.check_reviewer(request):
             return fun()
     # Require an owner or dev for POST requests.
     if request.method == 'POST':
         if acl.check_addon_ownership(request, addon,
                                      dev=not owner_for_post):
             return fun()
     # Ignore disabled so they can view their add-on.
     elif acl.check_addon_ownership(request, addon, viewer=True,
                                    ignore_disabled=True):
         step = SubmitStep.objects.filter(addon=addon)
         # Redirect to the submit flow if they're not done.
         if not getattr(f, 'submitting', False) and step:
             return _resume(addon, step)
         return fun()
     raise PermissionDenied
Пример #18
0
def app_header(context, app, page_type=''):
    t = env.get_template('lookup/helpers/app_header.html')
    is_admin = acl.action_allowed(context['request'], 'Users', 'Edit')
    is_staff = acl.action_allowed(context['request'], 'Apps', 'Configure')
    is_reviewer = acl.check_reviewer(context['request'])
    return jinja2.Markup(t.render(app=app, page_type=page_type,
                                  is_admin=is_admin, is_staff=is_staff,
                                  is_reviewer=is_reviewer))
Пример #19
0
def _record(request, addon):
    logged = request.user.is_authenticated()
    premium = addon.is_premium()

    # Require login for premium.
    if not logged and premium:
        return http.HttpResponseRedirect(reverse('users.login'))

    ctx = {'addon': addon.pk}

    # Don't generate receipts if we're allowing logged-out install.
    if logged:
        is_dev = request.check_ownership(addon,
                                         require_owner=False,
                                         ignore_disabled=True,
                                         admin=False)
        is_reviewer = acl.check_reviewer(request)
        if (not addon.is_webapp()
                or not addon.is_public() and not (is_reviewer or is_dev)):
            raise http.Http404

        if (premium and not addon.has_purchased(request.amo_user)
                and not is_reviewer and not is_dev):
            raise PermissionDenied

        # If you are reviewer, you get a user receipt. Use the reviewer tools
        # to get a reviewer receipt. App developers still get their special
        # receipt.
        install_type = (apps.INSTALL_TYPE_DEVELOPER
                        if is_dev else apps.INSTALL_TYPE_USER)
        # Log the install.
        installed, c = Installed.objects.get_or_create(
            addon=addon, user=request.amo_user, install_type=install_type)

        # Get a suitable uuid for this receipt.
        uuid = get_uuid(addon, request.amo_user)

        error = ''
        receipt_cef.log(request, addon, 'sign', 'Receipt requested')
        try:
            receipt = create_receipt(addon, request.amo_user, uuid)
        except SigningError:
            error = _('There was a problem installing the app.')

        ctx.update(receipt=receipt, error=error)
    else:
        if not addon.is_public() or not addon.is_webapp():
            raise http.Http404

    amo.log(amo.LOG.INSTALL_ADDON, addon)
    record_action(
        'install', request, {
            'app-domain': addon.domain_from_url(addon.origin, allow_none=True),
            'app-id': addon.pk,
            'anonymous': request.user.is_anonymous(),
        })

    return ctx
Пример #20
0
def global_settings(request):
    """Store global Marketplace-wide info. used in the header."""
    account_links = []
    tools_links = []
    context = {}

    tools_title = _('Tools')

    if request.user.is_authenticated() and hasattr(request, 'amo_user'):
        amo_user = request.amo_user
        account_links = []
        context['is_reviewer'] = acl.check_reviewer(request)
        if getattr(request, 'can_view_consumer', True):
            account_links = [
                {'text': _('Account History'),
                 'href': reverse('account.purchases')},
                {'text': _('Account Settings'),
                 'href': reverse('account.settings')},
            ]
        account_links += [
            {'text': _('Change Password'),
             'href': 'https://browserid.org/signin'},
            {'text': _('Log out'), 'href': reverse('users.logout')},
        ]
        if '/developers/' not in request.path:
            if amo_user.is_app_developer:
                tools_links.append({'text': _('My Submissions'),
                                    'href': reverse('mkt.developers.apps')})
            else:
                tools_links.append({'text': _('Developers'),
                                    'href': reverse('ecosystem.landing')})
        if '/reviewers/' not in request.path and context['is_reviewer']:
            tools_links.append({'text': _('Reviewer Tools'),
                                'href': reverse('reviewers.home')})
        if acl.action_allowed(request, 'Localizers', '%'):
            tools_links.append({'text': _('Localizer Tools'),
                                'href': '/localizers'})
        if acl.action_allowed(request, 'AccountLookup', '%'):
            tools_links.append({'text': _('Lookup Tool'),
                                'href': reverse('lookup.home')})
        if acl.action_allowed(request, 'Admin', '%'):
            tools_links.append({'text': _('Admin Tools'),
                                'href': reverse('zadmin.home')})

        context['amo_user'] = amo_user
    else:
        context['amo_user'] = AnonymousUser()

    context.update(account_links=account_links,
                   settings=settings,
                   amo=amo, mkt=mkt,
                   APP=amo.FIREFOX,
                   tools_links=tools_links,
                   tools_title=tools_title,
                   ADMIN_MESSAGE=get_config('site_notice'),
                   collect_timings_percent=get_collect_timings(),
                   is_admin=acl.action_allowed(request, 'Addons', 'Edit'))
    return context
Пример #21
0
def privacy(request, addon):
    is_dev = request.check_ownership(addon,
                                     require_owner=False,
                                     ignore_disabled=True)
    if not (addon.is_public() or acl.check_reviewer(request) or is_dev):
        raise http.Http404
    if not addon.privacy_policy:
        return http.HttpResponseRedirect(addon.get_url_path())
    return jingo.render(request, 'detail/privacy.html', {'product': addon})
Пример #22
0
def _record(request, addon):
    logged = request.user.is_authenticated()
    premium = addon.is_premium()

    # Require login for premium.
    if not logged and premium:
        return http.HttpResponseRedirect(reverse('users.login'))

    ctx = {'addon': addon.pk}

    # Don't generate receipts if we're allowing logged-out install.
    if logged:
        is_dev = request.check_ownership(addon, require_owner=False,
                                         ignore_disabled=True, admin=False)
        is_reviewer = acl.check_reviewer(request)
        if (not addon.is_webapp() or not addon.is_public() and
            not (is_reviewer or is_dev)):
            raise http.Http404

        if (premium and
            not addon.has_purchased(request.amo_user) and
            not is_reviewer and not is_dev):
            raise PermissionDenied

        # If you are reviewer, you get a user receipt. Use the reviewer tools
        # to get a reviewer receipt. App developers still get their special
        # receipt.
        install_type = (apps.INSTALL_TYPE_DEVELOPER if is_dev
                        else apps.INSTALL_TYPE_USER)
        # Log the install.
        installed, c = Installed.objects.get_or_create(addon=addon,
            user=request.amo_user, install_type=install_type)

        # Get a suitable uuid for this receipt.
        uuid = get_uuid(addon, request.amo_user)

        error = ''
        receipt_cef.log(request, addon, 'sign', 'Receipt requested')
        try:
            receipt = create_receipt(addon, request.amo_user, uuid)
        except SigningError:
            error = _('There was a problem installing the app.')

        ctx.update(receipt=receipt, error=error)
    else:
        if not addon.is_public() or not addon.is_webapp():
            raise http.Http404

    amo.log(amo.LOG.INSTALL_ADDON, addon)
    record_action('install', request, {
        'app-domain': addon.domain_from_url(addon.origin, allow_none=True),
        'app-id': addon.pk,
        'anonymous': request.user.is_anonymous(),
    })

    return ctx
Пример #23
0
def app_header(context, app, page_type=''):
    t = env.get_template('lookup/helpers/app_header.html')
    is_admin = acl.action_allowed(context['request'], 'Users', 'Edit')
    is_staff = acl.action_allowed(context['request'], 'Apps', 'Configure')
    is_reviewer = acl.check_reviewer(context['request'])
    return jinja2.Markup(
        t.render(app=app,
                 page_type=page_type,
                 is_admin=is_admin,
                 is_staff=is_staff,
                 is_reviewer=is_reviewer))
Пример #24
0
def app_header(context, app, page_type=''):
    t = env.get_template('lookup/helpers/app_header.html')

    is_author = acl.check_ownership(context['request'], app)
    is_operator = any(g.name == 'Operators' for g in context['request'].groups)
    is_admin = acl.action_allowed(context['request'], 'Users', 'Edit')
    is_staff = acl.action_allowed(context['request'], 'Apps', 'Configure')
    is_reviewer = acl.check_reviewer(context['request'])
    return jinja2.Markup(t.render(app=app, page_type=page_type,
                                  is_admin=is_admin, is_staff=is_staff,
                                  is_reviewer=is_reviewer, is_author=is_author,
                                  is_operator=is_operator))
Пример #25
0
def _record(request, addon):
    # TODO(andym): simplify this.
    logged = request.user.is_authenticated()
    premium = addon.is_premium()
    allow_anon_install = waffle.switch_is_active('anonymous-free-installs')

    # Require login for premium.
    if not logged and (premium or not allow_anon_install):
        return redirect(reverse('users.login'))

    ctx = {'addon': addon.pk}

    # Don't generate receipts if we're allowing logged-out install.
    if logged or not allow_anon_install:
        is_dev = request.check_ownership(addon, require_owner=False,
                                     ignore_disabled=True)
        is_reviewer = acl.check_reviewer(request)
        if (not addon.is_webapp() or not addon.is_public() and
            not (is_reviewer or is_dev)):
            raise http.Http404

        if (premium and
            not addon.has_purchased(request.amo_user) and
            not is_reviewer and not is_dev):
            return http.HttpResponseForbidden()

        installed, c = Installed.objects.safer_get_or_create(addon=addon,
            user=request.amo_user)
        # Look up to see if its in the receipt cache and log if we have
        # to recreate it.
        receipt = memoize_get('create-receipt', installed.pk)
        error = ''
        receipt_cef.log(request, addon, 'request', 'Receipt requested')
        if not receipt:
            receipt_cef.log(request, addon, 'sign', 'Receipt signing')
            try:
                receipt = create_receipt(installed.pk)
            except SigningError:
                error = _('There was a problem installing the app.')

        ctx.update(receipt=receipt, error=error)
    else:
        if not addon.is_public() or not addon.is_webapp():
            raise http.Http404

    amo.log(amo.LOG.INSTALL_ADDON, addon)
    send_request('install', request, {
        'app-domain': addon.domain_from_url(addon.origin),
        'app-id': addon.pk
    })

    return ctx
Пример #26
0
def _record(request, addon):
    # TODO(andym): simplify this.
    logged = request.user.is_authenticated()
    premium = addon.is_premium()
    allow_anon_install = waffle.switch_is_active('anonymous-free-installs')

    # Require login for premium.
    if not logged and (premium or not allow_anon_install):
        return redirect(reverse('users.login'))

    ctx = {'addon': addon.pk}

    # Don't generate receipts if we're allowing logged-out install.
    if logged or not allow_anon_install:
        is_dev = request.check_ownership(addon,
                                         require_owner=False,
                                         ignore_disabled=True)
        is_reviewer = acl.check_reviewer(request)
        if (not addon.is_webapp()
                or not addon.is_public() and not (is_reviewer or is_dev)):
            raise http.Http404

        if (premium and not addon.has_purchased(request.amo_user)
                and not is_reviewer and not is_dev):
            return http.HttpResponseForbidden()

        installed, c = Installed.objects.safer_get_or_create(
            addon=addon, user=request.amo_user)
        # Look up to see if its in the receipt cache and log if we have
        # to recreate it.
        receipt = memoize_get('create-receipt', installed.pk)
        error = ''
        receipt_cef.log(request, addon, 'request', 'Receipt requested')
        if not receipt:
            receipt_cef.log(request, addon, 'sign', 'Receipt signing')
            try:
                receipt = create_receipt(installed.pk)
            except SigningError:
                error = _('There was a problem installing the app.')

        ctx.update(receipt=receipt, error=error)
    else:
        if not addon.is_public() or not addon.is_webapp():
            raise http.Http404

    amo.log(amo.LOG.INSTALL_ADDON, addon)
    send_request('install', request, {
        'app-domain': addon.domain_from_url(addon.origin),
        'app-id': addon.pk
    })

    return ctx
Пример #27
0
 def dehydrate(self, bundle):
     allowed = partial(acl.action_allowed, bundle.request)
     permissions = {
         'reviewer': acl.check_reviewer(bundle.request),
         'admin': allowed('Admin', '%'),
         'localizer': allowed('Localizers', '%'),
         'lookup': allowed('AccountLookup', '%'),
         'developer': bundle.request.amo_user.is_app_developer,
         'webpay': (allowed('Transaction', 'NotifyFailure')
                    and allowed('ProductIcon', 'Create')),
     }
     bundle.data['permissions'] = permissions
     return bundle
Пример #28
0
def allowed(request, file):
    allowed = acl.check_reviewer(request)
    if not allowed:
        try:
            addon = file.version.addon
        except ObjectDoesNotExist:
            return http.Http404()

        if addon.view_source and addon.status in amo.REVIEWED_STATUSES:
            allowed = True
        else:
            allowed = acl.check_addon_ownership(request, addon, viewer=True, dev=True)
    if not allowed:
        raise PermissionDenied
    return True
Пример #29
0
        def wrapper(request, addon, *args, **kw):
            from mkt.submit.views import _resume
            if webapp:
                kw['webapp'] = addon.is_webapp()
            fun = lambda: f(
                request, addon_id=addon.id, addon=addon, *args, **kw)

            if allow_editors and acl.check_reviewer(request):
                return fun()

            if staff and (acl.action_allowed(request, 'Apps', 'Configure')
                          or acl.action_allowed(request, 'Apps',
                                                'ViewConfiguration')):
                return fun()

            if support:
                # Let developers and support people do their thangs.
                if (acl.check_addon_ownership(request, addon, support=True) or
                        acl.check_addon_ownership(request, addon, dev=True)):
                    return fun()
            else:
                # Require an owner or dev for POST requests.
                if request.method == 'POST':

                    if acl.check_addon_ownership(request,
                                                 addon,
                                                 dev=not owner_for_post):
                        return fun()

                # Ignore disabled so they can view their add-on.
                elif acl.check_addon_ownership(request,
                                               addon,
                                               viewer=True,
                                               ignore_disabled=True):
                    if not skip_submit_check:
                        try:
                            # If it didn't go through the app submission
                            # checklist. Don't die. This will be useful for
                            # creating apps with an API later.
                            step = addon.appsubmissionchecklist.get_next()
                        except ObjectDoesNotExist:
                            step = None
                        # Redirect to the submit flow if they're not done.
                        if not getattr(f, 'submitting', False) and step:
                            return _resume(addon, step)
                    return fun()

            return http.HttpResponseForbidden()
Пример #30
0
def app_header(context, app, page_type=''):
    t = env.get_template('lookup/helpers/app_header.html')

    is_author = acl.check_ownership(context['request'], app)
    is_operator = any(g.name == 'Operators' for g in context['request'].groups)
    is_admin = acl.action_allowed(context['request'], 'Users', 'Edit')
    is_staff = acl.action_allowed(context['request'], 'Apps', 'Configure')
    is_reviewer = acl.check_reviewer(context['request'])
    return jinja2.Markup(
        t.render(app=app,
                 page_type=page_type,
                 is_admin=is_admin,
                 is_staff=is_staff,
                 is_reviewer=is_reviewer,
                 is_author=is_author,
                 is_operator=is_operator))
Пример #31
0
def allowed(request, file):
    allowed = acl.check_reviewer(request)
    if not allowed:
        try:
            addon = file.version.addon
        except ObjectDoesNotExist:
            return http.Http404()

        if addon.view_source and addon.status in amo.REVIEWED_STATUSES:
            allowed = True
        else:
            allowed = acl.check_addon_ownership(request, addon, viewer=True,
                                                dev=True)
    if not allowed:
        raise PermissionDenied
    return True
Пример #32
0
def market_tile(context, product, link=True, src=''):
    request = context['request']
    if product.is_webapp():
        classes = ['product', 'mkt-tile']
        purchased = (request.amo_user
                     and product.pk in request.amo_user.purchase_ids())

        is_dev = product.has_author(request.amo_user)
        is_reviewer = acl.check_reviewer(request)
        receipt_type = 'developer' if is_dev or is_reviewer else None
        product_dict = product_as_dict(request,
                                       product,
                                       purchased=purchased,
                                       receipt_type=receipt_type,
                                       src=src)
        product_dict['prepareNavPay'] = reverse('bluevia.prepare_pay',
                                                args=[product.app_slug])

        data_attrs = {
            'product': json.dumps(product_dict, cls=JSONEncoder),
            'manifest_url': product.get_manifest_url(),
            'src': src
        }
        if product.is_premium() and product.premium:
            classes.append('premium')
        c = dict(request=request,
                 product=product,
                 data_attrs=data_attrs,
                 classes=' '.join(classes),
                 link=link)
        t = env.get_template('site/tiles/app.html')
        return jinja2.Markup(t.render(c))

    elif product.is_persona():
        classes = ['product', 'mkt-tile', 'arrow']
        product_dict = product_as_dict_theme(request, product)
        data_attrs = {
            'product': json.dumps(product_dict, cls=JSONEncoder),
            'src': src
        }
        c = dict(product=product,
                 data_attrs=data_attrs,
                 classes=' '.join(classes),
                 link=link)
        t = env.get_template('site/tiles/theme.html')
        return jinja2.Markup(t.render(c))
Пример #33
0
def manifest(request, addon):
    """
    Returns the "mini" manifest for packaged apps.

    If not a packaged app, returns an empty JSON doc.

    """
    is_reviewer = acl.check_reviewer(request)
    is_dev = addon.has_author(request.amo_user)
    is_public = addon.status == amo.STATUS_PUBLIC

    # If webapp is blocklisted, show the blocklisted manifest.
    if addon.status == amo.STATUS_BLOCKED:
        # TODO: Consider caching the os.stat call to avoid FS hits.
        package_name = 'packaged-apps/blocklisted.zip'
        data = {
            'name': addon.name,
            'size': os.stat(os.path.join(settings.MEDIA_ROOT,
                                         package_name)).st_size,
            'release_notes':
                _(u'This app has been blocked for your protection.'),
            'package_path': absolutify(os.path.join(settings.MEDIA_URL,
                                                    package_name)),
        }
        manifest_content = json.dumps(data, cls=JSONEncoder)
        manifest_etag = hashlib.md5(manifest_content).hexdigest()

        log.info('Serving up blocklisted app for addon: %s' % addon)

    elif (not addon.is_packaged or addon.disabled_by_user or (
        not is_public and not (is_reviewer or is_dev))):
        raise http.Http404

    else:
        manifest_content = addon.get_cached_manifest()
        manifest_etag = hashlib.md5(manifest_content).hexdigest()

    @etag(lambda r, a: manifest_etag)
    def _inner_view(request, addon):
        response = http.HttpResponse(
            manifest_content,
            content_type='application/x-web-app-manifest+json')
        response['ETag'] = manifest_etag
        return response

    return _inner_view(request, addon)
Пример #34
0
def user_can_delete_review(request, review):
    """Return whether or not the request.user can delete reviews.

    People who can delete reviews:
      * The original review author.
      * Editors, but only if they aren't listed as an author of the add-on.
      * Users in a group with "Users:Edit" privileges.
      * Users in a group with "Addons:Edit" privileges.

    TODO: Make this more granular when we have multiple reviewer types, e.g.
    persona reviewers shouldn't be able to delete add-on reviews.
    """
    is_editor = acl.check_reviewer(request)
    is_author = review.addon.has_author(request.user)
    return (review.user_id == request.user.id or not is_author and
            (is_editor or acl.action_allowed(request, 'Users', 'Edit')
             or acl.action_allowed(request, 'Addons', 'Edit')))
Пример #35
0
        def wrapper(request, addon, *args, **kw):
            from mkt.submit.views import _resume
            if webapp:
                kw['webapp'] = addon.is_webapp()
            fun = lambda: f(request, addon_id=addon.id, addon=addon,
                            *args, **kw)

            if allow_editors and acl.check_reviewer(request):
                return fun()

            if staff and (acl.action_allowed(request, 'Apps', 'Configure') or
                          acl.action_allowed(request, 'Apps',
                                             'ViewConfiguration')):
                return fun()

            if support:
                # Let developers and support people do their thangs.
                if (acl.check_addon_ownership(request, addon, support=True) or
                    acl.check_addon_ownership(request, addon, dev=True)):
                    return fun()
            else:
                # Require an owner or dev for POST requests.
                if request.method == 'POST':

                    if acl.check_addon_ownership(request, addon,
                                                 dev=not owner_for_post):
                        return fun()

                # Ignore disabled so they can view their add-on.
                elif acl.check_addon_ownership(request, addon, viewer=True,
                                               ignore_disabled=True):
                    if not skip_submit_check:
                        try:
                            # If it didn't go through the app submission
                            # checklist. Don't die. This will be useful for
                            # creating apps with an API later.
                            step = addon.appsubmissionchecklist.get_next()
                        except ObjectDoesNotExist:
                            step = None
                        # Redirect to the submit flow if they're not done.
                        if not getattr(f, 'submitting', False) and step:
                            return _resume(addon, step)
                    return fun()

            return http.HttpResponseForbidden()
Пример #36
0
def review_list(request, addon, review_id=None, user_id=None, rating=None):
    qs = Rating.objects.valid().filter(addon=addon).order_by('-created')

    ctx = {'product': addon, 'score': rating, 'review_perms': {}}

    # If we want to filter by only positive or only negative.
    score = {'positive': 1, 'negative': -1}.get(rating)
    if score:
        qs = qs.filter(score=score)

    if review_id is not None:
        qs = qs.filter(pk=review_id)
        ctx['page'] = 'detail'
        # If this is a dev reply, find the first msg for context.
        review = get_object_or_404(Rating, pk=review_id)
        if review.reply_to_id:
            review_id = review.reply_to_id
            ctx['reply'] = review
    elif user_id is not None:
        qs = qs.filter(user=user_id)
        ctx['page'] = 'user'
        if not qs:
            raise http.Http404()
    else:
        ctx['page'] = 'list'
        qs = qs.filter(is_latest=True)

    ctx['ratings'] = ratings = amo.utils.paginate(request, qs)
    ctx['replies'] = Rating.get_replies(ratings.object_list)
    ctx['review_history'] = [[2, 12], [50, 2], [3, 0], [4, 1]]
    if request.user.is_authenticated():
        ctx['review_perms'] = {
            'is_admin':
            acl.action_allowed(request, 'Addons', 'Edit'),
            'is_editor':
            acl.check_reviewer(request),
            'is_author':
            acl.check_addon_ownership(request,
                                      addon,
                                      viewer=True,
                                      dev=True,
                                      support=True),
        }
        ctx['flags'] = get_flags(request, ratings.object_list)
    return jingo.render(request, 'ratings/listing.html', ctx)
Пример #37
0
 def dehydrate(self, bundle):
     allowed = partial(acl.action_allowed, bundle.request)
     permissions = {
         'reviewer':
         acl.check_reviewer(bundle.request),
         'admin':
         allowed('Admin', '%'),
         'localizer':
         allowed('Localizers', '%'),
         'lookup':
         allowed('AccountLookup', '%'),
         'developer':
         bundle.request.amo_user.is_app_developer,
         'webpay': (allowed('Transaction', 'NotifyFailure')
                    and allowed('ProductIcon', 'Create')),
     }
     bundle.data['permissions'] = permissions
     return bundle
Пример #38
0
def user_can_delete_review(request, review):
    """Return whether or not the request.user can delete reviews.

    People who can delete reviews:
      * The original review author.
      * Editors, but only if they aren't listed as an author of the add-on.
      * Users in a group with "Users:Edit" privileges.
      * Users in a group with "Addons:Edit" privileges.

    TODO: Make this more granular when we have multiple reviewer types, e.g.
    persona reviewers shouldn't be able to delete add-on reviews.
    """
    is_editor = acl.check_reviewer(request)
    is_author = review.addon.has_author(request.user)
    return (
        review.user_id == request.user.id or
        (is_editor and not is_author) or
        acl.action_allowed(request, 'Users', 'Edit') or
        acl.action_allowed(request, 'Addons', 'Edit'))
Пример #39
0
def download_file(request, file_id, type=None):
    file = get_object_or_404(File, pk=file_id)
    webapp = get_object_or_404(Webapp, pk=file.version.addon_id,
                               is_packaged=True)

    if webapp.is_disabled or file.status == amo.STATUS_DISABLED:
        if not acl.check_addon_ownership(request, webapp, viewer=True,
                                         ignore_disabled=True):
            log.info('Download of %s denied: disabled.' % (webapp.id))
            raise http.Http404()

    # We treat blocked files like public files so users get the update.
    if file.status in [amo.STATUS_PUBLIC, amo.STATUS_BLOCKED]:
        path = webapp.sign_if_packaged(file.version_id)

    else:
        # This is someone asking for an unsigned packaged app.
        if not acl.check_addon_ownership(request, webapp, dev=True):
            log.info('Download of %s denied: not signed yet.' % (webapp.id))
            raise http.Http404()

        path = file.file_path

    # If it's a paid app and its not been paid for stop it downloading unless..
    if webapp.is_premium():
        if not request.user.is_authenticated():
            log.info('Download of %s denied: not logged in.' % (webapp.id))
            return http.HttpResponseForbidden()

        if not webapp.has_purchased(request.amo_user):
            # User hasn't purchased, are they a developer of the app,
            # or a reviewer?
            log.info('Download of %s: not purchased by user.' % (webapp.id))
            if (not request.check_ownership(webapp, require_owner=False,
                                            ignore_disabled=True, admin=False)
                and not acl.check_reviewer(request, only='app')):
                log.info('Download of %s denied: not developer or reviewer.' %
                         (webapp.id))
                return http.HttpResponse(status=402)

    log.info('Downloading package: %s from %s' % (webapp.id, path))
    return HttpResponseSendFile(request, path, content_type='application/zip',
                                etag=file.hash.split(':')[-1])
Пример #40
0
def download_file(request, file_id, type=None):
    file = get_object_or_404(File.objects, pk=file_id)
    addon = get_object_or_404(Addon.objects, pk=file.version.addon_id)

    if addon.is_disabled or file.status == amo.STATUS_DISABLED:
        if (acl.check_addon_ownership(request, addon, viewer=True,
                                      ignore_disabled=True) or
            acl.check_reviewer(request)):
            return HttpResponseSendFile(request, file.guarded_file_path,
                                        content_type='application/xp-install')
        else:
            raise http.Http404()

    attachment = (type == 'attachment' or not request.APP.browser)

    loc = file.get_mirror(addon, attachment=attachment)
    response = http.HttpResponseRedirect(loc)
    response['X-Target-Digest'] = file.hash
    return response
Пример #41
0
def review_list(request, addon, review_id=None, user_id=None, template=None):
    q = (Review.objects.valid().filter(addon=addon).order_by('-created'))

    ctx = {'addon': addon, 'grouped_ratings': GroupedRating.get(addon.id)}

    ctx['form'] = forms.ReviewForm(None)

    if review_id is not None:
        ctx['page'] = 'detail'
        # If this is a dev reply, find the first msg for context.
        review = get_object_or_404(Review.objects.all(), pk=review_id)
        if review.reply_to_id:
            review_id = review.reply_to_id
            ctx['reply'] = review
        q = q.filter(pk=review_id)
    elif user_id is not None:
        ctx['page'] = 'user'
        q = q.filter(user=user_id)
        if not q:
            raise http.Http404()
    else:
        ctx['page'] = 'list'
        q = q.filter(is_latest=True)

    ctx['reviews'] = reviews = amo.utils.paginate(request, q)
    ctx['replies'] = Review.get_replies(reviews.object_list)
    if request.user.is_authenticated():
        ctx['review_perms'] = {
            'is_admin':
            acl.action_allowed(request, 'Addons', 'Edit'),
            'is_editor':
            acl.check_reviewer(request),
            'is_author':
            acl.check_addon_ownership(request,
                                      addon,
                                      viewer=True,
                                      dev=True,
                                      support=True),
        }
        ctx['flags'] = get_flags(request, reviews.object_list)
    else:
        ctx['review_perms'] = {}
    return jingo.render(request, template, ctx)
Пример #42
0
def record(request, addon):
    if not (addon.is_public() or acl.check_reviewer(request)):
        raise http.Http404
    if addon.is_webapp():
        installed, c = Installed.objects.safer_get_or_create(addon=addon, user=request.amo_user)
        send_request("install", request, {"app-domain": addon.domain_from_url(addon.origin), "app-id": addon.pk})

        # Look up to see if its in the receipt cache and log if we have
        # to recreate it.
        receipt = memoize_get("create-receipt", installed.pk)
        error = ""
        cef(request, addon, "request", "Receipt requested")
        if not receipt:
            cef(request, addon, "sign", "Receipt signing")
            try:
                receipt = create_receipt(installed.pk)
            except SigningError:
                error = _("There was a problem installing the app.")

        return {"addon": addon.pk, "receipt": receipt, "error": error}
Пример #43
0
def global_settings(request):
    """Store global Marketplace-wide info. used in the header."""
    account_links = []
    tools_links = []
    context = {}

    tools_title = _('Tools')

    if request.user.is_authenticated() and hasattr(request, 'amo_user'):
        amo_user = request.amo_user
        account_links = [
            {'text': _('Change Password'),
             'href': 'https://browserid.org/signin'},
            {'text': _('Log out'), 'href': reverse('users.logout')},
        ]
        if '/developers/' not in request.path:
            tools_links.append({'text': _('Developer Hub'),
                                'href': reverse('mkt.developers.index')})
        if '/reviewers/' not in request.path and acl.check_reviewer(request):
            tools_links.append({'text': _('Reviewer Tools'),
                                'href': reverse('reviewers.home')})
        if acl.action_allowed(request, 'Localizers', '%'):
            tools_links.append({'text': _('Localizer Tools'),
                                'href': '/localizers'})
        if acl.action_allowed(request, 'Admin', '%'):
            tools_links.append({'text': _('Admin Tools'),
                                'href': reverse('zadmin.home')})

        context['amo_user'] = amo_user
    else:
        context['amo_user'] = AnonymousUser()

    context.update(account_links=account_links,
                   settings=settings,
                   amo=amo, mkt=mkt,
                   tools_links=tools_links,
                   tools_title=tools_title,
                   ADMIN_MESSAGE=get_config('site_notice'),
                   collect_timings_percent=get_collect_timings(),
                   is_admin=acl.action_allowed(request, 'Addons', 'Edit'))
    return context
Пример #44
0
def review_list(request, addon, review_id=None, user_id=None, rating=None):
    qs = Review.objects.valid().filter(addon=addon).order_by('-created')

    ctx = {'product': addon, 'score': rating, 'review_perms': {}}

    if review_id is not None:
        qs = qs.filter(pk=review_id)
        ctx['page'] = 'detail'
        # If this is a dev reply, find the first msg for context.
        review = get_object_or_404(Review, pk=review_id)
        if review.reply_to_id:
            review_id = review.reply_to_id
            ctx['reply'] = review
    elif user_id is not None:
        qs = qs.filter(user=user_id)
        ctx['page'] = 'user'
        if not qs:
            raise http.Http404()
    else:
        ctx['page'] = 'list'
        qs = qs.filter(is_latest=True)

    ctx['ratings'] = ratings = amo.utils.paginate(request, qs, 20)
    if not ctx.get('reply'):
        ctx['replies'] = Review.get_replies(ratings.object_list)
    if request.user.is_authenticated():
        ctx['review_perms'] = {
            'is_admin':
            acl.action_allowed(request, 'Addons', 'Edit'),
            'is_editor':
            acl.check_reviewer(request),
            'is_author':
            acl.check_addon_ownership(request,
                                      addon,
                                      viewer=True,
                                      dev=True,
                                      support=True),
        }
        ctx['flags'] = get_flags(request, ratings.object_list)
        ctx['has_review'] = addon.reviews.filter(user=request.user.id).exists()
    return jingo.render(request, 'ratings/listing.html', ctx)
Пример #45
0
        def wrapper(request, addon, *args, **kw):
            from devhub.views import _resume

            if webapp:
                kw["webapp"] = addon.is_webapp()
            fun = lambda: f(request, addon_id=addon.id, addon=addon, *args, **kw)
            if allow_editors:
                if acl.check_reviewer(request):
                    return fun()
            # Require an owner or dev for POST requests.
            if request.method == "POST":
                if acl.check_addon_ownership(request, addon, dev=not owner_for_post):
                    return fun()
            # Ignore disabled so they can view their add-on.
            elif acl.check_addon_ownership(request, addon, viewer=True, ignore_disabled=True):
                step = SubmitStep.objects.filter(addon=addon)
                # Redirect to the submit flow if they're not done.
                if not getattr(f, "submitting", False) and step:
                    return _resume(addon, step)
                return fun()
            raise PermissionDenied
Пример #46
0
def review_list(request, addon, review_id=None, user_id=None, template=None):
    q = (Review.objects.valid().filter(addon=addon)
         .order_by('-created'))

    ctx = {'addon': addon,
           'grouped_ratings': GroupedRating.get(addon.id)}

    ctx['form'] = forms.ReviewForm(None)

    if review_id is not None:
        ctx['page'] = 'detail'
        # If this is a dev reply, find the first msg for context.
        review = get_object_or_404(Review.objects.all(), pk=review_id)
        if review.reply_to_id:
            review_id = review.reply_to_id
            ctx['reply'] = review
        q = q.filter(pk=review_id)
    elif user_id is not None:
        ctx['page'] = 'user'
        q = q.filter(user=user_id)
        if not q:
            raise http.Http404()
    else:
        ctx['page'] = 'list'
        q = q.filter(is_latest=True)

    ctx['reviews'] = reviews = amo.utils.paginate(request, q)
    ctx['replies'] = Review.get_replies(reviews.object_list)
    if request.user.is_authenticated():
        ctx['review_perms'] = {
            'is_admin': acl.action_allowed(request, 'Admin', 'EditAnyAddon'),
            'is_editor': acl.check_reviewer(request),
            'is_author': acl.check_addon_ownership(request, addon, dev=True),
            'can_delete': acl.action_allowed(request, 'Editors',
                                             'DeleteReview'),
        }
        ctx['flags'] = get_flags(request, reviews.object_list)
    else:
        ctx['review_perms'] = {}
    return jingo.render(request, template, ctx)
Пример #47
0
def market_tile(context, product, link=True, src=''):
    request = context['request']
    if product.is_webapp():
        classes = ['product', 'mkt-tile']
        purchased = (request.amo_user and
                     product.pk in request.amo_user.purchase_ids())

        is_dev = product.has_author(request.amo_user)
        is_reviewer = acl.check_reviewer(request)
        receipt_type = 'developer' if is_dev or is_reviewer else None
        product_dict = product_as_dict(request, product, purchased=purchased,
                                       receipt_type=receipt_type)
        product_dict['prepareNavPay'] = reverse('bluevia.prepare_pay',
                                                args=[product.app_slug])

        data_attrs = {
            'product': json.dumps(product_dict, cls=JSONEncoder),
            'manifestUrl': product.manifest_url,
            'src': src
        }
        if product.is_premium() and product.premium:
            classes.append('premium')
        c = dict(request=request, product=product, data_attrs=data_attrs,
                 classes=' '.join(classes), link=link)
        t = env.get_template('site/tiles/app.html')
        return jinja2.Markup(t.render(c))

    elif product.is_persona():
        classes = ['product', 'mkt-tile', 'arrow']
        product_dict = product_as_dict_theme(request, product)
        data_attrs = {
            'product': json.dumps(product_dict, cls=JSONEncoder),
            'src': src
        }
        c = dict(product=product, data_attrs=data_attrs,
                 classes=' '.join(classes), link=link)
        t = env.get_template('site/tiles/theme.html')
        return jinja2.Markup(t.render(c))
Пример #48
0
def manifest(request, uuid):
    """Returns the "mini" manifest for packaged apps.

    If not a packaged app, returns a 404.

    """
    addon = get_object_or_404(Webapp, guid=uuid, is_packaged=True)

    is_reviewer = acl.check_reviewer(request)
    is_dev = addon.has_author(request.amo_user)
    is_avail = addon.status in [amo.STATUS_PUBLIC, amo.STATUS_BLOCKED]

    package_etag = hashlib.sha256()

    if (not addon.is_packaged or addon.disabled_by_user
            or not (is_avail or is_reviewer or is_dev)):
        raise http.Http404

    else:
        manifest_content = addon.get_cached_manifest()
        package_etag.update(manifest_content)

        if addon.is_packaged:
            # Update the hash with the content of the package itself.
            package_file = addon.get_latest_file()
            if package_file:
                package_etag.update(package_file.hash)

    manifest_etag = package_etag.hexdigest()

    @etag(lambda r, a: manifest_etag)
    def _inner_view(request, addon):
        response = http.HttpResponse(
            manifest_content,
            content_type='application/x-web-app-manifest+json; charset=utf-8')
        return response

    return _inner_view(request, addon)
Пример #49
0
def review_list(request, addon, review_id=None, user_id=None, rating=None):
    qs = Review.objects.valid().filter(addon=addon).order_by('-created')

    # Mature regions show only reviews from within that region.
    if not request.REGION.adolescent:
        qs = qs.filter(client_data__region=request.REGION.id)
    ctx = {'product': addon, 'score': rating, 'review_perms': {}}

    if review_id is not None:
        qs = qs.filter(pk=review_id)
        ctx['page'] = 'detail'
    elif user_id is not None:
        qs = qs.filter(user=user_id)
        ctx['page'] = 'user'
        if not qs:
            raise http.Http404()
    else:
        ctx['page'] = 'list'
        qs = qs.filter(is_latest=True)

    ctx['ratings'] = ratings = amo.utils.paginate(request, qs, 20)
    if request.user.is_authenticated():
        ctx['review_perms'] = {
            'is_admin':
            acl.action_allowed(request, 'Addons', 'Edit'),
            'is_editor':
            acl.check_reviewer(request),
            'is_author':
            acl.check_addon_ownership(request,
                                      addon,
                                      viewer=True,
                                      dev=True,
                                      support=True),
        }
        ctx['flags'] = get_flags(request, ratings.object_list)
        ctx['has_review'] = addon.reviews.filter(user=request.user.id).exists()
    return jingo.render(request, 'ratings/listing.html', ctx)
Пример #50
0
    def is_visible(self, request):
        """Returns whether the app has a visible search result listing. Its
        detail page will always be there.

        This does not consider whether an app is excluded in the current region
        by the developer.
        """

        region = getattr(request, 'REGION', mkt.regions.WORLDWIDE)

        # See if it's a game without a content rating.
        if (region == mkt.regions.BR and self.listed_in(category='games')
                and not self.content_ratings_in(mkt.regions.BR, 'games')):
            unrated_brazil_game = True
        else:
            unrated_brazil_game = False

        # Let developers see it always.
        can_see = (self.has_author(request.amo_user)
                   or action_allowed(request, 'Apps', 'Edit'))

        # Let app reviewers see it only when it's pending.
        if check_reviewer(request, only='app') and self.is_pending():
            can_see = True

        visible = False

        if can_see:
            # Developers and reviewers should see it always.
            visible = True
        elif self.is_public() and not unrated_brazil_game:
            # Everyone else can see it only if it's public -
            # and if it's a game, it must have a content rating.
            visible = True

        return visible
Пример #51
0
def _record(request, addon):
    # TODO(andym): we have an API now, replace this with that.
    logged = request.user.is_authenticated()
    premium = addon.is_premium()

    # Require login for premium.
    if not logged and premium:
        return http.HttpResponseRedirect(reverse('users.login'))

    ctx = {'addon': addon.pk}

    # Don't generate receipts if we're allowing logged-out install.
    if logged:
        is_dev = request.check_ownership(addon,
                                         require_owner=False,
                                         ignore_disabled=True,
                                         admin=False)
        is_reviewer = acl.check_reviewer(request)
        if (not addon.is_webapp()
                or not addon.is_public() and not (is_reviewer or is_dev)):
            raise http.Http404

        if (premium and not addon.has_purchased(request.amo_user)
                and not is_reviewer and not is_dev):
            raise PermissionDenied

        # If you are reviewer, you get a user receipt. Use the reviewer tools
        # to get a reviewer receipt. App developers still get their special
        # receipt.
        install_type = (apps.INSTALL_TYPE_DEVELOPER
                        if is_dev else apps.INSTALL_TYPE_USER)
        # Log the install.
        installed, c = Installed.objects.safer_get_or_create(
            addon=addon, user=request.amo_user, install_type=install_type)

        # Get download source from GET if it exists, if so get the download
        # source object if it exists. Then grab a client data object to hook up
        # with the Installed object.
        download_source = DownloadSource.objects.filter(
            name=request.REQUEST.get('src', None))
        download_source = download_source[0] if download_source else None
        try:
            region = request.REGION.id
        except AttributeError:
            region = mkt.regions.WORLDWIDE.id
        client_data, c = ClientData.objects.get_or_create(
            download_source=download_source,
            device_type=request.POST.get('device_type', ''),
            user_agent=request.META.get('HTTP_USER_AGENT', ''),
            is_chromeless=request.POST.get('chromeless', False),
            language=request.LANG,
            region=region)
        installed.update(client_data=client_data)

        # Look up to see if its in the receipt cache and log if we have
        # to recreate it.
        receipt = memoize_get('create-receipt', installed.pk)
        error = ''
        receipt_cef.log(request, addon, 'request', 'Receipt requested')
        if not receipt:
            receipt_cef.log(request, addon, 'sign', 'Receipt signing')
            try:
                receipt = create_receipt(installed.pk)
            except SigningError:
                error = _('There was a problem installing the app.')

        ctx.update(receipt=receipt, error=error)
    else:
        if not addon.is_public() or not addon.is_webapp():
            raise http.Http404

    amo.log(amo.LOG.INSTALL_ADDON, addon)
    record_action(
        'install', request, {
            'app-domain': addon.domain_from_url(addon.origin),
            'app-id': addon.pk,
            'anonymous': request.user.is_anonymous(),
        })

    return ctx
Пример #52
0
 def wrapper(request, *args, **kw):
     if (acl.check_reviewer(request, only, region=kw.get('region'))
             or _view_on_get(request)):
         return f(request, *args, **kw)
     else:
         raise PermissionDenied
Пример #53
0
def global_settings(request):
    """
    Storing standard AMO-wide information used in global headers, such as
    account links and settings.
    """
    account_links = []
    tools_links = []
    context = {}

    tools_title = _('Tools')

    if request.user.is_authenticated() and hasattr(request, 'amo_user'):
        amo_user = request.amo_user
        account_links.append({
            'text': _('My Profile'),
            'href': request.user.get_profile().get_url_path(),
        })
        account_links.append({
            'text': _('Account Settings'),
            'href': reverse('users.edit')
        })
        if not settings.APP_PREVIEW:
            account_links.append({
                'text':
                _('My Collections'),
                'href':
                reverse('collections.user', args=[amo_user.username])
            })

            if amo_user.favorite_addons:
                account_links.append({
                    'text':
                    _('My Favorites'),
                    'href':
                    reverse('collections.detail',
                            args=[amo_user.username, 'favorites'])
                })

        if waffle.switch_is_active('marketplace'):
            account_links.append({
                'text': _('My Purchases'),
                'href': reverse('users.purchases')
            })

        if waffle.flag_is_active(request, 'allow-pre-auth'):
            account_links.append({
                'text': loc('Payment Profile'),
                'href': reverse('users.payments')
            })

        account_links.append({
            'text':
            _('Log out'),
            'href':
            remora_url('/users/logout?to=' + urlquote(request.path)),
        })

        if request.amo_user.is_developer:
            tools_links.append({
                'text': _('Manage My Add-ons'),
                'href': reverse('devhub.addons')
            })
        tools_links.append({
            'text': _('Submit a New Add-on'),
            'href': reverse('devhub.submit.1')
        })

        if waffle.flag_is_active(request, 'submit-personas'):
            # TODO(cvan)(fligtar): Do we want this here?
            tools_links.append({
                'text': 'Submit a New Persona',
                'href': reverse('devhub.personas.submit')
            })

        tools_links.append({
            'text': _('Developer Hub'),
            'href': reverse('devhub.index')
        })

        if acl.check_reviewer(request):
            tools_links.append({
                'text': _('Editor Tools'),
                'href': reverse('editors.home')
            })
        if acl.action_allowed(request, 'L10nTools', 'View'):
            tools_links.append({
                'text': _('Localizer Tools'),
                'href': '/localizers'
            })
        if (acl.action_allowed(request, 'Admin', '%')
                or acl.action_allowed(request, 'AdminTools', 'View')):
            tools_links.append({
                'text': _('Admin Tools'),
                'href': reverse('zadmin.home')
            })

        context['amo_user'] = request.amo_user
    else:
        context['amo_user'] = AnonymousUser()

    context.update({
        'account_links': account_links,
        'settings': settings,
        'amo': amo,
        'tools_links': tools_links,
        'tools_title': tools_title,
        'ADMIN_MESSAGE': get_config('site_notice'),
        'collect_timings_percent': get_collect_timings()
    })
    return context
Пример #54
0
def global_settings(request):
    """Store global Marketplace-wide info. used in the header."""
    account_links = []
    tools_links = []
    footer_links = []
    context = {}

    tools_title = _('Tools')

    if request.user.is_authenticated() and getattr(request, 'amo_user', None):
        amo_user = request.amo_user
        context['is_reviewer'] = acl.check_reviewer(request)
        account_links = [
            # TODO: Coming soon with payments.
            # {'text': _('Account History'),
            #  'href': reverse('account.purchases')},
            {
                'text': _('Account Settings'),
                'href': reverse('account.settings')
            },
            {
                'text': _('Change Password'),
                'href': 'https://login.persona.org/signin'
            },
            {
                'text': _('Sign out'),
                'href': reverse('users.logout')
            },
        ]
        if '/developers/' not in request.path:
            tools_links.append({
                'text': _('Developer Hub'),
                'href': reverse('ecosystem.landing')
            })
            if amo_user.is_app_developer:
                tools_links.append({
                    'text': _('My Submissions'),
                    'href': reverse('mkt.developers.apps')
                })
        if '/reviewers/' not in request.path and context['is_reviewer']:
            footer_links.append({
                'text':
                _('Reviewer Tools'),
                'href':
                reverse('reviewers.apps.queue_pending'),
            })
        if acl.action_allowed(request, 'Localizers', '%'):
            footer_links.append({
                'text':
                _('Localizer Tools'),
                'href':
                'https://addons.mozilla.org/localizers/'
            })
        if acl.action_allowed(request, 'AccountLookup', '%'):
            footer_links.append({
                'text': _('Lookup Tool'),
                'href': reverse('lookup.home')
            })
        if acl.action_allowed(request, 'Admin', '%'):
            footer_links.append({
                'text': _('Admin Tools'),
                'href': reverse('zadmin.home')
            })

        tools_links += footer_links

        context['amo_user'] = amo_user
        logged = True
    else:
        context['amo_user'] = AnonymousUser()
        logged = False

    DESKTOP = request.TABLET or not request.MOBILE

    context.update(account_links=account_links,
                   settings=settings,
                   amo=amo,
                   mkt=mkt,
                   APP=amo.FIREFOX,
                   tools_links=tools_links,
                   tools_title=tools_title,
                   footer_links=footer_links,
                   ADMIN_MESSAGE=get_config('site_notice'),
                   collect_timings_percent=get_collect_timings(),
                   is_admin=acl.action_allowed(request, 'Addons', 'Edit'),
                   DESKTOP=DESKTOP,
                   logged=logged)
    return context
Пример #55
0
 def wrapper(request, *args, **kw):
     if acl.check_reviewer(request, only) or _view_on_get(request):
         return f(request, *args, **kw)
     else:
         raise PermissionDenied
Пример #56
0
def global_settings(request):
    """Store global Marketplace-wide info. used in the header."""
    account_links = []
    tools_links = []
    context = {}

    tools_title = _('Tools')

    if request.user.is_authenticated() and hasattr(request, 'amo_user'):
        amo_user = request.amo_user
        account_links = []
        context['is_reviewer'] = acl.check_reviewer(request)
        if getattr(request, 'can_view_consumer', True):
            account_links = [
                # TODO: Coming soon with payments.
                # {'text': _('Account History'),
                #  'href': reverse('account.purchases')},
                {
                    'text': _('Account Settings'),
                    'href': reverse('account.settings')
                },
            ]
        account_links += [
            {
                'text': _('Change Password'),
                'href': 'https://login.persona.org/signin'
            },
            {
                'text': _('Log out'),
                'href': reverse('users.logout')
            },
        ]
        if '/developers/' not in request.path:
            tools_links.append({
                'text': _('Developer Hub'),
                'href': reverse('ecosystem.landing'),
                'target': '_blank'
            })
            if amo_user.is_app_developer:
                tools_links.append({
                    'text': _('My Submissions'),
                    'href': reverse('mkt.developers.apps'),
                    'target': '_blank'
                })
        if '/reviewers/' not in request.path and context['is_reviewer']:
            tools_links.append({
                'text': _('Reviewer Tools'),
                'href': reverse('reviewers.home')
            })
        if acl.action_allowed(request, 'Localizers', '%'):
            tools_links.append({
                'text': _('Localizer Tools'),
                'href': '/localizers'
            })
        if acl.action_allowed(request, 'AccountLookup', '%'):
            tools_links.append({
                'text': _('Lookup Tool'),
                'href': reverse('lookup.home')
            })
        if acl.action_allowed(request, 'Admin', '%'):
            tools_links.append({
                'text': _('Admin Tools'),
                'href': reverse('zadmin.home')
            })

        context['amo_user'] = amo_user
    else:
        context['amo_user'] = AnonymousUser()

    context.update(account_links=account_links,
                   settings=settings,
                   amo=amo,
                   mkt=mkt,
                   APP=amo.FIREFOX,
                   tools_links=tools_links,
                   tools_title=tools_title,
                   ADMIN_MESSAGE=get_config('site_notice'),
                   collect_timings_percent=get_collect_timings(),
                   is_admin=acl.action_allowed(request, 'Addons', 'Edit'))
    return context
Пример #57
0
def market_tile(context, product, link=True, src=''):
    request = context['request']
    if product.is_webapp():
        classes = []
        notices = []
        purchased = (request.amo_user
                     and product.pk in request.amo_user.purchase_ids())

        is_dev = product.has_author(request.amo_user)
        is_reviewer = acl.check_reviewer(request)
        receipt_type = 'developer' if is_dev or is_reviewer else None
        product_dict = product_as_dict(request,
                                       product,
                                       purchased=purchased,
                                       receipt_type=receipt_type,
                                       src=src)
        product_dict['prepareNavPay'] = reverse('bluevia.prepare_pay',
                                                args=[product.app_slug])

        data_attrs = {
            'product': json.dumps(product_dict, cls=JSONEncoder),
            'manifest_url': product.get_manifest_url(),
            'src': src
        }

        ua = request.META.get('HTTP_USER_AGENT', '')
        need_firefox, need_upgrade = check_firefox(ua)

        if product.is_premium() and product.premium:
            classes.append('premium')

            if waffle.switch_is_active('disabled-payments'):
                notices.append(
                    _('This app is temporarily unavailable for '
                      'purchase.'))
            elif not request.GAIA:
                notices.append(
                    _('This app is available for purchase on '
                      'only Firefox OS.'))

        if product.is_packaged and not request.GAIA:
            notices.append(_('This app is available on only Firefox OS.'))

        # if not request.MOBILE:
        #     notices.append(_('This app is available on only Firefox for '
        #                      'Android and Firefox OS.'))

        if need_firefox:
            if request.MOBILE:
                url = ('https://www.mozilla.org/en-US/mobile/android-download'
                       '.html')
                # We can't have nested anchors, so deal with this hack.
                notices.append(
                    _('To use this app, '
                      '<b data-href="{url}">download and install '
                      'Firefox for Android</b>.').format(url=url))
            # TODO: Comment out when we disable installs on desktop again!
            else:
                url = 'https://www.mozilla.org/en-US/firefox/'
                notices.append(
                    _('To use this app, <b data-href="{url}">'
                      'download and install '
                      'Firefox</b>.').format(url=url))
        elif need_upgrade:
            notices.append(_('To use this app, upgrade Firefox.'))

        if notices:
            classes += ['bad', 'disabled']

        c = dict(request=request,
                 product=product,
                 data_attrs=data_attrs,
                 classes=classes,
                 link=link,
                 notices=notices[:1])
        t = env.get_template('site/tiles/app.html')
        return jinja2.Markup(t.render(c))

    elif product.is_persona():
        classes = ['product', 'mkt-tile', 'arrow']
        product_dict = product_as_dict_theme(request, product)
        data_attrs = {
            'product': json.dumps(product_dict, cls=JSONEncoder),
            'src': src
        }
        c = dict(product=product,
                 data_attrs=data_attrs,
                 classes=' '.join(classes),
                 link=link)
        t = env.get_template('site/tiles/theme.html')
        return jinja2.Markup(t.render(c))
Пример #58
0
 def wrapper(request, *args, **kw):
     if acl.check_reviewer(request, only) or _view_on_get(request):
         return f(request, *args, **kw)
     else:
         return http.HttpResponseForbidden()
Пример #59
0
def global_settings(request):
    """
    Storing standard AMO-wide information used in global headers, such as
    account links and settings.
    """
    account_links = []
    tools_links = []
    context = {}

    tools_title = _('Tools')
    is_reviewer = False

    if request.user.is_authenticated() and hasattr(request, 'amo_user'):
        amo_user = request.amo_user
        profile = request.user.get_profile()
        is_reviewer = acl.check_reviewer(request)

        account_links.append({'text': _('My Profile'),
                              'href': profile.get_url_path()})
        if amo_user.is_artist:
            account_links.append({'text': _('My Themes'),
                                  'href': profile.get_user_url('themes')})

        account_links.append({'text': _('Account Settings'),
                              'href': reverse('users.edit')})
        if not settings.APP_PREVIEW:
            account_links.append({
                'text': _('My Collections'),
                'href': reverse('collections.user', args=[amo_user.username])})

            if amo_user.favorite_addons:
                account_links.append(
                    {'text': _('My Favorites'),
                     'href': reverse('collections.detail',
                                     args=[amo_user.username, 'favorites'])})

        account_links.append({
            'text': _('Log out'),
            'href': remora_url('/users/logout?to=' + urlquote(request.path)),
        })

        if request.amo_user.is_developer:
            tools_links.append({'text': _('Manage My Submissions'),
                                'href': reverse('devhub.addons')})
        tools_links += [
            {'text': _('Submit a New Add-on'),
             'href': reverse('devhub.submit.1')},
            {'text': _('Submit a New Theme'),
             'href': reverse('devhub.themes.submit')},
            {'text': _('Developer Hub'),
             'href': reverse('devhub.index')},
        ]

        if is_reviewer:
            tools_links.append({'text': _('Editor Tools'),
                                'href': reverse('editors.home')})
        if acl.action_allowed(request, 'L10nTools', 'View'):
            tools_links.append({'text': _('Localizer Tools'),
                                'href': '/localizers'})
        if (acl.action_allowed(request, 'Admin', '%') or
            acl.action_allowed(request, 'AdminTools', 'View')):
            tools_links.append({'text': _('Admin Tools'),
                                'href': reverse('zadmin.home')})

        context['amo_user'] = request.amo_user
    else:
        context['amo_user'] = AnonymousUser()

    context.update({'account_links': account_links,
                    'settings': settings, 'amo': amo,
                    'tools_links': tools_links,
                    'tools_title': tools_title,
                    'ADMIN_MESSAGE': get_config('site_notice'),
                    'collect_timings_percent': get_collect_timings(),
                    'is_reviewer': is_reviewer})
    return context