Close reports for already removed content
Fixes: mozilla/addons#14928
Description
If the content is already removed (either by us, or by the author) when a report is received auto-handle it.
Context
It's possible to report abuse for content that is already disabled, deleted, or banned on AMO (maybe using an old link; maybe because it's an add-on they have installed before it was disabled), but we then have no other action we can take - it's already gone - so rather than wasting the effort of reviewing the report, we will instead auto-"close" it. Not actually close the report - because we don't close abuse reports - but not opening a job, and instead sending an email immediately and log a decision for record keeping.
Testing
- Remove some content
- for an add-on, either set to status disabled, or delete it
- for a user, ban or delete it
- for a collection or rating delete it.
- Report that content via frontend
- See you get an email immediately saying we didn't process the report because it was already removed (look in fakemail)
- See a decision is sent to cinder as
amo-closed-no-action(needs cinder API integration set up)
Checklist
- [x] Add
#ISSUENUMat the top of your PR to an existing open issue in the mozilla/addons repository. - [x] Successfully verified the change locally.
- [x] The change is covered by automated tests, or otherwise indicated why doing so is unnecessary/impossible.
- [ ] Add before and after screenshots (Only for changes that impact the UI).
- [ ] Add or update relevant docs reflecting the changes made.
Locally, I got this in celery logs while reporting a force-disabled add-on:
ValueError: invalid literal for int() with base 10: '043dc640-71bb-4806-b328-186a97a9748d'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/deps/lib/python3.11/site-packages/celery/app/trace.py", line 453, in trace_task
R = retval = fun(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/sentry_sdk/integrations/celery.py", line 280, in _inner
reraise(*exc_info)
File "/deps/lib/python3.11/site-packages/sentry_sdk/_compat.py", line 115, in reraise
raise value
File "/deps/lib/python3.11/site-packages/sentry_sdk/integrations/celery.py", line 275, in _inner
return f(*args, **kwargs)
^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/celery/app/trace.py", line 736, in __protected_call__
return self.run(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/olympia/src/olympia/amo/decorators.py", line 125, in wrapper
return f(*args, **kw)
^^^^^^^^^^^^^^
File "/data/olympia/src/olympia/abuse/tasks.py", line 70, in report_to_cinder
CinderJob.report(abuse_report)
File "/data/olympia/src/olympia/abuse/models.py", line 195, in report
cls.handle_already_removed(abuse_report)
File "/data/olympia/src/olympia/abuse/models.py", line 182, in handle_already_removed
decision.save()
File "/data/olympia/src/olympia/amo/models.py", line 398, in save
return super().save(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/base.py", line 814, in save
self.save_base(
File "/deps/lib/python3.11/site-packages/django/db/models/base.py", line 877, in save_base
updated = self._save_table(
^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/base.py", line 990, in _save_table
updated = self._do_update(
^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/base.py", line 1033, in _do_update
filtered = base_qs.filter(pk=pk_val)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/query.py", line 1436, in filter
return self._filter_or_exclude(False, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/query.py", line 1454, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "/deps/lib/python3.11/site-packages/django/db/models/query.py", line 1461, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/deps/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1546, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1577, in _add_q
child_clause, needed_inner = self.build_filter(
^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1492, in build_filter
condition = self.build_lookup(lookups, col, value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1319, in build_lookup
lookup = lookup_class(lhs, rhs)
^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/lookups.py", line 27, in __init__
self.rhs = self.get_prep_lookup()
^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/lookups.py", line 341, in get_prep_lookup
return super().get_prep_lookup()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/lookups.py", line 85, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/fields/__init__.py", line 2055, in get_prep_value
raise e.__class__(
ValueError: Field 'id' expected a number but got '043dc640-71bb-4806-b328-186a97a9748d'.
", "args": "(5,)", "kwargs": "{}", "description": "raised unexpected", "internal": false}, "uid": "", "remoteAddressChain": "", "msg": "Task olympia.abuse.tasks.report_to_cinder[d90e33b8-8e21-432c-bc37-60c2ded4122a] raised unexpected: ValueError("Field 'id' expected a number but got '043dc640-71bb-4806-b328-186a97a9748d'.")", "error": "ValueError("Field 'id' expected a number but got '043dc640-71bb-4806-b328-186a97a9748d'.")", "traceback": "Uncaught exception:
File "/deps/lib/python3.11/site-packages/celery/app/trace.py", line 453, in trace_task
R = retval = fun(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/sentry_sdk/integrations/celery.py", line 280, in _inner
reraise(*exc_info)
File "/deps/lib/python3.11/site-packages/sentry_sdk/_compat.py", line 115, in reraise
raise value
File "/deps/lib/python3.11/site-packages/sentry_sdk/integrations/celery.py", line 275, in _inner
return f(*args, **kwargs)
^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/celery/app/trace.py", line 736, in __protected_call__
return self.run(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/olympia/src/olympia/amo/decorators.py", line 125, in wrapper
return f(*args, **kw)
^^^^^^^^^^^^^^
File "/data/olympia/src/olympia/abuse/tasks.py", line 70, in report_to_cinder
CinderJob.report(abuse_report)
File "/data/olympia/src/olympia/abuse/models.py", line 195, in report
cls.handle_already_removed(abuse_report)
File "/data/olympia/src/olympia/abuse/models.py", line 182, in handle_already_removed
decision.save()
File "/data/olympia/src/olympia/amo/models.py", line 398, in save
return super().save(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/base.py", line 814, in save
self.save_base(
File "/deps/lib/python3.11/site-packages/django/db/models/base.py", line 877, in save_base
updated = self._save_table(
^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/base.py", line 990, in _save_table
updated = self._do_update(
^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/base.py", line 1033, in _do_update
filtered = base_qs.filter(pk=pk_val)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/query.py", line 1436, in filter
return self._filter_or_exclude(False, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/query.py", line 1454, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "/deps/lib/python3.11/site-packages/django/db/models/query.py", line 1461, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/deps/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1546, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1577, in _add_q
child_clause, needed_inner = self.build_filter(
^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1492, in build_filter
condition = self.build_lookup(lookups, col, value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1319, in build_lookup
lookup = lookup_class(lhs, rhs)
^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/lookups.py", line 27, in __init__
self.rhs = self.get_prep_lookup()
^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/lookups.py", line 341, in get_prep_lookup
return super().get_prep_lookup()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/lookups.py", line 85, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/deps/lib/python3.11/site-packages/django/db/models/fields/__init__.py", line 2055, in get_prep_value
raise e.__class__(
<class 'ValueError'>
ValueError("Field 'id' expected a number but got '043dc640-71bb-4806-b328-186a97a9748d'.")
"
(Note that I was using its guid to open the feedback page)