custom_user: set email verification sources (#66054)
This commit is contained in:
parent
bf85976e04
commit
43ccdfea68
|
@ -736,7 +736,7 @@ class UserCsvImporter:
|
|||
if getattr(user, cell.header.name) != cell.value:
|
||||
setattr(user, cell.header.name, cell.value)
|
||||
if cell.header.name == 'email' and cell.header.verified:
|
||||
user.set_email_verified(True)
|
||||
user.set_email_verified(True, source='csv')
|
||||
if cell.header.name == 'phone' and cell.header.verified:
|
||||
user.phone_verified_on = now()
|
||||
cell.action = 'updated'
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# Generated by Django 2.2.26 on 2022-06-08 12:33
|
||||
|
||||
import django.contrib.postgres.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('custom_user', '0033_user_keepalive'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='email_verified_sources',
|
||||
field=django.contrib.postgres.fields.ArrayField(
|
||||
base_field=models.CharField(max_length=63),
|
||||
default=list,
|
||||
size=None,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name='email verification sources',
|
||||
),
|
||||
),
|
||||
]
|
|
@ -28,6 +28,7 @@ from django.contrib.auth.models import AbstractBaseUser, Group
|
|||
from django.contrib.auth.models import Permission as AuthPermission
|
||||
from django.contrib.auth.models import _user_has_module_perms, _user_has_perm
|
||||
from django.contrib.contenttypes.fields import GenericRelation
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from django.core.exceptions import MultipleObjectsReturned, ValidationError
|
||||
from django.core.mail import send_mail
|
||||
from django.db import models, transaction
|
||||
|
@ -183,6 +184,13 @@ class User(AbstractBaseUser):
|
|||
email_verified_date = models.DateTimeField(
|
||||
default=None, blank=True, null=True, verbose_name=_('email verified date')
|
||||
)
|
||||
email_verified_sources = ArrayField(
|
||||
verbose_name=_('email verification sources'),
|
||||
base_field=models.CharField(max_length=63),
|
||||
default=list,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
is_superuser = models.BooleanField(
|
||||
_('superuser status'),
|
||||
default=False,
|
||||
|
@ -607,16 +615,22 @@ class User(AbstractBaseUser):
|
|||
def get_absolute_url(self):
|
||||
return reverse('a2-manager-user-detail', kwargs={'pk': self.pk})
|
||||
|
||||
def set_email_verified(self, value):
|
||||
if isinstance(value, datetime.datetime):
|
||||
self.email_verified = True
|
||||
self.email_verified_date = value
|
||||
elif bool(value):
|
||||
self.email_verified = True
|
||||
self.email_verified_date = timezone.now()
|
||||
def set_email_verified(self, value, source=None):
|
||||
if bool(value):
|
||||
if isinstance(value, datetime.datetime):
|
||||
self.email_verified = True
|
||||
self.email_verified_date = value
|
||||
else:
|
||||
self.email_verified = True
|
||||
self.email_verified_date = timezone.now()
|
||||
if source and source not in self.email_verified_sources:
|
||||
self.email_verified_sources.append(source)
|
||||
else:
|
||||
self.email_verified = False
|
||||
self.email_verified_date = None
|
||||
if source and source in self.email_verified_sources:
|
||||
self.email_verified_sources.remove(source)
|
||||
if not source or not self.email_verified_sources:
|
||||
self.email_verified = False
|
||||
self.email_verified_date = None
|
||||
|
||||
|
||||
class DeletedUser(models.Model):
|
||||
|
|
|
@ -139,7 +139,7 @@ class RegistrationCompletionFormNoPassword(profile_forms.BaseUserForm):
|
|||
return BaseUserManager.normalize_email(email)
|
||||
|
||||
def save(self, commit=True):
|
||||
self.instance.set_email_verified(True)
|
||||
self.instance.set_email_verified(True, source='registration')
|
||||
self.instance.is_active = True
|
||||
user = super().save(commit=commit)
|
||||
if commit and app_settings.A2_REGISTRATION_GROUPS:
|
||||
|
|
|
@ -294,7 +294,7 @@ class EmailChangeVerifyView(TemplateView):
|
|||
raise ValidationError(_('This email is already used by another account.'))
|
||||
old_email = user.email
|
||||
user.email = email
|
||||
user.set_email_verified(True)
|
||||
user.set_email_verified(True, source='user')
|
||||
user.save()
|
||||
messages.info(
|
||||
request, _('your request for changing your email for {0} is successful').format(email)
|
||||
|
@ -994,7 +994,7 @@ class PasswordResetConfirmView(cbv.RedirectToNextURLViewMixin, FormView):
|
|||
|
||||
def form_valid(self, form):
|
||||
# Changing password by mail validate the email
|
||||
form.user.set_email_verified(True)
|
||||
form.user.set_email_verified(True, source='user')
|
||||
form.save()
|
||||
hooks.call_hooks('event', name='password-reset-confirm', user=form.user, token=self.token, form=form)
|
||||
logger.info('password reset for user %s with token %r', self.user, self.token.uuid)
|
||||
|
|
|
@ -368,7 +368,7 @@ class OIDCBackend(ModelBackend):
|
|||
logger.info('auth_oidc: set user %s attribute %s to value %s', user, attribute, value)
|
||||
setattr(user, attribute, value)
|
||||
if attribute == 'email':
|
||||
user.set_email_verified(verified)
|
||||
user.set_email_verified(verified, source='oidc')
|
||||
save_user = True
|
||||
|
||||
if user.ou != user_ou:
|
||||
|
|
|
@ -63,6 +63,7 @@ USER_ATTRIBUTES_SET = {
|
|||
'modified',
|
||||
'email_verified',
|
||||
'email_verified_date',
|
||||
'email_verified_sources',
|
||||
'phone',
|
||||
'phone_verified_on',
|
||||
'last_account_deletion_alert',
|
||||
|
|
|
@ -71,6 +71,7 @@ class SerializerTests(TestCase):
|
|||
'uuid': u.uuid,
|
||||
'email_verified': False,
|
||||
'email_verified_date': None,
|
||||
'email_verified_sources': '[]', # weird ArrayField serialization behavior
|
||||
'username': 'john.doe',
|
||||
'email': '',
|
||||
'phone': None,
|
||||
|
|
|
@ -165,3 +165,35 @@ def test_service_profile_type(db):
|
|||
ServiceProfileType.objects.create(service=service, profile_type=pft)
|
||||
assert list(service.profile_types.all()) == [pft]
|
||||
assert list(pft.services.all()) == [service]
|
||||
|
||||
|
||||
def test_user_email_verified(app, simple_user, superuser_or_admin):
|
||||
simple_user.set_email_verified(True, source='tests')
|
||||
simple_user.save()
|
||||
user = User.objects.get(id=simple_user.id)
|
||||
assert user.email_verified
|
||||
assert user.email_verified_sources == ['tests']
|
||||
|
||||
simple_user.set_email_verified(True, source='other')
|
||||
simple_user.save()
|
||||
user = User.objects.get(id=simple_user.id)
|
||||
assert user.email_verified
|
||||
assert user.email_verified_sources == ['tests', 'other']
|
||||
|
||||
simple_user.set_email_verified(False, source='tests')
|
||||
simple_user.save()
|
||||
user = User.objects.get(id=simple_user.id)
|
||||
assert user.email_verified
|
||||
assert user.email_verified_sources == ['other']
|
||||
|
||||
simple_user.set_email_verified(True, source='other')
|
||||
simple_user.save()
|
||||
user = User.objects.get(id=simple_user.id)
|
||||
assert user.email_verified
|
||||
assert user.email_verified_sources == ['other']
|
||||
|
||||
simple_user.set_email_verified(False, source='other')
|
||||
simple_user.save()
|
||||
user = User.objects.get(id=simple_user.id)
|
||||
assert not user.email_verified
|
||||
assert user.email_verified_sources == []
|
||||
|
|
Loading…
Reference in New Issue