Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement bulk moderation actions #4654

Merged
merged 31 commits into from
Jul 30, 2024
Merged

Implement bulk moderation actions #4654

merged 31 commits into from
Jul 30, 2024

Conversation

dhruvkb
Copy link
Member

@dhruvkb dhruvkb commented Jul 24, 2024

Fixes

Fixes #3840 by @stacimc
Fixes #3841 by @stacimc

Partially addresses #3842 by @stacimc
Partially addresses #3843 by @stacimc

Description

This PR

  • enables sensitive and deleted media models to make bulk calls to ES
  • adds bulk moderation actions to the Django admin with a confirmation page to view the summary of the changes and provide an explanation
  • makes some UX improvements to the Django admin
  • fixes some typos and tightens more permissions

Testing Instructions

Note that while the instructions only say images, the same steps can be taken for audio models.

Permissions

We must test that bulk moderation actions are only visible to moderators and not to other staff members.

  • Create a new test user from the API shell.
    • Open the shell using just api/ipython
    • Create the new staff user and give it view/delete perms.
      from django.contrib.auth.models import Permission, Group, User
      from django.db.models import Q
      
      test = User.objects.create_user(username="test", password="deploy")
      test.is_staff = True
      test.save()
      
      for perm in Permission.objects.filter(Q(name__contains="view") | Q(name__contains="delete")):
          perm.user_set.add(test)
  • Visit the following pages.
  • See the options in the "Action" dropdown menu. You should not see the bulk moderation operations.

Marking sensitive

  • Go to the image list page: http://localhost:50280/admin/api/image/?pending_record_count=all
  • Select a bunch of images, and note their IDs.
  • From the "Action menu" chose "Mark selected images as sensitive" and press "Go".
  • Note that all your IDs are listed for confirmation.
  • Enter a message and press "Yes, I’m sure". You will be taken back to the list with a banner on the top linking to the new decision.
  • Click the link, go to the decision details and verify the decision is created correctly.
  • Visit the sensitive-image list page: http://localhost:50280/admin/api/sensitiveimage/. The IDs should be listed there.
  • Visit the detail page of the selected IDs: http://localhost:50280/v1/images/. The field "mature" should be true.

Re-marking sensitive

  • Go to the image list page: http://localhost:50280/admin/api/image/?pending_record_count=all
  • Select a bunch of images, including some overlapping from the previous step, and note their IDs.
  • From the "Action menu" chose "Mark selected images as sensitive" and press "Go".
  • Note that only the new, non-overlapping IDs are listed for confirmation and that existing sensitive image are excluded from this operation.

Deindexing

Unmarking sensitive

  • Go to the sensitive-image list page: http://localhost:50280/admin/api/sensitiveimage/
  • Select some sensitive images, including some that have subsequently been deindexed, and note their IDs.
  • From the "Action menu" chose "Unmark selected sensitive images as sensitive" and press "Go".
  • Note that all your IDs are listed for confirmation.
  • Enter a message and press "Yes, I’m sure". You will be taken back to the list with a banner on the top linking to the new decision.
  • Click the link, go to the decision details and verify the decision is created correctly.
  • Visit the sensitive-image list page: http://localhost:50280/admin/api/sensitiveimage/. The IDs should be gone from there.
  • Visit the detail page of the selected IDs: http://localhost:50280/v1/images/. The field "mature" should be false.
  • Visit the detail page of the deindexed IDs: http://localhost:50280/v1/images/. You should see a 404 page.

Reindexing

History

  • Visit the image-decision list page: http://localhost:50280/admin/api/imagedecision/. See all the bulk moderations made so far are listed there and paint a clear picture of the events.
  • Check the following field.
    • The moderator should be you.
    • The notes should be the content entered on the confirmation page.
    • The affected media items should include all IDs regardless of whether the media item exists or has been deindexed. Those that exist should be links.

Checklist

  • My pull request has a descriptive title (not a vague title likeUpdate index.md).
  • My pull request targets the default branch of the repository (main) or a parent feature branch.
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • I added or updated tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no visible errors.
  • I ran the DAG documentation generator (ov just catalog/generate-docs for catalog
    PRs) or the media properties generator (ov just catalog/generate-docs media-props
    for the catalog or ov just api/generate-docs for the API) where applicable.

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

@openverse-bot openverse-bot added 🧱 stack: api Related to the Django API 🟨 priority: medium Not blocking but should be addressed soon 🌟 goal: addition Addition of new feature 💻 aspect: code Concerns the software code in the repository labels Jul 24, 2024
@dhruvkb dhruvkb marked this pull request as ready for review July 24, 2024 21:57
@dhruvkb dhruvkb requested review from a team as code owners July 24, 2024 21:57
@dhruvkb dhruvkb requested review from zackkrida, krysal and obulat July 24, 2024 21:57
@dhruvkb dhruvkb added 🟧 priority: high Stalls work on the project or its dependents and removed 🟨 priority: medium Not blocking but should be addressed soon labels Jul 24, 2024
@dhruvkb
Copy link
Member Author

dhruvkb commented Jul 24, 2024

I bumped up the priority to 🟧 high because the issue it resolves (#3840) is blocking three others.

@zackkrida
Copy link
Member

zackkrida commented Jul 26, 2024

@dhruvkb all of the core moderation actions worked as described 🎉. This is awesome! As a future moderator I can see this being really useful.

I found one thing, the "Resolved" filtered view, which seems broken.

Also, I do not feel completely qualified to evaluate the python code for performance or for being idiomatic with Django. You might want to ping another reviewer for those concerns. But I am happy to approve this once you clarify the "Resolved" filtered view. Thanks!

Copy link
Member

@krysal krysal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work here. There are a ton of things happening, so it's incredible to see the view workflows going smoothly.

As the test user you provided in the instructions, I couldn't see the bulk moderation operations as expected ✔️ So for trying the bulk actions I assume the user must be granted the specific permissions, right?

I was able to mark images as sensitive and deindex them in bulk with the original deploy user. I have yet to try the other actions, but given the many complex operations involving ES, groups of media, and specific user permissions, it seems this requires some automated testing. At the very least, it would be prudent to test the critical bulk functions.

Aside from that, this looks promising! I'll come back to this later.

Comment on lines +44 to +46
Note that bulk moderation will not resolve any open reports. It is
up to the moderator to manually link open reports with the
appropriate decisions and resolve them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a surprise to me, I didn't think the IP defined this like this (I must admit I have to read it carefully). Sounds like a lot of manual work that could be taken out of the moderators 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a bit of manual work that can be automated if we auto-close reports. However, there are two main issues preventing that.

The main case we need to avoid that I can think of is if we marked an image as sensitive based on one report, but another report (that gets closed for having the same reason) actually contains information or context which would lead us to deindex the image.
@zackkrida

Also need to keep in mind reversing a bulk action — if creating one results in reports being resolved, reversing it ought to reopen them
@stacimc

With this limitation in mind, I decided to keep the reports unchanged for now and potentially revisit this in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, with moderation happening regularly, the need to triage multiple concurrent reports of a single work will be very infrequent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that mean we should implement report closing functionality as a part of bulk moderation? It can be pretty complex in terms of logic so I would ideally like that to be a different issue-PR pair to avoid complicating this PR further.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that it would increase complexity, and this PR is already well-rounded. Good to know there was a previous consensus 👍

@dhruvkb
Copy link
Member Author

dhruvkb commented Jul 26, 2024

I found one thing, the "Resolved" filtered view, which seems broken.

@zackkrida I just confirmed that it works as I expect. To check that view, open a media item from the "All" view, create a report for it and create a decision for that report. Now that media item will appear in "Resolved".

@dhruvkb dhruvkb marked this pull request as draft July 26, 2024 11:37
@dhruvkb
Copy link
Member Author

dhruvkb commented Jul 27, 2024

So for trying the bulk actions I assume the user must be granted the specific permissions, right?

@krysal, yes, the bulk moderation capability is available only to members of the "Content Moderators" group. It is determined by whether they have the "Can add image decision" and "Can add audio decision" permissions.

it seems this requires some automated testing

I agree with you there. I have added unit tests for the ES bulk update code in ede4e38 and for the perform_moderation util in 1945a08. These tests cover all the bulk moderation actions and should be sufficient to establish confidence.

@dhruvkb dhruvkb marked this pull request as ready for review July 27, 2024 17:07
@zackkrida zackkrida requested a review from krysal July 29, 2024 12:38
Copy link
Member

@zackkrida zackkrida left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving based on the functionality, and the test logic looks good. Again, I don't feel the most qualified to speak to the specific code patterns or Django best practices.

Copy link
Member

@krysal krysal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is working like a charm! I tested all the cases, and the only thing I noticed is that, when marking as sensitive, the media gets a value in "unstable__sensitivity" of ["user_reported_sensitivity"] when that didn't come from a user report, but that is a minor thing that can be addressed separately.

Excellent work 💯

api/test/unit/models/test_media.py Outdated Show resolved Hide resolved
api/api/utils/moderation.py Outdated Show resolved Hide resolved
api/api/utils/moderation.py Outdated Show resolved Hide resolved
Comment on lines +44 to +46
Note that bulk moderation will not resolve any open reports. It is
up to the moderator to manually link open reports with the
appropriate decisions and resolve them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that it would increase complexity, and this PR is already well-rounded. Good to know there was a previous consensus 👍

Co-authored-by: Krystle Salazar <[email protected]>
@dhruvkb dhruvkb merged commit dff3a85 into main Jul 30, 2024
51 checks passed
@dhruvkb dhruvkb deleted the bulk_moderation branch July 30, 2024 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💻 aspect: code Concerns the software code in the repository 🌟 goal: addition Addition of new feature 🟧 priority: high Stalls work on the project or its dependents 🧱 stack: api Related to the Django API
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Update admin Media views with new filters and bulk actions Create bulk moderation actions
4 participants