models.py 11.1 KB
Newer Older
lhark's avatar
lhark committed
1
from django.db import models
2
from django.forms import ModelForm, Form
3
from django import forms
4

chirac's avatar
chirac committed
5
import re
lhark's avatar
lhark committed
6

7
from django.utils import timezone
8
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
9

10
from topologie.models import Room
11
from cotisations.models import Cotisation, Facture
12

chirac's avatar
chirac committed
13 14 15 16 17 18 19 20 21
def remove_user_room(room):
    """ Déménage de force l'ancien locataire de la chambre """
    try:
        user = User.objects.get(room=room)
    except User.DoesNotExist:
        return
    user.room = None
    user.save()

22 23

def linux_user_check(login):
chirac's avatar
chirac committed
24 25
    """ Validation du pseudo pour respecter les contraintes unix"""
    UNIX_LOGIN_PATTERN = re.compile("^[a-z_][a-z0-9_-]*[$]?$")
26 27 28 29 30
    return UNIX_LOGIN_PATTERN.match(login)


def linux_user_validator(login):
    if not linux_user_check(login):
chirac's avatar
chirac committed
31 32 33 34 35
        raise forms.ValidationError(
                ", ce pseudo ('%(label)s') contient des carractères interdits",
                params={'label': login},
        )

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

def get_admin_right():
    try:
        admin_right = ListRight.objects.get(listright="admin")
    except ListRight.DoesNotExist:
        admin_right = ListRight(listright="admin")
        admin_right.save()
    return admin_right


class UserManager(BaseUserManager):
    def _create_user(self, pseudo, name, surname, email, password=None, su=False):
        if not pseudo:
            raise ValueError('Users must have an username')

        if not linux_user_check(pseudo):
            raise ValueError('Username shall only contain [a-z0-9_-]')

        user = self.model(
            pseudo=pseudo,
            name=name,
            surname=surname,
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        if su:
            user.make_admin()
        return user

    def create_user(self, pseudo, name, surname, email, password=None):
        """
        Creates and saves a User with the given pseudo, name, surname, email,
        and password.
        """
        return self._create_user(pseudo, name, surname, email, password, False)

    def create_superuser(self, pseudo, name, surname, email, password):
        """
        Creates and saves a superuser with the given pseudo, name, surname,
        email, and password.
        """
        return self._create_user(pseudo, name, surname, email, password, True)


class User(AbstractBaseUser):
lhark's avatar
lhark committed
83 84 85 86
    STATE_ACTIVE = 0
    STATE_DEACTIVATED = 1
    STATE_ARCHIVED = 2
    STATES = (
chirac's avatar
chirac committed
87 88 89
            (0, 'STATE_ACTIVE'),
            (1, 'STATE_DEACTIVATED'),
            (2, 'STATE_ARCHIVED'),
lhark's avatar
lhark committed
90 91 92 93
            )

    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
94
    pseudo = models.CharField(max_length=32, unique=True, help_text="Doit contenir uniquement des lettres, chiffres, ou tirets", validators=[linux_user_validator])
lhark's avatar
lhark committed
95
    email = models.EmailField()
96
    school = models.ForeignKey('School', on_delete=models.PROTECT, null=False, blank=False)
97
    comment = models.CharField(help_text="Commentaire, promo", max_length=255, blank=True)
98
    room = models.OneToOneField('topologie.Room', on_delete=models.PROTECT, blank=True, null=True)
lhark's avatar
lhark committed
99
    pwd_ntlm = models.CharField(max_length=255)
100
    state = models.IntegerField(choices=STATES, default=STATE_ACTIVE)
101
    registered = models.DateTimeField(auto_now_add=True)
lhark's avatar
lhark committed
102

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    USERNAME_FIELD = 'pseudo'
    REQUIRED_FIELDS = ['name', 'surname', 'email']

    objects = UserManager()

    @property
    def is_active(self):
        return self.state == self.STATE_ACTIVE

    @property
    def is_staff(self):
        return self.is_admin

    @property
    def is_admin(self):
        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 get_full_name(self):
        return '%s %s' % (self.name, self.surname)

    def get_short_name(self):
        return self.name

137 138 139 140 141 142
    def has_perms(self, perms, obj=None):
        for perm in perms:
            try:
                Right.objects.get(user=self, right__listright=perm)
            except Right.DoesNotExist:
                return False
143 144
        return True

145 146 147
    def has_perm(self, perm, obj=None):
        return True

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
    def end_adhesion(self):
        date_max = Cotisation.objects.all().filter(facture=Facture.objects.all().filter(user=self).exclude(valid=False)).aggregate(models.Max('date_end'))['date_end__max']
        return date_max

    def is_adherent(self):
        end = self.end_adhesion()
        if not end:
            return False
        elif end < timezone.now():
            return False
        else:
            return True

    def end_ban(self):
        """ Renvoie la date de fin de ban d'un user, False sinon """
        date_max = Ban.objects.all().filter(user=self).aggregate(models.Max('date_end'))['date_end__max']
        return date_max

    def end_whitelist(self):
        """ Renvoie la date de fin de ban d'un user, False sinon """
        date_max = Whitelist.objects.all().filter(user=self).aggregate(models.Max('date_end'))['date_end__max']
        return date_max

    def is_ban(self):
        """ Renvoie si un user est banni ou non """
        end = self.end_ban()
        if not end:
            return False
        elif end < timezone.now():
            return False
        else:
            return True

    def is_whitelisted(self):
        """ Renvoie si un user est whitelisté ou non """
        end = self.end_whitelist()
        if not end:
            return False
        elif end < timezone.now():
            return False
        else:
            return True

    def has_access(self):
        """ Renvoie si un utilisateur a accès à internet """
        return self.state == User.STATE_ACTIVE \
            and not self.is_ban() and (self.is_adherent() or self.is_whitelisted())

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
    def has_module_perms(self, app_label):
        # Simplest version again
        return True

    def make_admin(self):
        """ Make User admin """
        user_admin_right = Right(user=self, right=get_admin_right())
        user_admin_right.save()

    def un_admin(self):
        try:
            user_right = Right.objects.get(user=self,right=get_admin_right())
        except Right.DoesNotExist:
            return
        user_right.delete()

212
    def __str__(self):
213
        return self.pseudo
lhark's avatar
lhark committed
214

215

216
class Right(models.Model):
217
    user = models.ForeignKey('User', on_delete=models.PROTECT)
218
    right = models.ForeignKey('ListRight', on_delete=models.PROTECT)
219

220 221 222
    class Meta:
        unique_together = ("user", "right")

223 224 225
    def __str__(self):
        return str(self.user) + " - " + str(self.right)

226

lhark's avatar
lhark committed
227 228 229
class School(models.Model):
    name = models.CharField(max_length=255)

230 231 232
    def __str__(self):
        return self.name

233

234
class ListRight(models.Model):
235
    listright = models.CharField(max_length=255, unique=True)
236 237 238 239

    def __str__(self):
        return self.listright

240

chirac's avatar
chirac committed
241 242 243
class Ban(models.Model):
    user = models.ForeignKey('User', on_delete=models.PROTECT)
    raison = models.CharField(max_length=255)
244
    date_start = models.DateTimeField(auto_now_add=True)
245
    date_end = models.DateTimeField(help_text='%d/%m/%y %H:%M:%S')
chirac's avatar
chirac committed
246 247 248 249

    def __str__(self):
        return str(self.user) + ' ' + str(self.raison)

250

chirac's avatar
chirac committed
251 252 253 254
class Whitelist(models.Model):
    user = models.ForeignKey('User', on_delete=models.PROTECT)
    raison = models.CharField(max_length=255)
    date_start = models.DateTimeField(auto_now_add=True)
255
    date_end = models.DateTimeField(help_text='%d/%m/%y %H:%M:%S')
chirac's avatar
chirac committed
256 257 258 259

    def __str__(self):
        return str(self.user) + ' ' + str(self.raison)

260
class BaseInfoForm(ModelForm):
chirac's avatar
chirac committed
261
    def __init__(self, *args, **kwargs):
262
        super(BaseInfoForm, self).__init__(*args, **kwargs)
chirac's avatar
chirac committed
263
        self.fields['name'].label = 'Nom'
chirac's avatar
chirac committed
264 265
        self.fields['surname'].label = 'Prénom'
        self.fields['school'].label = 'Établissement'
266 267
        self.fields['comment'].label = 'Commentaire'
        self.fields['room'].label = 'Chambre'
268 269
        self.fields['room'].empty_label = "Pas de chambre"
        self.fields['school'].empty_label = "Séléctionner un établissement"
chirac's avatar
chirac committed
270

chirac's avatar
chirac committed
271 272
    class Meta:
        model = User
273 274 275 276 277 278 279 280 281 282
        fields = [
            'name',
            'surname',
            'pseudo',
            'email',
            'school',
            'comment',
            'room',
        ]

283 284 285 286 287 288 289
class InfoForm(BaseInfoForm):
    force = forms.BooleanField(label="Forcer le déménagement ?", initial=False, required=False)

    def clean_force(self):
        if self.cleaned_data.get('force', False):
            remove_user_room(self.cleaned_data.get('room'))
        return
chirac's avatar
chirac committed
290

291 292 293 294
class UserForm(InfoForm):
    class Meta(InfoForm.Meta):
        fields = '__all__'

295

chirac's avatar
chirac committed
296 297 298
class PasswordForm(ModelForm):
    class Meta:
        model = User
299 300
        fields = ['password', 'pwd_ntlm']

chirac's avatar
chirac committed
301

chirac's avatar
chirac committed
302
class StateForm(ModelForm):
chirac's avatar
chirac committed
303 304 305
    class Meta:
        model = User
        fields = ['state']
lhark's avatar
lhark committed
306

307

lhark's avatar
lhark committed
308 309 310 311
class SchoolForm(ModelForm):
    class Meta:
        model = School
        fields = ['name']
312

chirac's avatar
chirac committed
313 314
    def __init__(self, *args, **kwargs):
        super(SchoolForm, self).__init__(*args, **kwargs)
315
        self.fields['name'].label = 'Établissement'
chirac's avatar
chirac committed
316

317

chirac's avatar
chirac committed
318 319 320 321 322 323 324
class DelSchoolForm(ModelForm):
    schools = forms.ModelMultipleChoiceField(queryset=School.objects.all(), label="Etablissements actuels",  widget=forms.CheckboxSelectMultiple)

    class Meta:
        exclude = ['name']
        model = School

325

326 327 328 329
class RightForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(RightForm, self).__init__(*args, **kwargs)
        self.fields['right'].label = 'Droit'
330
        self.fields['right'].empty_label = "Choisir un nouveau droit"
331 332 333

    class Meta:
        model = Right
334
        fields = ['right']
335

336

337 338 339 340 341 342
class DelRightForm(ModelForm):
    rights = forms.ModelMultipleChoiceField(queryset=Right.objects.all(), label="Droits actuels",  widget=forms.CheckboxSelectMultiple)

    class Meta:
        model = Right
        exclude = ['user', 'right']
343

344

chirac's avatar
chirac committed
345 346 347 348 349 350 351 352
class BanForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(BanForm, self).__init__(*args, **kwargs)
        self.fields['date_end'].label = 'Date de fin'

    class Meta:
        model = Ban
        exclude = ['user']
353 354 355 356 357 358

    def clean_date_end(self):
        date_end = self.cleaned_data['date_end']
        if date_end < timezone.now():
            raise forms.ValidationError("Triple buse, la date de fin ne peut pas être avant maintenant... Re2o ne voyage pas dans le temps")
        return date_end
359

360

chirac's avatar
chirac committed
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
class WhitelistForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(WhitelistForm, self).__init__(*args, **kwargs)
        self.fields['date_end'].label = 'Date de fin'

    class Meta:
        model = Whitelist
        exclude = ['user']

    def clean_date_end(self):
        date_end = self.cleaned_data['date_end']
        if date_end < timezone.now():
            raise forms.ValidationError("Triple buse, la date de fin ne peut pas être avant maintenant... Re2o ne voyage pas dans le temps")
        return date_end

376

377
class ProfilForm(Form):
378
    user = forms.CharField(label='Ok', max_length=100)