Example #1
0
def download_file(request, file_id, type=None):
    # Fetch what we need with a minimum amount of queries (Transforms on
    # Version and Webapp are avoided). This breaks several things like
    # translations, but it should be fine here, we don't need much to go on.
    file_ = get_object_or_404(File.objects.select_related('version'),
                              pk=file_id)
    webapp = get_object_or_404(Webapp.objects.all().no_transforms(),
                               pk=file_.version.addon_id, is_packaged=True)

    if webapp.is_disabled or file_.status == mkt.STATUS_DISABLED:
        if not acl.check_addon_ownership(request, webapp, viewer=True,
                                         ignore_disabled=True):
            raise http.Http404()

    # We treat blocked files like public files so users get the update.
    if file_.status in [mkt.STATUS_PUBLIC, mkt.STATUS_BLOCKED]:
        path = file_.signed_file_path

    else:
        # This is someone asking for an unsigned packaged app.
        if not acl.check_addon_ownership(request, webapp, dev=True):
            raise http.Http404()

        path = file_.file_path

    log.info('Downloading package: %s from %s' % (webapp.id, path))
    return HttpResponseSendFile(request, path, content_type='application/zip',
                                etag=file_.hash.split(':')[-1])
Example #2
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):
            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):
            raise http.Http404()

        path = file.file_path

    log.info('Downloading package: %s from %s' % (webapp.id, path))
    return HttpResponseSendFile(request,
                                path,
                                content_type='application/zip',
                                etag=file.hash.split(':')[-1])
Example #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
Example #4
0
def in_app_products(request, addon_id, addon, webapp=True, account=None):
    owner = acl.check_addon_ownership(request, addon)
    products = addon.inappproduct_set.all()
    new_product = InAppProduct(webapp=addon)
    form = InAppProductForm()

    if addon.origin:
        inapp_origin = addon.origin
    elif addon.guid:
        # Derive a marketplace specific origin out of the GUID.
        # This is for apps that do not specify a custom origin.
        inapp_origin = 'marketplace:{}'.format(addon.guid)
    else:
        # Theoretically this is highly unlikely. A hosted app will
        # always have a domain and a packaged app will always have
        # a generated GUID.
        raise TypeError(
            'Cannot derive origin: no declared origin, no GUID')

    list_url = _fix_origin_link(reverse('in-app-products-list',
                                        kwargs={'origin': inapp_origin}))
    detail_url = _fix_origin_link(reverse('in-app-products-detail',
                                          # {guid} is replaced in JS.
                                          kwargs={'origin': inapp_origin,
                                                  'guid': "{guid}"}))

    return render(request, 'developers/payments/in-app-products.html',
                  {'addon': addon, 'form': form, 'new_product': new_product,
                   'owner': owner, 'products': products, 'form': form,
                   'list_url': list_url, 'detail_url': detail_url,
                   'active_lang': request.LANG.lower()})
Example #5
0
def in_app_products(request, addon_id, addon, webapp=True, account=None):
    owner = acl.check_addon_ownership(request, addon)
    products = addon.inappproduct_set.all()
    new_product = InAppProduct(webapp=addon)
    form = InAppProductForm()
    list_url = None
    detail_url = None
    if addon.origin:
        list_url = _fix_origin_link(reverse("in-app-products-list", kwargs={"origin": addon.origin}))
        detail_url = _fix_origin_link(
            reverse(
                "in-app-products-detail",
                # {guid} is replaced in JS.
                kwargs={"origin": addon.origin, "guid": "{guid}"},
            )
        )
    return render(
        request,
        "developers/payments/in-app-products.html",
        {
            "addon": addon,
            "form": form,
            "new_product": new_product,
            "owner": owner,
            "products": products,
            "form": form,
            "list_url": list_url,
            "detail_url": detail_url,
            "active_lang": request.LANG.lower(),
        },
    )
Example #6
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
Example #7
0
        def wrapper(request, addon, *args, **kw):
            from mkt.submit.views import _resume
            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()

            raise PermissionDenied
Example #8
0
def in_app_products(request, addon_id, addon, webapp=True, account=None):
    owner = acl.check_addon_ownership(request, addon)
    products = addon.inappproduct_set.all()
    new_product = InAppProduct(webapp=addon)
    form = InAppProductForm()
    return render(request, 'developers/payments/in-app-products.html',
                  {'addon': addon, 'form': form, 'new_product': new_product,
                   'owner': owner, 'products': products, 'form': form})
Example #9
0
def in_app_products(request, addon_id, addon, webapp=True, account=None):
    owner = acl.check_addon_ownership(request, addon)
    products = addon.inappproduct_set.all()
    new_product = InAppProduct(webapp=addon)
    form = InAppProductForm()
    return render(
        request,
        "developers/payments/in-app-products.html",
        {"addon": addon, "form": form, "new_product": new_product, "owner": owner, "products": products, "form": form},
    )
Example #10
0
        def wrapper(request, addon, *args, **kw):
            from mkt.submit.views import _resume
            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()

            raise PermissionDenied
Example #11
0
    def get_app(self, ident):
        try:
            app = Webapp.objects.by_identifier(ident)
        except Webapp.DoesNotExist:
            raise Http404

        if not app.is_public() and not check_addon_ownership(
                self.request, app):
            # App owners and admin can see the app even if it's not public.
            # Regular users or anonymous users can't.
            raise PermissionDenied('The app requested is not public')
        return app
Example #12
0
    def get_app(self, ident):
        try:
            app = Webapp.objects.by_identifier(ident)
        except Webapp.DoesNotExist:
            raise Http404

        if not app.is_public() and not check_addon_ownership(
                self.request, app):
            # App owners and admin can see the app even if it's not public.
            # Regular users or anonymous users can't.
            raise PermissionDenied('The app requested is not public')
        return app
Example #13
0
 def get_app(self, ident):
     try:
         app = Webapp.objects.by_identifier(ident)
     except Webapp.DoesNotExist:
         raise Http404
     current_region = get_region()
     if ((not app.is_public()
          or not app.listed_in(region=current_region))
          and not check_addon_ownership(self.request, app)):
         # App owners and admin can see the app even if it's not public
         # or not available in the current region. Regular users or
         # anonymous users can't.
         raise PermissionDenied('The app requested is not public or not '
             'available in region "%s".' % current_region.slug)
     return app
Example #14
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):
            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):
            raise http.Http404()

        path = file.file_path

    log.info('Downloading package: %s from %s' % (webapp.id, path))
    return HttpResponseSendFile(request, path, content_type='application/zip',
                                etag=file.hash.split(':')[-1])
Example #15
0
def download_file(request, file_id, type=None):
    # Fetch what we need with a minimum amount of queries (Transforms on
    # Version and Webapp are avoided). This breaks several things like
    # translations, but it should be fine here, we don't need much to go on.
    file_ = get_object_or_404(File.objects.select_related('version'),
                              pk=file_id)
    webapp = get_object_or_404(Webapp.objects.all().no_transforms(),
                               pk=file_.version.addon_id,
                               is_packaged=True)

    if webapp.is_disabled or file_.status in [
            mkt.STATUS_DISABLED, mkt.STATUS_REJECTED
    ]:
        if not acl.check_addon_ownership(
                request, webapp, viewer=True, ignore_disabled=True):
            raise http.Http404()

    # We treat blocked files like public files so users get the update.
    if file_.status in [mkt.STATUS_PUBLIC, mkt.STATUS_BLOCKED]:
        path = file_.signed_file_path
        public = True

    else:
        # This is someone asking for an unsigned packaged app.
        if not acl.check_addon_ownership(request, webapp, dev=True):
            raise http.Http404()

        path = file_.file_path
        public = False

    log.info('Downloading package: %s from %s' % (webapp.id, path))
    return get_file_response(request,
                             path,
                             content_type='application/zip',
                             etag=file_.hash.split(':')[-1],
                             public=public)
Example #16
0
def allowed(request, file):
    allowed = acl.check_reviewer(request)
    if not allowed:
        try:
            addon = file.version.addon
        except ObjectDoesNotExist:
            raise http.Http404

        if 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
Example #17
0
 def get_app(self, ident):
     try:
         app = Webapp.objects.by_identifier(ident)
     except Webapp.DoesNotExist:
         raise Http404
     current_region = get_region()
     if ((not app.is_public() or not app.listed_in(region=current_region))
             and not check_addon_ownership(self.request, app)):
         # App owners and admin can see the app even if it's not public
         # or not available in the current region. Regular users or
         # anonymous users can't.
         raise PermissionDenied(
             'The app requested is not public or not available in region '
             '"%s".' % current_region.slug)
     return app
Example #18
0
def in_app_config(request, addon_id, addon, webapp=True):
    """
    Allows developers to get a key/secret for doing in-app payments.
    """
    config = get_inapp_config(addon)

    owner = acl.check_addon_ownership(request, addon)
    if request.method == "POST":
        # Reset the in-app secret for the app.
        (client.api.generic.product(config["resource_pk"]).patch(data={"secret": generate_key(48)}))
        messages.success(request, _("Changes successfully saved."))
        return redirect(reverse("mkt.developers.apps.in_app_config", args=[addon.app_slug]))

    return render(
        request, "developers/payments/in-app-config.html", {"addon": addon, "owner": owner, "seller_config": config}
    )
Example #19
0
def in_app_products(request, addon_id, addon, webapp=True, account=None):
    owner = acl.check_addon_ownership(request, addon)
    products = addon.inappproduct_set.all()
    new_product = InAppProduct(webapp=addon)
    form = InAppProductForm()
    list_url = None
    detail_url = None
    if addon.origin:
        list_url = _fix_origin_link(reverse('in-app-products-list',
                                            kwargs={'origin': addon.origin}))
        detail_url = _fix_origin_link(reverse('in-app-products-detail',
                                              # {guid} is replaced in JS.
                                              kwargs={'origin': addon.origin,
                                                      'guid': "{guid}"}))
    return render(request, 'developers/payments/in-app-products.html',
                  {'addon': addon, 'form': form, 'new_product': new_product,
                   'owner': owner, 'products': products, 'form': form,
                   'list_url': list_url, 'detail_url': detail_url})
Example #20
0
def allowed(request, file):
    allowed = acl.check_reviewer(request)
    if not allowed:
        try:
            addon = file.version.addon
        except ObjectDoesNotExist:
            raise http.Http404

        if 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
Example #21
0
def in_app_config(request, addon_id, addon, webapp=True):
    """
    Allows developers to get a key/secret for doing in-app payments.
    """
    config = get_inapp_config(addon)

    owner = acl.check_addon_ownership(request, addon)
    if request.method == 'POST':
        # Reset the in-app secret for the app.
        (client.api.generic
               .product(config['resource_pk'])
               .patch(data={'secret': generate_key(48)}))
        messages.success(request, _('Changes successfully saved.'))
        return redirect(reverse('mkt.developers.apps.in_app_config',
                                args=[addon.app_slug]))

    return render(request, 'developers/payments/in-app-config.html',
                  {'addon': addon, 'owner': owner,
                   'seller_config': config})
Example #22
0
def in_app_products(request, addon_id, addon, webapp=True, account=None):
    owner = acl.check_addon_ownership(request, addon)
    products = addon.inappproduct_set.all()
    new_product = InAppProduct(webapp=addon)
    form = InAppProductForm()
    list_url = None
    detail_url = None
    if addon.origin:
        list_url = _fix_origin_link(reverse('in-app-products-list',
                                            kwargs={'origin': addon.origin}))
        detail_url = _fix_origin_link(reverse('in-app-products-detail',
                                              # {guid} is replaced in JS.
                                              kwargs={'origin': addon.origin,
                                                      'guid': "{guid}"}))
    return render(request, 'developers/payments/in-app-products.html',
                  {'addon': addon, 'form': form, 'new_product': new_product,
                   'owner': owner, 'products': products, 'form': form,
                   'list_url': list_url, 'detail_url': detail_url,
                   'active_lang': request.LANG.lower()})
Example #23
0
def in_app_config(request, addon_id, addon, webapp=True):
    """
    Allows developers to get a key/secret for doing in-app payments.
    """
    config = get_inapp_config(addon)

    owner = acl.check_addon_ownership(request, addon)
    if request.method == 'POST':
        # Reset the in-app secret for the app.
        (client.api.generic
               .product(config['resource_pk'])
               .patch(data={'secret': generate_key(48)}))
        messages.success(request, _('Changes successfully saved.'))
        return redirect(reverse('mkt.developers.apps.in_app_config',
                                args=[addon.app_slug]))

    return render(request, 'developers/payments/in-app-config.html',
                  {'addon': addon, 'owner': owner,
                   'seller_config': config})
Example #24
0
def in_app_products(request, addon_id, addon, webapp=True, account=None):
    owner = acl.check_addon_ownership(request, addon)
    products = addon.inappproduct_set.all()
    new_product = InAppProduct(webapp=addon)
    form = InAppProductForm()

    if addon.origin:
        inapp_origin = addon.origin
    elif addon.guid:
        # Derive a marketplace specific origin out of the GUID.
        # This is for apps that do not specify a custom origin.
        inapp_origin = 'marketplace:{}'.format(addon.guid)
    else:
        # Theoretically this is highly unlikely. A hosted app will
        # always have a domain and a packaged app will always have
        # a generated GUID.
        raise TypeError('Cannot derive origin: no declared origin, no GUID')

    list_url = _fix_origin_link(
        reverse('in-app-products-list', kwargs={'origin': inapp_origin}))
    detail_url = _fix_origin_link(
        reverse(
            'in-app-products-detail',
            # {guid} is replaced in JS.
            kwargs={
                'origin': inapp_origin,
                'guid': "{guid}"
            }))

    return render(
        request, 'developers/payments/in-app-products.html', {
            'addon': addon,
            'form': form,
            'new_product': new_product,
            'owner': owner,
            'products': products,
            'form': form,
            'list_url': list_url,
            'detail_url': detail_url,
            'active_lang': request.LANG.lower()
        })
Example #25
0
def addons_section(request, addon_id, addon, section, editable=False):
    models = {
        "basic": AppFormBasic,
        "media": AppFormMedia,
        "details": AppFormDetails,
        "support": AppFormSupport,
        "technical": AppFormTechnical,
        "admin": forms.AdminSettingsForm,
    }

    is_dev = acl.check_addon_ownership(request, addon, dev=True)

    if section not in models:
        raise http.Http404()

    version = addon.current_version or addon.latest_version

    tags, previews, restricted_tags = [], [], []
    cat_form = appfeatures = appfeatures_form = version_form = None
    formdata = request.POST if request.method == "POST" else None

    # Permissions checks.
    # Only app owners can edit any of the details of their apps.
    # Users with 'Apps:Configure' can edit the admin settings.
    if (section != "admin" and not is_dev) or (
        section == "admin"
        and not acl.action_allowed(request, "Apps", "Configure")
        and not acl.action_allowed(request, "Apps", "ViewConfiguration")
    ):
        raise PermissionDenied

    if section == "basic":
        cat_form = CategoryForm(formdata, product=addon, request=request)
        # Only show/use the release notes form for hosted apps, packaged apps
        # can do that from the version edit page.
        if not addon.is_packaged:
            version_form = AppVersionForm(formdata, instance=version)

    elif section == "media":
        previews = PreviewFormSet(request.POST or None, prefix="files", queryset=addon.get_previews())

    elif section == "technical":
        # Only show/use the features form for hosted apps, packaged apps
        # can do that from the version edit page.
        if not addon.is_packaged:
            appfeatures = version.features
            appfeatures_form = AppFeaturesForm(formdata, instance=appfeatures)

    elif section == "admin":
        tags = addon.tags.not_blacklisted().values_list("tag_text", flat=True)
        restricted_tags = addon.tags.filter(restricted=True)

    # Get the slug before the form alters it to the form data.
    valid_slug = addon.app_slug
    if editable:
        if request.method == "POST":

            if section == "admin" and not acl.action_allowed(request, "Apps", "Configure"):
                raise PermissionDenied

            form = models[section](formdata, request.FILES, instance=addon, version=version, request=request)

            all_forms = [form, previews]
            for additional_form in (appfeatures_form, cat_form, version_form):
                if additional_form:
                    all_forms.append(additional_form)

            if all(not f or f.is_valid() for f in all_forms):
                if cat_form:
                    cat_form.save()

                addon = form.save(addon)

                if appfeatures_form:
                    appfeatures_form.save()

                if version_form:
                    # We are re-using version_form without displaying all its
                    # fields, so we need to override the boolean fields,
                    # otherwise they'd be considered empty and therefore False.
                    version_form.cleaned_data["publish_immediately"] = version_form.fields[
                        "publish_immediately"
                    ].initial
                    version_form.save()

                if "manifest_url" in form.changed_data:
                    addon.update(app_domain=addon.domain_from_url(addon.manifest_url))
                    update_manifests([addon.pk])

                if previews:
                    for preview in previews.forms:
                        preview.save(addon)

                editable = False
                if section == "media":
                    amo.log(amo.LOG.CHANGE_ICON, addon)
                else:
                    amo.log(amo.LOG.EDIT_PROPERTIES, addon)

                valid_slug = addon.app_slug
        else:
            form = models[section](instance=addon, version=version, request=request)
    else:
        form = False

    data = {
        "addon": addon,
        "version": version,
        "form": form,
        "editable": editable,
        "tags": tags,
        "restricted_tags": restricted_tags,
        "cat_form": cat_form,
        "version_form": version_form,
        "preview_form": previews,
        "valid_slug": valid_slug,
    }

    if appfeatures_form and appfeatures:
        data.update(
            {
                "appfeatures": appfeatures,
                "feature_list": [unicode(f) for f in appfeatures.to_list()],
                "appfeatures_form": appfeatures_form,
            }
        )

    return render(request, "developers/apps/edit/%s.html" % section, data)
Example #26
0
def addons_section(request, addon_id, addon, section, editable=False):
    models = {
        'basic': AppFormBasic,
        'media': AppFormMedia,
        'details': AppFormDetails,
        'support': AppFormSupport,
        'technical': AppFormTechnical,
        'admin': forms.AdminSettingsForm
    }

    is_dev = acl.check_addon_ownership(request, addon, dev=True)

    if section not in models:
        raise http.Http404()

    version = addon.current_version or addon.latest_version

    tags, previews, restricted_tags = [], [], []
    cat_form = appfeatures = appfeatures_form = version_form = None
    formdata = request.POST if request.method == 'POST' else None

    # Permissions checks.
    # Only app owners can edit any of the details of their apps.
    # Users with 'Apps:Configure' can edit the admin settings.
    if (section != 'admin' and not is_dev) or (
            section == 'admin'
            and not acl.action_allowed(request, 'Apps', 'Configure')
            and not acl.action_allowed(request, 'Apps', 'ViewConfiguration')):
        raise PermissionDenied

    if section == 'basic':
        cat_form = CategoryForm(formdata, product=addon, request=request)
        # Only show/use the release notes form for hosted apps, packaged apps
        # can do that from the version edit page.
        if not addon.is_packaged:
            version_form = AppVersionForm(formdata, instance=version)

    elif section == 'media':
        previews = PreviewFormSet(request.POST or None,
                                  prefix='files',
                                  queryset=addon.get_previews())

    elif section == 'technical':
        # Only show/use the features form for hosted apps, packaged apps
        # can do that from the version edit page.
        if not addon.is_packaged:
            appfeatures = version.features
            appfeatures_form = AppFeaturesForm(formdata, instance=appfeatures)

    elif section == 'admin':
        tags = addon.tags.not_blacklisted().values_list('tag_text', flat=True)
        restricted_tags = addon.tags.filter(restricted=True)

    # Get the slug before the form alters it to the form data.
    valid_slug = addon.app_slug
    if editable:
        if request.method == 'POST':

            if (section == 'admin'
                    and not acl.action_allowed(request, 'Apps', 'Configure')):
                raise PermissionDenied

            form = models[section](formdata,
                                   request.FILES,
                                   instance=addon,
                                   version=version,
                                   request=request)

            all_forms = [form, previews]
            for additional_form in (appfeatures_form, cat_form, version_form):
                if additional_form:
                    all_forms.append(additional_form)

            if all(not f or f.is_valid() for f in all_forms):
                if cat_form:
                    cat_form.save()

                addon = form.save(addon)

                if appfeatures_form:
                    appfeatures_form.save()

                if version_form:
                    # We are re-using version_form without displaying all its
                    # fields, so we need to override the boolean fields,
                    # otherwise they'd be considered empty and therefore False.
                    version_form.cleaned_data['publish_immediately'] = (
                        version_form.fields['publish_immediately'].initial)
                    version_form.save()

                if 'manifest_url' in form.changed_data:
                    addon.update(
                        app_domain=addon.domain_from_url(addon.manifest_url))
                    update_manifests([addon.pk])

                if previews:
                    for preview in previews.forms:
                        preview.save(addon)

                editable = False
                if section == 'media':
                    amo.log(amo.LOG.CHANGE_ICON, addon)
                else:
                    amo.log(amo.LOG.EDIT_PROPERTIES, addon)

                valid_slug = addon.app_slug
        else:
            form = models[section](instance=addon,
                                   version=version,
                                   request=request)
    else:
        form = False

    data = {
        'addon': addon,
        'version': version,
        'form': form,
        'editable': editable,
        'tags': tags,
        'restricted_tags': restricted_tags,
        'cat_form': cat_form,
        'version_form': version_form,
        'preview_form': previews,
        'valid_slug': valid_slug,
    }

    if appfeatures_form and appfeatures:
        data.update({
            'appfeatures': appfeatures,
            'feature_list': [unicode(f) for f in appfeatures.to_list()],
            'appfeatures_form': appfeatures_form
        })

    return render(request, 'developers/apps/edit/%s.html' % section, data)
Example #27
0
def addons_section(request, addon_id, addon, section, editable=False):
    basic = AppFormBasic
    models = {'basic': basic,
              'media': AppFormMedia,
              'details': AppFormDetails,
              'support': AppFormSupport,
              'technical': AppFormTechnical,
              'admin': forms.AdminSettingsForm}

    is_dev = acl.check_addon_ownership(request, addon, dev=True)

    if section not in models:
        raise http.Http404()

    version = addon.current_version or addon.latest_version

    tags, previews, restricted_tags = [], [], []
    cat_form = appfeatures = appfeatures_form = version_form = None
    formdata = request.POST if request.method == 'POST' else None

    # Permissions checks.
    # Only app owners can edit any of the details of their apps.
    # Users with 'Apps:Configure' can edit the admin settings.
    if (section != 'admin' and not is_dev) or (section == 'admin' and
        not acl.action_allowed(request, 'Apps', 'Configure') and
        not acl.action_allowed(request, 'Apps', 'ViewConfiguration')):
        raise PermissionDenied

    if section == 'basic':
        cat_form = CategoryForm(formdata, product=addon, request=request)
        # Only show/use the release notes form for hosted apps, packaged apps
        # can do that from the version edit page.
        if not addon.is_packaged:
            version_form = AppVersionForm(formdata, instance=version)

    elif section == 'media':
        previews = PreviewFormSet(
            request.POST or None, prefix='files',
            queryset=addon.get_previews())

    elif section == 'technical':
        # Only show/use the features form for hosted apps, packaged apps
        # can do that from the version edit page.
        if not addon.is_packaged:
            appfeatures = version.features
            appfeatures_form = AppFeaturesForm(formdata, instance=appfeatures)

    elif section == 'admin':
        tags = addon.tags.not_blacklisted().values_list('tag_text', flat=True)
        restricted_tags = addon.tags.filter(restricted=True)

    # Get the slug before the form alters it to the form data.
    valid_slug = addon.app_slug
    if editable:
        if request.method == 'POST':

            if (section == 'admin' and
                not acl.action_allowed(request, 'Apps', 'Configure')):
                raise PermissionDenied

            form = models[section](formdata, request.FILES,
                                   instance=addon, request=request)

            all_forms = [form, previews]
            for additional_form in (appfeatures_form, cat_form, version_form):
                if additional_form:
                    all_forms.append(additional_form)

            if all(not f or f.is_valid() for f in all_forms):
                if cat_form:
                    cat_form.save()

                addon = form.save(addon)

                if appfeatures_form:
                    appfeatures_form.save()

                if version_form:
                    # We are re-using version_form without displaying all its
                    # fields, so we need to override the boolean fields,
                    # otherwise they'd be considered empty and therefore False.
                    version_form.cleaned_data['publish_immediately'] = (
                        version_form.fields['publish_immediately'].initial)
                    version_form.save()

                if 'manifest_url' in form.changed_data:
                    addon.update(
                        app_domain=addon.domain_from_url(addon.manifest_url))
                    update_manifests([addon.pk])

                if previews:
                    for preview in previews.forms:
                        preview.save(addon)

                editable = False
                if section == 'media':
                    amo.log(amo.LOG.CHANGE_ICON, addon)
                else:
                    amo.log(amo.LOG.EDIT_PROPERTIES, addon)

                valid_slug = addon.app_slug
        else:
            form = models[section](instance=addon, request=request)
    else:
        form = False

    data = {'addon': addon,
            'version': version,
            'form': form,
            'editable': editable,
            'tags': tags,
            'restricted_tags': restricted_tags,
            'cat_form': cat_form,
            'version_form': version_form,
            'preview_form': previews,
            'valid_slug': valid_slug, }

    if appfeatures_form and appfeatures:
        data.update({
            'appfeatures': appfeatures,
            'feature_list': [unicode(f) for f in appfeatures.to_list()],
            'appfeatures_form': appfeatures_form
        })

    return render(request, 'developers/apps/edit/%s.html' % section, data)