mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-17 05:22:16 +00:00
FEAT: Add periodic cleanup command
Currently performs two functions: 1. Inactivates users that have not logged in for at least one year. Closes #478 (Need to circle back round to full deletion SoonTM) 2. Ensures the supervisor database flag is set correctly for each user This is run automatically by the Heroku Scheduler addon at midnight daily.
This commit is contained in:
18
RIGS/migrations/0045_alter_profile_is_approved.py
Normal file
18
RIGS/migrations/0045_alter_profile_is_approved.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.12 on 2022-10-20 23:02
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('RIGS', '0044_profile_is_supervisor'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='profile',
|
||||||
|
name='is_approved',
|
||||||
|
field=models.BooleanField(default=False, help_text='Designates whether a staff member has approved this user.', verbose_name='Approval Status'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -36,7 +36,7 @@ class Profile(AbstractUser):
|
|||||||
initials = models.CharField(max_length=5, null=True, blank=False)
|
initials = models.CharField(max_length=5, null=True, blank=False)
|
||||||
phone = models.CharField(max_length=13, blank=True, default='')
|
phone = models.CharField(max_length=13, blank=True, default='')
|
||||||
api_key = models.CharField(max_length=40, blank=True, editable=False, default='')
|
api_key = models.CharField(max_length=40, blank=True, editable=False, default='')
|
||||||
is_approved = models.BooleanField(default=False)
|
is_approved = models.BooleanField(default=False, verbose_name="Approval Status", help_text="Designates whether a staff member has approved this user.")
|
||||||
# Currently only populated by the admin approval email. TODO: Populate it each time we send any email, might need that...
|
# Currently only populated by the admin approval email. TODO: Populate it each time we send any email, might need that...
|
||||||
last_emailed = models.DateTimeField(blank=True, null=True)
|
last_emailed = models.DateTimeField(blank=True, null=True)
|
||||||
dark_theme = models.BooleanField(default=False)
|
dark_theme = models.BooleanField(default=False)
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
{% load nice_errors from filters %}
|
{% load nice_errors from filters %}
|
||||||
{% if form.errors %}
|
{% if form.errors %}
|
||||||
<div class="alert alert-danger alert-dismissable">
|
<div class="alert alert-danger mb-0">
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
|
||||||
<dl>
|
<dl>
|
||||||
{% with form|nice_errors as qq %}
|
{% with form|nice_errors as qq %}
|
||||||
{% for error_name,desc in qq.items %}
|
{% for error_name,desc in qq.items %}
|
||||||
<span class="row">
|
<span class="row">
|
||||||
<dt class="col-4">{{error_name}}</dt>
|
<dt class="col-3">{{error_name}}</dt>
|
||||||
<dd class="col-8">{{desc}}</dd>
|
<dd class="col-9">{{desc}}</dd>
|
||||||
</span>
|
</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
{% load widget_tweaks %}
|
{% load widget_tweaks %}
|
||||||
{% include 'form_errors.html' %}
|
{% include 'form_errors.html' %}
|
||||||
|
{% if form.errors %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<p><strong>Please note:</strong> If it has been more than a year since you last logged in, your account will have been automatically deactivated. Contact <a href="mailto:it@nottinghamtec.co.uk">it@nottinghamtec.co.uk</a> for assistance.</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="col-sm-6 offset-sm-3 col-lg-4 offset-lg-4">
|
<div class="col-sm-6 offset-sm-3 col-lg-4 offset-lg-4">
|
||||||
<form action="{% url 'login' %}" method="post" role="form" target="_self">{% csrf_token %}
|
<form action="{% url 'login' %}" method="post" role="form" target="_self">{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
26
users/management/commands/usercleanup.py
Normal file
26
users/management/commands/usercleanup.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from datetime import datetime, timedelta
|
||||||
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from RIGS.models import Profile
|
||||||
|
from training.models import TrainingLevel
|
||||||
|
|
||||||
|
|
||||||
|
# This is triggered nightly by Heroku Scheduler
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Performs perodic user maintenance tasks'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
for person in Profile.objects.all():
|
||||||
|
# Inactivate users that have not logged in for a year (or have never logged in)
|
||||||
|
if person.last_login is None or (timezone.now() - person.last_login).days > 365:
|
||||||
|
person.is_active = False
|
||||||
|
person.is_approved = False
|
||||||
|
person.save()
|
||||||
|
# Ensure everyone with a supervisor level has the flag correctly set in the database
|
||||||
|
if person.level_qualifications.exclude(confirmed_on=None).select_related('level') \
|
||||||
|
.filter(level__level__gte=TrainingLevel.SUPERVISOR) \
|
||||||
|
.exclude(level__department=TrainingLevel.HAULAGE) \
|
||||||
|
.exclude(level__department__isnull=True).exists():
|
||||||
|
person.is_supervisor = True
|
||||||
|
person.save()
|
||||||
Reference in New Issue
Block a user