mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-09 19:40:19 +00:00
Make core.User
inherit from AbstractUser
instead of AbstractBaseUser
This commit is contained in:
@ -261,19 +261,19 @@ class Command(BaseCommand):
|
||||
User.groups.through.objects.bulk_create(
|
||||
[
|
||||
User.groups.through(
|
||||
realgroup_id=settings.SITH_GROUP_COUNTER_ADMIN_ID, user=counter
|
||||
group_id=settings.SITH_GROUP_COUNTER_ADMIN_ID, user=counter
|
||||
),
|
||||
User.groups.through(
|
||||
realgroup_id=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID, user=comptable
|
||||
group_id=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID, user=comptable
|
||||
),
|
||||
User.groups.through(
|
||||
realgroup_id=settings.SITH_GROUP_COM_ADMIN_ID, user=comunity
|
||||
group_id=settings.SITH_GROUP_COM_ADMIN_ID, user=comunity
|
||||
),
|
||||
User.groups.through(
|
||||
realgroup_id=settings.SITH_GROUP_PEDAGOGY_ADMIN_ID, user=tutu
|
||||
group_id=settings.SITH_GROUP_PEDAGOGY_ADMIN_ID, user=tutu
|
||||
),
|
||||
User.groups.through(
|
||||
realgroup_id=settings.SITH_GROUP_SAS_ADMIN_ID, user=skia
|
||||
group_id=settings.SITH_GROUP_SAS_ADMIN_ID, user=skia
|
||||
),
|
||||
]
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ from django.utils.timezone import localdate, make_aware, now
|
||||
from faker import Faker
|
||||
|
||||
from club.models import Club, Membership
|
||||
from core.models import RealGroup, User
|
||||
from core.models import Group, User
|
||||
from counter.models import (
|
||||
Counter,
|
||||
Customer,
|
||||
@ -225,9 +225,7 @@ class Command(BaseCommand):
|
||||
ae = Club.objects.get(unix_name="ae")
|
||||
other_clubs = random.sample(list(Club.objects.all()), k=3)
|
||||
groups = list(
|
||||
RealGroup.objects.filter(
|
||||
name__in=["Subscribers", "Old subscribers", "Public"]
|
||||
)
|
||||
Group.objects.filter(name__in=["Subscribers", "Old subscribers", "Public"])
|
||||
)
|
||||
counters = list(
|
||||
Counter.objects.filter(name__in=["Foyer", "MDE", "La Gommette", "Eboutic"])
|
||||
|
@ -0,0 +1,82 @@
|
||||
# Generated by Django 4.2.16 on 2024-11-20 16:22
|
||||
|
||||
import django.contrib.auth.validators
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("auth", "0012_alter_user_first_name_max_length"),
|
||||
("core", "0039_alter_user_managers"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="user",
|
||||
options={"verbose_name": "user", "verbose_name_plural": "users"},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="user_permissions",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="Specific permissions for this user.",
|
||||
related_name="user_set",
|
||||
related_query_name="user",
|
||||
to="auth.permission",
|
||||
verbose_name="user permissions",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="date_joined",
|
||||
field=models.DateTimeField(
|
||||
default=django.utils.timezone.now, verbose_name="date joined"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="is_superuser",
|
||||
field=models.BooleanField(
|
||||
default=False,
|
||||
help_text="Designates that this user has all permissions without explicitly assigning them.",
|
||||
verbose_name="superuser status",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="username",
|
||||
field=models.CharField(
|
||||
error_messages={"unique": "A user with that username already exists."},
|
||||
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
|
||||
max_length=150,
|
||||
unique=True,
|
||||
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
|
||||
verbose_name="username",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="groups",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
|
||||
related_name="user_set",
|
||||
related_query_name="user",
|
||||
to="auth.group",
|
||||
verbose_name="groups",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="groups",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
|
||||
related_name="users",
|
||||
to="core.group",
|
||||
verbose_name="groups",
|
||||
),
|
||||
),
|
||||
]
|
@ -30,19 +30,13 @@ import string
|
||||
import unicodedata
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, Optional, Self
|
||||
from typing import TYPE_CHECKING, Optional, Self
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AbstractBaseUser, UserManager
|
||||
from django.contrib.auth.models import (
|
||||
AnonymousUser as AuthAnonymousUser,
|
||||
)
|
||||
from django.contrib.auth.models import (
|
||||
Group as AuthGroup,
|
||||
)
|
||||
from django.contrib.auth.models import (
|
||||
GroupManager as AuthGroupManager,
|
||||
)
|
||||
from django.contrib.auth.models import AbstractUser, UserManager
|
||||
from django.contrib.auth.models import AnonymousUser as AuthAnonymousUser
|
||||
from django.contrib.auth.models import Group as AuthGroup
|
||||
from django.contrib.auth.models import GroupManager as AuthGroupManager
|
||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
||||
from django.core import validators
|
||||
from django.core.cache import cache
|
||||
@ -242,7 +236,7 @@ class CustomUserManager(UserManager.from_queryset(UserQuerySet)):
|
||||
pass
|
||||
|
||||
|
||||
class User(AbstractBaseUser):
|
||||
class User(AbstractUser):
|
||||
"""Defines the base user class, useable in every app.
|
||||
|
||||
This is almost the same as the auth module AbstractUser since it inherits from it,
|
||||
@ -253,51 +247,22 @@ class User(AbstractBaseUser):
|
||||
Required fields: email, first_name, last_name, date_of_birth
|
||||
"""
|
||||
|
||||
username = models.CharField(
|
||||
_("username"),
|
||||
max_length=254,
|
||||
unique=True,
|
||||
help_text=_(
|
||||
"Required. 254 characters or fewer. Letters, digits and ./+/-/_ only."
|
||||
),
|
||||
validators=[
|
||||
validators.RegexValidator(
|
||||
r"^[\w.+-]+$",
|
||||
_(
|
||||
"Enter a valid username. This value may contain only "
|
||||
"letters, numbers "
|
||||
"and ./+/-/_ characters."
|
||||
),
|
||||
)
|
||||
],
|
||||
error_messages={"unique": _("A user with that username already exists.")},
|
||||
)
|
||||
first_name = models.CharField(_("first name"), max_length=64)
|
||||
last_name = models.CharField(_("last name"), max_length=64)
|
||||
email = models.EmailField(_("email address"), unique=True)
|
||||
date_of_birth = models.DateField(_("date of birth"), blank=True, null=True)
|
||||
nick_name = models.CharField(_("nick name"), max_length=64, null=True, blank=True)
|
||||
is_staff = models.BooleanField(
|
||||
_("staff status"),
|
||||
default=False,
|
||||
help_text=_("Designates whether the user can log into this admin site."),
|
||||
)
|
||||
is_active = models.BooleanField(
|
||||
_("active"),
|
||||
default=True,
|
||||
help_text=_(
|
||||
"Designates whether this user should be treated as active. "
|
||||
"Unselect this instead of deleting accounts."
|
||||
),
|
||||
)
|
||||
date_joined = models.DateField(_("date joined"), auto_now_add=True)
|
||||
last_update = models.DateTimeField(_("last update"), auto_now=True)
|
||||
is_superuser = models.BooleanField(
|
||||
_("superuser"),
|
||||
default=False,
|
||||
help_text=_("Designates whether this user is a superuser. "),
|
||||
groups = models.ManyToManyField(
|
||||
Group,
|
||||
verbose_name=_("groups"),
|
||||
help_text=_(
|
||||
"The groups this user belongs to. A user will get all permissions "
|
||||
"granted to each of their groups."
|
||||
),
|
||||
related_name="users",
|
||||
blank=True,
|
||||
)
|
||||
groups = models.ManyToManyField(RealGroup, related_name="users", blank=True)
|
||||
home = models.OneToOneField(
|
||||
"SithFile",
|
||||
related_name="home_of",
|
||||
@ -401,8 +366,6 @@ class User(AbstractBaseUser):
|
||||
|
||||
objects = CustomUserManager()
|
||||
|
||||
USERNAME_FIELD = "username"
|
||||
|
||||
def __str__(self):
|
||||
return self.get_display_name()
|
||||
|
||||
@ -422,12 +385,6 @@ class User(AbstractBaseUser):
|
||||
settings.BASE_DIR / f"core/static/core/img/promo_{self.promo}.png"
|
||||
).exists()
|
||||
|
||||
def has_module_perms(self, package_name: str) -> bool:
|
||||
return self.is_active
|
||||
|
||||
def has_perm(self, perm: str, obj: Any = None) -> bool:
|
||||
return self.is_active and self.is_superuser
|
||||
|
||||
@cached_property
|
||||
def was_subscribed(self) -> bool:
|
||||
return self.subscriptions.exists()
|
||||
@ -599,11 +556,6 @@ class User(AbstractBaseUser):
|
||||
"date_of_birth": self.date_of_birth,
|
||||
}
|
||||
|
||||
def get_full_name(self):
|
||||
"""Returns the first_name plus the last_name, with a space in between."""
|
||||
full_name = "%s %s" % (self.first_name, self.last_name)
|
||||
return full_name.strip()
|
||||
|
||||
def get_short_name(self):
|
||||
"""Returns the short name for the user."""
|
||||
if self.nick_name:
|
||||
@ -982,13 +934,11 @@ class SithFile(models.Model):
|
||||
if copy_rights:
|
||||
self.copy_rights()
|
||||
if self.is_in_sas:
|
||||
for u in (
|
||||
RealGroup.objects.filter(id=settings.SITH_GROUP_SAS_ADMIN_ID)
|
||||
.first()
|
||||
.users.all()
|
||||
for user in User.objects.filter(
|
||||
groups__id__in=[settings.SITH_GROUP_SAS_ADMIN_ID]
|
||||
):
|
||||
Notification(
|
||||
user=u,
|
||||
user=user,
|
||||
url=reverse("sas:moderation"),
|
||||
type="SAS_MODERATION",
|
||||
param="1",
|
||||
|
@ -118,7 +118,9 @@ class TestUserRegistration:
|
||||
response = client.post(reverse("core:register"), valid_payload)
|
||||
|
||||
assert response.status_code == 200
|
||||
error_html = "<li>Un objet User avec ce champ Adresse email existe déjà.</li>"
|
||||
error_html = (
|
||||
"<li>Un objet Utilisateur avec ce champ Adresse email existe déjà.</li>"
|
||||
)
|
||||
assertInHTML(error_html, str(response.content.decode()))
|
||||
|
||||
def test_register_fail_with_not_existing_email(
|
||||
|
@ -14,7 +14,7 @@ from PIL import Image
|
||||
from pytest_django.asserts import assertNumQueries
|
||||
|
||||
from core.baker_recipes import board_user, old_subscriber_user, subscriber_user
|
||||
from core.models import Group, RealGroup, SithFile, User
|
||||
from core.models import Group, SithFile, User
|
||||
from sas.models import Picture
|
||||
from sith import settings
|
||||
|
||||
@ -26,12 +26,10 @@ class TestImageAccess:
|
||||
[
|
||||
lambda: baker.make(User, is_superuser=True),
|
||||
lambda: baker.make(
|
||||
User,
|
||||
groups=[RealGroup.objects.get(pk=settings.SITH_GROUP_SAS_ADMIN_ID)],
|
||||
User, groups=[Group.objects.get(pk=settings.SITH_GROUP_SAS_ADMIN_ID)]
|
||||
),
|
||||
lambda: baker.make(
|
||||
User,
|
||||
groups=[RealGroup.objects.get(pk=settings.SITH_GROUP_COM_ADMIN_ID)],
|
||||
User, groups=[Group.objects.get(pk=settings.SITH_GROUP_COM_ADMIN_ID)]
|
||||
),
|
||||
],
|
||||
)
|
||||
|
@ -21,6 +21,7 @@ from wsgiref.util import FileWrapper
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models import Exists, OuterRef
|
||||
from django.forms.models import modelform_factory
|
||||
from django.http import Http404, HttpRequest, HttpResponse
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
@ -31,7 +32,7 @@ from django.views.generic import DetailView, ListView
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.views.generic.edit import DeleteView, FormMixin, UpdateView
|
||||
|
||||
from core.models import Notification, RealGroup, SithFile, User
|
||||
from core.models import Notification, SithFile, User
|
||||
from core.views import (
|
||||
AllowFragment,
|
||||
CanEditMixin,
|
||||
@ -159,19 +160,18 @@ class AddFilesForm(forms.Form):
|
||||
% {"file_name": f, "msg": repr(e)},
|
||||
)
|
||||
if notif:
|
||||
for u in (
|
||||
RealGroup.objects.filter(id=settings.SITH_GROUP_COM_ADMIN_ID)
|
||||
.first()
|
||||
.users.all()
|
||||
unread_notif_subquery = Notification.objects.filter(
|
||||
user=OuterRef("pk"), type="FILE_MODERATION", viewed=False
|
||||
)
|
||||
for user in User.objects.filter(
|
||||
~Exists(unread_notif_subquery),
|
||||
groups__id__in=[settings.SITH_GROUP_COM_ADMIN_ID],
|
||||
):
|
||||
if not u.notifications.filter(
|
||||
type="FILE_MODERATION", viewed=False
|
||||
).exists():
|
||||
Notification(
|
||||
user=u,
|
||||
url=reverse("core:file_moderation"),
|
||||
type="FILE_MODERATION",
|
||||
).save()
|
||||
Notification.objects.create(
|
||||
user=user,
|
||||
url=reverse("core:file_moderation"),
|
||||
type="FILE_MODERATION",
|
||||
)
|
||||
|
||||
|
||||
class FileListView(ListView):
|
||||
|
@ -167,9 +167,7 @@ class RegisteringForm(UserCreationForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("first_name", "last_name", "email")
|
||||
field_classes = {
|
||||
"email": AntiSpamEmailField,
|
||||
}
|
||||
field_classes = {"email": AntiSpamEmailField}
|
||||
|
||||
|
||||
class UserProfileForm(forms.ModelForm):
|
||||
|
@ -23,9 +23,7 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
||||
|
||||
from core.models import RealGroup, User
|
||||
from core.views import CanCreateMixin, CanEditMixin, DetailFormView
|
||||
from core.views.widgets.select import (
|
||||
AutoCompleteSelectMultipleUser,
|
||||
)
|
||||
from core.views.widgets.select import AutoCompleteSelectMultipleUser
|
||||
|
||||
# Forms
|
||||
|
||||
|
Reference in New Issue
Block a user