Skip to content

Commit

Permalink
2561 Deactivating inactive user automatically (#3145)
Browse files Browse the repository at this point in the history
* Added logic and test for deactivating the user automatically

* 2561- linting

* added admin notification

* linting

* [2561] added sending email to admin

* Update tdrs-backend/tdpservice/email/helpers/admin_notifications.py

Co-authored-by: Alex P.  <[email protected]>

---------

Co-authored-by: Alex P. <[email protected]>
  • Loading branch information
raftmsohani and ADPennington authored Sep 4, 2024
1 parent abd8609 commit edeaac7
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 3 deletions.
1 change: 1 addition & 0 deletions tdrs-backend/tdpservice/email/email_enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ class EmailType(Enum):
REQUEST_DENIED = 'request-denied.html'
DEACTIVATION_WARNING = 'account-deactivation-warning.html'
ACCOUNT_DEACTIVATED = 'account-deactivated.html'
ACCOUNT_DEACTIVATED_ADMIN = 'account-deactivated-admin.html'
UPCOMING_SUBMISSION_DEADLINE = 'upcoming-submission-deadline.html'
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
from tdpservice.email.email import automated_email
from datetime import datetime, timedelta, timezone
from django.conf import settings

from tdpservice.users.models import User

def send_deactivation_warning_email(users, days):
"""Send an email to users that are about to be deactivated."""
from tdpservice.users.models import User

template_path = EmailType.DEACTIVATION_WARNING.value
text_message = f'Your account will be deactivated in {days} days.'
subject = f'Account Deactivation Warning: {days} days remaining'
Expand Down
35 changes: 35 additions & 0 deletions tdrs-backend/tdpservice/email/helpers/admin_notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""helper functions to administer user accounts."""

def email_admin_deactivated_user(user):
"""Send an email to OFA Admins when a user is deactivated."""
from tdpservice.users.models import User
from tdpservice.email.email_enums import EmailType
from tdpservice.email.email import automated_email, log
from tdpservice.email.tasks import get_ofa_admin_user_emails

recipient_emails = get_ofa_admin_user_emails()
logger_context = {
'user_id': user.id,
'object_id': user.id,
'object_repr': user.username,
'content_type': User,
}

template_path = EmailType.ACCOUNT_DEACTIVATED_ADMIN.value
text_message = 'A user account has been deactivated.'
subject = ' TDP User Account Deactivated due to Inactivity'
context = {
'user': user,
}

log(f"Preparing email to OFA Admins for deactivated user {user.username}", logger_context=logger_context)

for recipient_email in recipient_emails:
automated_email(
email_path=template_path,
recipient_email=recipient_email,
subject=subject,
email_context=context,
text_message=text_message,
logger_context=logger_context
)
25 changes: 25 additions & 0 deletions tdrs-backend/tdpservice/email/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,35 @@
from tdpservice.email.email import automated_email, log
from tdpservice.email.email_enums import EmailType
from tdpservice.parsers.util import calendar_to_fiscal
from tdpservice.email.helpers.admin_notifications import email_admin_deactivated_user


logger = logging.getLogger(__name__)

@shared_task
def deactivate_users():
"""Deactivate users that have not logged in in the last 180 days."""
users_to_deactivate = User.objects.filter(
last_login__lte=datetime.now(tz=timezone.utc) - timedelta(days=180),
account_approval_status=AccountApprovalStatusChoices.APPROVED,
)

for user in users_to_deactivate:
user.account_approval_status = AccountApprovalStatusChoices.DEACTIVATED
user.groups.clear()
user.save()

logger_context = {
'user_id': user.id,
'object_id': user.id,
'object_repr': user.username,
}
email_admin_deactivated_user(user)
log(
f"Deactivated user {user.username} for inactivity.",
logger_context=logger_context if not settings.DEBUG else None
)


@shared_task
def check_for_accounts_needing_deactivation_warning():
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{% extends 'base.html' %}
{% block content %}
<!-- Body copy -->
<p style="color: #000000;">

<p>The following user account for the TANF Data Portal (TDP) has been deactivated.</p>

<p>Account Information:</p>
<ul>
<li>Name: {{ user.first_name }}</li>
<li>Last name: {{ user.last_name }}</li>
<li>Email: {{ user.email }}</li>
</ul>

<p>Thank you,</p>
TDP Team
</p>
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ def test_deactivation_email_10_days(user, mocker):
assert tdpservice.email.helpers.account_deactivation_warning.send_deactivation_warning_email.called_once_with(
users=[user], days=10)

@pytest.mark.django_db
def test_deactivate_users(user, mocker):
"""Test that the deactivate_users task runs."""
mocker.patch(
'tdpservice.email.helpers.admin_notifications.email_admin_deactivated_user',
return_value=None
)
user.groups.add()
user.last_login = datetime.now(tz=timezone.utc) - timedelta(days=181)
user.account_approval_status = AccountApprovalStatusChoices.APPROVED
user.save()
tdpservice.email.tasks.deactivate_users()
assert user.groups.count() == 0
assert tdpservice.email.helpers.admin_notifications.email_admin_deactivated_user.called_once_with(user)


@pytest.mark.django_db
def test_deactivation_email_3_days(user, mocker):
"""Test that the check_for_accounts_needing_deactivation_warning task runs."""
Expand Down
7 changes: 7 additions & 0 deletions tdrs-backend/tdpservice/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,13 @@ class Common(Configuration):
'expires': 15.0,
},
},
'Deactivate Users': {
'task': 'tdpservice.email.tasks.deactivate_users',
'schedule': crontab(day_of_week='*', hour='13', minute='0'), # Every day at 1pm UTC (9am EST)
'options': {
'expires': 15.0,
},
},
'Email Admin Number of Access Requests' : {
'task': 'tdpservice.email.tasks.email_admin_num_access_requests',
'schedule': crontab(minute='0', hour='1', day_of_week='*', day_of_month='*', month_of_year='*'), # Every day at 1am UTC (9pm EST)
Expand Down

0 comments on commit edeaac7

Please sign in to comment.