misc: prevent cleaning of unused LDAP and OIDC accounts (#47387)

This commit is contained in:
Benjamin Dauvergne 2020-10-06 13:49:46 +02:00
parent ed6be9daed
commit 6c231ae2b9
2 changed files with 42 additions and 10 deletions

View File

@ -27,6 +27,7 @@ from django.utils import timezone, translation
from django.utils.six.moves.urllib import parse as urlparse
from django_rbac.utils import get_ou_model
from authentic2.backends.ldap_backend import LDAPBackend
from authentic2.utils import send_templated_mail
from django.conf import settings
@ -61,6 +62,15 @@ class Command(BaseCommand):
logger.propagate = False
self.now = timezone.now()
# exclude user from LDAP directories based on their source name (or realm)
realms = [block['realm'] for block in LDAPBackend.get_config() if block.get('realm')]
self.user_qs = (
User.objects.all()
.exclude(oidc_account__isnull=False)
.exclude(userexternalid__source__in=realms)
)
translation.activate(settings.LANGUAGE_CODE)
try:
self.clean_unused_accounts()
@ -71,7 +81,7 @@ class Command(BaseCommand):
for ou in get_ou_model().objects.filter(clean_unused_accounts_alert__isnull=False):
alert_delay = timedelta(days=ou.clean_unused_accounts_alert)
deletion_delay = timedelta(days=ou.clean_unused_accounts_deletion)
ou_users = User.objects.filter(ou=ou)
ou_users = self.user_qs.filter(ou=ou)
# reset last_account_deletion_alert for users which connected since last alert
active_users = ou_users.filter(last_login__gte=F('last_account_deletion_alert'))

View File

@ -26,7 +26,8 @@ from django.utils.timezone import now
import py
from authentic2.a2_rbac.utils import get_default_ou
from authentic2_auth_oidc.models import OIDCProvider
from authentic2.models import UserExternalId
from authentic2_auth_oidc.models import OIDCProvider, OIDCAccount
from django_rbac.models import ADMIN_OP
from django_rbac.models import Operation
from django_rbac.utils import get_operation
@ -37,6 +38,8 @@ from django.contrib.auth import get_user_model
from .utils import login, call_command
User = get_user_model()
if six.PY2:
FileType = file # noqa: F821
else:
@ -57,30 +60,50 @@ def test_changepassword(db, simple_user, monkeypatch):
assert old_pass != simple_user.password
def test_clean_unused_account(db, simple_user, mailoutbox, freezer):
def test_clean_unused_account(db, simple_user, mailoutbox, freezer, settings):
settings.LDAP_AUTH_SETTINGS = [{'realm': 'ldap', 'url': 'ldap://ldap.com/', 'basedn': 'dc=ldap,dc=com'}]
ldap_user = User.objects.create(username='ldap-user',
email='ldap-user@example.com',
ou=simple_user.ou)
oidc_user = User.objects.create(username='oidc-user',
email='oidc-user@example.com',
ou=simple_user.ou)
UserExternalId.objects.create(user=ldap_user, source='ldap',
external_id='whatever')
provider = OIDCProvider.objects.create(name='oidc', ou=simple_user.ou)
OIDCAccount.objects.create(user=oidc_user, provider=provider, sub='1')
email = simple_user.email
freezer.move_to('2018-01-01')
simple_user.ou.clean_unused_accounts_alert = 2
simple_user.ou.clean_unused_accounts_deletion = 3
simple_user.ou.save()
simple_user.last_login = now() - datetime.timedelta(days=2)
simple_user.save()
last_login = now() - datetime.timedelta(days=2, seconds=30)
for user in (simple_user, ldap_user, oidc_user):
user.last_login = last_login
user.save()
call_command('clean-unused-accounts')
simple_user.refresh_from_db()
assert not simple_user.deleted
for user in (simple_user, ldap_user, oidc_user):
user.refresh_from_db()
assert not simple_user.deleted
assert len(mailoutbox) == 1
freezer.move_to('2018-01-01 12:00:00')
# no new mail, no deletion
call_command('clean-unused-accounts')
simple_user.refresh_from_db()
assert not simple_user.deleted
for user in (simple_user, ldap_user, oidc_user):
user.refresh_from_db()
assert not simple_user.deleted
assert len(mailoutbox) == 1
freezer.move_to('2018-01-02')
call_command('clean-unused-accounts')
for user in (ldap_user, oidc_user):
user.refresh_from_db()
assert not simple_user.deleted
simple_user.refresh_from_db()
assert simple_user.deleted
assert len(mailoutbox) == 2
@ -318,7 +341,6 @@ def test_check_identifiers_uniqueness(db, capsys, settings):
settings.A2_EMAIL_IS_UNIQUE = False
settings.A2_USERNAME_IS_UNIQUE = False
User = get_user_model()
user1 = User.objects.create(
username='foo', email='foo@example.net',
first_name='Toto', last_name='Foo')