Skip to content

Commit

Permalink
Merge pull request #1025 from kartoza/merge-duplicate-emails
Browse files Browse the repository at this point in the history
patch: merge duplicate emails
  • Loading branch information
tinashechiraya authored May 20, 2024
2 parents e87e215 + bed57fa commit 75fae70
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 30 deletions.
30 changes: 0 additions & 30 deletions deployment/docker/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,36 +57,6 @@ echo 'Updating active field for all users...'
export PGPASSWORD="${POSTGRES_PASS}"
psql -d "${DJANGO_DB}" -p 5432 -U "${POSTGRES_USER}" -h "${DATABASE_HOST}" -c "UPDATE auth_user SET is_active = TRUE;"

# delete all the james smith and their related objects
echo 'Deleting specific users and their related data...'
psql -d "${DJANGO_DB}" -p 5432 -U "${POSTGRES_USER}" -h "${DATABASE_HOST}" <<EOF
DELETE FROM user_profile WHERE id IN (
SELECT u.id
FROM auth_user u
WHERE u.first_name = 'James'
AND u.last_name = 'Smith'
AND DATE(u.date_joined) = DATE(u.last_login)
AND DATE(u.date_joined) < '2023-01-01'
);
DELETE FROM password_history WHERE user_id IN (
SELECT u.id
FROM auth_user u
WHERE u.first_name = 'James'
AND u.last_name = 'Smith'
AND DATE(u.date_joined) = DATE(u.last_login)
AND DATE(u.date_joined) < '2023-01-01'
);
DELETE FROM auth_user WHERE id IN (
SELECT u.id
FROM auth_user u
WHERE u.first_name = 'James'
AND u.last_name = 'Smith'
AND DATE(u.date_joined) = DATE(u.last_login)
AND DATE(u.date_joined) < '2023-01-01'
);
EOF

# Run tests
echo 'Running tests.'
Expand Down
84 changes: 84 additions & 0 deletions django_project/minisass/clean_up_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from django.core.management.base import BaseCommand
from django.db import transaction
from django.contrib.auth.models import User
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.conf import settings
from minisass_authentication.models import (
UserProfile,
PasswordHistory
)
from monitor.models import (
Observations,
Sites
)
from django.contrib.sites.models import Site

class Command(BaseCommand):
help = 'Merge users with duplicate emails, reassign related objects, and delete specific users/bots'

def handle(self, *args, **kwargs):
self.delete_specific_users()
self.merge_duplicate_users()

@transaction.atomic
def delete_specific_users(self):
users_to_delete = User.objects.filter(
first_name='James',
last_name='Smith',
date_joined__date=models.F('last_login__date'),
date_joined__lt='2023-01-01'
)

for user in users_to_delete:
UserProfile.objects.filter(user=user).delete()
PasswordHistory.objects.filter(user=user).delete()
Sites.objects.filter(user=user).delete()
Observations.objects.filter(user=user).delete()
user.delete()

self.stdout.write(self.style.SUCCESS('Successfully deleted specific users based on criteria.'))


@transaction.atomic
def merge_duplicate_users(self):
duplicate_emails = User.objects.values('email').annotate(count=models.Count('id')).filter(count__gt=1)
for item in duplicate_emails:
email = item['email']
users = User.objects.filter(email=email)
primary_user = users.first() # Keep the first user as the primary

for user in users.exclude(id=primary_user.id):
# Reassign related objects to primary user
UserProfile.objects.filter(user=user).update(user=primary_user)
PasswordHistory.objects.filter(user=user).update(user=primary_user)
Sites.objects.filter(user=user).update(user=primary_user)
Observations.objects.filter(user=user).update(user=primary_user)

# Delete the duplicate user
user.delete()

# Ensure email is unique
primary_user.email = email
primary_user.save()

# Send notification email
self.send_notification_email(primary_user)

self.stdout.write(self.style.SUCCESS('Successfully merged users with duplicate emails.'))

def send_notification_email(self, user):
subject = 'Important: Your miniSASS Accounts Have Been Merged'
login_url = Site.objects.get_current().domain
message = render_to_string('duplicate_email_merge_notification.html', {
'user': user,
'login_url': login_url,
})
send_mail(
subject,
message,
settings.CONTACT_US_RECEPIENT_EMAIL,
[user.email],
fail_silently=False,
html_message=message,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Account Merge Notification</title>
</head>
<body style="font-family: Arial, sans-serif; background-color: #f4f4f4; color: #333; margin: 0; padding: 0;">
<div style="max-width: 600px; margin: 20px auto; padding: 20px; background-color: #fff; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
<div style="background-color: #0e4981; color: #fff; text-align: center; padding: 20px; border-radius: 8px;">
<span style="font-size: 24px; font-weight: bold;">miniSASS</span>
</div>

<h2>Account Merge Notification</h2>
<p>Dear {{ user.username }},</p>
<p>We have identified multiple accounts registered with your email address and have merged them into a single account to ensure data consistency and better user experience.</p>
<p>Please log in to your account and update your password at your earliest convenience to ensure your account's security:</p>
<p><a href="{{ login_url }}" style="display: inline-block; padding: 10px 20px; background-color: #288b31; color: #fff; text-decoration: none; border-radius: 5px;">Login to miniSASS</a></p>
<p>If the button above doesn't work, you can also <a href="{{ login_url }}" style="color: #007bff; text-decoration: none;">click here</a> or copy and paste the following link into your browser:</p>
<p>{{ login_url }}</p>
<p>If you have any questions, feel free to contact us.</p>
<p>Thank you,<br> The miniSASS Team</p>
</div>
</body>
</html>

0 comments on commit 75fae70

Please sign in to comment.