0001-custom_user-add-field-to-store-user-deactivation-tim.patch
src/authentic2/admin.py | ||
---|---|---|
277 | 277 |
(_('Personal info'), {'fields': ('username', 'first_name', 'last_name', 'email')}), |
278 | 278 |
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', |
279 | 279 |
'groups')}), |
280 |
(_('Important dates'), {'fields': ('last_login', 'date_joined')}), |
|
280 |
(_('Important dates'), {'fields': ('last_login', 'date_joined', 'deactivation')}),
|
|
281 | 281 |
) |
282 | 282 |
add_fieldsets = ( |
283 | 283 |
(None, { |
... | ... | |
287 | 287 |
readonly_fields = ('uuid',) |
288 | 288 |
list_filter = UserAdmin.list_filter + (UserRealmListFilter, ExternalUserListFilter) + ('deleted',) |
289 | 289 |
list_display = ['__str__', 'ou', 'first_name', 'last_name', 'email', 'deleted'] |
290 |
actions = UserAdmin.actions + ['mark_as_deleted', 'unmark_as_deleted', 'apply_deletion'] |
|
290 |
actions = UserAdmin.actions + ['mark_as_inactive', 'mark_as_deleted', |
|
291 |
'unmark_as_deleted', 'apply_deletion'] |
|
291 | 292 | |
292 | 293 |
def get_fieldsets(self, request, obj=None): |
293 | 294 |
fieldsets = deepcopy(super(AuthenticUserAdmin, self).get_fieldsets(request, obj)) |
... | ... | |
327 | 328 |
kwargs['fields'] = fields |
328 | 329 |
return super(AuthenticUserAdmin, self).get_form(request, obj=obj, **kwargs) |
329 | 330 | |
331 |
@transaction.atomic |
|
332 |
def mark_as_inactive(self, request, queryset): |
|
333 |
timestamp = timezone.now() |
|
334 |
for user in queryset: |
|
335 |
user.mark_as_inactive(timestamp=timestamp) |
|
336 |
mark_as_inactive.short_description = _('Mark as inactive') |
|
337 | ||
330 | 338 |
@transaction.atomic |
331 | 339 |
def mark_as_deleted(self, request, queryset): |
332 | 340 |
timestamp = timezone.now() |
src/authentic2/custom_user/migrations/0025_user_deactivation.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
# Generated by Django 1.11.29 on 2021-02-09 09:37 |
|
3 |
from __future__ import unicode_literals |
|
4 | ||
5 |
from django.db import migrations, models |
|
6 | ||
7 | ||
8 |
class Migration(migrations.Migration): |
|
9 | ||
10 |
dependencies = [ |
|
11 |
('custom_user', '0024_index_email_by_trigrams'), |
|
12 |
] |
|
13 | ||
14 |
operations = [ |
|
15 |
migrations.AddField( |
|
16 |
model_name='user', |
|
17 |
name='deactivation', |
|
18 |
field=models.DateTimeField(blank=True, null=True, verbose_name='Deactivation datetime'), |
|
19 |
), |
|
20 |
] |
src/authentic2/custom_user/models.py | ||
---|---|---|
193 | 193 |
verbose_name=_('Deletion date'), |
194 | 194 |
null=True, |
195 | 195 |
blank=True) |
196 |
deactivation = models.DateTimeField( |
|
197 |
verbose_name=_('Deactivation datetime'), |
|
198 |
null=True, |
|
199 |
blank=True) |
|
196 | 200 | |
197 | 201 |
objects = UserManager.from_queryset(UserQuerySet)() |
198 | 202 |
attributes = AttributesDescriptor() |
... | ... | |
363 | 367 |
del self._a2_attributes_cache |
364 | 368 |
return super(User, self).refresh_from_db(*args, **kwargs) |
365 | 369 | |
366 |
def mark_as_deleted(self, timestamp=None, force=True, save=True):
|
|
370 |
def mark_as_inactive(self, timestamp=None):
|
|
367 | 371 |
self.is_active = False |
372 |
self.deactivation = timestamp or timezone.now() |
|
373 |
self.save(update_fields=['is_active', 'deactivation']) |
|
374 | ||
375 |
def mark_as_deleted(self, timestamp=None, force=True, save=True): |
|
376 |
self.mark_as_inactive(timestamp) |
|
368 | 377 |
if force or not self.deleted: |
369 | 378 |
self.deleted = timestamp or timezone.now() |
370 | 379 |
if save: |
371 |
self.save(update_fields=['is_active', 'deleted'])
|
|
380 |
self.save(update_fields=['deleted']) |
|
372 | 381 | |
373 | 382 |
def set_random_password(self): |
374 | 383 |
self.set_password(base64.b64encode(os.urandom(32)).decode('ascii')) |
tests/test_all.py | ||
---|---|---|
92 | 92 |
'password': '', |
93 | 93 |
'ou': None, |
94 | 94 |
'deleted': None, |
95 |
'deactivation': None, |
|
95 | 96 |
} |
96 | 97 |
}, |
97 | 98 |
{ |
tests/test_api.py | ||
---|---|---|
416 | 416 |
'last_name_verified', 'date_joined', 'last_login', |
417 | 417 |
'username', 'password', 'email', 'is_active', 'title', |
418 | 418 |
'title_verified', 'modified', 'email_verified', |
419 |
'last_account_deletion_alert', 'deleted']) == set(resp.json.keys()) |
|
419 |
'last_account_deletion_alert', 'deleted', |
|
420 |
'deactivation']) == set(resp.json.keys()) |
|
420 | 421 |
assert resp.json['first_name'] == payload['first_name'] |
421 | 422 |
assert resp.json['last_name'] == payload['last_name'] |
422 | 423 |
assert resp.json['email'] == payload['email'] |
... | ... | |
483 | 484 |
'last_name_verified', 'date_joined', 'last_login', |
484 | 485 |
'username', 'password', 'email', 'is_active', 'title', |
485 | 486 |
'title_verified', 'modified', 'email_verified', |
486 |
'last_account_deletion_alert', 'deleted']) == set(resp.json.keys()) |
|
487 |
'last_account_deletion_alert', 'deleted', |
|
488 |
'deactivation']) == set(resp.json.keys()) |
|
487 | 489 |
user = get_user_model().objects.get(pk=resp.json['id']) |
488 | 490 |
assert AttributeValue.objects.with_owner(user).filter(verified=True).count() == 3 |
489 | 491 |
assert AttributeValue.objects.with_owner(user).filter(verified=False).count() == 0 |
490 |
- |