#5392 Add a new admin command to clean a spam user
Merged 2 years ago by ryanlerch. Opened 2 years ago by ryanlerch.
ryanlerch/pagure admin-clean-spammer  into  master

file modified
+177
@@ -439,6 +439,30 @@ 

      local_parser.set_defaults(func=do_delete_project)

  

  

+ def _parser_sanitize_spam_user(subparser):

+     """Set up the CLI argument parser for the delete-user-activity action.

+ 

+     :arg subparser: an argparse subparser allowing to have action's specific

+         arguments

+ 

+     """

+     local_parser = subparser.add_parser(

+         "sanitize-spam-user",

+         help="Delete repos and tickets by the user specified",

+     )

+ 

+     local_parser.add_argument(

+         "user",

+         help="Username of the spam user to sanitize",

+     )

+     local_parser.add_argument(

+         "action_user",

+         help="Username of the admin user doing the action (ie: deleting the "

+         "users activity)",

+     )

+     local_parser.set_defaults(func=do_sanitize_spam_user)

+ 

+ 

  def _parser_create_branch(subparser):

      """Set up the CLI argument parser for the create-branch action.

  
@@ -578,6 +602,9 @@ 

      # delete-project

      _parser_delete_project(subparser)

  

+     # delete-all-user-acitvity

+     _parser_sanitize_spam_user(subparser)

+ 

      # create-branch

      _parser_create_branch(subparser)

  
@@ -924,6 +951,156 @@ 

      print("Project deleted")

  

  

+ def do_sanitize_spam_user(args):

+     """Block and remove activity by a spam user

+ 

+     :arg args: the argparse object returned by ``parse_arguments()``.

+ 

+     """

+     _log.debug("user:          %s", args.user)

+     _log.debug("user deleting: %s", args.action_user)

+ 

+     # Validate users

+     user = pagure.lib.query.get_user(session, args.user)

+     action_user = pagure.lib.query.get_user(session, args.action_user)

+ 

+     projects = (

+         session.query(pagure.lib.model.Project).filter(

+             pagure.lib.model.Project.user_id == user.id

+         )

+     ).all()

+ 

+     issues = (

+         session.query(pagure.lib.model.Issue).filter(

+             pagure.lib.model.Issue.user_id == user.id

+         )

+     ).all()

+ 

+     comments = (

+         session.query(pagure.lib.model.IssueComment).filter(

+             pagure.lib.model.IssueComment.user_id == user.id

+         )

+     ).all()

+ 

+     prs = (

+         session.query(pagure.lib.model.PullRequest).filter(

+             pagure.lib.model.PullRequest.user_id == user.id

+         )

+     ).all()

+ 

+     prcomments = (

+         session.query(pagure.lib.model.PullRequestComment).filter(

+             pagure.lib.model.PullRequestComment.user_id == user.id

+         )

+     ).all()

+ 

+     groups = (

+         session.query(pagure.lib.model.PagureGroup).filter(

+             pagure.lib.model.PagureGroup.user_id == user.id

+         )

+     ).all()

+ 

+     blocked = bool(

+         pagure.lib.query.get_blocked_users(

+             session, username=user.user, date=None

+         )

+     )

+ 

+     print("# Projects")

+     if projects:

+         for project in projects:

+             print(f"* {project.full_url}")

+     else:

+         print("    ***User has no Projects***")

+ 

+     print("# Issues")

+     if issues:

+         for issue in issues:

+             print(f"* {issue.full_url}")

+     else:

+         print("    ***User has no Issues***")

+ 

+     print("# Blocked Status")

+     if blocked:

+         print("    ***User is already blocked***")

+     else:

+         print("    User is NOT blocked on pagure")

+ 

+     if issues or projects or not blocked:

+         print("\nAre you sure you want to:")

+         if projects:

+             print(f"* DELETE {len(projects)} projects")

+         if issues:

+             print(f"* DELETE {len(issues)} issues")

+         if not blocked:

+             print(f"* BLOCK {user.user} on pagure until 2099-01-01")

+ 

+         if not _ask_confirmation():

+             return

+ 

+         if issues:

+             for issue in issues:

+                 print(f"DELETING ISSUE: {issue.full_url}")

+                 pagure.lib.query.drop_issue(

+                     session,

+                     issue=issue,

+                     user=action_user.user,

+                 )

+                 session.commit()

+ 

+         if projects:

+             for project in projects:

+                 print(f"DELETING PROJECT: {project.full_url}")

+                 pagure.lib.tasks.delete_project(

+                     namespace=project.namespace,

+                     name=project.name,

+                     user=project.user.user if project.is_fork else None,

+                     action_user=action_user.user,

+                 )

+                 session.commit()

+ 

+         if not blocked:

+             # block the user

+             print(f"BLOCKING USER: {user.user} until 2099-01-01")

+             date = arrow.get("2099-01-01", "YYYY-MM-DD").replace(tzinfo="UTC")

+             user.refuse_sessions_before = date.datetime

+             session.add(user)

+             session.commit()

+ 

+     print(

+         f"\n\n# Other Activity by {user.user} that needs to be removed manually:"

+     )

+ 

+     print("## Issue Comments")

+     if comments:

+         for comment in comments:

+             print(f"* {comment.issue.full_url}#comment-{comment.id}")

+     else:

+         print("    ***User has no Issue Comments***")

+     print("## Pull Requests")

+     if prs:

+         for pr in prs:

+             print(f"* {pr.full_url}")

+     else:

+         print("    ***User has no Pull Requests***")

+ 

+     print("## Pull Request Comments")

+     if prcomments:

+         for prcomment in prcomments:

+             print(

+                 f"* {prcomment.pull_request.full_url}#comment-{prcomment.id}"

+             )

+     else:

+         print("    ***User has no Pull Request Comments***")

+ 

+     print("## Groups Created by the User")

+     if groups:

+         for group in groups:

+             print(f"* {group.full_url}")

+     else:

+         print("    ***User has not created any Groups***")

+ 

+ 

  def do_update_acls(args):

      """Update the ACLs in the database from the list present in the

      configuration file.

Adds a new command to the pagure-admin cli tool that:

  • blocks the given user
  • deletes all the repos of the given user
  • deleles all the issues a user has filed
  • lists all the comments a user has done

In the future, will add deleting of comments as well, but there was no
method for doing this in the models (it appears it is done manaully in
the UI modules at the moment) -- I didnt want to dive too deep to get
this done, so we manually delete comments for now.

Signed-off-by: Ryan Lerch rlerch@redhat.com

I would add an extra flag that would be either --dry-run or --delete so that there is way to review what will be done before committing to it

We should add PR comments there as well, otherwise spammer will quickly realize they can spam there as well :)

ok, I see you've added an confirmation prompt down the line, so that'll do :)

Here you've printed before doing the deletion while for issues you did it after, we may want to be consistent (so it fails in a consistent place if it fails)

Too many empty lines for pep8/black to be happy here :)

rebased onto c51903c

2 years ago

OK a few changes:

  • ran black over the code this time
  • changed the wording and location of the DELETING prompts -- these are now printed before we acutually do the change -- there was an issue with it not printing the information i needed after actaully deleting it, so i print them all before now.
  • still just only deleting projects and issue comments -- but now it prints out pull requests, pull request comments, and groups that the user has created.

I did not run it, but from the looks of it, it looks good to me!

Pull-Request has been merged by ryanlerch

2 years ago
Metadata