Merge pull request #18097 from edx/sstudent/EDUCATOR-2690
make password history retirable
This commit is contained in:
@@ -29,7 +29,7 @@ from django.contrib.auth.models import User
|
||||
from django.contrib.auth.signals import user_logged_in, user_logged_out
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
|
||||
from django.db import IntegrityError, models
|
||||
from django.db import IntegrityError, models, transaction
|
||||
from django.db.models import Count, Q
|
||||
from django.db.models.signals import post_save, pre_save
|
||||
from django.dispatch import receiver
|
||||
@@ -900,6 +900,20 @@ class PasswordHistory(models.Model):
|
||||
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def retire_user(cls, user_id):
|
||||
"""
|
||||
Updates the password in all rows corresponding to a user
|
||||
to an empty string as part of removing PII for user retirement.
|
||||
"""
|
||||
changed_password = False
|
||||
with transaction.atomic():
|
||||
for row, _ in cls.objects.filter(user_id=user_id):
|
||||
changed_password = True
|
||||
row.password = ""
|
||||
|
||||
return changed_password
|
||||
|
||||
|
||||
class LoginFailures(models.Model):
|
||||
"""
|
||||
|
||||
@@ -203,3 +203,20 @@ class TestPasswordHistory(TestCase):
|
||||
student = self._user_factory_with_history()
|
||||
|
||||
self.assertFalse(PasswordHistory.is_password_reset_too_soon(student))
|
||||
|
||||
def test_retirement(self):
|
||||
"""
|
||||
Verify that the user's password history contains no actual
|
||||
passwords after retirement is called.
|
||||
"""
|
||||
user = self._user_factory_with_history()
|
||||
|
||||
# create multiple rows in the password history table
|
||||
self._change_password(user, "different")
|
||||
self._change_password(user, "differentagain")
|
||||
for row in PasswordHistory.objects.filter(user_id=user.id):
|
||||
self.assertFalse(row.password == "")
|
||||
|
||||
PasswordHistory.retire_user(user.id)
|
||||
for row in PasswordHistory.objects.filter(user_id=user.id):
|
||||
self.assertEqual(row.password, "")
|
||||
|
||||
Reference in New Issue
Block a user