From 03250d4b613dd767f711ca54e3925582fae35c7a Mon Sep 17 00:00:00 2001
From: Dorian Lesbre <dorian.lesbre@gmail.com>
Date: Wed, 3 Mar 2021 18:44:08 +0100
Subject: [PATCH] Switched to email username + required first and last name for
 accounts

---
 accounts/admin.py      | 17 +++++++++++++++-
 accounts/forms.py      |  7 +++----
 accounts/models.py     | 46 +++++++++++++++++++++++++++++++++++++++++-
 accounts/views.py      |  2 +-
 home/models.py         |  5 +++--
 interludes/settings.py |  2 ++
 6 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/accounts/admin.py b/accounts/admin.py
index 8c38f3f..9818714 100644
--- a/accounts/admin.py
+++ b/accounts/admin.py
@@ -1,3 +1,18 @@
 from django.contrib import admin
+from django.contrib.auth.models import Group
 
-# Register your models here.
+from accounts.models import EmailUser
+
+# no need for groups - we only have regular users and superusers
+admin.site.unregister(Group)
+
+@admin.register(EmailUser)
+class EmailUserAdmin(admin.ModelAdmin):
+	"""option d'affichage des activités dans la vue django admin"""
+	list_display = ("email", "last_name", "first_name", "is_superuser")
+	list_filter = ("is_superuser",)
+	list_editable = ("is_superuser",)
+	ordering = ("last_name", "first_name")
+	readonly_fields = ("date_joined", "last_login",)
+	exclude = ("groups","password",)
+	list_per_page = 200
diff --git a/accounts/forms.py b/accounts/forms.py
index 9632d7a..a49fa5f 100644
--- a/accounts/forms.py
+++ b/accounts/forms.py
@@ -1,10 +1,9 @@
 from django.contrib.auth.forms import UserCreationForm
-from django.contrib.auth.models import User
 
-from home.models import InterludesParticipant
+from accounts.models import EmailUser
 
 class CreateAccountForm(UserCreationForm):
 	"""Form used to register a new user"""
 	class Meta:
-		model = User
-		fields = ('username', 'password1', 'password2',)
+		model = EmailUser
+		fields = ('email', 'first_name', 'last_name', 'password1', 'password2',)
diff --git a/accounts/models.py b/accounts/models.py
index 71a8362..bd52c6f 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -1,3 +1,47 @@
 from django.db import models
+from django.contrib.auth.base_user import BaseUserManager
+from django.contrib.auth.models import AbstractUser
 
-# Create your models here.
+
+class EmailUserManager(BaseUserManager):
+	"""User model manager that replaces username with email"""
+	def create_user(self, email, password, **extra_fields):
+		"""Create and save a User with the given email and password."""
+		if not email:
+			raise ValueError("Creating user with no email")
+		email = self.normalize_email(email)
+		user = self.model(email=email, **extra_fields)
+		user.set_password(password)
+		user.save()
+		return user
+
+	def create_superuser(self, email, password, **extra_fields):
+		"""Create and save a SuperUser with the given email and password."""
+		extra_fields.setdefault('is_staff', True)
+		extra_fields.setdefault('is_superuser', True)
+		extra_fields.setdefault('is_active', True)
+
+		if extra_fields.get('is_staff') is not True:
+			raise ValueError('Superuser must have is_staff=True.')
+		if extra_fields.get('is_superuser') is not True:
+			raise ValueError('Superuser must have is_superuser=True.')
+		return self.create_user(email, password, **extra_fields)
+
+class EmailUser(AbstractUser):
+	"""Utilisateur identifié par son email et non
+	un nom d'utilisateur"""
+	username = None
+	email = models.EmailField('adresse email', unique=True)
+	first_name = models.CharField('prénom', max_length=100)
+	last_name = models.CharField("nom", max_length=100)
+
+	USERNAME_FIELD = 'email'
+	REQUIRED_FIELDS = ("last_name", "first_name",)
+
+	objects = EmailUserManager()
+
+	def __str__(self):
+		return self.email
+
+	class Meta:
+		verbose_name = "utilisateur"
diff --git a/accounts/views.py b/accounts/views.py
index e4d73a1..3212e21 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -22,7 +22,7 @@ def create_account(request):
 			raw_password = form.cleaned_data.get('password1')
 
 			# login user after signing up
-			user = authenticate(username=user.username, password=raw_password)
+			user = authenticate(email=user.email, password=raw_password)
 			login(request, user)
 
 			# redirect user to home page
diff --git a/home/models.py b/home/models.py
index 34c4d83..de4d430 100644
--- a/home/models.py
+++ b/home/models.py
@@ -1,7 +1,8 @@
-from django.contrib.auth.models import User
 from django.db import models
 from django.utils.translation import gettext_lazy as _
 
+from accounts.models import EmailUser
+
 class InterludesActivity(models.Model):
 	"""une activité des interludes (i.e. JDR, murder)..."""
 	title = models.CharField("Titre", max_length=200)
@@ -42,7 +43,7 @@ class InterludesParticipant(models.Model):
 		ENS_RENNES = "R", _("ENS Rennes")
 		ENS_CACHAN = "C", _("ENS Paris Saclay")
 
-	user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="Utilisateur")
+	user = models.OneToOneField(EmailUser, on_delete=models.CASCADE, related_name="Utilisateur")
 	name = models.CharField("Nom complet", max_length=200)
 	email = models.EmailField("email")
 	school = models.CharField("ENS de rattachement", choices=ENS.choices, max_length=1)
diff --git a/interludes/settings.py b/interludes/settings.py
index d74a5df..e82bcad 100644
--- a/interludes/settings.py
+++ b/interludes/settings.py
@@ -90,6 +90,8 @@ AUTHENTICATION_BACKENDS = (
 # Password validation
 # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
 
+AUTH_USER_MODEL = 'accounts.EmailUser'
+
 AUTH_PASSWORD_VALIDATORS = [
 	{
 		'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
-- 
GitLab