Beispiel #1
0
    def get_and_check_ownership(self, request, allow_anon=False, **kwargs):
        try:
            # Use queryset, not get_object_list to ensure a distinction
            # between a 404 and a 403.
            obj = self._meta.queryset.get(**kwargs)
        except self._meta.object_class.DoesNotExist:
            unavail = self._meta.queryset_base.filter(**kwargs)
            if unavail.exists():
                obj = unavail[0]
                # Owners can see their app no matter what region.
                if AppOwnerAuthorization().is_authorized(request, object=obj):
                    return obj
                data = {}
                for key in ('name', 'support_email', 'support_url'):
                    value = getattr(obj, key)
                    data[key] = unicode(value) if value else ''
                raise http_error(HttpLegallyUnavailable,
                                 'Not available in your region.',
                                 extra_data=data)
            raise http_error(http.HttpNotFound,
                             'No such app.')

        # If it's public, just return it.
        if allow_anon and obj.is_public():
            return obj

        # Now do the final check to see if you are allowed to see it and
        # return a 403 if you can't.
        if not AppOwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You do not own that app.')
        return obj
Beispiel #2
0
    def obj_create(self, bundle, request=None, **kwargs):
        """
        Handle POST requests to the resource. If the data validates, create a
        new Review from bundle data.
        """
        form = ReviewForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        app = self.get_app(bundle.data["app"])

        # Return 409 if the user has already reviewed this app.
        qs = self._meta.queryset.filter(addon=app, user=request.user)
        if app.is_packaged:
            qs = qs.filter(version_id=bundle.data.get("version", app.current_version.id))
        if qs.exists():
            raise http_error(http.HttpConflict, "You have already reviewed this app.")

        # Return 403 if the user is attempting to review their own app:
        if app.has_author(request.user):
            raise http_error(http.HttpForbidden, "You may not review your own app.")

        # Return 403 if not a free app and the user hasn't purchased it.
        if app.is_premium() and not app.is_purchased(request.amo_user):
            raise http_error(http.HttpForbidden, "You may not review paid apps you haven't purchased.")

        bundle.obj = Review.objects.create(**self._review_data(request, app, form))

        amo.log(amo.LOG.ADD_REVIEW, app, bundle.obj)
        log.debug("[Review:%s] Created by user %s " % (bundle.obj.id, request.user.id))
        record_action("new-review", request, {"app-id": app.id})

        return bundle
Beispiel #3
0
    def handle(self, bundle, request, **kwargs):
        form = ReceiptForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        bundle.obj = form.cleaned_data["app"]
        type_ = install_type(request, bundle.obj)

        if type_ == apps.INSTALL_TYPE_DEVELOPER:
            return self.record(bundle, request, apps.INSTALL_TYPE_DEVELOPER)

        # The app must be public and if its a premium app, you
        # must have purchased it.
        if not bundle.obj.is_public():
            log.info("App not public: %s" % bundle.obj.pk)
            raise http_error(http.HttpForbidden, "App not public.")

        if bundle.obj.is_premium() and not bundle.obj.has_purchased(request.amo_user):
            # Apps that are premium but have no charge will get an
            # automatic purchase record created. This will ensure that
            # the receipt will work into the future if the price changes.
            if bundle.obj.premium and not bundle.obj.premium.price.price:
                log.info("Create purchase record: {0}".format(bundle.obj.pk))
                AddonPurchase.objects.get_or_create(addon=bundle.obj, user=request.amo_user, type=CONTRIB_NO_CHARGE)
            else:
                log.info("App not purchased: %s" % bundle.obj.pk)
                raise http_error(HttpPaymentRequired, "You have not purchased this app.")

        return self.record(bundle, request, type_)
Beispiel #4
0
    def get_and_check_ownership(self, request, allow_anon=False, **kwargs):
        try:
            # Use queryset, not get_object_list to ensure a distinction
            # between a 404 and a 403.
            obj = self._meta.queryset.get(**kwargs)
        except self._meta.object_class.DoesNotExist:
            unavail = self._meta.queryset_base.filter(**kwargs)
            if unavail.exists():
                obj = unavail[0]
                # Owners can see their app no matter what region.
                if AppOwnerAuthorization().is_authorized(request, object=obj):
                    return obj
                raise http_error(HttpLegallyUnavailable,
                                 'Not available in your region.')
            raise http_error(http.HttpNotFound,
                             'No such app.')

        # If it's public, just return it.
        if allow_anon and obj.is_public():
            return obj

        # Now do the final check to see if you are allowed to see it and
        # return a 403 if you can't.
        if not AppOwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You do not own that app.')
        return obj
Beispiel #5
0
    def obj_create(self, bundle, request, **kwargs):
        form = UploadForm(bundle.data)

        if not request.amo_user.read_dev_agreement:
            log.info(u'Attempt to use API without dev agreement: %s'
                     % request.amo_user.pk)
            raise http_error(http.HttpUnauthorized,
                             'Terms of service not accepted.')

        if not form.is_valid():
            raise self.form_errors(form)

        if not (OwnerAuthorization()
                .is_authorized(request, object=form.obj)):
            raise http_error(http.HttpForbidden,
                             'You do not own that app.')

        plats = [Platform.objects.get(id=amo.PLATFORM_ALL.id)]

        # Create app, user and fetch the icon.
        bundle.obj = Addon.from_upload(form.obj, plats,
                                       is_packaged=form.is_packaged)
        AddonUser(addon=bundle.obj, user=request.amo_user).save()

        self._icons_and_images(bundle.obj)
        record_action('app-submitted', request, {'app-id': bundle.obj.pk})

        log.info('App created: %s' % bundle.obj.pk)
        return bundle
Beispiel #6
0
    def obj_create(self, bundle, request, **kwargs):
        form = UploadForm(bundle.data)

        if not request.amo_user.read_dev_agreement:
            log.info(u'Attempt to use API without dev agreement: %s'
                     % request.amo_user.pk)
            raise http_error(http.HttpUnauthorized,
                             'Terms of service not accepted.')

        if not form.is_valid():
            raise self.form_errors(form)

        if not (OwnerAuthorization()
                .is_authorized(request, object=form.obj)):
            raise http_error(http.HttpForbidden,
                             'You do not own that app.')

        plats = [Platform.objects.get(id=amo.PLATFORM_ALL.id)]

        # Create app, user and fetch the icon.
        bundle.obj = Addon.from_upload(form.obj, plats,
                                       is_packaged=form.is_packaged)
        AddonUser(addon=bundle.obj, user=request.amo_user).save()

        self._icons_and_images(bundle.obj)
        record_action('app-submitted', request, {'app-id': bundle.obj.pk})

        log.info('App created: %s' % bundle.obj.pk)
        return bundle
Beispiel #7
0
    def build_filters(self, filters=None):
        """
        If `addon__exact` is a filter and its value cannot be coerced into an
        int, assume that it's a slug lookup.

        Run the query necessary to determine the app, and substitute the slug
        with the PK in the filter so tastypie will continue doing its thing.
        """
        built = super(RatingResource, self).build_filters(filters)
        if 'addon__exact' in built:
            try:
                int(built['addon__exact'])
            except ValueError:
                app = self.get_app(built['addon__exact'])
                if app:
                    built['addon__exact'] = str(app.pk)

        if built.get('user__exact', None) == 'mine':
            # This is a cheat. Would prefer /mine/ in the URL.
            user = get_user()
            if not user:
                # You must be logged in to use "mine".
                raise http_error(http.HttpUnauthorized,
                                 'You must be logged in to access "mine".')

            built['user__exact'] = user.pk
        return built
Beispiel #8
0
 def get_object_list(self, request):
     if not request.amo_user:
         log.info('Anonymous listing not allowed')
         raise http_error(http.HttpForbidden,
                          'Anonymous listing not allowed.')
     return self._meta.queryset.filter(type=amo.ADDON_WEBAPP,
                                       authors=request.amo_user)
Beispiel #9
0
    def obj_create(self, bundle, request, **kwargs):
        with statsd.timer("auth.browserid.verify"):
            profile, msg = browserid_authenticate(
                request,
                bundle.data["assertion"],
                browserid_audience=bundle.data["audience"],
                is_native=bundle.data.get("is_native", False),
            )
        if profile is None:
            log.info("No profile")
            raise http_error(http.HttpUnauthorized, "No profile.")

        request.user, request.amo_user = profile.user, profile
        request.groups = profile.groups.all()

        # TODO: move this to the signal.
        profile.log_login_attempt(True)
        user_logged_in.send(sender=profile.user.__class__, request=request, user=profile.user)
        bundle.data = {
            "error": None,
            "token": self.get_token(request.user.email),
            "settings": {"display_name": request.amo_user.display_name, "email": request.user.email},
        }
        bundle.data.update(PermissionResource().dehydrate(Bundle(request=request)).data)
        return bundle
Beispiel #10
0
    def obj_create(self, bundle, request, **kwargs):
        # Ensure that people don't pass strings through.
        args = PreviewArgsForm(request.GET)
        if not args.is_valid():
            raise self.form_errors(args)

        addon = self.get_object_or_404(Addon,
                                       pk=args.cleaned_data['app'],
                                       type=amo.ADDON_WEBAPP)
        if not AppOwnerAuthorization().is_authorized(request, object=addon):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        data_form = PreviewJSONForm(bundle.data)
        if not data_form.is_valid():
            raise self.form_errors(data_form)

        form = PreviewForm(data_form.cleaned_data)
        if not form.is_valid():
            raise self.form_errors(form)

        form.save(addon)
        bundle.obj = form.instance
        log.info('Preview created: %s' % bundle.obj.pk)
        return bundle
Beispiel #11
0
    def build_filters(self, filters=None):
        """
        If `addon__exact` is a filter and its value cannot be coerced into an
        int, assume that it's a slug lookup.

        Run the query necessary to determine the app, and substitute the slug
        with the PK in the filter so tastypie will continue doing its thing.
        """
        built = super(RatingResource, self).build_filters(filters)
        if 'addon__exact' in built:
            try:
                int(built['addon__exact'])
            except ValueError:
                app = self.get_app(built['addon__exact'])
                if app:
                    built['addon__exact'] = str(app.pk)

        if built.get('user__exact', None) == 'mine':
            # This is a cheat. Would prefer /mine/ in the URL.
            user = get_user()
            if not user:
                # You must be logged in to use "mine".
                raise http_error(http.HttpUnauthorized, 'You must be logged in to access "mine".')

            built['user__exact'] = user.pk
        return built
Beispiel #12
0
 def get_object_list(self, request):
     if not request.amo_user:
         log.info('Anonymous listing not allowed')
         raise http_error(http.HttpForbidden,
                          'Anonymous listing not allowed.')
     return self._meta.queryset.filter(type=amo.ADDON_WEBAPP,
                                       authors=request.amo_user)
Beispiel #13
0
    def obj_update(self, bundle, request, **kwargs):
        """
        Handle PUT requests to the resource. If authorized and the data
        validates, update the indicated resource with bundle data.
        """
        obj = self.get_by_resource_or_404(request, **kwargs)
        if not OwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(
                http.HttpForbidden,
                'You do not have permission to update this review.')

        form = ReviewForm(bundle.data)
        if not form.is_valid():
            raise self.form_errors(form)

        if 'app' in bundle.data:
            error = ('app', "Cannot update a rating's `app`")
            raise self.non_form_errors([error])

        sup = super(RatingResource, self).obj_update(bundle, request, **kwargs)

        amo.log(amo.LOG.EDIT_REVIEW, bundle.obj.addon, bundle.obj)
        log.debug('[Review:%s] Edited by %s' % (bundle.obj.id, request.user.id))

        return sup
Beispiel #14
0
    def obj_create(self, bundle, request, **kwargs):
        # Ensure that people don't pass strings through.
        args = PreviewArgsForm(request.GET)
        if not args.is_valid():
            raise self.form_errors(args)

        addon = self.get_object_or_404(Addon,
                                       pk=args.cleaned_data['app'],
                                       type=amo.ADDON_WEBAPP)
        if not AppOwnerAuthorization().is_authorized(request, object=addon):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        data_form = PreviewJSONForm(bundle.data)
        if not data_form.is_valid():
            raise self.form_errors(data_form)

        form = PreviewForm(data_form.cleaned_data)
        if not form.is_valid():
            raise self.form_errors(form)

        form.save(addon)
        bundle.obj = form.instance
        log.info('Preview created: %s' % bundle.obj.pk)
        return bundle
Beispiel #15
0
    def dispatch(self, request_type, request, **kwargs):
        if not waffle.switch_is_active('stats-api'):
            raise http_error(http.HttpNotImplemented,
                             'Stats not enabled for this host.')

        return super(GlobalStatsResource, self).dispatch(request_type, request,
                                                         **kwargs)
Beispiel #16
0
    def obj_create(self, bundle, request, **kwargs):
        with statsd.timer('auth.browserid.verify'):
            profile, msg = browserid_authenticate(
                request,
                bundle.data['assertion'],
                browserid_audience=bundle.data['audience'],
                is_native=bundle.data.get('is_native', False))
        if profile is None:
            log.info('No profile')
            raise http_error(http.HttpUnauthorized, 'No profile.')

        request.user, request.amo_user = profile.user, profile
        request.groups = profile.groups.all()

        # TODO: move this to the signal.
        profile.log_login_attempt(True)
        user_logged_in.send(sender=profile.user.__class__,
                            request=request,
                            user=profile.user)
        bundle.data = {
            'error': None,
            'token': self.get_token(request.user.email),
            'settings': {
                'display_name': request.amo_user.display_name,
                'email': request.user.email,
            }
        }
        bundle.data.update(PermissionResource().dehydrate(
            Bundle(request=request)).data)
        return bundle
Beispiel #17
0
    def obj_create(self, bundle, request, **kwargs):
        with statsd.timer('auth.browserid.verify'):
            profile, msg = browserid_authenticate(
                request, bundle.data['assertion'],
                browserid_audience=bundle.data['audience'],
                is_native=bundle.data.get('is_native', False)
            )
        if profile is None:
            log.info('No profile: %s' % (msg or ''))
            raise http_error(http.HttpUnauthorized,
                             'No profile.')

        request.user, request.amo_user = profile.user, profile
        request.groups = profile.groups.all()

        # TODO: move this to the signal.
        profile.log_login_attempt(True)
        user_logged_in.send(sender=profile.user.__class__, request=request,
                            user=profile.user)
        bundle.data = {
            'error': None,
            'token': self.get_token(request.amo_user.email),
            'settings': {
                'display_name': request.amo_user.display_name,
                'email': request.amo_user.email,
            }
        }
        bundle.data.update(PermissionResource()
                           .dehydrate(Bundle(request=request)).data)
        return bundle
Beispiel #18
0
    def obj_get(self, request=None, **kwargs):
        obj = super(StatusResource, self).obj_get(request=request, **kwargs)
        if not AppOwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        log.info('App status retreived: %s' % obj.pk)
        return obj
Beispiel #19
0
    def obj_get(self, request=None, **kwargs):
        obj = super(StatusResource, self).obj_get(request=request, **kwargs)
        if not AppOwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        log.info('App status retreived: %s' % obj.pk)
        return obj
Beispiel #20
0
    def obj_delete(self, request, **kwargs):
        obj = self.get_by_resource_or_404(request, **kwargs)
        if not AppOwnerAuthorization().is_authorized(request,
                                                     object=obj.addon):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        log.info('Preview deleted: %s' % obj.pk)
        return super(PreviewResource, self).obj_delete(request, **kwargs)
Beispiel #21
0
    def obj_update(self, bundle, request, **kwargs):
        try:
            obj = self.get_object_list(bundle.request).get(**kwargs)
        except Addon.DoesNotExist:
            raise http_error(http.HttpNotFound, 'No such addon.')

        if not AppOwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        form = StatusForm(bundle.data, instance=obj)
        if not form.is_valid():
            raise self.form_errors(form)

        form.save()
        log.info('App status updated: %s' % obj.pk)
        bundle.obj = obj
        return bundle
Beispiel #22
0
    def obj_delete(self, request, **kwargs):
        obj = self.get_by_resource_or_404(request, **kwargs)
        if not AppOwnerAuthorization().is_authorized(request,
                                                     object=obj.addon):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        log.info('Preview deleted: %s' % obj.pk)
        return super(PreviewResource, self).obj_delete(request, **kwargs)
Beispiel #23
0
    def obj_get(self, request=None, **kwargs):
        if kwargs.get("pk") == "mine":
            kwargs["pk"] = request.amo_user.pk

        # TODO: put in acl checks for admins to get other users information.
        obj = super(Mine, self).obj_get(request=request, **kwargs)
        if not OwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden, "You do not have access to that account.")
        return obj
Beispiel #24
0
    def obj_update(self, bundle, request, **kwargs):
        try:
            obj = self.get_object_list(bundle.request).get(**kwargs)
        except Addon.DoesNotExist:
            raise http_error(http.HttpNotFound, 'No such addon.')

        if not AppOwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        form = StatusForm(bundle.data, instance=obj)
        if not form.is_valid():
            raise self.form_errors(form)

        form.save()
        log.info('App status updated: %s' % obj.pk)
        bundle.obj = obj
        return bundle
Beispiel #25
0
    def obj_get(self, request=None, **kwargs):
        if kwargs.get('pk') == 'mine':
            kwargs['pk'] = request.amo_user.pk

        # TODO: put in acl checks for admins to get other users information.
        obj = super(Mine, self).obj_get(request=request, **kwargs)
        if not OwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You do not have access to that account.')
        return obj
Beispiel #26
0
    def obj_get(self, request, **kw):
        if kw['pk'] != 'site':
            raise http_error(http.HttpNotFound, 'No such configuration.')

        return GenericObject({
            # This is the git commit on IT servers.
            'version': getattr(settings, 'BUILD_ID_JS', ''),
            'flags': waffles(request),
            'settings': get_settings(),
        })
Beispiel #27
0
    def obj_get(self, request, **kw):
        if kw['pk'] != 'site':
            raise http_error(http.HttpNotFound,
                             'No such configuration.')

        return GenericObject({
            # This is the git commit on IT servers.
            'version': getattr(settings, 'BUILD_ID_JS', ''),
            'flags': waffles(request),
            'settings': get_settings(),
        })
Beispiel #28
0
    def obj_get(self, request=None, **kwargs):
        # Until the perms branch lands, this is the only way to lock
        # permissions down on gets, since the object doesn't actually
        # get passed through to OwnerAuthorization.
        try:
            obj = FileUpload.objects.get(pk=kwargs['pk'])
        except FileUpload.DoesNotExist:
            raise http_error(http.HttpNotFound, 'No upload with that ID.')

        log.info('Validation retreived: %s' % obj.pk)
        return obj
Beispiel #29
0
    def obj_get(self, request=None, **kwargs):
        # Until the perms branch lands, this is the only way to lock
        # permissions down on gets, since the object doesn't actually
        # get passed through to OwnerAuthorization.
        try:
            obj = FileUpload.objects.get(pk=kwargs['pk'])
        except FileUpload.DoesNotExist:
            raise http_error(http.HttpNotFound, 'No upload with that ID.')

        log.info('Validation retreived: %s' % obj.pk)
        return obj
Beispiel #30
0
    def obj_create(self, bundle, request=None, **kwargs):
        """
        Handle POST requests to the resource. If the data validates, create a
        new Review from bundle data.
        """
        form = ReviewForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        app = self.get_app(bundle.data['app'])

        # Return 409 if the user has already reviewed this app.
        qs = self._meta.queryset.filter(addon=app, user=request.user)
        if app.is_packaged:
            qs = qs.filter(
                version_id=bundle.data.get('version', app.current_version.id))
        if qs.exists():
            raise http_error(http.HttpConflict,
                             'You have already reviewed this app.')

        # Return 403 if the user is attempting to review their own app:
        if app.has_author(request.user):
            raise http_error(http.HttpForbidden,
                             'You may not review your own app.')

        # Return 403 if not a free app and the user hasn't purchased it.
        if app.is_premium() and not app.is_purchased(request.amo_user):
            raise http_error(
                http.HttpForbidden,
                "You may not review paid apps you haven't purchased.")

        bundle.obj = Review.objects.create(
            **self._review_data(request, app, form))

        amo.log(amo.LOG.ADD_REVIEW, app, bundle.obj)
        log.debug('[Review:%s] Created by user %s ' %
                  (bundle.obj.id, request.user.id))
        record_action('new-review', request, {'app-id': app.id})

        return bundle
Beispiel #31
0
    def obj_delete(self, request, **kwargs):
        obj = self.get_by_resource_or_404(request, **kwargs)
        if not (
            AppOwnerAuthorization().is_authorized(request, object=obj.addon)
            or OwnerAuthorization().is_authorized(request, object=obj)
            or PermissionAuthorization("Users", "Edit").is_authorized(request)
            or PermissionAuthorization("Addons", "Edit").is_authorized(request)
        ):
            raise http_error(http.HttpForbidden, "You do not have permission to delete this review.")

        log.info("Rating %s deleted from addon %s" % (obj.pk, obj.addon.pk))
        return super(RatingResource, self).obj_delete(request, **kwargs)
Beispiel #32
0
    def obj_get(self, request, **kw):
        if kw["pk"] != "site":
            raise http_error(http.HttpNotFound, "No such configuration.")

        return GenericObject(
            {
                # This is the git commit on IT servers.
                "version": getattr(settings, "BUILD_ID_JS", ""),
                "flags": waffles(request),
                "settings": get_settings(),
            }
        )
Beispiel #33
0
 def post_list(self, request, **kwargs):
     data = self.deserialize(request, request.raw_post_data,
                             format='application/json')
     email = data['email']
     try:
         validate_email(email)
     except ValidationError:
         raise http_error(http.HttpBadRequest, 'Invalid email address')
     basket.subscribe(data['email'], 'marketplace',
                      format='H', country=request.REGION.slug,
                      lang=request.LANG, optin='Y',
                      trigger_welcome='Y')
Beispiel #34
0
 def post_list(self, request, **kwargs):
     data = self.deserialize(request, request.raw_post_data,
                             format='application/json')
     email = data['email']
     try:
         validate_email(email)
     except ValidationError:
         raise http_error(http.HttpBadRequest, 'Invalid email address')
     basket.subscribe(data['email'], 'marketplace',
                      format='H', country=request.REGION.slug,
                      lang=request.LANG, optin='Y',
                      trigger_welcome='Y')
Beispiel #35
0
    def obj_create(self, bundle, request, **kwargs):
        region = getattr(request, 'REGION', None)

        if region and region.id not in settings.PURCHASE_ENABLED_REGIONS:
            log.info('Region {0} is not in {1}'.format(
                region.id, settings.PURCHASE_ENABLED_REGIONS))
            if not waffle.flag_is_active(request, 'allow-paid-app-search'):
                log.info('Flag not active')
                raise http_error(http.HttpForbidden,
                                 'Not allowed to purchase for this flag')

        bundle.obj = GenericObject(_prepare_pay(request, bundle.data['app']))
        return bundle
Beispiel #36
0
    def obj_create(self, bundle, request, **kwargs):
        region = getattr(request, 'REGION', None)

        if region and region.id not in settings.PURCHASE_ENABLED_REGIONS:
            log.info('Region {0} is not in {1}'
                     .format(region.id, settings.PURCHASE_ENABLED_REGIONS))
            if not waffle.flag_is_active(request, 'allow-paid-app-search'):
                log.info('Flag not active')
                raise http_error(http.HttpForbidden,
                                 'Not allowed to purchase for this flag')

        bundle.obj = GenericObject(_prepare_pay(request, bundle.data['app']))
        return bundle
Beispiel #37
0
    def get_and_check_ownership(self, request, allow_anon=False, **kwargs):
        try:
            # Use queryset, not get_object_list to ensure a distinction
            # between a 404 and a 403.
            obj = self._meta.queryset.get(**kwargs)
        except self._meta.object_class.DoesNotExist:
            unavail = self._meta.queryset_base.filter(**kwargs).exists()
            if unavail:
                raise http_error(HttpLegallyUnavailable,
                                 'Not available in your region.')
            raise http_error(http.HttpNotFound,
                             'No such app.')

        # If it's public, just return it.
        if allow_anon and obj.is_public():
            return obj

        # Now do the final check to see if you are allowed to see it and
        # return a 403 if you can't.
        if not AppOwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You do not own that app.')
        return obj
Beispiel #38
0
    def obj_delete(self, request, **kwargs):
        obj = self.get_by_resource_or_404(request, **kwargs)
        if not (AppOwnerAuthorization().is_authorized(request,
                                                      object=obj.addon)
                or OwnerAuthorization().is_authorized(request, object=obj) or
                PermissionAuthorization('Users', 'Edit').is_authorized(request)
                or PermissionAuthorization('Addons',
                                           'Edit').is_authorized(request)):
            raise http_error(
                http.HttpForbidden,
                'You do not have permission to delete this review.')

        log.info('Rating %s deleted from addon %s' % (obj.pk, obj.addon.pk))
        return super(RatingResource, self).obj_delete(request, **kwargs)
Beispiel #39
0
    def obj_create(self, bundle, request, **kwargs):
        region = getattr(request, 'REGION', None)
        app = bundle.data['app']

        if region and region.id not in app.get_price_region_ids():
            log.info('Region {0} is not in {1}'.format(
                region.id, app.get_price_region_ids()))
            if payments_enabled(request):
                log.info('Flag not active')
                raise http_error(http.HttpForbidden,
                                 'Payments are limited and flag not enabled')

        bundle.obj = GenericObject(_prepare_pay(request, bundle.data['app']))
        return bundle
Beispiel #40
0
    def obj_create(self, bundle, request, **kwargs):
        region = getattr(request, 'REGION', None)
        app = bundle.data['app']

        if region and region.id not in app.get_price_region_ids():
            log.info('Region {0} is not in {1}'
                     .format(region.id, app.get_price_region_ids()))
            if payments_enabled(request):
                log.info('Flag not active')
                raise http_error(http.HttpForbidden,
                                 'Payments are limited and flag not enabled')

        bundle.obj = GenericObject(_prepare_pay(request, bundle.data['app']))
        return bundle
Beispiel #41
0
    def handle(self, bundle, request, **kwargs):
        form = ReceiptForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        bundle.obj = form.cleaned_data['app']
        type_ = install_type(request, bundle.obj)

        if type_ == apps.INSTALL_TYPE_DEVELOPER:
            return self.record(bundle, request, apps.INSTALL_TYPE_DEVELOPER)

        # The app must be public and if its a premium app, you
        # must have purchased it.
        if not bundle.obj.is_public():
            log.info('App not public: %s' % bundle.obj.pk)
            raise http_error(http.HttpForbidden, 'App not public.')

        if (bundle.obj.is_premium()
                and not bundle.obj.has_purchased(request.amo_user)):
            # Apps that are premium but have no charge will get an
            # automatic purchase record created. This will ensure that
            # the receipt will work into the future if the price changes.
            if bundle.obj.premium and not bundle.obj.premium.price.price:
                log.info('Create purchase record: {0}'.format(bundle.obj.pk))
                AddonPurchase.objects.get_or_create(addon=bundle.obj,
                                                    user=request.amo_user,
                                                    type=CONTRIB_NO_CHARGE)
            else:
                log.info('App not purchased: %s' % bundle.obj.pk)
                raise http_error(HttpPaymentRequired,
                                 'You have not purchased this app.')

        # Anonymous users will fall through, they don't need anything else
        # handling.
        if request.user.is_authenticated():
            return self.record(bundle, request, type_)
Beispiel #42
0
    def handle(self, bundle, request, **kwargs):
        form = ReceiptForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        bundle.obj = form.cleaned_data['app']

        # Developers get handled quickly.
        if check_ownership(request, bundle.obj, require_owner=False,
                           ignore_disabled=True, admin=False):
            return self.record(bundle, request, apps.INSTALL_TYPE_DEVELOPER)

        # The app must be public and if its a premium app, you
        # must have purchased it.
        if not bundle.obj.is_public():
            log.info('App not public: %s' % bundle.obj.pk)
            raise http_error(http.HttpForbidden, 'App not public.')

        if (bundle.obj.is_premium() and
            not bundle.obj.has_purchased(request.amo_user)):
            # Apps that are premium but have no charge will get an
            # automatic purchase record created. This will ensure that
            # the receipt will work into the future if the price changes.
            if bundle.obj.premium and not bundle.obj.premium.has_price():
                log.info('Create purchase record: {0}'.format(bundle.obj.pk))
                AddonPurchase.objects.get_or_create(addon=bundle.obj,
                    user=request.amo_user, type=CONTRIB_NO_CHARGE)
            else:
                log.info('App not purchased: %s' % bundle.obj.pk)
                raise http_error(HttpPaymentRequired, 'You have not purchased this app.')

        # Anonymous users will fall through, they don't need anything else
        # handling.
        if request.user.is_authenticated():
            return self.record(bundle, request, apps.INSTALL_TYPE_USER)
Beispiel #43
0
 def post_list(self, request, **kwargs):
     data = self.deserialize(request, request.raw_post_data, format="application/json")
     email = data["email"]
     try:
         validate_email(email)
     except ValidationError:
         raise http_error(http.HttpBadRequest, "Invalid email address")
     basket.subscribe(
         data["email"],
         "marketplace",
         format="H",
         country=request.REGION.slug,
         lang=request.LANG,
         optin="Y",
         trigger_welcome="Y",
     )
Beispiel #44
0
    def obj_get(self, request=None, **kw):
        try:
            obj = super(StatusPayResource, self).obj_get(request=request, **kw)
        except ObjectDoesNotExist:
            # Anything that's not correct will be raised as a 404 so that it's
            # harder to iterate over contribution values.
            log.info('Contribution not found')
            return None

        if not OwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        if not obj.addon.has_purchased(request.amo_user):
            log.info('Not in AddonPurchase table')
            return None

        return obj
Beispiel #45
0
    def obj_get(self, request=None, **kw):
        try:
            obj = super(StatusPayResource, self).obj_get(request=request, **kw)
        except ObjectDoesNotExist:
            # Anything that's not correct will be raised as a 404 so that it's
            # harder to iterate over contribution values.
            log.info('Contribution not found')
            return None

        if not OwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(http.HttpForbidden,
                             'You are not an author of that app.')

        if not obj.addon.has_purchased(request.amo_user):
            log.info('Not in AddonPurchase table')
            return None

        return obj
Beispiel #46
0
    def get_detail(self, request, **kwargs):
        metric = kwargs.get('metric')
        if metric not in STATS:
            raise http_error(http.HttpNotFound, 'No metric by that name.')

        # Trigger form validation which doesn't normally happen for GETs.
        bundle = self.build_bundle(data=request.GET, request=request)
        self.is_valid(bundle, request)

        start = bundle.data.get('start')
        end = bundle.data.get('end')
        interval = bundle.data.get('interval')

        client = get_monolith_client()

        data = list(client(STATS[metric]['metric'], start, end, interval))
        to_be_serialized = self.alter_list_data_to_serialize(
            request, {'objects': data})

        return self.create_response(request, to_be_serialized)
Beispiel #47
0
    def get_list(self, request=None, **kwargs):
        form_data = self.search_form(request)
        is_admin = acl.action_allowed(request, 'Admin', '%')
        is_reviewer = acl.action_allowed(request, 'Apps', 'Review')

        # Pluck out status and addon type first since it forms part of the base
        # query, but only for privileged users.
        status = form_data['status']
        addon_type = form_data['type']

        base_filters = {
            'type': addon_type,
        }

        # Allow reviewers and admins to search by statuses other than PUBLIC.
        if status and (status == 'any' or status != amo.STATUS_PUBLIC):
            if is_admin or is_reviewer:
                base_filters['status'] = status
            else:
                raise http_error(http.HttpUnauthorized,
                                 _('Unauthorized to filter by status.'))

        # Only allow reviewers and admin to search by private fields or fields
        # depending on the latest_version (which may or may not be public yet).
        restricted_data = [form_data.get('is_privileged', None),
                           form_data.get('has_editor_comment', None),
                           form_data.get('has_info_request', None),
                           form_data.get('is_escalated', None)]

        if not (is_admin or is_reviewer) and any(f is not None
                                                 for f in restricted_data):
            return http.HttpUnauthorized(content=json.dumps(
                {'reason': _('Unauthorized to filter by private fields.')}))

        # Filter by device feature profile.
        profile = None
        if request.GET.get('dev') in ('firefoxos', 'android'):
            sig = request.GET.get('pro')
            if sig:
                profile = FeatureProfile.from_signature(sig)

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

        qs = _get_query(request, region, gaia=request.GAIA,
                        mobile=request.MOBILE, tablet=request.TABLET,
                        filters=base_filters, new_idx=True)
        qs = _filter_search(request, qs, form_data, region=region,
                            profile=profile)
        paginator = self._meta.paginator_class(request.GET, qs,
            resource_uri=self.get_resource_list_uri(),
            limit=self._meta.limit)
        page = paginator.page()

        # Rehydrate the results as per tastypie.
        objs = []
        for obj in page['objects']:
            obj.pk = obj.id
            objs.append(self.build_bundle(obj=obj, request=request))

        page['objects'] = [self.full_dehydrate(bundle) for bundle in objs]

        # This isn't as quite a full as a full TastyPie meta object,
        # but at least it's namespaced that way and ready to expand.
        to_be_serialized = self.alter_list_data_to_serialize(request, page)
        return self.create_response(request, to_be_serialized)
Beispiel #48
0
    def get_list(self, request=None, **kwargs):
        form_data = self.search_form(request)
        is_admin = acl.action_allowed(request, 'Admin', '%')
        is_reviewer = acl.action_allowed(request, 'Apps', 'Review')

        uses_es = waffle.switch_is_active('search-api-es')

        # Pluck out status and addon type first since it forms part of the base
        # query, but only for privileged users.
        status = form_data['status']
        addon_type = form_data['type']

        base_filters = {
            'type': addon_type,
        }

        # Allow reviewers and admins to search by statuses other than PUBLIC.
        if status and (status == 'any' or status != amo.STATUS_PUBLIC):
            if is_admin or is_reviewer:
                base_filters['status'] = status
            else:
                raise http_error(http.HttpUnauthorized,
                                 _('Unauthorized to filter by status.'))

        # Filter by device feature profile.
        profile = None
        # TODO: Remove uses_es conditional with 'search-api-es' waffle.
        if uses_es and request.GET.get('dev') in ('firefoxos', 'android'):
            sig = request.GET.get('pro')
            if sig:
                profile = FeatureProfile.from_signature(sig)

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

        qs = _get_query(request, region, gaia=request.GAIA,
                        mobile=request.MOBILE, tablet=request.TABLET,
                        filters=base_filters, new_idx=True)
        qs = _filter_search(request, qs, form_data, region=region,
                            profile=profile)
        paginator = self._meta.paginator_class(request.GET, qs,
            resource_uri=self.get_resource_list_uri(),
            limit=self._meta.limit)
        page = paginator.page()

        # Rehydrate the results as per tastypie.
        objs = []
        for obj in page['objects']:
            obj.pk = obj.id
            objs.append(self.build_bundle(obj=obj, request=request))

        if uses_es:
            page['objects'] = [self.full_dehydrate(bundle)
                               for bundle in objs]
        else:
            page['objects'] = [AppResource().full_dehydrate(bundle)
                               for bundle in objs]

        # This isn't as quite a full as a full TastyPie meta object,
        # but at least it's namespaced that way and ready to expand.
        to_be_serialized = self.alter_list_data_to_serialize(request, page)
        return self.create_response(request, to_be_serialized)