Skip to content

Commit

Permalink
[Fix readthedocs#3182] Better user deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
safwanrahman committed Oct 31, 2017
1 parent b65e2f3 commit 309abd2
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
30 changes: 28 additions & 2 deletions readthedocs/core/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
import logging

from corsheaders import signals
from django.contrib.auth import get_user_model
from django.db.models.signals import pre_delete
from django.dispatch import Signal
from django.db.models import Q
from django.db.models import Q, Count
from django.dispatch import receiver
from future.backports.urllib.parse import urlparse

from readthedocs.oauth.tasks import bulk_delete_oauth_remote_organizations
from readthedocs.projects.models import Project, Domain

from readthedocs.projects.tasks import bulk_delete_projects

log = logging.getLogger(__name__)
User = get_user_model()

WHITELIST_URLS = ['/api/v2/footer_html', '/api/v2/search', '/api/v2/docsearch']

Expand Down Expand Up @@ -62,4 +67,25 @@ def decide_if_cors(sender, request, **kwargs): # pylint: disable=unused-argumen

return False


@receiver(pre_delete, sender=User)
def delete_projects_and_organizations(instance, *args, **kwargs):
# Projects id where user is the only owner

# Here we count the owner list from the projects that the user own
# Then exclude the projects where there are more than one owner
projects_id = (instance.projects.all().annotate(num_users=Count('users'))
.exclude(num_users__gt=1)
.values_list('id', flat=True))

# Here we count the users list from the organization that the user belong
# Then exclude the organizations where there are more than one user
oauth_organizations_id = (instance.oauth_organizations.annotate(num_users=Count('users'))
.exclude(num_users__gt=1)
.values_list('id', flat=True))

bulk_delete_projects.delay(projects_id)
bulk_delete_oauth_remote_organizations.delay(oauth_organizations_id)


signals.check_request_enabled.connect(decide_if_cors)
6 changes: 6 additions & 0 deletions readthedocs/oauth/tasks.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""Tasks for OAuth services"""

from __future__ import absolute_import
from celery import task
from django.contrib.auth.models import User
from djcelery import celery as celery_app

from readthedocs.core.utils.tasks import PublicTask
from readthedocs.core.utils.tasks import permission_check
from readthedocs.core.utils.tasks import user_id_matches
from readthedocs.oauth.models import RemoteOrganization
from .services import registry


Expand All @@ -21,5 +23,9 @@ def run_public(self, user_id):
for service in service_cls.for_user(user):
service.sync()

@task()
def bulk_delete_oauth_remote_organizations(organizations_id):
RemoteOrganization.objects.filter(id__in=organizations_id).delete()


sync_remote_repositories = celery_app.tasks[SyncRemoteRepositories.name]
5 changes: 5 additions & 0 deletions readthedocs/projects/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -984,3 +984,8 @@ def clear_html_artifacts(version):
if isinstance(version, int):
version = Version.objects.get(pk=version)
remove_dir(version.project.rtd_build_path(version=version.slug))


@task()
def bulk_delete_projects(projects_id):
Project.objects.filter(id__in=projects_id).delete()
2 changes: 2 additions & 0 deletions readthedocs/templates/profiles/private/delete_account.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
<form method="POST" action=".">
{% csrf_token %}
{{ form }}
<br>
<strong>Be careful! This can not be undone!</strong>
<input type="submit" name="submit" value="{% trans "Delete Account" %}" id="submit"/>
</form>
{% endblock %}

0 comments on commit 309abd2

Please sign in to comment.