med/users/models.py

220 lines
6.9 KiB
Python
Raw Normal View History

2019-08-02 12:57:53 +00:00
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import datetime
2019-08-02 12:57:53 +00:00
import uuid
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
2019-08-02 19:35:30 +00:00
from django.contrib.auth.validators import ASCIIUsernameValidator, UnicodeUsernameValidator
2019-08-02 12:57:53 +00:00
from django.db import models
2019-08-02 19:35:30 +00:00
from django.utils import six, timezone
2019-08-02 12:57:53 +00:00
from django.utils.translation import gettext_lazy as _
from med.settings import MAX_EMPRUNT, REQ_EXPIRE_HRS
class UserManager(BaseUserManager):
2019-08-02 19:14:16 +00:00
use_in_migrations = True
2019-08-02 19:14:16 +00:00
def _create_user(self, username, name, surname, email, password=None, su=False):
"""
Creates and saves a User with the given username, email and password.
"""
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
username = self.model.normalize_username(username)
user = self.model(
2019-08-02 19:35:30 +00:00
username=username,
name=name,
surname=surname,
2019-08-02 19:14:16 +00:00
email=email,
)
user.set_password(password)
user.save(using=self._db)
if su:
user.make_admin()
return user
2019-08-02 19:35:30 +00:00
def create_user(self, username, name, surname, email, password=None):
"""
2019-08-02 19:35:30 +00:00
Creates and saves a User with the given username, name, surname, email,
and password.
"""
2019-08-02 19:35:30 +00:00
return self._create_user(username, name, surname, email, password, False)
2019-08-02 19:35:30 +00:00
def create_superuser(self, username, name, surname, email, password):
"""
2019-08-02 19:35:30 +00:00
Creates and saves a superuser with the given username, name, surname,
email, and password.
"""
2019-08-02 19:35:30 +00:00
return self._create_user(username, name, surname, email, password, True)
class User(AbstractBaseUser):
2019-08-02 19:35:30 +00:00
username_validator = UnicodeUsernameValidator() if six.PY3 else ASCIIUsernameValidator()
PRETTY_NAME = "Utilisateurs"
name = models.CharField(max_length=255)
surname = models.CharField(max_length=255)
2017-11-14 22:06:01 +00:00
email = models.EmailField()
2017-06-30 01:25:07 +00:00
telephone = models.CharField(max_length=15, null=True, blank=True)
adresse = models.CharField(max_length=255, null=True, blank=True)
2019-08-02 12:57:53 +00:00
maxemprunt = models.IntegerField(default=MAX_EMPRUNT, help_text="Maximum d'emprunts autorisés")
2019-08-02 19:35:30 +00:00
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
comment = models.CharField(help_text="Commentaire, promo", max_length=255, blank=True)
2019-08-02 16:37:54 +00:00
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.'
),
)
registered = models.DateTimeField(auto_now_add=True)
2017-06-30 01:25:07 +00:00
2019-08-02 19:35:30 +00:00
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['name', 'surname', 'email']
objects = UserManager()
@property
def is_admin(self):
2017-06-30 01:25:07 +00:00
try:
Right.objects.get(user=self, right__listright='admin')
except Right.DoesNotExist:
return False
return True
@is_admin.setter
def is_admin(self, value):
if value and not self.is_admin:
self.make_admin()
elif not value and self.is_admin:
self.un_admin()
def has_perms(self, perms, obj=None):
for perm in perms:
2017-06-30 01:25:07 +00:00
try:
Right.objects.get(user=self, right__listright=perm)
return True
except Right.DoesNotExist:
return False
def get_full_name(self):
return '%s %s' % (self.name, self.surname)
def get_short_name(self):
return self.name
def has_perm(self, perm, obj=None):
return True
2017-06-30 01:25:07 +00:00
def has_right(self, right):
return Right.objects.filter(user=self).filter(right=ListRight.objects.get(listright=right)).exists()
def has_module_perms(self, app_label):
# Simplest version again
return True
@property
def is_adherent(self):
2019-08-02 19:35:30 +00:00
last_adh_year = Adhesion.objects.all().order_by('annee_debut').reverse().first()
return last_adh_year and self in last_adh_year.adherent.all()
2017-06-30 01:25:07 +00:00
def get_admin_right(self):
admin, created = ListRight.objects.get_or_create(listright="admin")
2019-08-02 12:57:53 +00:00
return admin
2017-06-30 01:25:07 +00:00
def make_admin(self):
""" Make User admin """
2017-06-30 01:25:07 +00:00
user_admin_right = Right(user=self, right=self.get_admin_right())
user_admin_right.save()
2019-08-02 19:18:03 +00:00
self.is_staff = True
self.save()
2019-08-02 12:57:53 +00:00
def un_admin(self):
2017-06-30 01:25:07 +00:00
try:
2019-08-02 12:57:53 +00:00
user_right = Right.objects.get(user=self, right=self.get_admin_right())
2017-06-30 01:25:07 +00:00
except Right.DoesNotExist:
return
user_right.delete()
def __str__(self):
2019-08-02 19:35:30 +00:00
return self.username
class Request(models.Model):
PASSWD = 'PW'
EMAIL = 'EM'
TYPE_CHOICES = (
(PASSWD, 'Mot de passe'),
(EMAIL, 'Email'),
)
type = models.CharField(max_length=2, choices=TYPE_CHOICES)
token = models.CharField(max_length=32)
user = models.ForeignKey('User', on_delete=models.PROTECT)
created_at = models.DateTimeField(auto_now_add=True, editable=False)
expires_at = models.DateTimeField()
def save(self):
if not self.expires_at:
self.expires_at = timezone.now() \
2019-08-02 12:57:53 +00:00
+ datetime.timedelta(hours=REQ_EXPIRE_HRS)
if not self.token:
self.token = str(uuid.uuid4()).replace('-', '') # remove hyphens
super(Request, self).save()
2019-08-02 12:57:53 +00:00
2017-06-30 01:25:07 +00:00
class Right(models.Model):
PRETTY_NAME = "Droits affectés à des users"
2019-08-02 12:57:53 +00:00
2017-06-30 01:25:07 +00:00
user = models.ForeignKey('User', on_delete=models.PROTECT)
right = models.ForeignKey('ListRight', on_delete=models.PROTECT)
2019-08-02 12:57:53 +00:00
2017-06-30 01:25:07 +00:00
class Meta:
2019-08-02 12:57:53 +00:00
verbose_name = _("right")
verbose_name_plural = _("rights")
2017-06-30 01:25:07 +00:00
unique_together = ("user", "right")
2019-08-02 12:57:53 +00:00
2017-06-30 01:25:07 +00:00
def __str__(self):
return str(self.user)
2017-06-30 01:25:07 +00:00
2019-08-02 12:57:53 +00:00
2017-06-30 01:25:07 +00:00
class ListRight(models.Model):
PRETTY_NAME = "Liste des droits existants"
listright = models.CharField(max_length=255, unique=True)
details = models.CharField(help_text="Description", max_length=255, blank=True)
2019-08-02 12:57:53 +00:00
2017-06-30 01:25:07 +00:00
def __str__(self):
return self.listright
2019-08-02 12:57:53 +00:00
2017-07-03 18:06:21 +00:00
class Clef(models.Model):
nom = models.CharField(max_length=255, unique=True)
proprio = models.ForeignKey('User', on_delete=models.PROTECT, blank=True, null=True)
commentaire = models.CharField(max_length=255, null=True, blank=True)
2019-08-02 12:57:53 +00:00
class Adhesion(models.Model):
annee_debut = models.IntegerField(unique=True)
annee_fin = models.IntegerField(unique=True)
adherent = models.ManyToManyField('User', blank=True)