Esempio n. 1
0
    def save(self):
        u = super(UserEditForm, self).save(commit=False)
        data = self.cleaned_data

        photo = data['photo']
        if photo:
            u.picture_type = 'image/png'
            tmp_destination = u.picture_path + '__unconverted'

            if not os.path.exists(u.picture_dir):
                os.makedirs(u.picture_dir)

            fh = open(tmp_destination, 'w')
            for chunk in photo.chunks():
                fh.write(chunk)

            fh.close()
            resize_photo.delay(tmp_destination, u.picture_path,
                               set_modified_on=[u])

        for i, n in email.APP_NOTIFICATIONS_BY_ID.iteritems():
            enabled = n.mandatory or (str(i) in data['notifications'])
            UserNotification.update_or_create(user=u, notification_id=i,
                update={'enabled': enabled})

        log.debug(u'User (%s) updated their profile' % u)

        u.save()
        return u
Esempio n. 2
0
    def save(self, commit=False):
        from .tasks import create_persona_preview_image, save_persona_image
        # We ignore `commit`, since we need it to be `False` so we can save
        # the ManyToMany fields on our own.
        addon = super(NewPersonaForm, self).save(commit=False)
        addon.status = amo.STATUS_UNREVIEWED
        addon.type = amo.ADDON_PERSONA
        addon.save()
        addon._current_version = Version.objects.create(addon=addon,
                                                        version='0')
        addon.save()
        amo.log(amo.LOG.CREATE_ADDON, addon)
        log.debug('New persona %r uploaded' % addon)

        data = self.cleaned_data

        header = data['header_hash']
        footer = data['footer_hash']

        header = os.path.join(settings.TMP_PATH, 'persona_header', header)
        footer = os.path.join(settings.TMP_PATH, 'persona_footer', footer)
        dst = os.path.join(settings.PERSONAS_PATH, str(addon.id))

        # Save header, footer, and preview images.
        save_persona_image(src=header, dst=dst, img_basename='header.jpg')
        save_persona_image(src=footer, dst=dst, img_basename='footer.jpg')
        create_persona_preview_image(src=header, dst=dst,
                                     img_basename='preview.jpg',
                                     set_modified_on=[addon])

        # Save user info.
        user = self.request.amo_user
        AddonUser(addon=addon, user=user).save()

        p = Persona()
        p.persona_id = 0
        p.addon = addon
        p.header = 'header.jpg'
        p.footer = 'footer.jpg'
        if data['accentcolor']:
            p.accentcolor = data['accentcolor'].lstrip('#')
        if data['textcolor']:
            p.textcolor = data['textcolor'].lstrip('#')
        p.license_id = data['license']
        p.submit = datetime.now()
        p.author = user.name
        p.display_username = user.username
        p.save()

        # Save tags.
        for t in data['tags']:
            Tag(tag_text=t).save_tag(addon)

        # Save categories.
        tb_c = Category.objects.get(application=amo.THUNDERBIRD.id,
                                    name__id=data['category'].name_id)
        AddonCategory(addon=addon, category=data['category']).save()
        AddonCategory(addon=addon, category=tb_c).save()

        return addon
Esempio n. 3
0
def revision_add_attachment(request, pk):
    """Add attachment, download if necessary
    """
    revision = get_object_or_404(PackageRevision, pk=pk)
    if request.user.pk != revision.author.pk:
        log_msg = ("[security] Attempt to add attachment to package (%s) by "
                   "non-owner (%s)" % (revision.package, request.user))
        log.warning(log_msg)
        return HttpResponseForbidden(
            'You are not the author of this %s' % escape(
                revision.package.get_type_name()))
    url = request.POST.get('url', None)
    filename = request.POST.get('filename', None)
    log.debug(filename)
    if not filename or filename == "":
        log.error('Trying to create an attachment without name')
        return HttpResponseForbidden('Path not found.')
    content = ''
    if url:
        # validate url
        field = URLField(verify_exists=True)
        try:
            url = field.clean(url)
        except ValidationError, err:
            log.debug('Invalid url provided (%s)\n%s' % (url,
                '\n'.join(err.messages)))
            return HttpResponseForbidden(("Loading attachment failed<br/>"
                "%s") % '<br/>'.join(err.messages))
        except Exception, err:
            return HttpResponseForbidden(str(err))
Esempio n. 4
0
def collection_subscribers():
    """
    Collection weekly and monthly subscriber counts.
    """
    log.debug('Starting collection subscriber update...')
    cursor = connection.cursor()
    cursor.execute("""
        UPDATE collections SET weekly_subscribers = 0, monthly_subscribers = 0
    """)
    cursor.execute("""
        UPDATE collections AS c
        INNER JOIN (
            SELECT
                COUNT(collection_id) AS count,
                collection_id
            FROM collection_subscriptions
            WHERE created >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
            GROUP BY collection_id
        ) AS weekly ON (c.id = weekly.collection_id)
        INNER JOIN (
            SELECT
                COUNT(collection_id) AS count,
                collection_id
            FROM collection_subscriptions
            WHERE created >= DATE_SUB(CURDATE(), INTERVAL 31 DAY)
            GROUP BY collection_id
        ) AS monthly ON (c.id = monthly.collection_id)
        SET c.weekly_subscribers = weekly.count,
            c.monthly_subscribers = monthly.count
    """)
    transaction.commit_unless_managed()
Esempio n. 5
0
def prepare_pay(request, addon):
    """Prepare a BlueVia JWT to pass into navigator.pay()"""
    amount, currency, uuid_, contrib_for = start_purchase(request, addon)
    log.debug('Storing contrib for uuid: %s' % uuid_)
    Contribution.objects.create(addon_id=addon.id, amount=amount,
                                source=request.REQUEST.get('src', ''),
                                source_locale=request.LANG,
                                uuid=str(uuid_), type=amo.CONTRIB_PENDING,
                                paykey=None, user=request.amo_user,
                                price_tier=addon.premium.price,
                                client_data=ClientData.get_or_create(request))
    data = {'amount': str(amount), 'currency': currency,
            'app_name': unicode(addon.name),
            'app_description': unicode(addon.description),
            'postback_url': absolutify(reverse('bluevia.postback')),
            'chargeback_url': absolutify(reverse('bluevia.chargeback')),
            'seller': addon.pk,
            'product_data': urlencode({'contrib_uuid': uuid_,
                                       'addon_id': addon.pk}),
            'typ': 'tu.com/payments/inapp/v1',
            'aud': 'tu.com',
            'memo': contrib_for}

    if waffle.flag_is_active(request, 'solitude-payments'):
        bluevia_jwt = client.prepare_bluevia_pay(data)
    else:
        bluevia_jwt = prepare_bluevia_pay(data)
    return {'blueviaJWT': bluevia_jwt,
            'contribStatusURL': reverse('bluevia.pay_status',
                                        args=[addon.app_slug, uuid_])}
Esempio n. 6
0
def activity_log_scrubber():
    """
    Scans activity log for REMOVE_FROM_COLLECTION and ADD_TO_COLLECTION, looks
    for collections in arguments and checks whether collection is listed.
    """

    items = ActivityLog.objects.filter(
            action__in=[amo.LOG.ADD_TO_COLLECTION.id,
                        amo.LOG.REMOVE_FROM_COLLECTION.id])

    ids = []
    count = 0
    # ~127K
    for item in items:
        count += 1
        for arg in item.arguments:
            if isinstance(arg, Collection) and not arg.listed:
                log.debug('Flagging %s.' % item)
                log.debug('%d items seen.' % count)
                ids.append(item.id)

    log.info('Deleting %d items.' % len(ids))

    for chunk in chunked(ids, 100):
        _activity_log_scrubber.delay(chunk)
Esempio n. 7
0
def reply(request, addon, review_id):
    is_admin = acl.action_allowed(request, 'Addons', 'Edit')
    is_author = acl.check_addon_ownership(request, addon, dev=True)
    if not (is_admin or is_author):
        return http.HttpResponseForbidden()

    review = get_object_or_404(Review.objects, pk=review_id, addon=addon)
    form = forms.ReviewReplyForm(request.POST or None)
    if request.method == 'POST' and form.is_valid():
        d = dict(reply_to=review, addon=addon,
                 defaults=dict(user=request.amo_user))
        reply, new = Review.objects.get_or_create(**d)
        for key, val in _review_details(request, addon, form).items():
            setattr(reply, key, val)
        reply.save()
        action = 'New' if new else 'Edited'
        log.debug('%s reply to %s: %s' % (action, review_id, reply.id))

        if new:
            reply_url = shared_url('reviews.detail', addon, review.id,
                                   add_prefix=False)
            data = {'name': addon.name,
                    'reply_title': reply.title,
                    'reply': reply.body,
                    'reply_url': absolutify(reply_url)}
            emails = [review.user.email]
            sub = u'Mozilla Add-on Developer Reply: %s' % addon.name
            send_mail('reviews/emails/reply_review.ltxt',
                      sub, emails, Context(data), 'reply')

        return redirect(shared_url('reviews.detail', addon, review_id))
    ctx = dict(review=review, form=form, addon=addon)
    return jingo.render(request, 'reviews/reply.html', ctx)
Esempio n. 8
0
def cleanup_extracted_file():
    log.info('Removing extracted files for file viewer.')
    root = os.path.join(settings.TMP_PATH, 'file_viewer')
    # Local storage uses local time for file modification. S3 uses UTC time.
    now = datetime.utcnow if storage_is_remote() else datetime.now
    for path in private_storage.listdir(root)[0]:
        full = os.path.join(root, path)
        age = now() - private_storage.modified_time(
            os.path.join(full, 'manifest.webapp'))
        if age.total_seconds() > (60 * 60):
            log.debug('Removing extracted files: %s, %dsecs old.' %
                      (full, age.total_seconds()))
            for subroot, dirs, files in walk_storage(full):
                for f in files:
                    private_storage.delete(os.path.join(subroot, f))
            # Nuke out the file and diff caches when the file gets removed.
            id = os.path.basename(path)
            try:
                int(id)
            except ValueError:
                continue

            key = hashlib.md5()
            key.update(str(id))
            cache.delete('%s:memoize:%s:%s' % (settings.CACHE_PREFIX,
                                               'file-viewer', key.hexdigest()))
Esempio n. 9
0
    def save(self, log_for_developer=True):
        u = super(UserEditForm, self).save(commit=False)
        data = self.cleaned_data
        photo = data['photo']
        if photo:
            u.picture_type = 'image/png'
            tmp_destination = u.picture_path + '__unconverted'

            with storage.open(tmp_destination, 'wb') as fh:
                for chunk in photo.chunks():
                    fh.write(chunk)

            tasks.resize_photo.delay(tmp_destination, u.picture_path,
                                     set_modified_on=[u])

        if data['password']:
            u.set_password(data['password'])
            log_cef('Password Changed', 5, self.request, username=u.username,
                    signature='PASSWORDCHANGED', msg='User changed password')
            if log_for_developer:
                amo.log(amo.LOG.CHANGE_PASSWORD)
                log.info(u'User (%s) changed their password' % u)

        for (i, n) in email.NOTIFICATIONS_BY_ID.items():
            enabled = n.mandatory or (str(i) in data['notifications'])
            UserNotification.update_or_create(user=u, notification_id=i,
                    update={'enabled': enabled})

        log.debug(u'User (%s) updated their profile' % u)

        u.save()
        return u
Esempio n. 10
0
    def arguments(self):

        try:
            # d is a structure:
            # ``d = [{'addons.addon':12}, {'addons.addon':1}, ... ]``
            d = json.loads(self._arguments)
        except:
            log.debug('unserializing data from addon_log failed: %s' % self.id)
            return None

        objs = []
        for item in d:
            # item has only one element.
            model_name, pk = item.items()[0]
            if model_name in ('str', 'int', 'null'):
                objs.append(pk)
            else:
                (app_label, model_name) = model_name.split('.')
                model = models.loading.get_model(app_label, model_name)
                # Cope with soft deleted models.
                if hasattr(model, 'with_deleted'):
                    objs.extend(model.with_deleted.filter(pk=pk))
                else:
                    objs.extend(model.objects.filter(pk=pk))

        return objs
Esempio n. 11
0
def upload_attachment(request, revision_id):
    """ Upload new attachment to the PackageRevision
    """
    revision = get_object_with_related_or_404(PackageRevision, pk=revision_id)
    log.debug(revision)
    if request.user.pk != revision.author.pk:
        log_msg = ("[security] Attempt to upload attachment to package (%s) "
                "by non-owner (%s)" % (revision_id, request.user))
        log.warning(log_msg)
        return HttpResponseForbidden(
            'You are not the author of this %s' % escape(
                revision.package.get_type_name()))

    f = request.FILES.get('upload_attachment')
    filename = request.META.get('HTTP_X_FILE_NAME')

    if not f:
        log_msg = 'Path not found: %s, revision: %s.' % (
            filename, revision_id)
        log.error(log_msg)
        return HttpResponseServerError('Path not found.')

    content = f.read()
    # try to force UTF-8 code, on error continue with original data
    try:
        content = unicode(content, 'utf-8')
    except:
        pass

    try:
        attachment = revision.attachment_create_by_filename(
            request.user, filename, content)
    except ValidationError, e:
        return HttpResponseForbidden(
                'Validation errors.\n%s' % parse_validation_messages(e))
Esempio n. 12
0
def extract_lang(project, locale, path, entities=False):
    """Extract .lang file with path and save or update in DB."""

    lang = parse_lang(path)
    relative_path = get_relative_path(path, locale)

    resource, created = Resource.objects.get_or_create(
        project=project, path=relative_path, format='lang')

    if entities:
        for order, (key, value) in enumerate(lang):
            save_entity(
                resource=resource, string=key, comment=value[1], order=order)

        update_entity_count(resource)

    else:
        for key, value in lang:
            if key != value[2] or '{ok}' in value[3]:
                try:
                    e = Entity.objects.get(
                        resource=resource, string__iexact=key)
                    save_translation(
                        entity=e, locale=locale, string=value[2])

                except Entity.DoesNotExist:
                    continue

        update_stats(resource, locale)

    log.debug("[" + locale.code + "]: " + path + " saved to DB.")
Esempio n. 13
0
def add(request, addon, template=None):
    if addon.has_author(request.user):
        raise PermissionDenied
    form = forms.ReviewForm(request.POST or None)
    if (request.method == 'POST' and form.is_valid() and
            not request.POST.get('detailed')):
        details = _review_details(request, addon, form)
        review = Review.objects.create(**details)
        if 'flag' in form.cleaned_data and form.cleaned_data['flag']:
            rf = ReviewFlag(review=review,
                            user_id=request.user.id,
                            flag=ReviewFlag.OTHER,
                            note='URLs')
            rf.save()

        amo.log(amo.LOG.ADD_REVIEW, addon, review)
        log.debug('New review: %s' % review.id)

        reply_url = helpers.url('addons.reviews.reply', addon.slug, review.id,
                                add_prefix=False)
        data = {'name': addon.name,
                'rating': '%s out of 5 stars' % details['rating'],
                'review': details['body'],
                'reply_url': helpers.absolutify(reply_url)}

        emails = [a.email for a in addon.authors.all()]
        send_mail('reviews/emails/add_review.ltxt',
                  u'Mozilla Add-on User Review: %s' % addon.name,
                  emails, Context(data), 'new_review')

        return redirect(helpers.url('addons.reviews.list', addon.slug))
    return render(request, template, dict(addon=addon, form=form))
Esempio n. 14
0
    def commit(self, path=None, message=None, user=None):
        log.debug("Git: Commit to repository.")

        path = path or self.path
        message = message or self.message
        user = user or self.user
        author = self.get_author(user)

        # Add
        add = ["git", "add", "-A"]
        execute(add, path)

        # Commit
        commit = ["git", "commit", "-m", message, "--author", author]
        code, output, error = execute(commit, path)
        if code != 0 and len(error):
            raise CommitToRepositoryException(unicode(error))

        # Push
        push = ["git", "push"]
        code, output, error = execute(push, path)
        if code != 0:
            raise CommitToRepositoryException(unicode(error))

        if 'Everything up-to-date' in error:
            self.nothing_to_commit()

        log.info(message)
Esempio n. 15
0
def dump_po(project, locale):
    """Update .po (gettext) files from database."""

    locale_paths = get_locale_paths(project, locale)

    for path in locale_paths:
        po = polib.pofile(path)
        date = datetime.datetime(1, 1, 1)
        newest = Translation()
        relative_path = get_relative_path(path, locale)
        resource = Resource.objects.filter(project=project, path=relative_path)
        entities = Entity.objects.filter(resource=resource, obsolete=False)

        for entity in entities:
            entry = po.find(polib.unescape(smart_text(entity.string)))
            if entry:
                if not entry.msgid_plural:
                    translation = get_translation(entity=entity, locale=locale)
                    if translation.string != '':
                        entry.msgstr = polib.unescape(translation.string)
                        if translation.date > date:
                            date = translation.date
                            newest = translation
                        if ('fuzzy' in entry.flags and not translation.fuzzy):
                            entry.flags.remove('fuzzy')

                else:
                    for i in range(0, 6):
                        if i < (locale.nplurals or 1):
                            translation = get_translation(
                                entity=entity, locale=locale, plural_form=i)
                            if translation.string != '':
                                entry.msgstr_plural[unicode(i)] = \
                                    polib.unescape(translation.string)
                                if translation.date > date:
                                    date = translation.date
                                    newest = translation
                                if ('fuzzy' in entry.flags and
                                   not translation.fuzzy):
                                    entry.flags.remove('fuzzy')
                        # Remove obsolete plural forms if exist
                        else:
                            if unicode(i) in entry.msgstr_plural:
                                del entry.msgstr_plural[unicode(i)]

        # Update PO metadata
        if newest.id:
            po.metadata['PO-Revision-Date'] = newest.date
            if newest.user:
                po.metadata['Last-Translator'] = '%s <%s>' \
                    % (newest.user.first_name, newest.user.email)
        po.metadata['Language'] = locale.code
        po.metadata['X-Generator'] = 'Pontoon'

        if locale.nplurals:
            po.metadata['Plural-Forms'] = 'nplurals=%s; plural=%s;' \
                % (str(locale.nplurals), locale.plural_rule)

        po.save()
        log.debug("File updated: " + path)
Esempio n. 16
0
def start_purchase(request, addon):
    log.debug('Starting purchase of addon: %s by user: %s'
              % (addon.pk, request.amo_user.pk))
    amount = addon.premium.get_price()
    uuid_ = hashlib.md5(str(uuid.uuid4())).hexdigest()
    # L10n: {0} is the addon name.
    contrib_for = (_(u'Firefox Marketplace purchase of {0}')
                   .format(addon.name))

    # Default is USD.
    amount, currency = addon.premium.get_price(), 'USD'

    # If tier is specified, then let's look it up.
    if waffle.switch_is_active('currencies'):
        form = PriceCurrencyForm(data=request.POST, addon=addon)
        if form.is_valid():
            tier = form.get_tier()
            if tier:
                amount, currency = tier.price, tier.currency

    if waffle.flag_is_active(request, 'solitude-payments'):
        # TODO(solitude): when the migration of data is completed, we
        # will be able to remove this. Seller data is populated in solitude
        # on submission or devhub changes. If those don't occur, you won't be
        # able to sell at all.
        client.create_seller_for_pay(addon)

    return amount, currency, uuid_, contrib_for
Esempio n. 17
0
    def save(self, log_for_developer=True):
        u = super(UserEditForm, self).save(commit=False)
        data = self.cleaned_data
        photo = data['photo']
        if photo:
            u.picture_type = 'image/png'
            tmp_destination = u.picture_path + '__unconverted'

            if not os.path.exists(u.picture_dir):
                os.makedirs(u.picture_dir)

            fh = open(tmp_destination, 'w')
            for chunk in photo.chunks():
                fh.write(chunk)

            fh.close()
            tasks.resize_photo.delay(tmp_destination, u.picture_path,
                                     set_modified_on=[u])

        if data['password']:
            u.set_password(data['password'])
            if log_for_developer:
                amo.log(amo.LOG.CHANGE_PASSWORD)
                log.info(u'User (%s) changed their password' % u)

        for (i, n) in email.NOTIFICATIONS_BY_ID.items():
            enabled = n.mandatory or (str(i) in data['notifications'])
            UserNotification.update_or_create(user=u, notification_id=i,
                    update={'enabled': enabled})

        log.debug(u'User (%s) updated their profile' % u)

        u.save()
        return u
Esempio n. 18
0
def reply(request, addon, review_id):
    is_admin = acl.action_allowed(request, 'Addons', 'Edit')
    is_author = acl.check_addon_ownership(request, addon, dev=True)
    if not (is_admin or is_author):
        raise PermissionDenied

    review = get_object_or_404(Review.objects, pk=review_id, addon=addon)
    form = ReviewReplyForm(request.POST or None)
    if form.is_valid():
        d = dict(reply_to=review, addon=addon,
                 defaults=dict(user=request.amo_user))
        reply, new = Review.objects.get_or_create(**d)
        for k, v in _review_details(request, addon, form).items():
            setattr(reply, k, v)
        reply.save()
        action = 'New' if new else 'Edited'
        if new:
            amo.log(amo.LOG.ADD_REVIEW, addon, reply)
        else:
            amo.log(amo.LOG.EDIT_REVIEW, addon, reply)

        log.debug('%s reply to %s: %s' % (action, review_id, reply.id))
        messages.success(request,
                         _('Your reply was successfully added.') if new else
                         _('Your reply was successfully updated.'))

    return http.HttpResponse()
Esempio n. 19
0
    def handle(self, *args, **options):
        day = options["date"]
        if not day:
            raise CommandError("You must specify a --date parameter in the " " YYYY-MM-DD format.")
        filename = options["filename"]
        if filename is None:
            filename = day
        sep = options["separator"]
        limit = options["limit"]
        with_updates = options["with_updates"]
        with_downloads = options["with_downloads"]
        if not with_updates and not with_downloads:
            raise CommandError("Please specify at least one of --with-updates " "or --with-downloads.")

        with ClevererConnection(
            host="peach-gw.peach.metrics.scl3.mozilla.com",
            port=10000,
            user="******",
            password="",
            authMechanism="PLAIN",
        ) as conn:
            num_reqs = 0
            with conn.cursor() as cur:
                start = datetime.now()  # Measure the time to run the script.
                if with_downloads:
                    num_reqs += self.process_downloads(cur, day, filename, sep=sep, limit=limit)
                if with_updates:
                    num_reqs += self.process_updates(cur, day, filename, sep=sep, limit=limit)

        total_time = (datetime.now() - start).total_seconds()
        log.info("Stored a total of %s requests" % num_reqs)
        log.debug("Total processing time: %s seconds" % total_time)
        log.debug("Time spent fetching data from hive over the network: %s" % fetch_time)
Esempio n. 20
0
    def pull(self, source=None, target=None):
        log.debug("Mercurial: Update repository.")

        source = source or self.source
        target = target or self.target

        # Undo local changes
        command = ["hg", "revert", "--all", "--no-backup"]
        execute(command, target)

        command = ["hg", "pull", "-u"]
        code, output, error = execute(command, target)

        if code == 0:
            log.debug("Mercurial: Repository at " + source + " updated.")

        else:
            log.debug("Mercurial: " + unicode(error))
            log.debug("Mercurial: Clone instead.")
            command = ["hg", "clone", source, target]
            code, output, error = execute(command)

            if code == 0:
                log.debug("Mercurial: Repository at " + source + " cloned.")

            else:
                raise PullFromRepositoryException(unicode(error))
Esempio n. 21
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.
        if self._meta.queryset.filter(addon=app, user=request.user).exists():
            raise ImmediateHttpResponse(response=http.HttpConflict())

        # Return 403 if the user is attempting to review their own app:
        if app.has_author(request.user):
            raise ImmediateHttpResponse(response=http.HttpForbidden())

        # 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 ImmediateHttpResponse(response=http.HttpForbidden())

        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
Esempio n. 22
0
def _xpi_form_error(f, request):
    resp = rc.BAD_REQUEST
    error = ','.join([e[0] for e in f.errors.values()])
    resp.write(': ' + _('Add-on did not validate: %s') % error)
    log.debug('Add-on did not validate (%s) for %s'
              % (error, request.amo_user))
    return resp
Esempio n. 23
0
def vouchify():
    """Synchronizes LDAP vouch info into database.

    This queries LDAP for users who's corresponding ``UserProfile`` has
    ``is_vouched`` as ``False``.  It then updates ``is_vouched`` and
    ``vouched_by`` with up-to-date data.
    """
    users = UserProfile.objects.filter(is_vouched=False)

    for user in users:
        person = user.get_ldap_person()
        if person and 'mozilliansVouchedBy' in person[1]:
            user.is_vouched = True
            voucher = (person[1]['mozilliansVouchedBy'][0].split(',')[0]
                                                          .split('=')[1])
            by = larper.get_user_by_uid(voucher)
            if by:
                email = by[1]['mail'][0]
                try:
                    user.vouched_by = (User.objects.get(email=email)
                                                   .get_profile())
                except User.DoesNotExist:
                    log.warning('No matching user for %s' % email)
                except UserProfile.DoesNotExist:
                    log.warning('No matching user_profile for %s' % email)
            user.save()
            log.info('Data copied for %s' % user.user.username)
        log.debug('%s is still unvouched... skipping' % user.user.username)
Esempio n. 24
0
def inherit_nomination(sender, instance, **kw):
    """For new versions pending review, ensure nomination date
    is inherited from last nominated version.
    """
    if kw.get("raw"):
        return
    addon = instance.addon
    if addon.type == amo.ADDON_WEBAPP and addon.is_packaged:
        # If prior version's file is pending, inherit nomination. Otherwise,
        # set nomination to now.
        last_ver = Version.objects.filter(addon=addon).exclude(pk=instance.pk).order_by("-nomination")
        if last_ver.exists() and last_ver[0].all_files[0].status == amo.STATUS_PENDING:
            instance.update(nomination=last_ver[0].nomination, _signal=False)
            log.debug("[Webapp:%s] Inheriting nomination from prior pending " "version" % addon.id)
        elif addon.status in amo.WEBAPPS_APPROVED_STATUSES and not instance.nomination:
            log.debug("[Webapp:%s] Setting nomination date to now for new " "version." % addon.id)
            instance.update(nomination=datetime.datetime.now(), _signal=False)
    else:
        if (
            instance.nomination is None
            and addon.status in (amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED)
            and not instance.is_beta
        ):
            last_ver = Version.objects.filter(addon=addon).exclude(nomination=None).order_by("-nomination")
            if last_ver.exists():
                instance.update(nomination=last_ver[0].nomination, _signal=False)
Esempio n. 25
0
def delete_photo(request):
    request.amo_user.update(picture_type='')
    delete_photo_task.delay(request.amo_user.picture_path)
    log.debug(u'User (%s) deleted photo' % request.amo_user)
    messages.success(request, _('Photo Deleted'))
    amo.log(amo.LOG.USER_EDITED)
    return http.HttpResponse()
Esempio n. 26
0
    def commit(self, path=None, message=None, user=None):
        log.debug("Mercurial: Commit to repository.")

        path = path or self.path
        message = message or self.message
        user = user or self.user
        author = self.get_author(user)

        # Add
        add = ["hg", "add"]
        execute(add, path)

        # Commit
        commit = ["hg", "commit", "-m", message, "-u", author]
        code, output, error = execute(commit, path)
        if code != 0 and len(error):
            raise CommitToRepositoryException(unicode(error))

        # Push
        push = ["hg", "push"]
        code, output, error = execute(push, path)
        if code == 1 and 'no changes found' in output:
            self.nothing_to_commit()

        if code != 0 and len(error):
            raise CommitToRepositoryException(unicode(error))

        log.info(message)
Esempio n. 27
0
def add(request, addon, template=None):
    if addon.has_author(request.user):
        return http.HttpResponseForbidden()
    form = forms.ReviewForm(request.POST or None)
    if (request.method == 'POST' and form.is_valid() and
        not request.POST.get('detailed')):
        details = _review_details(request, addon, form)
        review = Review.objects.create(**details)
        amo.log(amo.LOG.ADD_REVIEW, addon, review)
        log.debug('New review: %s' % review.id)

        reply_url = shared_url('reviews.reply', addon, review.id,
                               add_prefix=False)
        data = {'name': addon.name,
                'rating': '%s out of 5 stars' % details['rating'],
                'review': details['body'],
                'reply_url': absolutify(reply_url)}

        emails = [a.email for a in addon.authors.all()]
        send_mail('reviews/emails/add_review.ltxt',
                  u'Mozilla Add-on User Review: %s' % addon.name,
                  emails, Context(data), 'new_review')

        # Update the ratings and counts for the add-on.
        addon_review_aggregates.delay(addon.id, using='default')

        return redirect(shared_url('reviews.list', addon))
    return jingo.render(request, template, dict(addon=addon, form=form))
Esempio n. 28
0
    def pull(self, source=None, target=None):
        log.debug("Git: Update repository.")

        source = source or self.source
        target = target or self.target

        command = ["git", "fetch", "--all"]
        execute(command, target)

        # Undo local changes
        command = ["git", "reset", "--hard", "origin/master"]
        code, output, error = execute(command, target)

        if code == 0:
            log.debug("Git: Repository at " + source + " updated.")

        else:
            log.debug("Git: " + unicode(error))
            log.debug("Git: Clone instead.")
            command = ["git", "clone", source, target]
            code, output, error = execute(command)

            if code == 0:
                log.debug("Git: Repository at " + source + " cloned.")

            else:
                raise PullFromRepositoryException(unicode(error))
Esempio n. 29
0
def call_signing(file_obj, endpoint):
    """Get the jar signature and send it to the signing server to be signed."""
    # We only want the (unique) temporary file name.
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_filename = temp_file.name

    # Extract jar signature.
    jar = JarExtractor(path=storage.open(file_obj.file_path),
                       outpath=temp_filename,
                       omit_signature_sections=True,
                       extra_newlines=True)

    log.debug(u'File signature contents: {0}'.format(jar.signatures))

    log.debug(u'Calling signing service: {0}'.format(endpoint))
    with statsd.timer('services.sign.addon'):
        response = requests.post(
            endpoint,
            timeout=settings.SIGNING_SERVER_TIMEOUT,
            data={'addon_id': get_id(file_obj.version.addon)},
            files={'file': (u'mozilla.sf', unicode(jar.signatures))})
    if response.status_code != 200:
        msg = u'Posting to add-on signing failed: {0}'.format(response.reason)
        log.error(msg)
        raise SigningError(msg)

    pkcs7 = b64decode(json.loads(response.content)['mozilla.rsa'])
    cert_serial_num = get_signature_serial_number(pkcs7)
    jar.make_signed(pkcs7, sigpath=u'mozilla')
    shutil.move(temp_filename, file_obj.file_path)
    return cert_serial_num
Esempio n. 30
0
def extract_lang(project, locale, paths, entities=False):
    """Extract .lang files from paths and save or update in DB."""

    for path in paths:
        lang = parse_lang(path)
        relative_path = get_relative_path(path, locale)

        resource, created = Resource.objects.get_or_create(
            project=project, path=relative_path)

        if entities:
            for key, value in lang:
                save_entity(resource=resource, string=key,
                            comment=value[1])

            update_entity_count(resource, project)

        else:
            for key, value in lang:
                if key != value[2] or '{ok}' in value[3]:
                    try:
                        e = Entity.objects.get(resource=resource, string=key)
                        save_translation(
                            entity=e, locale=locale, string=value[2])

                    except Entity.DoesNotExist:
                        continue

            update_stats(resource, locale)

        log.debug("[" + locale.code + "]: " + path + " saved to DB.")
Esempio n. 31
0
 def post_save(self, obj, created=False):
     app = obj.addon
     if created:
         mkt.log(mkt.LOG.ADD_REVIEW, app, obj)
         log.debug('[Review:%s] Created by user %s ' %
                   (obj.pk, self.request.user.id))
         record_action('new-review', self.request, {'app-id': app.id})
     else:
         mkt.log(mkt.LOG.EDIT_REVIEW, app, obj)
         log.debug('[Review:%s] Edited by %s' %
                   (obj.pk, self.request.user.id))
Esempio n. 32
0
 def destroy(self, request, *args, **kwargs):
     obj = self.get_object()
     mkt.log(mkt.LOG.DELETE_REVIEW,
             obj.addon,
             obj,
             details=dict(title=unicode(obj.title),
                          body=unicode(obj.body),
                          addon_id=obj.addon.id,
                          addon_title=unicode(obj.addon.name)))
     log.debug('[Review:%s] Deleted by %s' % (obj.pk, self.request.user.id))
     return super(RatingViewSet, self).destroy(request, *args, **kwargs)
Esempio n. 33
0
def start_purchase(request, addon):
    log.debug('Starting purchase of app: %s by user: %s' %
              (addon.pk, request.amo_user.pk))
    amount = addon.get_price(region=request.REGION.id)
    uuid_ = hashlib.md5(str(uuid.uuid4())).hexdigest()
    # L10n: {0} is the addon name.
    contrib_for = (_(u'Firefox Marketplace purchase of {0}').format(
        addon.name))

    currency = request.REGION.default_currency
    return amount, currency, uuid_, contrib_for
Esempio n. 34
0
def clean_name(name, instance=None):
    if not instance:
        log.debug('clean_name called without an instance: %s' % name)

    id = reverse_name_lookup(name)

    # If we get an id and either there's no instance or the instance.id != id.
    if id and (not instance or id != instance.id):
        raise forms.ValidationError(_('This name is already in use. Please '
                                      'choose another.'))
    return name
Esempio n. 35
0
def calculate_activity_rating(pks,**kw):
    ids_str = ','.join(map(str, pks))
    log.debug('ES starting calculate_activity_rating for packages: [%s]'
              % ids_str)

    for package in Package.objects.filter(pk__in=pks):
        package.activity_rating = package.calc_activity_rating()
        package.save()

    log.debug('ES completed calculate_activity_rating for packages: [%s]'
              % ids_str)
Esempio n. 36
0
def add(request, addon):
    form = forms.ReviewForm(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            details = _review_details(request, addon, form)
            review = Review.objects.create(**details)
            amo.log(amo.LOG.ADD_REVIEW, addon, review)
            log.debug('New review: %s' % review.id)
            return redirect('reviews.list', addon.slug)
    return jingo.render(request, 'reviews/add.html',
                        dict(addon=addon, form=form))
Esempio n. 37
0
def zip_source(pk, hashtag, tqueued=None, **kw):
    if not hashtag:
        log.critical("[zip] No hashtag provided")
        return
    tstart = time.time()
    if tqueued:
        tinqueue = (tstart - tqueued) * 1000
        statsd.timing('zip.queued', tinqueue)
        log.info('[zip:%s] Addon job picked from queue (%dms)' % (hashtag, tinqueue))
    log.debug("[zip:%s] Compressing" % pk)
    PackageRevision.objects.get(pk=pk).zip_source(hashtag=hashtag, tstart=tstart)
    log.debug("[zip:%s] Compressed" % pk)
Esempio n. 38
0
def sdk_copy(sdk_source, sdk_dir):
    log.debug("Copying SDK from (%s) to (%s)" % (sdk_source, sdk_dir))
    with statsd.timer('xpi.copy'):
        if os.path.isdir(sdk_dir):
            for d in os.listdir(sdk_source):
                s_d = os.path.join(sdk_source, d)
                if os.path.isdir(s_d):
                    shutil.copytree(s_d, os.path.join(sdk_dir, d))
                else:
                    shutil.copy(s_d, sdk_dir)
        else:
            shutil.copytree(sdk_source, sdk_dir)
Esempio n. 39
0
def create_receipt(sender, instance, **kw):
    """
    When the AddonPurchase gets created, see if we need to create a receipt.
    """
    if (kw.get('raw') or instance.addon.type != amo.ADDON_WEBAPP
            or instance.receipt):
        return

    log.debug('Creating receipt for: addon %s, user %s' %
              (instance.addon.pk, instance.user.pk))
    instance.create_receipt()
    instance.save()
Esempio n. 40
0
def expired_resetcode():
    """
    Delete password reset codes that have expired.
    """
    log.debug('Removing reset codes that have expired...')
    cursor = connection.cursor()
    cursor.execute("""
    UPDATE users SET resetcode=DEFAULT,
                     resetcode_expires=DEFAULT
    WHERE resetcode_expires < NOW()
    """)
    transaction.commit_unless_managed()
Esempio n. 41
0
    def post(self, request, *args, **kwargs):
        form = PrepareWebAppForm(request.DATA)
        if not form.is_valid():
            return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)

        app = form.cleaned_data['app']

        region = getattr(request, 'REGION', None)
        if region:
            enabled_regions = app.get_price_region_ids()
            region_can_purchase = region.id in enabled_regions
            restofworld_can_purchase = RESTOFWORLD.id in enabled_regions

            if not region_can_purchase and not restofworld_can_purchase:
                log.info('Region {0} is not in {1}; '
                         'restofworld purchases are inactive'.format(
                             region.id, enabled_regions))
                return Response(
                    {'reason': 'Payments are restricted for this region'},
                    status=status.HTTP_403_FORBIDDEN)

        if app.is_premium() and app.has_purchased(request._request.user):
            log.info('Already purchased: {0}'.format(app.pk))
            return Response({'reason': u'Already purchased app.'},
                            status=status.HTTP_409_CONFLICT)

        app_pay_cef.log(request._request,
                        'Preparing JWT',
                        'preparing_jwt',
                        'Preparing JWT for: {0}'.format(app.pk),
                        severity=3)

        log.debug('Starting purchase of app: {0} by user: {1}'.format(
            app.pk, request._request.user))

        contribution = Contribution.objects.create(
            addon_id=app.pk,
            amount=app.get_price(region=request._request.REGION.id),
            paykey=None,
            price_tier=app.premium.price,
            source=request._request.GET.get('src', ''),
            source_locale=request._request.LANG,
            type=mkt.CONTRIB_PENDING,
            user=request._request.user,
            uuid=str(uuid.uuid4()),
        )

        log.debug('Storing contrib for uuid: {0}'.format(contribution.uuid))

        token = get_product_jwt(WebAppProduct(app), contribution)

        return Response(token, status=status.HTTP_201_CREATED)
Esempio n. 42
0
    def handle(self, *args, **options):
        start = datetime.datetime.now()  # Measure the time it takes to run.
        # The theme_update_counts_from_* gather data for the day before, at
        # best.
        yesterday = datetime.date.today() - datetime.timedelta(days=1)

        # Average number of users over the last 7 days (0 to 6 days ago).
        last_week_avgs = ThemeUpdateCount.objects.get_range_days_avg(
            start=yesterday - datetime.timedelta(days=6), end=yesterday)

        # Average number of users over the three weeks before last week
        # (7 to 27 days ago).
        prev_3_weeks_avgs = ThemeUpdateCount.objects.get_range_days_avg(
            start=yesterday - datetime.timedelta(days=27),
            end=yesterday - datetime.timedelta(days=7))

        # Perf: memoize the addon to persona relation.
        addon_to_persona = dict(Persona.objects.values_list('addon_id', 'id'))

        temp_update_counts = []

        for addon_id, popularity in last_week_avgs.iteritems():
            if addon_id not in addon_to_persona:
                continue
            # Create the temporary ThemeUpdateCountBulk for later bulk create.
            prev_3_weeks_avg = prev_3_weeks_avgs.get(addon_id, 0)
            tucb = ThemeUpdateCountBulk(persona_id=addon_to_persona[addon_id],
                                        popularity=popularity,
                                        movers=0)
            # Set movers to 0 if values aren't high enough.
            if popularity > 100 and prev_3_weeks_avg > 1:
                tucb.movers = (popularity -
                               prev_3_weeks_avg) / prev_3_weeks_avg
            temp_update_counts.append(tucb)

        # Create in bulk: this is much faster.
        ThemeUpdateCountBulk.objects.all().delete()  # Clean slate first.
        ThemeUpdateCountBulk.objects.bulk_create(temp_update_counts, 100)

        # Update in bulk from the above temp table: again, much faster.
        # TODO: remove _tmp from the fields when the ADI stuff is used
        raw_query = """
            UPDATE personas p, theme_update_counts_bulk t
            SET p.popularity_tmp=t.popularity,
                p.movers_tmp=t.movers
            WHERE t.persona_id=p.id
        """
        cursor = connection.cursor()
        cursor.execute(raw_query)

        log.debug('Total processing time: %s' %
                  (datetime.datetime.now() - start))
Esempio n. 43
0
def get_product_jwt(product, contribution):
    """
    Prepare a JWT describing the item about to be purchased when
    working with navigator.mozPay().

    See the MDN docs for details on the JWT fields:
    https://developer.mozilla.org/en-US/Marketplace/Monetization
        /In-app_payments_section/mozPay_iap
    """

    issued_at = calendar.timegm(time.gmtime())
    product_data = product.product_data(contribution)
    simulation = product.simulation()
    if not simulation and not product_data.get('public_id'):
        raise ValueError(
            'Cannot create JWT without a cached public_id for '
            'app {a}'.format(a=product.addon()))

    token_data = {
        'iss': settings.APP_PURCHASE_KEY,
        'typ': settings.APP_PURCHASE_TYP,
        'aud': settings.APP_PURCHASE_AUD,
        'iat': issued_at,
        'exp': issued_at + 3600,  # expires in 1 hour
        'request': {
            'id': product.external_id(),
            'name': unicode(product.name()),
            'defaultLocale': product.default_locale(),
            'locales': product.localized_properties(),
            'icons': product.icons(),
            'description': strip_tags(product.description()),
            'pricePoint': product.price().name,
            'productData': urlencode(product_data),
            'chargebackURL': absolutify(reverse('webpay.chargeback')),
            'postbackURL': absolutify(reverse('webpay.postback')),
        }
    }
    if simulation:
        token_data['request']['simulate'] = simulation

    token = sign_webpay_jwt(token_data)

    log.debug('Preparing webpay JWT for product {p}, contrib {c}: {t}'
              .format(p=product.id(), t=token_data, c=contribution))

    return {
        'webpayJWT': token,
        'contribStatusURL': reverse(
            'webpay-status',
            kwargs={'uuid': contribution.uuid}
        )
    }
Esempio n. 44
0
def _append_task(t):
    """Append a task to the queue.

    Expected argument is a tuple of the (task class, args, kwargs).

    This doesn't append to queue if the argument is already in the queue.

    """
    queue = _get_task_queue()
    if t not in queue:
        queue.append(t)
    else:
        log.debug('Removed duplicate task: %s' % (t, ))
Esempio n. 45
0
    def email_confirmation_code(self):
        from amo.utils import send_mail
        log.debug("Sending account confirmation code for user (%s)", self)

        url = "%s%s" % (settings.SITE_URL,
                        reverse('users.confirm',
                                args=[self.id, self.confirmationcode]))
        domain = settings.DOMAIN
        t = loader.get_template('users/email/confirm.ltxt')
        c = {'domain': domain, 'url': url, }
        send_mail(_("Please confirm your email address"),
                  t.render(Context(c)), None, [self.email],
                  use_blacklist=False)
Esempio n. 46
0
def mkt_gc(**kw):
    """Site-wide garbage collections."""

    days_ago = lambda days: datetime.today() - timedelta(days=days)

    log.debug('Collecting data to delete')
    logs = (ActivityLog.objects.filter(created__lt=days_ago(90)).exclude(
        action__in=amo.LOG_KEEP).values_list('id', flat=True))

    for chunk in chunked(logs, 100):
        chunk.sort()
        log.debug('Deleting log entries: %s' % str(chunk))
        amo.tasks.delete_logs.delay(chunk)
Esempio n. 47
0
def delete_icon(request, collection, username, slug):
    log.debug(u"User deleted collection (%s) icon " % slug)
    tasks.delete_icon(
        os.path.join(collection.get_img_dir(), '%d.png' % collection.id))

    collection.icontype = ''
    collection.save()

    if request.is_ajax():
        return {'icon': collection.icon_url}
    else:
        messages.success(request, _('Icon Deleted'))
        return redirect(collection.edit_url())
Esempio n. 48
0
def delete_photo(request):
    u = request.amo_user

    if request.method == 'POST':
        u.picture_type = ''
        u.save()
        log.debug(u"User (%s) deleted photo" % u)
        tasks.delete_photo.delay(u.picture_path)
        messages.success(request, _('Photo Deleted'))
        return http.HttpResponseRedirect(
            reverse('users.edit') + '#user-profile')

    return render(request, 'users/delete_photo.html', dict(user=u))
Esempio n. 49
0
def watch_email(old_attr=None,
                new_attr=None,
                instance=None,
                sender=None,
                **kw):
    if old_attr is None:
        old_attr = {}
    if new_attr is None:
        new_attr = {}
    new_email, old_email = new_attr.get('email'), old_attr.get('email')
    if old_email and new_email != old_email:
        log.debug('Creating user history for user: %s' % instance.pk)
        UserHistory.objects.create(email=old_email, user_id=instance.pk)
Esempio n. 50
0
    def save_upsold(self, obj, upsold):
        current_upsell = obj.upsold
        if upsold and upsold != obj.upsold.free:
            if not current_upsell:
                log.debug('[1@%s] Creating app upsell' % obj.pk)
                current_upsell = AddonUpsell(premium=obj)
            current_upsell.free = upsold
            current_upsell.save()

        elif current_upsell:
            # We're deleting the upsell.
            log.debug('[1@%s] Deleting the app upsell' % obj.pk)
            current_upsell.delete()
Esempio n. 51
0
 def create_user(self, username, email, fxa_id=None):
     # We'll send username=None when registering through FxA to generate
     # an anonymous username.
     now = timezone.now()
     user = self.model(
         username=username, email=email, fxa_id=fxa_id,
         last_login=now)
     if username is None:
         user.anonymize_username()
     log.debug('Creating user with email {} and username {}'.format(
         email, username))
     user.save(using=self._db)
     return user
Esempio n. 52
0
 def handle(self, *args, **kw):
     apps = {}
     for id, guid in Application.objects.values_list('id', 'guid'):
         apps[id] = dict(guid=guid,
                         versions=[],
                         name=amo.APPS_ALL[id].short)
     versions = (AppVersion.objects.values_list(
         'application', 'version').order_by('version_int'))
     for app, version in versions:
         apps[app]['versions'].append(version)
     with open(self.JSON_PATH, 'w') as f:
         json.dump(apps, f)
         log.debug("Wrote: %s" % f.name)
Esempio n. 53
0
def create_addon_purchase(sender, instance, **kw):
    """
    When the contribution table is updated with the data from PayPal,
    update the addon purchase table. Will figure out if we need to add to or
    delete from the AddonPurchase table.
    """
    if (kw.get('raw') or instance.type not in [
            mkt.CONTRIB_PURCHASE, mkt.CONTRIB_REFUND, mkt.CONTRIB_CHARGEBACK
    ]):
        # Filter the types we care about. Forget about the rest.
        return

    log.info('Processing addon purchase type: {t}, addon {a}, user {u}'.format(
        t=unicode(mkt.CONTRIB_TYPES[instance.type]),
        a=instance.addon and instance.addon.pk,
        u=instance.user and instance.user.pk))

    if instance.is_inapp_simulation():
        log.info('Simulated in-app product {i} for contribution {c}: '
                 'not adding a purchase record'.format(
                     i=instance.inapp_product, c=instance))
        return

    if instance.type == mkt.CONTRIB_PURCHASE:
        log.debug('Creating addon purchase: addon %s, user %s' %
                  (instance.addon.pk, instance.user.pk))

        data = {'addon': instance.addon, 'user': instance.user}
        purchase, created = AddonPurchase.objects.safer_get_or_create(**data)
        purchase.update(type=mkt.CONTRIB_PURCHASE)
        from mkt.webapps.models import Installed  # Circular import
        # Ensure that devs have the correct installed object found
        # or created.
        #
        is_dev = instance.addon.has_author(
            instance.user, (mkt.AUTHOR_ROLE_OWNER, mkt.AUTHOR_ROLE_DEV))
        install_type = (apps.INSTALL_TYPE_DEVELOPER
                        if is_dev else apps.INSTALL_TYPE_USER)
        Installed.objects.safer_get_or_create(user=instance.user,
                                              addon=instance.addon,
                                              install_type=install_type)

    elif instance.type in [mkt.CONTRIB_REFUND, mkt.CONTRIB_CHARGEBACK]:
        purchases = AddonPurchase.objects.filter(addon=instance.addon,
                                                 user=instance.user)
        for p in purchases:
            log.debug('Changing addon purchase: %s, addon %s, user %s' %
                      (p.pk, instance.addon.pk, instance.user.pk))
            p.update(type=instance.type)

    cache.delete(memoize_key('users:purchase-ids', instance.user.pk))
Esempio n. 54
0
def index_all(pks, **kw):
    ids_str = ','.join(map(str, pks))
    log.debug('ES starting bulk action for packages: [%s]' % ids_str)

    for package in Package.objects.filter(pk__in=pks):
        package.refresh_index(bulk=True)

    try:
        get_es().flush_bulk(forced=True)
    except KeyboardInterrupt:
        raise
    except Exception, e:
        log.error('ES failed bulk action (%s), package ids: [%s]' %
                  (e, ids_str))
Esempio n. 55
0
def add_can_localize(user):

    email = user.email
    log.debug(email)

    # Grant permission to Mozilla localizers
    url = "https://mozillians.org/api/v1/users/"
    payload = {
        "app_name": "pontoon",
        "app_key": settings.MOZILLIANS_API_KEY,
        "email": email,
        "is_vouched": True,
        "groups": "localization",
    }

    try:
        response = requests.get(url, params=payload)
        mozillians = response.json()["objects"]

        if len(mozillians) > 0:
            can_localize = Permission.objects.get(codename="can_localize")
            user.user_permissions.add(can_localize)
            log.debug("Permission can_localize set.")

            # Fallback if profile does not allow accessing data
            user.first_name = mozillians[0].get("full_name", email)
            user.save()

    except Exception as e:
        log.debug(e)
        log.debug("Is your MOZILLIANS_API_KEY set?")
        user.save()
Esempio n. 56
0
def clean_old_signed(seconds=60 * 60):
    """Clean out apps signed for reviewers."""
    log.info('Removing old apps signed for reviewers')
    root = settings.SIGNED_APPS_REVIEWER_PATH
    # Local storage uses local time for file modification. S3 uses UTC time.
    now = datetime.utcnow if storage_is_remote() else datetime.now
    for nextroot, dirs, files in walk_storage(root, storage=private_storage):
        for fn in files:
            full = os.path.join(nextroot, fn)
            age = now() - private_storage.modified_time(full)
            if age.total_seconds() > seconds:
                log.debug('Removing signed app: %s, %dsecs old.' %
                          (full, age.total_seconds()))
                private_storage.delete(full)
Esempio n. 57
0
def upload_to_amo(request, pk):
    """Upload a XPI to AMO
    """
    # check if there this Add-on was uploaded with the same version name
    revision = get_object_or_404(PackageRevision, pk=pk)
    version = revision.get_version_name()
    uploaded = PackageRevision.objects.filter(package=revision.package).filter(
        amo_version_name=version).exclude(amo_status=None).exclude(
            amo_status=STATUS_UPLOAD_FAILED).exclude(
                amo_status=STATUS_UPLOAD_SCHEDULED)
    if len(uploaded) > 0:
        log.debug("This Add-on was already uploaded using version \"%s\"" %
                  version)
        log.debug(revision.amo_status)
        return HttpResponseBadRequest(
            "This Add-on was already uploaded using version \"%s\"" % version)
    try:
        PackageRevision.objects.get(package=revision.package,
                                    amo_version_name=version,
                                    amo_status=STATUS_UPLOAD_SCHEDULED)
    except PackageRevision.DoesNotExist:
        pass
    else:
        log.debug("This Add-on is currently scheduled to upload")
        return HttpResponseBadRequest(
            "This Add-on is currently scheduled to upload")
    log.debug('AMOOAUTH: Scheduling upload to AMO')
    tasks.upload_to_amo.delay(pk)
    return HttpResponse('{"delayed": true}')
Esempio n. 58
0
def _redirect(request, login_url, redirect_field_name):
    """Redirects the request based on parameters."""
    path = request.build_absolute_uri()
    # If the login url is the same scheme and net location then just
    # use the path as the "next" url.
    login_scheme, login_netloc = urlparse.urlparse(login_url
                                                   or settings.LOGIN_URL)[:2]
    current_scheme, current_netloc = urlparse.urlparse(path)[:2]
    if ((not login_scheme or login_scheme == current_scheme)
            and (not login_netloc or login_netloc == current_netloc)):
        path = request.get_full_path()
    log.debug('Clearing user session')
    logout(request)
    return redirect_to_login(path, login_url, redirect_field_name)
Esempio n. 59
0
def change_password(unique_id, oldpass, password):
    """Changes a user's password."""
    dn = Person.dn(unique_id)

    conn = ldap.initialize(settings.LDAP_SYNC_PROVIDER_URI)
    try:
        conn.bind_s(dn, oldpass)

        conn.passwd_s(dn, None, password)
        log.debug("Changed %s password" % dn)
        return True
    except Exception, e:
        log.error("Password change failed %s", e)
        return False
Esempio n. 60
0
    def post(self, request, *args, **kwargs):
        form = PrepareInAppForm(request.DATA)
        if not form.is_valid():
            app_pay_cef.log(
                request._request,
                'Preparing InApp JWT Failed',
                'preparing_inapp_jwt_failed',
                'Preparing InApp JWT Failed error: {0}'.format(form.errors),
                severity=3
            )
            return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)

        inapp = form.cleaned_data['inapp']

        app_pay_cef.log(
            request._request,
            'Preparing InApp JWT',
            'preparing_inapp_jwt',
            'Preparing InApp JWT for: {0}'.format(inapp.pk), severity=3
        )

        log.debug('Starting purchase of in app: {0}'.format(inapp.pk))

        contribution = Contribution.objects.create(
            addon_id=inapp.webapp and inapp.webapp.pk,
            inapp_product=inapp,
            # In-App payments are unauthenticated so we have no user
            # and therefore can't determine a meaningful region.
            amount=None,
            paykey=None,
            price_tier=inapp.price,
            source=request._request.GET.get('src', ''),
            source_locale=request._request.LANG,
            type=mkt.CONTRIB_PENDING,
            user=None,
            uuid=str(uuid.uuid4()),
        )

        log.info('Storing contrib for uuid: {0}'.format(contribution.uuid))

        if inapp.simulate:
            log.info('Preparing in-app JWT simulation for {i}'
                     .format(i=inapp))
            product = SimulatedInAppProduct(inapp)
        else:
            log.info('Preparing in-app JWT for {i}'.format(i=inapp))
            product = InAppProduct(inapp)
        token = get_product_jwt(product, contribution)

        return Response(token, status=status.HTTP_201_CREATED)