@ -0,0 +1,63 @@ | |||
from datetime import timedelta | |||
import time | |||
from django.conf import settings | |||
from django.core.management.base import BaseCommand | |||
from django.utils.timezone import now | |||
from hc.accounts.models import Profile, Member | |||
from hc.api.models import Ping | |||
from hc.lib import emails | |||
class Command(BaseCommand): | |||
help = """Send deletion notices to inactive user accounts. | |||
Conditions for sending the notice: | |||
- deletion notice has not been sent recently | |||
- last login more than a year ago | |||
- none of the owned projects has invited team members | |||
""" | |||
def handle(self, *args, **options): | |||
year_ago = now() - timedelta(days=365) | |||
q = Profile.objects.order_by("id") | |||
# Exclude accounts with logins in the last year_ago | |||
q = q.exclude(user__last_login__gt=year_ago) | |||
# Exclude accounts less than a year_ago old | |||
q = q.exclude(user__date_joined__gt=year_ago) | |||
# Exclude accounts with the deletion notice already sent | |||
q = q.exclude(deletion_notice_date__gt=year_ago) | |||
# Exclude paid accounts | |||
q = q.exclude(sms_limit__gt=0) | |||
sent = 0 | |||
for profile in q: | |||
members = Member.objects.filter(project__owner_id=profile.user_id) | |||
if members.exists(): | |||
print("Skipping %s, has team members" % profile) | |||
continue | |||
pings = Ping.objects | |||
pings = pings.filter(owner__project__owner_id=profile.user_id) | |||
pings = pings.filter(created__gt=year_ago) | |||
if pings.exists(): | |||
print("Skipping %s, has pings in last year" % profile) | |||
continue | |||
self.stdout.write("Sending notice to %s" % profile.user.email) | |||
profile.deletion_notice_date = now() | |||
profile.save() | |||
ctx = { | |||
"email": profile.user.email, | |||
"support_email": settings.SUPPORT_EMAIL | |||
} | |||
emails.deletion_notice(profile.user.email, ctx) | |||
# Throttle so we don't send too many emails at once: | |||
time.sleep(1) | |||
sent += 1 | |||
return "Done! Sent %d notices" % sent |
@ -0,0 +1,18 @@ | |||
# Generated by Django 2.1.7 on 2019-03-12 17:16 | |||
from django.db import migrations, models | |||
class Migration(migrations.Migration): | |||
dependencies = [ | |||
('accounts', '0026_auto_20190204_2042'), | |||
] | |||
operations = [ | |||
migrations.AddField( | |||
model_name='profile', | |||
name='deletion_notice_date', | |||
field=models.DateTimeField(blank=True, null=True), | |||
), | |||
] |
@ -0,0 +1,18 @@ | |||
# Generated by Django 2.1.7 on 2019-03-12 17:16 | |||
from django.db import migrations, models | |||
class Migration(migrations.Migration): | |||
dependencies = [ | |||
('api', '0057_auto_20190118_1319'), | |||
] | |||
operations = [ | |||
migrations.AlterField( | |||
model_name='channel', | |||
name='kind', | |||
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('pagertree', 'PagerTree'), ('po', 'Pushover'), ('pushbullet', 'Pushbullet'), ('opsgenie', 'OpsGenie'), ('victorops', 'VictorOps'), ('discord', 'Discord'), ('telegram', 'Telegram'), ('sms', 'SMS'), ('zendesk', 'Zendesk'), ('trello', 'Trello'), ('matrix', 'Matrix')], max_length=20), | |||
), | |||
] |
@ -31,6 +31,7 @@ SECRET_KEY = os.getenv("SECRET_KEY", "---") | |||
DEBUG = envbool("DEBUG", "True") | |||
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",") | |||
DEFAULT_FROM_EMAIL = os.getenv("DEFAULT_FROM_EMAIL", "[email protected]") | |||
SUPPORT_EMAIL = os.getenv("SUPPORT_EMAIL") | |||
USE_PAYMENTS = envbool("USE_PAYMENTS", "False") | |||
REGISTRATION_OPEN = envbool("REGISTRATION_OPEN", "True") | |||
@ -0,0 +1,20 @@ | |||
{% extends "emails/base.html" %} | |||
{% load hc_extras %} | |||
{% block content %} | |||
Hello,<br /> | |||
We’re sending this email to notify you that your {% site_name %} account, registered to {{ email }} has been inactive for 1 year or more. If you no longer wish to keep your {% site_name %} account active then we will make sure that your account is closed and any data associated with your account is permanently deleted from our systems.<br /><br /> | |||
If you wish to keep your account, simply log in within 30 days. If you continue to be inactive, <strong>your account will be permanently deleted after the 30 day period</strong>.<br /><br /> | |||
If you have issues logging in, or have any questions, please reach out to us at {{ support_email }}.<br /><br /> | |||
Sincerely,<br /> | |||
The {% site_name %} Team | |||
{% endblock %} | |||
{% block unsub %} | |||
<br /> | |||
This is a one-time message we're sending out to notify you about your account closure. | |||
{% endblock %} |
@ -0,0 +1,14 @@ | |||
{% load hc_extras %} | |||
Hello, | |||
We’re sending this email to notify you that your {% site_name %} account, registered to {{ email }} has been inactive for 1 year or more. If you no longer wish to keep your {% site_name %} account active then we will make sure that your account is closed and any data associated with your account is permanently deleted from our systems. | |||
If you wish to keep your account, simply log in within 30 days. If you continue to be inactive, your account will be permanently deleted after the 30 day period. | |||
If you have issues logging in, or have any questions, please reach out to us at {{ support_email }}. | |||
This is a one-time message we're sending out to notify you about your account closure. | |||
-- | |||
Sincerely, | |||
The {% site_name %} Team |
@ -0,0 +1 @@ | |||
Inactive Account Notification |