2016-06-30 01:39:07 +00:00
from django . db import models
2016-07-10 02:49:09 +00:00
from django . db . models import Q
2016-07-03 12:36:51 +00:00
from django . forms import ModelForm , Form
2016-07-02 02:40:24 +00:00
from django import forms
2016-07-10 02:02:48 +00:00
2016-07-20 01:53:46 +00:00
from re2o . settings import RIGHTS_LINK , REQ_EXPIRE_HRS
import re , uuid
import datetime
2016-06-30 01:39:07 +00:00
2016-07-03 00:15:17 +00:00
from django . utils import timezone
2016-07-08 01:12:28 +00:00
from django . contrib . auth . models import AbstractBaseUser , BaseUserManager
2016-07-03 00:15:17 +00:00
2016-07-03 12:36:51 +00:00
from topologie . models import Room
2016-07-18 03:30:35 +00:00
from cotisations . models import Cotisation , Facture , Vente
2016-07-03 12:36:51 +00:00
2016-07-03 13:26:44 +00:00
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 ( )
2016-07-08 01:12:28 +00:00
def linux_user_check ( login ) :
2016-07-06 00:56:30 +00:00
""" Validation du pseudo pour respecter les contraintes unix """
UNIX_LOGIN_PATTERN = re . compile ( " ^[a-z_][a-z0-9_-]*[$]?$ " )
2016-07-08 01:12:28 +00:00
return UNIX_LOGIN_PATTERN . match ( login )
def linux_user_validator ( login ) :
if not linux_user_check ( login ) :
2016-07-06 00:56:30 +00:00
raise forms . ValidationError (
" , ce pseudo ( ' %(label)s ' ) contient des carractères interdits " ,
params = { ' label ' : login } ,
)
2016-07-08 01:12:28 +00:00
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 ) :
2016-06-30 01:39:07 +00:00
STATE_ACTIVE = 0
STATE_DEACTIVATED = 1
STATE_ARCHIVED = 2
STATES = (
2016-06-30 18:18:06 +00:00
( 0 , ' STATE_ACTIVE ' ) ,
( 1 , ' STATE_DEACTIVATED ' ) ,
( 2 , ' STATE_ARCHIVED ' ) ,
2016-06-30 01:39:07 +00:00
)
name = models . CharField ( max_length = 255 )
surname = models . CharField ( max_length = 255 )
2016-07-06 10:02:49 +00:00
pseudo = models . CharField ( max_length = 32 , unique = True , help_text = " Doit contenir uniquement des lettres, chiffres, ou tirets " , validators = [ linux_user_validator ] )
2016-06-30 01:39:07 +00:00
email = models . EmailField ( )
2016-07-05 09:33:27 +00:00
school = models . ForeignKey ( ' School ' , on_delete = models . PROTECT , null = False , blank = False )
2016-07-04 15:54:52 +00:00
comment = models . CharField ( help_text = " Commentaire, promo " , max_length = 255 , blank = True )
2016-07-03 12:36:51 +00:00
room = models . OneToOneField ( ' topologie.Room ' , on_delete = models . PROTECT , blank = True , null = True )
2016-06-30 01:39:07 +00:00
pwd_ntlm = models . CharField ( max_length = 255 )
2016-06-30 23:03:28 +00:00
state = models . IntegerField ( choices = STATES , default = STATE_ACTIVE )
2016-07-02 23:29:26 +00:00
registered = models . DateTimeField ( auto_now_add = True )
2016-06-30 01:39:07 +00:00
2016-07-08 01:12:28 +00:00
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
2016-07-09 02:12:09 +00:00
def has_perms ( self , perms , obj = None ) :
for perm in perms :
2016-07-10 14:39:21 +00:00
if perm in RIGHTS_LINK :
query = Q ( )
for right in RIGHTS_LINK [ perm ] :
query = query | Q ( right__listright = right )
if Right . objects . filter ( Q ( user = self ) & query ) :
return True
2016-07-09 02:12:09 +00:00
try :
Right . objects . get ( user = self , right__listright = perm )
except Right . DoesNotExist :
return False
2016-07-08 01:12:28 +00:00
return True
2016-07-09 12:17:05 +00:00
def has_perm ( self , perm , obj = None ) :
return True
2016-07-10 02:02:48 +00:00
def end_adhesion ( self ) :
2016-07-18 03:30:35 +00:00
date_max = Cotisation . objects . all ( ) . filter ( vente = Vente . objects . all ( ) . filter ( facture = Facture . objects . all ( ) . filter ( user = self ) . exclude ( valid = False ) ) ) . aggregate ( models . Max ( ' date_end ' ) ) [ ' date_end__max ' ]
2016-07-10 02:02:48 +00:00
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 ( ) )
2016-07-08 01:12:28 +00:00
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 ( )
2016-06-30 23:03:28 +00:00
def __str__ ( self ) :
2016-07-02 02:40:24 +00:00
return self . pseudo
2016-06-30 01:39:07 +00:00
2016-07-08 01:12:28 +00:00
2016-07-02 00:42:04 +00:00
class Right ( models . Model ) :
2016-07-08 01:12:28 +00:00
user = models . ForeignKey ( ' User ' , on_delete = models . PROTECT )
2016-07-02 00:42:04 +00:00
right = models . ForeignKey ( ' ListRight ' , on_delete = models . PROTECT )
2016-07-08 01:12:28 +00:00
2016-07-02 00:42:04 +00:00
class Meta :
unique_together = ( " user " , " right " )
2016-07-02 02:40:24 +00:00
def __str__ ( self ) :
return str ( self . user ) + " - " + str ( self . right )
2016-07-08 01:12:28 +00:00
2016-06-30 01:39:07 +00:00
class School ( models . Model ) :
name = models . CharField ( max_length = 255 )
2016-06-30 23:03:28 +00:00
def __str__ ( self ) :
return self . name
2016-07-08 01:12:28 +00:00
2016-07-02 00:42:04 +00:00
class ListRight ( models . Model ) :
2016-07-08 01:12:28 +00:00
listright = models . CharField ( max_length = 255 , unique = True )
2016-07-02 00:42:04 +00:00
def __str__ ( self ) :
return self . listright
2016-07-08 01:12:28 +00:00
2016-07-02 19:57:31 +00:00
class Ban ( models . Model ) :
user = models . ForeignKey ( ' User ' , on_delete = models . PROTECT )
raison = models . CharField ( max_length = 255 )
2016-07-02 23:29:26 +00:00
date_start = models . DateTimeField ( auto_now_add = True )
2016-07-08 01:12:28 +00:00
date_end = models . DateTimeField ( help_text = ' %d / % m/ % y % H: % M: % S ' )
2016-07-02 19:57:31 +00:00
def __str__ ( self ) :
return str ( self . user ) + ' ' + str ( self . raison )
2016-07-08 01:12:28 +00:00
2016-07-04 18:04:11 +00:00
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 )
2016-07-05 14:30:46 +00:00
date_end = models . DateTimeField ( help_text = ' %d / % m/ % y % H: % M: % S ' )
2016-07-04 18:04:11 +00:00
def __str__ ( self ) :
return str ( self . user ) + ' ' + str ( self . raison )
2016-07-20 01:53:46 +00:00
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 ( ) \
+ datetime . timedelta ( hours = REQ_EXPIRE_HRS )
if not self . token :
self . token = str ( uuid . uuid4 ( ) ) . replace ( ' - ' , ' ' ) # remove hyphens
super ( Request , self ) . save ( )
2016-07-09 17:51:37 +00:00
class BaseInfoForm ( ModelForm ) :
2016-07-01 09:08:35 +00:00
def __init__ ( self , * args , * * kwargs ) :
2016-07-09 17:51:37 +00:00
super ( BaseInfoForm , self ) . __init__ ( * args , * * kwargs )
2016-07-01 09:08:35 +00:00
self . fields [ ' name ' ] . label = ' Nom '
2016-07-04 20:45:30 +00:00
self . fields [ ' surname ' ] . label = ' Prénom '
self . fields [ ' school ' ] . label = ' Établissement '
2016-07-04 15:54:52 +00:00
self . fields [ ' comment ' ] . label = ' Commentaire '
self . fields [ ' room ' ] . label = ' Chambre '
2016-07-05 09:33:27 +00:00
self . fields [ ' room ' ] . empty_label = " Pas de chambre "
self . fields [ ' school ' ] . empty_label = " Séléctionner un établissement "
2016-07-01 09:08:35 +00:00
2016-06-30 01:46:31 +00:00
class Meta :
model = User
2016-07-08 01:12:28 +00:00
fields = [
' name ' ,
' surname ' ,
' pseudo ' ,
' email ' ,
' school ' ,
' comment ' ,
' room ' ,
]
2016-07-09 17:51:37 +00:00
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
2016-06-30 01:46:31 +00:00
2016-07-05 09:33:27 +00:00
class UserForm ( InfoForm ) :
class Meta ( InfoForm . Meta ) :
fields = ' __all__ '
2016-06-30 01:46:31 +00:00
class PasswordForm ( ModelForm ) :
class Meta :
model = User
2016-07-08 01:12:28 +00:00
fields = [ ' password ' , ' pwd_ntlm ' ]
2016-06-30 01:46:31 +00:00
2016-07-01 09:08:35 +00:00
class StateForm ( ModelForm ) :
2016-06-30 01:46:31 +00:00
class Meta :
model = User
fields = [ ' state ' ]
2016-06-30 01:39:07 +00:00
2016-07-08 01:12:28 +00:00
2016-06-30 01:39:07 +00:00
class SchoolForm ( ModelForm ) :
class Meta :
model = School
fields = [ ' name ' ]
2016-07-02 00:42:04 +00:00
2016-07-06 17:45:36 +00:00
def __init__ ( self , * args , * * kwargs ) :
super ( SchoolForm , self ) . __init__ ( * args , * * kwargs )
2016-07-08 00:25:12 +00:00
self . fields [ ' name ' ] . label = ' Établissement '
2016-07-06 17:45:36 +00:00
2016-07-08 01:12:28 +00:00
2016-07-06 17:45:36 +00:00
class DelSchoolForm ( ModelForm ) :
schools = forms . ModelMultipleChoiceField ( queryset = School . objects . all ( ) , label = " Etablissements actuels " , widget = forms . CheckboxSelectMultiple )
class Meta :
exclude = [ ' name ' ]
model = School
2016-07-08 01:12:28 +00:00
2016-07-02 00:42:04 +00:00
class RightForm ( ModelForm ) :
def __init__ ( self , * args , * * kwargs ) :
super ( RightForm , self ) . __init__ ( * args , * * kwargs )
self . fields [ ' right ' ] . label = ' Droit '
2016-07-05 09:33:27 +00:00
self . fields [ ' right ' ] . empty_label = " Choisir un nouveau droit "
2016-07-02 00:42:04 +00:00
class Meta :
model = Right
2016-07-04 20:37:04 +00:00
fields = [ ' right ' ]
2016-07-02 02:40:24 +00:00
2016-07-08 01:12:28 +00:00
2016-07-02 02:40:24 +00:00
class DelRightForm ( ModelForm ) :
rights = forms . ModelMultipleChoiceField ( queryset = Right . objects . all ( ) , label = " Droits actuels " , widget = forms . CheckboxSelectMultiple )
class Meta :
model = Right
exclude = [ ' user ' , ' right ' ]
2016-07-02 19:17:21 +00:00
2016-07-08 01:12:28 +00:00
2016-07-02 19:57:31 +00:00
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 ' ]
2016-07-03 00:15:17 +00:00
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
2016-07-03 12:36:51 +00:00
2016-07-08 01:12:28 +00:00
2016-07-04 18:04:11 +00:00
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
2016-07-08 01:12:28 +00:00
2016-07-03 12:36:51 +00:00
class ProfilForm ( Form ) :
2016-07-08 01:12:28 +00:00
user = forms . CharField ( label = ' Ok ' , max_length = 100 )