Пример #1
0
def find_abuse_escalations(addon_id, **kw):
    weekago = datetime.date.today() - datetime.timedelta(days=7)
    add_to_queue = True

    for abuse in AbuseReport.recent_high_abuse_reports(1, weekago, addon_id):
        if EscalationQueue.objects.filter(addon=abuse.addon).exists():
            # App is already in the queue, no need to re-add it.
            task_log.info(u'[app:%s] High abuse reports, but already '
                          u'escalated' % abuse.addon)
            add_to_queue = False

        # We have an abuse report... has it been detected and dealt with?
        logs = (AppLog.objects.filter(
            activity_log__action=mkt.LOG.ESCALATED_HIGH_ABUSE.id,
            addon=abuse.addon).order_by('-created'))
        if logs:
            abuse_since_log = AbuseReport.recent_high_abuse_reports(
                1, logs[0].created, addon_id)
            # If no abuse reports have happened since the last logged abuse
            # report, do not add to queue.
            if not abuse_since_log:
                task_log.info(u'[app:%s] High abuse reports, but none since '
                              u'last escalation' % abuse.addon)
                continue

        # If we haven't bailed out yet, escalate this app.
        msg = u'High number of abuse reports detected'
        if add_to_queue:
            EscalationQueue.objects.create(addon=abuse.addon)
        mkt.log(mkt.LOG.ESCALATED_HIGH_ABUSE,
                abuse.addon,
                abuse.addon.current_version,
                details={'comments': msg})
        task_log.info(u'[app:%s] %s' % (abuse.addon, msg))
Пример #2
0
    def create_note(self, action):
        """
        Permissions default to developers + reviewers + Mozilla contacts.
        For escalation/comment, exclude the developer from the conversation.
        """
        details = {
            'comments': self.data['comments'],
            'reviewtype': self.review_type
        }
        if self.files:
            details['files'] = [f.id for f in self.files]

        tested = self.get_tested()  # You really should...
        if tested:
            self.data['comments'] += '\n\n%s' % tested

        # Commbadge (the future).
        note_type = comm.ACTION_MAP(action.id)
        self.comm_thread, self.comm_note = create_comm_note(
            self.addon,
            self.version,
            self.request.user,
            self.data['comments'],
            note_type=note_type,
            attachments=self.attachment_formset)

        # ActivityLog (ye olde).
        mkt.log(action,
                self.addon,
                self.version,
                user=self.user,
                created=datetime.now(),
                details=details)
Пример #3
0
def find_abuse_escalations(addon_id, **kw):
    weekago = datetime.date.today() - datetime.timedelta(days=7)
    add_to_queue = True

    for abuse in AbuseReport.recent_high_abuse_reports(1, weekago, addon_id):
        if EscalationQueue.objects.filter(addon=abuse.addon).exists():
            # App is already in the queue, no need to re-add it.
            task_log.info(u'[app:%s] High abuse reports, but already '
                          u'escalated' % abuse.addon)
            add_to_queue = False

        # We have an abuse report... has it been detected and dealt with?
        logs = (AppLog.objects.filter(
            activity_log__action=mkt.LOG.ESCALATED_HIGH_ABUSE.id,
            addon=abuse.addon).order_by('-created'))
        if logs:
            abuse_since_log = AbuseReport.recent_high_abuse_reports(
                1, logs[0].created, addon_id)
            # If no abuse reports have happened since the last logged abuse
            # report, do not add to queue.
            if not abuse_since_log:
                task_log.info(u'[app:%s] High abuse reports, but none since '
                              u'last escalation' % abuse.addon)
                continue

        # If we haven't bailed out yet, escalate this app.
        msg = u'High number of abuse reports detected'
        if add_to_queue:
            EscalationQueue.objects.create(addon=abuse.addon)
        mkt.log(mkt.LOG.ESCALATED_HIGH_ABUSE, abuse.addon,
                abuse.addon.current_version, details={'comments': msg})
        task_log.info(u'[app:%s] %s' % (abuse.addon, msg))
Пример #4
0
 def perform_create(self, serializer):
     serializer.save()
     app = serializer.instance.addon
     mkt.log(mkt.LOG.ADD_REVIEW, app, serializer.instance)
     log.debug('[Review:%s] Created by user %s ' %
               (serializer.instance.pk, self.request.user.id))
     record_action('new-review', self.request, {'app-id': app.id})
Пример #5
0
    def delete(self):
        log.info(u'Version deleted: %r (%s)' % (self, self.id))
        mkt.log(mkt.LOG.DELETE_VERSION, self.addon, str(self.version))

        models.signals.pre_delete.send(sender=Version, instance=self)

        was_current = False
        if self == self.addon.current_version:
            was_current = True

        self.update(deleted=True)

        # Set file status to disabled.
        f = self.all_files[0]
        f.update(status=mkt.STATUS_DISABLED, _signal=False)
        f.hide_disabled_file()

        # If version deleted was the current version and there now exists
        # another current_version, we need to call some extra methods to update
        # various bits for packaged apps.
        if was_current and self.addon.current_version:
            self.addon.update_name_from_package_manifest()
            self.addon.update_supported_locales()

        if self.addon.is_packaged:
            # Unlink signed packages if packaged app.
            storage.delete(f.signed_file_path)
            log.info(u'Unlinked file: %s' % f.signed_file_path)
            storage.delete(f.signed_reviewer_file_path)
            log.info(u'Unlinked file: %s' % f.signed_reviewer_file_path)

        models.signals.post_delete.send(sender=Version, instance=self)
Пример #6
0
    def test_rejected(self):
        comments = "oh no you di'nt!!"
        mkt.set_user(UserProfile.objects.get(email='*****@*****.**'))
        mkt.log(mkt.LOG.REJECT_VERSION, self.webapp,
                self.webapp.current_version, user_id=999,
                details={'comments': comments, 'reviewtype': 'pending'})
        self.webapp.update(status=mkt.STATUS_REJECTED)
        make_rated(self.webapp)
        (self.webapp.versions.latest()
                             .all_files[0].update(status=mkt.STATUS_REJECTED))

        r = self.client.get(self.url)
        eq_(r.status_code, 200)
        doc = pq(r.content)('#version-status')
        eq_(doc('.status-rejected').length, 1)
        eq_(doc('#rejection').length, 1)
        eq_(doc('#rejection blockquote').text(), comments)

        my_reply = 'fixed just for u, brah'
        r = self.client.post(self.url, {'notes': my_reply,
                                        'resubmit-app': ''})
        self.assert3xx(r, self.url, 302)

        webapp = self.get_webapp()
        eq_(webapp.status, mkt.STATUS_PENDING,
            'Reapplied apps should get marked as pending')
        eq_(webapp.versions.latest().all_files[0].status, mkt.STATUS_PENDING,
            'Files for reapplied apps should get marked as pending')
        action = mkt.LOG.WEBAPP_RESUBMIT
        assert AppLog.objects.filter(
            addon=webapp, activity_log__action=action.id).exists(), (
                "Didn't find `%s` action in logs." % action.short)
Пример #7
0
    def test_older_abuses_cleared_then_new(self):
        for x in range(2):
            ar = AbuseReport.objects.create(addon=self.app)
            ar.created = datetime.datetime.now() - datetime.timedelta(days=1)
            ar.save()
        find_abuse_escalations(self.app.id)
        eq_(EscalationQueue.objects.filter(addon=self.app).count(), 1)

        # Simulate a reviewer clearing an escalation... remove app from queue,
        # and write a log.
        EscalationQueue.objects.filter(addon=self.app).delete()
        mkt.log(mkt.LOG.ESCALATION_CLEARED,
                self.app,
                self.app.current_version,
                details={'comments': 'All clear'})
        eq_(EscalationQueue.objects.filter(addon=self.app).count(), 0)

        # Task will find it again but not add it again.
        find_abuse_escalations(self.app.id)
        eq_(EscalationQueue.objects.filter(addon=self.app).count(), 0)

        # New abuse reports that come in should re-add to queue.
        for x in range(2):
            AbuseReport.objects.create(addon=self.app)
        find_abuse_escalations(self.app.id)
        eq_(EscalationQueue.objects.filter(addon=self.app).count(), 1)
Пример #8
0
    def test_rejected(self):
        comments = "oh no you di'nt!!"
        mkt.set_user(UserProfile.objects.get(email='*****@*****.**'))
        mkt.log(mkt.LOG.REJECT_VERSION, self.webapp,
                self.webapp.current_version, user_id=999,
                details={'comments': comments, 'reviewtype': 'pending'})
        self.webapp.update(status=mkt.STATUS_REJECTED)
        make_rated(self.webapp)
        (self.webapp.versions.latest()
                             .all_files[0].update(status=mkt.STATUS_DISABLED))

        r = self.client.get(self.url)
        eq_(r.status_code, 200)
        doc = pq(r.content)('#version-status')
        eq_(doc('.status-rejected').length, 1)
        eq_(doc('#rejection').length, 1)
        eq_(doc('#rejection blockquote').text(), comments)

        my_reply = 'fixed just for u, brah'
        r = self.client.post(self.url, {'notes': my_reply,
                                        'resubmit-app': ''})
        self.assert3xx(r, self.url, 302)

        webapp = self.get_webapp()
        eq_(webapp.status, mkt.STATUS_PENDING,
            'Reapplied apps should get marked as pending')
        eq_(webapp.versions.latest().all_files[0].status, mkt.STATUS_PENDING,
            'Files for reapplied apps should get marked as pending')
        action = mkt.LOG.WEBAPP_RESUBMIT
        assert AppLog.objects.filter(
            addon=webapp, activity_log__action=action.id).exists(), (
                "Didn't find `%s` action in logs." % action.short)
Пример #9
0
 def setUp(self):
     self.user = UserProfile.objects.create(email='*****@*****.**',
                                            name='gc_test')
     mkt.log(mkt.LOG.CUSTOM_TEXT,
             'testing',
             user=self.user,
             created=datetime(2001, 1, 1))
Пример #10
0
 def save(self):
     for form in self.forms:
         if form.cleaned_data:
             mark_read = form.cleaned_data.get('action', False)
             inst = form.instance
             if mark_read:
                 for report in inst.abuse_reports.all().filter(read=False):
                     report.read = True
                     report.save()
                     if report.addon:
                         mkt.log(mkt.LOG.APP_ABUSE_MARKREAD, report.addon,
                                 report,
                                 details=dict(
                                     body=unicode(report.message),
                                     addon_id=report.addon.id,
                                     addon_title=unicode(
                                         report.addon.name)))
                     elif report.user:
                         # Not possible on Marketplace currently.
                         pass
                     elif report.website:
                         mkt.log(mkt.LOG.WEBSITE_ABUSE_MARKREAD,
                                 report.website, report,
                                 details=dict(
                                     body=unicode(report.message),
                                     website_id=report.website.id,
                                     website_title=unicode(
                                         report.website.name)))
Пример #11
0
    def create_note(self, action):
        """
        Permissions default to developers + reviewers + Mozilla contacts.
        For escalation/comment, exclude the developer from the conversation.
        """
        details = {'comments': self.data['comments'],
                   'reviewtype': self.review_type}
        if self.files:
            details['files'] = [f.id for f in self.files]

        tested = self.get_tested()  # You really should...
        if tested:
            self.data['comments'] += '\n\n%s' % tested

        # Commbadge (the future).
        note_type = comm.ACTION_MAP(action.id)
        self.comm_thread, self.comm_note = create_comm_note(
            self.addon, self.version, self.request.user,
            self.data['comments'], note_type=note_type,
            attachments=self.attachment_formset)

        # ActivityLog (ye olde).
        mkt.log(action, self.addon, self.version, user=self.user,
                created=datetime.now(), details=details,
                attachments=self.attachment_formset)
Пример #12
0
 def perform_create(self, serializer):
     serializer.save()
     app = serializer.instance.addon
     mkt.log(mkt.LOG.ADD_REVIEW, app, serializer.instance)
     log.debug('[Review:%s] Created by user %s ' %
               (serializer.instance.pk, self.request.user.id))
     record_action('new-review', self.request, {'app-id': app.id})
Пример #13
0
 def test_empty_comment(self):
     mkt.log(mkt.LOG.REQUEST_VERSION, self.app, self.version,
             user=self.user, details={})
     call_command('migrate_activity_log')
     note = CommunicationNote.objects.get()
     eq_(note.thread.addon, self.app)
     eq_(note.body, '')
Пример #14
0
    def delete(self):
        log.info(u'Version deleted: %r (%s)' % (self, self.id))
        mkt.log(mkt.LOG.DELETE_VERSION, self.webapp, str(self.version))

        models.signals.pre_delete.send(sender=Version, instance=self)

        was_current = False
        if self == self.webapp.current_version:
            was_current = True

        self.update(deleted=True)

        # Set file status to disabled.
        f = self.all_files[0]
        f.update(status=mkt.STATUS_DISABLED, _signal=False)
        f.hide_disabled_file()

        # If version deleted was the current version and there now exists
        # another current_version, we need to call some extra methods to update
        # various bits for packaged apps.
        if was_current and self.webapp.current_version:
            self.webapp.update_name_from_package_manifest()
            self.webapp.update_supported_locales()

        if self.webapp.is_packaged:
            # Unlink signed packages if packaged app.
            public_storage.delete(f.signed_file_path)
            log.info(u'Unlinked file: %s' % f.signed_file_path)
            private_storage.delete(f.signed_reviewer_file_path)
            log.info(u'Unlinked file: %s' % f.signed_reviewer_file_path)

        models.signals.post_delete.send(sender=Version, instance=self)
Пример #15
0
def process_iarc_changes(date=None):
    """
    Queries IARC for recent changes in the past 24 hours (or date provided).

    If date provided use it. It should be in the form YYYY-MM-DD.

    NOTE: Get_Rating_Changes only sends the diff of the changes
    by rating body. They only send data for the ratings bodies that
    changed.
    """
    if not date:
        date = datetime.date.today()
    else:
        date = datetime.datetime.strptime(date, '%Y-%m-%d').date()

    client = lib.iarc.client.get_iarc_client('services')
    xml = lib.iarc.utils.render_xml(
        'get_rating_changes.xml', {
            'date_from': date - datetime.timedelta(days=1),
            'date_to': date,
        })
    resp = client.Get_Rating_Changes(XMLString=xml)
    data = lib.iarc.utils.IARC_XML_Parser().parse_string(resp)

    for row in data.get('rows', []):
        iarc_id = row.get('submission_id')
        if not iarc_id:
            log.debug('IARC changes contained no submission ID: %s' % row)
            continue

        try:
            app = Webapp.objects.get(iarc_info__submission_id=iarc_id)
        except Webapp.DoesNotExist:
            log.debug('Could not find app associated with IARC submission ID: '
                      '%s' % iarc_id)
            continue

        try:
            # Fetch and save all IARC info.
            refresh_iarc_ratings([app.id])

            # Flag for rereview if it changed to adult.
            ratings_body = row.get('rating_system')
            rating = RATINGS[ratings_body.id].get(row['new_rating'])
            _flag_rereview_adult(app, ratings_body, rating)

            # Log change reason.
            reason = row.get('change_reason')
            mkt.log(mkt.LOG.CONTENT_RATING_CHANGED,
                    app,
                    details={
                        'comments':
                        '%s:%s, %s' % (ratings_body.name, rating.name, reason)
                    })

        except Exception as e:
            # Any exceptions we catch, log, and keep going.
            log.debug('Exception: %s' % e)
            continue
Пример #16
0
def prioritize_app(app, user):
    app.update(priority_review=True)
    msg = u'Priority Review Requested'
    # Create notes and log entries.
    create_comm_note(app, app.latest_version, user, msg,
                     note_type=comm.PRIORITY_REVIEW_REQUESTED)
    mkt.log(mkt.LOG.PRIORITY_REVIEW_REQUESTED, app, app.latest_version,
            created=datetime.now(), details={'comments': msg})
Пример #17
0
def prioritize_app(app, user):
    app.update(priority_review=True)
    msg = u'Priority Review Requested'
    # Create notes and log entries.
    create_comm_note(app, app.latest_version, user, msg,
                     note_type=comm.PRIORITY_REVIEW_REQUESTED)
    mkt.log(mkt.LOG.PRIORITY_REVIEW_REQUESTED, app, app.latest_version,
            created=datetime.now(), details={'comments': msg})
Пример #18
0
def _record(request, addon):
    logged = request.user.is_authenticated()
    premium = addon.is_premium()

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

    ctx = {'addon': addon.pk}

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

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

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

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

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

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

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

    return ctx
Пример #19
0
 def test_display(self):
     mkt.log(mkt.LOG.PURCHASE_ADDON, self.app, user=self.user)
     mkt.log(mkt.LOG.ADMIN_USER_EDITED, self.user, 'spite', user=self.user)
     self.login(self.reviewer)
     res = self.client.get(self.url)
     eq_(res.status_code, 200)
     doc = pq(res.content)
     assert 'purchased' in doc('li.item').eq(0).text()
     assert 'edited' in doc('li.item').eq(1).text()
Пример #20
0
def record(request, app):
    mkt.log(mkt.LOG.INSTALL_WEBAPP, app)
    domain = app.domain_from_url(app.origin, allow_none=True)
    record_action('install', request, {
        'app-domain': domain,
        'app-id': app.pk,
        'region': request.REGION.slug,
        'anonymous': request.user.is_anonymous(),
    })
Пример #21
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)
Пример #22
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)
Пример #23
0
def record(request, app):
    mkt.log(mkt.LOG.INSTALL_ADDON, app)
    domain = app.domain_from_url(app.origin, allow_none=True)
    record_action(
        'install', request, {
            'app-domain': domain,
            'app-id': app.pk,
            'region': request.REGION.slug,
            'anonymous': request.user.is_anonymous(),
        })
Пример #24
0
def _record(request, addon):
    logged = request.user.is_authenticated()
    premium = addon.is_premium()

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

    ctx = {'addon': addon.pk}

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

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

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

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

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

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

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

    return ctx
Пример #25
0
def process_iarc_changes(date=None):
    """
    Queries IARC for recent changes in the past 24 hours (or date provided).

    If date provided use it. It should be in the form YYYY-MM-DD.

    NOTE: Get_Rating_Changes only sends the diff of the changes
    by rating body. They only send data for the ratings bodies that
    changed.
    """
    if not date:
        date = datetime.date.today()
    else:
        date = datetime.datetime.strptime(date, '%Y-%m-%d').date()

    client = lib.iarc.client.get_iarc_client('services')
    xml = lib.iarc.utils.render_xml('get_rating_changes.xml', {
        'date_from': date - datetime.timedelta(days=1),
        'date_to': date,
    })
    resp = client.Get_Rating_Changes(XMLString=xml)
    data = lib.iarc.utils.IARC_XML_Parser().parse_string(resp)

    for row in data.get('rows', []):
        iarc_id = row.get('submission_id')
        if not iarc_id:
            log.debug('IARC changes contained no submission ID: %s' % row)
            continue

        try:
            app = Webapp.objects.get(iarc_info__submission_id=iarc_id)
        except Webapp.DoesNotExist:
            log.debug('Could not find app associated with IARC submission ID: '
                      '%s' % iarc_id)
            continue

        try:
            # Fetch and save all IARC info.
            refresh_iarc_ratings([app.id])

            # Flag for rereview if it changed to adult.
            ratings_body = row.get('rating_system')
            rating = RATINGS[ratings_body.id].get(row['new_rating'])
            _flag_rereview_adult(app, ratings_body, rating)

            # Log change reason.
            reason = row.get('change_reason')
            mkt.log(mkt.LOG.CONTENT_RATING_CHANGED, app,
                    details={'comments': '%s:%s, %s' %
                             (ratings_body.name, rating.name, reason)})

        except Exception as e:
            # Any exceptions we catch, log, and keep going.
            log.debug('Exception: %s' % e)
            continue
Пример #26
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))
Пример #27
0
def log_reviewer_action(addon, user, msg, action, **kwargs):
    create_comm_note(addon,
                     addon.latest_version,
                     user,
                     msg,
                     note_type=comm.ACTION_MAP(action.id))
    mkt.log(action,
            addon,
            addon.latest_version,
            details={'comments': msg},
            **kwargs)
Пример #28
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))
Пример #29
0
 def save(self):
     version = self.product.versions.latest()
     notes = self.cleaned_data["notes"]
     if notes:
         mkt.log(mkt.LOG.WEBAPP_RESUBMIT, self.product, version, details={"comments": notes})
     else:
         mkt.log(mkt.LOG.WEBAPP_RESUBMIT, self.product, version)
     # Mark app and file as pending again.
     self.product.update(status=mkt.WEBAPPS_UNREVIEWED_STATUS)
     version.all_files[0].update(status=mkt.WEBAPPS_UNREVIEWED_STATUS)
     return version
Пример #30
0
    def test_logs(self):
        # Admin log.
        mkt.log(mkt.LOG.COMMENT_VERSION, self.app, self.app.current_version,
                user=self.user)
        # Regular log.
        mkt.log(mkt.LOG.MANIFEST_UPDATED, self.app, user=self.user)

        self.login(self.reviewer)
        res = self.client.get(self.url)
        doc = pq(res.content)
        assert 'manifest updated' in doc('li.item').eq(0).text()
        assert 'Comment on' in doc('li.item').eq(1).text()
Пример #31
0
 def save(self):
     version = self.product.versions.latest()
     notes = self.cleaned_data['notes']
     if notes:
         mkt.log(mkt.LOG.WEBAPP_RESUBMIT, self.product, version,
                 details={'comments': notes})
     else:
         mkt.log(mkt.LOG.WEBAPP_RESUBMIT, self.product, version)
     # Mark app and file as pending again.
     self.product.update(status=mkt.WEBAPPS_UNREVIEWED_STATUS)
     version.all_files[0].update(status=mkt.WEBAPPS_UNREVIEWED_STATUS)
     return version
Пример #32
0
def escalate_app(app, version, user, msg, log_type):
    # Add to escalation queue
    EscalationQueue.objects.get_or_create(addon=app)

    # Create comm note
    create_comm_note(app, version, user, msg,
                     note_type=comm.ACTION_MAP(log_type))

    # Log action
    mkt.log(log_type, app, version, created=datetime.now(),
            details={'comments': msg})
    log.info(u'[app:%s] escalated - %s' % (app.name, msg))
Пример #33
0
def escalate_app(app, version, user, msg, log_type):
    # Add to escalation queue
    EscalationQueue.objects.get_or_create(addon=app)

    # Create comm note
    create_comm_note(app, version, user, msg,
                     note_type=comm.ACTION_MAP(log_type))

    # Log action
    mkt.log(log_type, app, version, created=datetime.now(),
            details={'comments': msg})
    log.info(u'[app:%s] escalated - %s' % (app.name, msg))
Пример #34
0
    def flag(cls, addon, event, message=None):
        cls.objects.get_or_create(addon=addon)
        version = addon.current_version or addon.latest_version
        if message:
            mkt.log(event, addon, version, details={"comments": message})
        else:
            mkt.log(event, addon, version)

        # TODO: if we ever get rid of ActivityLog for reviewer notes, replace
        # all flag calls to use the comm constant and not have to use
        # ACTION_MAP.
        create_comm_note(addon, version, None, message, note_type=comm.ACTION_MAP(event))
Пример #35
0
def record(request, app):
    mkt.log(mkt.LOG.INSTALL_ADDON, app)
    domain = app.domain_from_url(app.origin, allow_none=True)
    record_action(
        "install",
        request,
        {
            "app-domain": domain,
            "app-id": app.pk,
            "region": request.REGION.slug,
            "anonymous": request.user.is_anonymous(),
        },
    )
Пример #36
0
def app_summary(request, addon_id):
    app = get_object_or_404(Webapp.with_deleted, pk=addon_id)

    if 'prioritize' in request.POST and not app.priority_review:
        app.update(priority_review=True)
        msg = u'Priority Review Requested'
        # Create notes and log entries.
        create_comm_note(app, app.latest_version, request.user, msg,
                         note_type=comm.PRIORITY_REVIEW_REQUESTED)
        mkt.log(mkt.LOG.PRIORITY_REVIEW_REQUESTED, app, app.latest_version,
                created=datetime.now(), details={'comments': msg})

    authors = (app.authors.filter(addonuser__role__in=(mkt.AUTHOR_ROLE_DEV,
                                                       mkt.AUTHOR_ROLE_OWNER))
               .order_by('display_name'))

    if app.premium and app.premium.price:
        price = app.premium.price
    else:
        price = None

    purchases, refunds = _app_purchases_and_refunds(app)
    provider_portals = get_payment_provider_portals(app=app)
    versions = None

    status_form = APIStatusForm(initial={
        'status': mkt.STATUS_CHOICES_API[app.status]
    })
    version_status_forms = {}
    if app.is_packaged:
        versions = app.versions.all().order_by('-created')
        for v in versions:
            version_status_forms[v.pk] = APIFileStatusForm(initial={
                'status': mkt.STATUS_CHOICES_API[v.all_files[0].status]
            })

    permissions = {}
    if app.latest_version:
        permissions = app.latest_version.manifest.get('permissions', {})

    return render(request, 'lookup/app_summary.html', {
        'abuse_reports': app.abuse_reports.count(), 'app': app,
        'authors': authors, 'purchases': purchases, 'refunds': refunds,
        'price': price, 'provider_portals': provider_portals,
        'status_form': status_form, 'versions': versions,
        'is_tarako': app.tags.filter(tag_text=QUEUE_TARAKO).exists(),
        'tarako_review':
            app.additionalreview_set.latest_for_queue(QUEUE_TARAKO),
        'version_status_forms': version_status_forms,
        'permissions': permissions,
    })
Пример #37
0
    def test_get_or_create(self):
        mkt.log(mkt.LOG.REQUEST_VERSION, self.app, self.version,
                user=self.user, details={'comments': 'something'})
        self._assert(comm.NO_ACTION)
        call_command('migrate_activity_log')
        call_command('migrate_activity_log')
        eq_(CommunicationNote.objects.count(), 1)

        mkt.log(mkt.LOG.REQUEST_VERSION, self.app, self.version,
                user=self.user, details={'comments': 'somethingNEW'})
        call_command('migrate_activity_log')
        eq_(CommunicationNote.objects.count(), 2)

        eq_(CommunicationThread.objects.count(), 1)
Пример #38
0
def user_delete(request, user_id):
    delete_form = DeleteUserForm(request.POST)
    if not delete_form.is_valid():
        messages.error(request, delete_form.errors)
        return HttpResponseRedirect(reverse('lookup.user_summary',
                                            args=[user_id]))

    user = get_object_or_404(UserProfile, pk=user_id)
    user.deleted = True
    user.save()  # Must call the save function to delete user.
    mkt.log(mkt.LOG.DELETE_USER_LOOKUP, user,
            details={'reason': delete_form.cleaned_data['delete_reason']},
            user=request.user)

    return HttpResponseRedirect(reverse('lookup.user_summary', args=[user_id]))
Пример #39
0
    def save(self):
        for form in self.forms:
            if form.cleaned_data:
                action = int(form.cleaned_data['action'])
                if action == ABUSE_REPORT_SKIP:
                    continue

                inst = form.instance

                app = None
                site = None
                user = None
                texts = []
                for report in inst.abuse_reports.all().filter(read=False):
                    report.read = True
                    report.save()
                    app = report.addon
                    site = report.website
                    user = report.user
                    if report.message:
                        texts.append(report.message)
                    if app:
                        mkt.log(mkt.LOG.APP_ABUSE_MARKREAD,
                                app,
                                report,
                                details=dict(body=unicode(report.message),
                                             addon_id=app.id,
                                             addon_title=unicode(app.name)))
                    elif user:
                        # Not possible on Marketplace currently.
                        pass
                    elif site:
                        mkt.log(mkt.LOG.WEBSITE_ABUSE_MARKREAD,
                                site,
                                report,
                                details=dict(body=unicode(report.message),
                                             website_id=site.id,
                                             website_title=unicode(site.name)))
                if app or site:
                    ReviewerScore.award_mark_abuse_points(self.request.user,
                                                          addon=app,
                                                          website=site)
                if app and action == ABUSE_REPORT_FLAG:
                    message = _('Abuse reports needing investigation: %s' %
                                (', '.join(texts)))
                    RereviewQueue.flag(app,
                                       mkt.LOG.REREVIEW_ABUSE_APP,
                                       message=message)
Пример #40
0
 def test_total_last_month(self):
     log = mkt.log(mkt.LOG["APPROVE_VERSION"], Webapp.objects.get())
     log.update(created=self.lm)
     result = ActivityLog.objects.total_reviews()
     eq_(len(result), 1)
     eq_(result[0]["approval_count"], 1)
     eq_(result[0]["user"], self.user.pk)
Пример #41
0
def version_publicise(request, addon_id, addon):
    version_id = request.POST.get("version_id")
    version = get_object_or_404(Version, pk=version_id, addon=addon)

    if version.all_files[0].status == mkt.STATUS_APPROVED:
        File.objects.filter(version=version).update(status=mkt.STATUS_PUBLIC)
        mkt.log(mkt.LOG.CHANGE_VERSION_STATUS, unicode(version.status[0]), version)
        # Call update_version, so various other bits of data update.
        addon.update_version()

        # Call to update names and locales if changed.
        addon.update_name_from_package_manifest()
        addon.update_supported_locales()
        messages.success(request, _("Version successfully made active."))

    return redirect(addon.get_dev_url("versions"))
Пример #42
0
    def test_created(self):
        """
        Verify that we preserve the create date.
        """
        al = mkt.log(mkt.LOG.CUSTOM_TEXT, 'hi', created=datetime(2009, 1, 1))

        eq_(al.created, datetime(2009, 1, 1))
Пример #43
0
    def flag(cls, addon, event, message=None):
        cls.objects.get_or_create(addon=addon)
        version = addon.current_version or addon.latest_version
        if message:
            mkt.log(event, addon, version, details={'comments': message})
        else:
            mkt.log(event, addon, version)

        # TODO: if we ever get rid of ActivityLog for reviewer notes, replace
        # all flag calls to use the comm constant and not have to use
        # ACTION_MAP.
        create_comm_note(addon,
                         version,
                         None,
                         message,
                         note_type=comm.ACTION_MAP(event))
Пример #44
0
def user_activity(request, user_id):
    """Shows the user activity page for another user."""
    user = get_object_or_404(UserProfile, pk=user_id)
    products = purchase_list(request, user)
    is_admin = acl.action_allowed(request, 'Users', 'Edit')

    user_items = ActivityLog.objects.for_user(user).exclude(
        action__in=mkt.LOG_HIDE_DEVELOPER)
    admin_items = ActivityLog.objects.for_user(user).filter(
        action__in=mkt.LOG_HIDE_DEVELOPER)
    mkt.log(mkt.LOG.ADMIN_VIEWED_LOG, request.user, user=user)
    return render(request, 'lookup/user_activity.html',
                  {'pager': products, 'account': user, 'is_admin': is_admin,
                   'single': bool(None),
                   'user_items': user_items, 'admin_items': admin_items,
                   'show_link': False})
Пример #45
0
    def test_already_escalated_for_other_still_logs(self):
        # Add app to queue for high refunds.
        EscalationQueue.objects.create(webapp=self.app)
        mkt.log(mkt.LOG.ESCALATED_HIGH_REFUNDS, self.app,
                self.app.current_version, details={'comments': 'hi refunds'})

        # Set up abuses.
        for x in range(2):
            AbuseReport.objects.create(webapp=self.app)
        find_abuse_escalations(self.app.id)

        # Verify it logged the high abuse reports.
        action = mkt.LOG.ESCALATED_HIGH_ABUSE
        assert AppLog.objects.filter(
            webapp=self.app, activity_log__action=action.id).exists(), (
                u'Expected high abuse to be logged')
Пример #46
0
 def test_total_last_month(self):
     log = mkt.log(mkt.LOG['APPROVE_VERSION'], Webapp.objects.get())
     log.update(created=self.lm)
     result = ActivityLog.objects.total_reviews()
     eq_(len(result), 1)
     eq_(result[0]['approval_count'], 1)
     eq_(result[0]['user'], self.user.pk)
Пример #47
0
    def save(self):

        for form in self.forms:
            if form.cleaned_data and user_can_delete_review(self.request, form.instance):
                action = int(form.cleaned_data["action"])

                is_flagged = form.instance.reviewflag_set.count() > 0

                if action != REVIEW_MODERATE_SKIP:  # Delete flags.
                    for flag in form.instance.reviewflag_set.all():
                        flag.delete()

                review = form.instance
                webapp = review.webapp
                if action == REVIEW_MODERATE_DELETE:
                    review.delete()
                    mkt.log(
                        mkt.LOG.DELETE_REVIEW,
                        webapp,
                        review,
                        details=dict(
                            title=unicode(review.title),
                            body=unicode(review.body),
                            webapp_id=webapp.id,
                            webapp_title=unicode(webapp.name),
                            is_flagged=is_flagged,
                        ),
                    )
                    if self.request:
                        ReviewerScore.award_moderation_points(self.request.user, webapp, review.id)
                elif action == REVIEW_MODERATE_KEEP:
                    review.editorreview = False
                    review.save()
                    mkt.log(
                        mkt.LOG.APPROVE_REVIEW,
                        webapp,
                        review,
                        details=dict(
                            title=unicode(review.title),
                            body=unicode(review.body),
                            webapp_id=webapp.id,
                            webapp_title=unicode(webapp.name),
                            is_flagged=is_flagged,
                        ),
                    )
                    if self.request:
                        ReviewerScore.award_moderation_points(self.request.user, webapp, review.id)
Пример #48
0
    def save(self):
        for form in self.forms:
            if form.cleaned_data:
                action = int(form.cleaned_data['action'])
                if action == ABUSE_REPORT_SKIP:
                    continue

                inst = form.instance

                app = None
                site = None
                user = None
                texts = []
                for report in inst.abuse_reports.all().filter(read=False):
                    report.read = True
                    report.save()
                    app = report.addon
                    site = report.website
                    user = report.user
                    if report.message:
                        texts.append(report.message)
                    if app:
                        mkt.log(mkt.LOG.APP_ABUSE_MARKREAD, app, report,
                                details=dict(
                                    body=unicode(report.message),
                                    addon_id=app.id,
                                    addon_title=unicode(app.name)
                                ))
                    elif user:
                        # Not possible on Marketplace currently.
                        pass
                    elif site:
                        mkt.log(mkt.LOG.WEBSITE_ABUSE_MARKREAD, site,
                                report,
                                details=dict(
                                    body=unicode(report.message),
                                    website_id=site.id,
                                    website_title=unicode(site.name)
                                ))
                if app or site:
                    ReviewerScore.award_mark_abuse_points(
                        self.request.user, addon=app, website=site)
                if app and action == ABUSE_REPORT_FLAG:
                    message = _('Abuse reports needing investigation: %s' %
                                (', '.join(texts)))
                    RereviewQueue.flag(
                        app, mkt.LOG.REREVIEW_ABUSE_APP, message=message)
Пример #49
0
    def test_rejected_packaged(self):
        self.webapp.update(is_packaged=True)
        comments = "oh no you di'nt!!"
        mkt.set_user(UserProfile.objects.get(email='*****@*****.**'))
        mkt.log(mkt.LOG.REJECT_VERSION, self.webapp,
                self.webapp.current_version, user_id=999,
                details={'comments': comments, 'reviewtype': 'pending'})
        self.webapp.update(status=mkt.STATUS_REJECTED)
        (self.webapp.versions.latest()
                             .all_files[0].update(status=mkt.STATUS_DISABLED))

        r = self.client.get(self.url)
        eq_(r.status_code, 200)
        doc = pq(r.content)('#version-status')
        eq_(doc('.status-rejected').length, 1)
        eq_(doc('#rejection').length, 1)
        eq_(doc('#rejection blockquote').text(), comments)
Пример #50
0
    def save(self):
        publish = self.cleaned_data['publish_type']
        limited = self.cleaned_data['limited']

        if publish == mkt.PUBLISH_HIDDEN and limited:
            publish = mkt.PUBLISH_PRIVATE

        status = self.STATUS_MAPPING[publish]
        self.addon.update(status=status)

        mkt.log(mkt.LOG.CHANGE_STATUS, self.addon.get_status_display(),
                self.addon)
        # Call update_version, so various other bits of data update.
        self.addon.update_version()
        # Call to update names and locales if changed.
        self.addon.update_name_from_package_manifest()
        self.addon.update_supported_locales()
Пример #51
0
    def test_rejected_packaged(self):
        self.webapp.update(is_packaged=True)
        comments = "oh no you di'nt!!"
        mkt.set_user(UserProfile.objects.get(email='*****@*****.**'))
        mkt.log(mkt.LOG.REJECT_VERSION, self.webapp,
                self.webapp.current_version, user_id=999,
                details={'comments': comments, 'reviewtype': 'pending'})
        self.webapp.update(status=mkt.STATUS_REJECTED)
        (self.webapp.versions.latest()
                             .all_files[0].update(status=mkt.STATUS_REJECTED))

        r = self.client.get(self.url)
        eq_(r.status_code, 200)
        doc = pq(r.content)('#version-status')
        eq_(doc('.status-rejected').length, 1)
        eq_(doc('#rejection').length, 1)
        eq_(doc('#rejection blockquote').text(), comments)
Пример #52
0
def version_publicise(request, addon_id, addon):
    version_id = request.POST.get('version_id')
    version = get_object_or_404(Version, pk=version_id, addon=addon)

    if version.all_files[0].status == mkt.STATUS_APPROVED:
        File.objects.filter(version=version).update(status=mkt.STATUS_PUBLIC)
        mkt.log(mkt.LOG.CHANGE_VERSION_STATUS, unicode(version.status[0]),
                version)
        # Call update_version, so various other bits of data update.
        addon.update_version()

        # Call to update names and locales if changed.
        addon.update_name_from_package_manifest()
        addon.update_supported_locales()
        messages.success(request, _('Version successfully made active.'))

    return redirect(addon.get_dev_url('versions'))
Пример #53
0
    def test_already_escalated_for_other_still_logs(self):
        # Add app to queue for high refunds.
        EscalationQueue.objects.create(addon=self.app)
        mkt.log(mkt.LOG.ESCALATED_HIGH_REFUNDS,
                self.app,
                self.app.current_version,
                details={'comments': 'hi refunds'})

        # Set up abuses.
        for x in range(2):
            AbuseReport.objects.create(addon=self.app)
        find_abuse_escalations(self.app.id)

        # Verify it logged the high abuse reports.
        action = mkt.LOG.ESCALATED_HIGH_ABUSE
        assert AppLog.objects.filter(
            addon=self.app, activity_log__action=action.id).exists(), (
                u'Expected high abuse to be logged')
Пример #54
0
    def save(self):

        for form in self.forms:
            if form.cleaned_data and user_can_delete_review(
                    self.request, form.instance):
                action = int(form.cleaned_data['action'])

                is_flagged = (form.instance.reviewflag_set.count() > 0)

                if action != REVIEW_MODERATE_SKIP:  # Delete flags.
                    for flag in form.instance.reviewflag_set.all():
                        flag.delete()

                review = form.instance
                addon = review.addon
                if action == REVIEW_MODERATE_DELETE:
                    review.delete()
                    mkt.log(mkt.LOG.DELETE_REVIEW,
                            addon,
                            review,
                            details=dict(title=unicode(review.title),
                                         body=unicode(review.body),
                                         addon_id=addon.id,
                                         addon_title=unicode(addon.name),
                                         is_flagged=is_flagged))
                    if self.request:
                        ReviewerScore.award_moderation_points(
                            self.request.user, addon, review.id)
                elif action == REVIEW_MODERATE_KEEP:
                    review.editorreview = False
                    review.save()
                    mkt.log(mkt.LOG.APPROVE_REVIEW,
                            addon,
                            review,
                            details=dict(title=unicode(review.title),
                                         body=unicode(review.body),
                                         addon_id=addon.id,
                                         addon_title=unicode(addon.name),
                                         is_flagged=is_flagged))
                    if self.request:
                        ReviewerScore.award_moderation_points(
                            self.request.user, addon, review.id)
Пример #55
0
    def test_details(self):
        """
        If we get details, verify they are stored as JSON, and we get out what
        we put in.
        """
        a = Webapp.objects.create(name='kumar is awesome')
        magic = dict(title='no', body='way!')
        al = mkt.log(mkt.LOG.DELETE_REVIEW, 1, a, details=magic)

        eq_(al.details, magic)
        eq_(al._details, '{"body": "way!", "title": "no"}')