This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/util/disableabuser.py

106 lines
4 KiB
Python
Raw Normal View History

import argparse
from datetime import datetime
2016-12-27 17:20:38 +00:00
from app import tf
from data import model
from data.model import db_transaction
from data.database import QueueItem, Repository, RepositoryBuild, RepositoryBuildTrigger
from data.queue import WorkQueue
def ask_disable_namespace(username, queue_name):
user = model.user.get_namespace_user(username)
2016-12-27 17:20:38 +00:00
if user is None:
raise Exception('Unknown user or organization %s' % username)
2016-12-27 17:20:38 +00:00
if not user.enabled:
print "NOTE: Namespace %s is already disabled" % username
2016-12-27 17:20:38 +00:00
queue_prefix = '%s/%s/%%' % (queue_name, username)
existing_queue_item_count = (QueueItem
.select()
.where(QueueItem.queue_name ** queue_prefix)
.where(QueueItem.available == 1,
QueueItem.retries_remaining > 0,
QueueItem.processing_expires > datetime.now())
.count())
repository_trigger_count = (RepositoryBuildTrigger
.select()
.join(Repository)
.where(Repository.namespace_user == user)
.count())
print "============================================="
print "For namespace %s" % username
print "============================================="
2016-12-27 17:20:38 +00:00
print "User %s has email address %s" % (username, user.email)
print "User %s has %s queued builds in their namespace" % (username, existing_queue_item_count)
print "User %s has %s build triggers in their namespace" % (username, repository_trigger_count)
confirm_msg = "Would you like to disable this user and delete their triggers and builds? [y/N]> "
letter = str(raw_input(confirm_msg))
if letter.lower() != 'y':
print "Action canceled"
return
print "============================================="
2017-07-13 09:14:17 +00:00
triggers = []
count_removed = 0
2016-12-27 17:20:38 +00:00
with db_transaction():
user.enabled = False
user.save()
repositories_query = Repository.select().where(Repository.namespace_user == user)
if len(repositories_query.clone()):
builds = list(RepositoryBuild
.select()
.where(RepositoryBuild.repository << list(repositories_query)))
triggers = list(RepositoryBuildTrigger
.select()
.where(RepositoryBuildTrigger.repository << list(repositories_query)))
# Delete all builds for the user's repositories.
if builds:
RepositoryBuild.delete().where(RepositoryBuild.id << builds).execute()
# Delete all build triggers for the user's repositories.
if triggers:
(RepositoryBuildTrigger
.delete()
.where(RepositoryBuildTrigger.id << triggers)
.execute())
# Delete all queue items for the user's namespace.
dockerfile_build_queue = WorkQueue(queue_name, tf, has_namespace=True)
count_removed = dockerfile_build_queue.delete_namespaced_items(user.username)
info = (user.username, len(triggers), count_removed)
print "Namespace %s disabled, %s triggers deleted, %s queued builds removed" % info
return user
def disable_abusing_user(username, queue_name):
if not username:
raise Exception('Must enter a username')
# Disable the namespace itself.
user = ask_disable_namespace(username, queue_name)
# If an organization, ask if all team members should be disabled as well.
if user.organization:
members = model.organization.get_organization_member_set(user)
for membername in members:
ask_disable_namespace(membername, queue_name)
2016-12-27 17:20:38 +00:00
parser = argparse.ArgumentParser(description='Disables a user abusing the build system')
parser.add_argument('username', help='The username of the abuser')
parser.add_argument('queuename', help='The name of the dockerfile build queue ' +
'(e.g. `dockerfilebuild` or `dockerfilebuildstaging`)')
2016-12-27 17:20:38 +00:00
args = parser.parse_args()
disable_abusing_user(args.username, args.queuename)