2017-01-15 23:01:18 +00:00
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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-26 00:54:32 +00:00
from django . db . models . signals import post_save , post_delete
from django . dispatch import receiver
2017-05-26 22:43:51 +00:00
from django . utils . functional import cached_property
2016-07-10 02:02:48 +00:00
2016-07-26 00:54:32 +00:00
import ldapdb . models
import ldapdb . models . fields
2016-10-12 10:24:01 +00:00
from re2o . settings import RIGHTS_LINK , REQ_EXPIRE_HRS , LDAP , GID_RANGES , UID_RANGES
2016-07-20 01:53:46 +00:00
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
2017-06-18 12:59:53 +00:00
from django . core . validators import MinLengthValidator
2016-07-03 12:36:51 +00:00
from topologie . models import Room
2017-06-26 17:23:01 +00:00
from cotisations . models import Cotisation , Facture , Paiement , Vente
2016-07-26 00:54:32 +00:00
from machines . models import Interface , Machine
2017-06-25 23:29:34 +00:00
from preferences . models import OptionalUser
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 """
2016-12-03 23:12:50 +00:00
UNIX_LOGIN_PATTERN = re . compile ( " ^[a-zA-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-10-12 10:24:01 +00:00
def get_fresh_user_uid ( ) :
uids = list ( range ( int ( min ( UID_RANGES [ ' users ' ] ) ) , int ( max ( UID_RANGES [ ' users ' ] ) ) ) )
2016-12-18 09:52:20 +00:00
try :
used_uids = [ user . uid_number for user in User . objects . all ( ) ]
except :
used_uids = [ ]
2016-10-12 10:24:01 +00:00
free_uids = [ id for id in uids if id not in used_uids ]
return min ( free_uids )
def get_fresh_gid ( ) :
gids = list ( range ( int ( min ( GID_RANGES [ ' posix ' ] ) ) , int ( max ( GID_RANGES [ ' posix ' ] ) ) ) )
used_gids = [ right . gid for right in ListRight . objects . all ( ) ]
free_gids = [ id for id in gids if id not in used_gids ]
return min ( free_gids )
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 " )
2016-10-12 10:24:01 +00:00
admin_right . gid = get_fresh_gid ( )
2016-07-08 01:12:28 +00:00
admin_right . save ( )
return admin_right
2017-05-26 22:43:51 +00:00
def all_adherent ( ) :
return User . objects . filter ( facture__in = Facture . objects . filter ( vente__in = Vente . objects . filter ( cotisation__in = Cotisation . objects . filter ( vente__in = Vente . objects . filter ( facture__in = Facture . objects . all ( ) . exclude ( valid = False ) ) ) . filter ( date_end__gt = timezone . now ( ) ) ) ) ) . distinct ( )
def all_baned ( ) :
return User . objects . filter ( ban__in = Ban . objects . filter ( date_end__gt = timezone . now ( ) ) ) . distinct ( )
def all_whitelisted ( ) :
return User . objects . filter ( whitelist__in = Whitelist . objects . filter ( date_end__gt = timezone . now ( ) ) ) . distinct ( )
def all_has_access ( ) :
return User . objects . filter ( Q ( state = User . STATE_ACTIVE ) & ~ Q ( ban__in = Ban . objects . filter ( date_end__gt = timezone . now ( ) ) ) & ( Q ( whitelist__in = Whitelist . objects . filter ( date_end__gt = timezone . now ( ) ) ) | Q ( facture__in = Facture . objects . filter ( vente__in = Vente . objects . filter ( cotisation__in = Cotisation . objects . filter ( vente__in = Vente . objects . filter ( facture__in = Facture . objects . all ( ) . exclude ( valid = False ) ) ) . filter ( date_end__gt = timezone . now ( ) ) ) ) ) ) ) . distinct ( )
2016-07-08 01:12:28 +00:00
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-11-01 01:14:06 +00:00
PRETTY_NAME = " Utilisateurs "
2016-06-30 01:39:07 +00:00
STATE_ACTIVE = 0
2016-10-18 15:11:45 +00:00
STATE_DISABLED = 1
STATE_ARCHIVE = 2
2016-06-30 01:39:07 +00:00
STATES = (
2016-06-30 18:18:06 +00:00
( 0 , ' STATE_ACTIVE ' ) ,
2016-10-18 15:11:45 +00:00
( 1 , ' STATE_DISABLED ' ) ,
( 2 , ' STATE_ARCHIVE ' ) ,
2016-06-30 01:39:07 +00:00
)
2016-07-31 03:03:07 +00:00
def auto_uid ( ) :
2016-10-12 10:24:01 +00:00
return get_fresh_user_uid ( )
2016-07-31 03:03:07 +00:00
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-10-11 15:11:46 +00:00
school = models . ForeignKey ( ' School ' , on_delete = models . PROTECT , null = True , blank = True )
2016-07-27 00:39:19 +00:00
shell = models . ForeignKey ( ' ListShell ' , on_delete = models . PROTECT , null = True , blank = True )
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 )
2017-06-25 02:12:21 +00:00
telephone = models . CharField ( max_length = 15 , blank = True , null = True )
2016-07-31 03:03:07 +00:00
uid_number = models . IntegerField ( default = auto_uid , unique = True )
2016-10-07 19:30:05 +00:00
rezo_rez_uid = models . IntegerField ( unique = True , blank = True , null = 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
2017-05-27 13:12:21 +00:00
def has_right ( self , right ) :
return Right . objects . filter ( user = self ) . filter ( right = ListRight . objects . get ( listright = right ) ) . exists ( )
@cached_property
def is_bureau ( self ) :
return Right . objects . filter ( user = self ) . filter ( right = ListRight . objects . get ( listright = ' bureau ' ) ) . exists ( )
@cached_property
def is_bofh ( self ) :
return Right . objects . filter ( user = self ) . filter ( right = ListRight . objects . get ( listright = ' bofh ' ) ) . exists ( )
@cached_property
def is_cableur ( self ) :
return self . has_right ( ' cableur ' ) or self . has_right ( ' bureau ' ) or self . has_right ( ' infra ' ) or self . has_right ( ' bofh ' )
@cached_property
def is_trez ( self ) :
return Right . objects . filter ( user = self ) . filter ( right = ListRight . objects . get ( listright = ' trésorier ' ) ) . exists ( )
@cached_property
def is_infra ( self ) :
return Right . objects . filter ( user = self ) . filter ( right = ListRight . objects . get ( listright = ' infra ' ) ) . exists ( )
2017-05-26 22:43:51 +00:00
@cached_property
2016-07-10 02:02:48 +00:00
def end_adhesion ( self ) :
2016-12-14 02:08:57 +00:00
date_max = Cotisation . objects . filter ( vente__in = Vente . objects . filter ( facture__in = Facture . objects . 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
2017-05-26 22:43:51 +00:00
@cached_property
2016-07-10 02:02:48 +00:00
def is_adherent ( self ) :
2017-05-26 22:43:51 +00:00
end = self . end_adhesion
2016-07-10 02:02:48 +00:00
if not end :
return False
elif end < timezone . now ( ) :
return False
else :
return True
2017-05-26 22:43:51 +00:00
@cached_property
2016-07-10 02:02:48 +00:00
def end_ban ( self ) :
""" Renvoie la date de fin de ban d ' un user, False sinon """
2016-12-14 02:08:57 +00:00
date_max = Ban . objects . filter ( user = self ) . aggregate ( models . Max ( ' date_end ' ) ) [ ' date_end__max ' ]
2016-07-10 02:02:48 +00:00
return date_max
2017-05-26 22:43:51 +00:00
@cached_property
2016-07-10 02:02:48 +00:00
def end_whitelist ( self ) :
2017-05-26 01:07:10 +00:00
""" Renvoie la date de fin de whitelist d ' un user, False sinon """
2016-12-14 02:08:57 +00:00
date_max = Whitelist . objects . filter ( user = self ) . aggregate ( models . Max ( ' date_end ' ) ) [ ' date_end__max ' ]
2016-07-10 02:02:48 +00:00
return date_max
2017-05-26 22:43:51 +00:00
@cached_property
2016-07-10 02:02:48 +00:00
def is_ban ( self ) :
""" Renvoie si un user est banni ou non """
2017-05-26 22:43:51 +00:00
end = self . end_ban
2016-07-10 02:02:48 +00:00
if not end :
return False
elif end < timezone . now ( ) :
return False
else :
return True
2017-05-26 22:43:51 +00:00
@cached_property
2016-07-10 02:02:48 +00:00
def is_whitelisted ( self ) :
""" Renvoie si un user est whitelisté ou non """
2017-05-26 22:43:51 +00:00
end = self . end_whitelist
2016-07-10 02:02:48 +00:00
if not end :
return False
elif end < timezone . now ( ) :
return False
else :
return True
2017-05-26 22:43:51 +00:00
@cached_property
2016-07-10 02:02:48 +00:00
def has_access ( self ) :
""" Renvoie si un utilisateur a accès à internet """
return self . state == User . STATE_ACTIVE \
2017-05-26 22:43:51 +00:00
and not self . is_ban and ( self . is_adherent or self . is_whitelisted )
2016-07-10 02:02:48 +00:00
2017-05-26 22:43:51 +00:00
@cached_property
2017-05-26 01:07:10 +00:00
def end_access ( self ) :
""" Renvoie la date de fin normale d ' accès (adhésion ou whiteliste) """
2017-05-26 22:43:51 +00:00
if not self . end_adhesion :
if not self . end_whitelist :
2017-05-26 01:07:10 +00:00
return None
else :
2017-05-26 22:43:51 +00:00
return self . end_whitelist
2017-05-26 01:07:10 +00:00
else :
2017-05-26 22:43:51 +00:00
if not self . end_whitelist :
return self . end_adhesion
2017-05-26 01:07:10 +00:00
else :
2017-05-26 22:43:51 +00:00
return max ( self . end_adhesion , self . end_whitelist )
2017-05-26 01:07:10 +00:00
2017-06-26 17:23:01 +00:00
@cached_property
def solde ( self ) :
options , created = OptionalUser . objects . get_or_create ( )
user_solde = options . user_solde
if user_solde :
solde_object , created = Paiement . objects . get_or_create ( moyen = ' Solde ' )
somme_debit = Vente . objects . filter ( facture__in = Facture . objects . filter ( user = self , paiement = solde_object ) ) . aggregate ( total = models . Sum ( models . F ( ' prix ' ) * models . F ( ' number ' ) , output_field = models . FloatField ( ) ) ) [ ' total ' ] or 0
somme_credit = Vente . objects . filter ( facture__in = Facture . objects . filter ( user = self ) , name = " solde " ) . aggregate ( total = models . Sum ( models . F ( ' prix ' ) * models . F ( ' number ' ) , output_field = models . FloatField ( ) ) ) [ ' total ' ] or 0
return somme_credit - somme_debit
else :
return 0
2016-11-24 00:18:15 +00:00
def user_interfaces ( self ) :
2016-12-18 22:25:21 +00:00
return Interface . objects . filter ( machine__in = Machine . objects . filter ( user = self , active = True ) )
2016-11-24 00:18:15 +00:00
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-07-26 00:54:32 +00:00
def ldap_sync ( self , base = True , access_refresh = True , mac_refresh = True ) :
2016-07-31 01:36:54 +00:00
self . refresh_from_db ( )
2016-07-26 00:54:32 +00:00
try :
2016-10-11 15:11:46 +00:00
user_ldap = LdapUser . objects . get ( uidNumber = self . uid_number )
2016-07-26 00:54:32 +00:00
except LdapUser . DoesNotExist :
2016-10-11 15:11:46 +00:00
user_ldap = LdapUser ( uidNumber = self . uid_number )
2016-07-26 00:54:32 +00:00
if base :
2016-07-31 03:03:07 +00:00
user_ldap . name = self . pseudo
2016-07-26 00:54:32 +00:00
user_ldap . sn = self . pseudo
2017-05-26 22:43:51 +00:00
user_ldap . dialupAccess = str ( self . has_access )
2016-07-26 00:54:32 +00:00
user_ldap . home_directory = ' /home/ ' + self . pseudo
user_ldap . mail = self . email
user_ldap . given_name = str ( self . surname ) . lower ( ) + ' _ ' + str ( self . name ) . lower ( ) [ : 3 ]
2016-07-27 00:39:19 +00:00
user_ldap . gid = LDAP [ ' user_gid ' ]
2016-11-20 15:53:59 +00:00
user_ldap . user_password = self . password [ : 6 ] + self . password [ 7 : ]
2016-11-21 17:32:53 +00:00
user_ldap . sambat_nt_password = self . pwd_ntlm . upper ( )
2016-07-31 01:36:54 +00:00
if self . shell :
2017-06-26 20:23:58 +00:00
user_ldap . login_shell = self . shell . shell
if self . state == self . STATE_DISABLED :
user_ldap . shadowexpire = str ( 0 )
else :
user_ldap . shadowexpire = None
2016-07-26 00:54:32 +00:00
if access_refresh :
2017-05-26 22:43:51 +00:00
user_ldap . dialupAccess = str ( self . has_access )
2016-07-26 00:54:32 +00:00
if mac_refresh :
2016-12-14 02:08:57 +00:00
user_ldap . macs = [ inter . mac_bare ( ) for inter in Interface . objects . filter ( machine__in = Machine . objects . filter ( user = self ) ) ]
2016-07-26 00:54:32 +00:00
user_ldap . save ( )
def ldap_del ( self ) :
try :
user_ldap = LdapUser . objects . get ( name = self . pseudo )
user_ldap . delete ( )
except LdapUser . DoesNotExist :
pass
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-11-20 15:53:59 +00:00
@receiver ( post_save , sender = User )
def user_post_save ( sender , * * kwargs ) :
user = kwargs [ ' instance ' ]
user . ldap_sync ( base = True , access_refresh = True , mac_refresh = False )
2016-07-26 00:54:32 +00:00
@receiver ( post_delete , sender = User )
def user_post_delete ( sender , * * kwargs ) :
user = kwargs [ ' instance ' ]
2016-11-20 15:53:59 +00:00
user . ldap_del ( )
2016-07-08 01:12:28 +00:00
2016-07-31 01:36:54 +00:00
class ServiceUser ( AbstractBaseUser ) :
2017-06-18 12:59:53 +00:00
readonly = ' readonly '
ACCESS = (
( ' auth ' , ' auth ' ) ,
( ' readonly ' , ' readonly ' ) ,
( ' usermgmt ' , ' usermgmt ' ) ,
)
2016-11-01 01:14:06 +00:00
PRETTY_NAME = " Utilisateurs de service "
2016-07-31 01:36:54 +00:00
pseudo = models . CharField ( max_length = 32 , unique = True , help_text = " Doit contenir uniquement des lettres, chiffres, ou tirets " , validators = [ linux_user_validator ] )
2017-06-18 12:59:53 +00:00
access_group = models . CharField ( choices = ACCESS , default = readonly , max_length = 32 )
2017-06-18 17:24:53 +00:00
comment = models . CharField ( help_text = " Commentaire " , max_length = 255 , blank = True )
2016-07-31 01:36:54 +00:00
USERNAME_FIELD = ' pseudo '
objects = UserManager ( )
def ldap_sync ( self ) :
try :
user_ldap = LdapServiceUser . objects . get ( name = self . pseudo )
except LdapServiceUser . DoesNotExist :
user_ldap = LdapServiceUser ( name = self . pseudo )
2017-06-18 12:59:53 +00:00
user_ldap . user_password = self . password [ : 6 ] + self . password [ 7 : ]
2016-07-31 01:36:54 +00:00
user_ldap . save ( )
2017-06-18 12:59:53 +00:00
self . serviceuser_group_sync ( )
2016-07-31 01:36:54 +00:00
def ldap_del ( self ) :
try :
user_ldap = LdapServiceUser . objects . get ( name = self . pseudo )
user_ldap . delete ( )
except LdapUser . DoesNotExist :
pass
2017-06-18 12:59:53 +00:00
self . serviceuser_group_sync ( )
def serviceuser_group_sync ( self ) :
try :
group = LdapServiceUserGroup . objects . get ( name = self . access_group )
except :
group = LdapServiceUserGroup ( name = self . access_group )
group . members = [ serviceuser . dn for serviceuser in LdapServiceUser . objects . filter ( name__in = [ user . pseudo for user in ServiceUser . objects . filter ( access_group = self . access_group ) ] ) ]
group . save ( )
2016-07-31 01:36:54 +00:00
def __str__ ( self ) :
return self . pseudo
@receiver ( post_save , sender = ServiceUser )
def service_user_post_save ( sender , * * kwargs ) :
service_user = kwargs [ ' instance ' ]
2017-06-18 12:59:53 +00:00
service_user . ldap_sync ( )
2016-07-31 01:36:54 +00:00
@receiver ( post_delete , sender = ServiceUser )
def service_user_post_delete ( sender , * * kwargs ) :
service_user = kwargs [ ' instance ' ]
2017-06-18 12:59:53 +00:00
service_user . ldap_del ( )
2016-07-31 01:36:54 +00:00
2016-07-02 00:42:04 +00:00
class Right ( models . Model ) :
2016-11-01 01:14:06 +00:00
PRETTY_NAME = " Droits affectés à des users "
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-26 00:54:32 +00:00
@receiver ( post_save , sender = Right )
def right_post_save ( sender , * * kwargs ) :
right = kwargs [ ' instance ' ] . right
2016-11-20 15:53:59 +00:00
right . ldap_sync ( )
2016-07-26 00:54:32 +00:00
@receiver ( post_delete , sender = Right )
def right_post_delete ( sender , * * kwargs ) :
right = kwargs [ ' instance ' ] . right
2016-11-20 15:53:59 +00:00
right . ldap_sync ( )
2016-07-08 01:12:28 +00:00
2016-06-30 01:39:07 +00:00
class School ( models . Model ) :
2016-11-01 01:14:06 +00:00
PRETTY_NAME = " Etablissements enregistrés "
2016-06-30 01:39:07 +00:00
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-11-01 01:14:06 +00:00
PRETTY_NAME = " Liste des droits existants "
2016-07-08 01:12:28 +00:00
listright = models . CharField ( max_length = 255 , unique = True )
2016-07-26 00:54:32 +00:00
gid = models . IntegerField ( unique = True , null = True )
2016-11-21 00:49:45 +00:00
details = models . CharField ( help_text = " Description " , max_length = 255 , blank = True )
2016-07-02 00:42:04 +00:00
def __str__ ( self ) :
return self . listright
2016-07-26 00:54:32 +00:00
def ldap_sync ( self ) :
try :
group_ldap = LdapUserGroup . objects . get ( gid = self . gid )
except LdapUserGroup . DoesNotExist :
group_ldap = LdapUserGroup ( gid = self . gid )
group_ldap . name = self . listright
group_ldap . members = [ right . user . pseudo for right in Right . objects . filter ( right = self ) ]
group_ldap . save ( )
def ldap_del ( self ) :
try :
group_ldap = LdapUserGroup . objects . get ( gid = self . gid )
group_ldap . delete ( )
except LdapUserGroup . DoesNotExist :
pass
@receiver ( post_save , sender = ListRight )
def listright_post_save ( sender , * * kwargs ) :
right = kwargs [ ' instance ' ]
2016-11-20 15:53:59 +00:00
right . ldap_sync ( )
2016-07-26 00:54:32 +00:00
@receiver ( post_delete , sender = ListRight )
def listright_post_delete ( sender , * * kwargs ) :
right = kwargs [ ' instance ' ]
2016-11-20 15:53:59 +00:00
right . ldap_del ( )
2016-07-26 00:54:32 +00:00
class ListShell ( models . Model ) :
2016-11-01 01:14:06 +00:00
PRETTY_NAME = " Liste des shells disponibles "
2016-07-26 00:54:32 +00:00
shell = models . CharField ( max_length = 255 , unique = True )
def __str__ ( self ) :
return self . shell
2016-07-08 01:12:28 +00:00
2016-07-02 19:57:31 +00:00
class Ban ( models . Model ) :
2016-11-01 01:14:06 +00:00
PRETTY_NAME = " Liste des bannissements "
2017-03-06 01:28:16 +00:00
STATE_HARD = 0
STATE_SOFT = 1
STATE_BRIDAGE = 2
STATES = (
( 0 , ' HARD (aucun accès) ' ) ,
( 1 , ' SOFT (accès local seulement) ' ) ,
( 2 , ' BRIDAGE (bridage du débit) ' ) ,
)
2016-07-02 19:57:31 +00:00
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 ' )
2017-03-06 01:28:16 +00:00
state = models . IntegerField ( choices = STATES , default = STATE_HARD )
2016-07-02 19:57:31 +00:00
def __str__ ( self ) :
return str ( self . user ) + ' ' + str ( self . raison )
2016-11-20 15:53:59 +00:00
@receiver ( post_save , sender = Ban )
def ban_post_save ( sender , * * kwargs ) :
ban = kwargs [ ' instance ' ]
user = ban . user
user . ldap_sync ( base = False , access_refresh = True , mac_refresh = False )
@receiver ( post_delete , sender = Ban )
def ban_post_delete ( sender , * * kwargs ) :
user = kwargs [ ' instance ' ] . user
user . ldap_sync ( base = False , access_refresh = True , mac_refresh = False )
2016-07-08 01:12:28 +00:00
2016-07-04 18:04:11 +00:00
class Whitelist ( models . Model ) :
2016-11-01 01:14:06 +00:00
PRETTY_NAME = " Liste des accès gracieux "
2016-07-04 18:04:11 +00:00
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-11-20 15:53:59 +00:00
@receiver ( post_save , sender = Whitelist )
def whitelist_post_save ( sender , * * kwargs ) :
whitelist = kwargs [ ' instance ' ]
user = whitelist . user
user . ldap_sync ( base = False , access_refresh = True , mac_refresh = False )
@receiver ( post_delete , sender = Whitelist )
def whitelist_post_delete ( sender , * * kwargs ) :
user = kwargs [ ' instance ' ] . user
user . ldap_sync ( base = False , access_refresh = True , mac_refresh = False )
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-26 00:54:32 +00:00
class LdapUser ( ldapdb . models . Model ) :
"""
Class for representing an LDAP user entry .
"""
# LDAP meta-data
2016-07-27 00:39:19 +00:00
base_dn = LDAP [ ' base_user_dn ' ]
2017-06-26 20:23:58 +00:00
object_classes = [ ' inetOrgPerson ' , ' top ' , ' posixAccount ' , ' sambaSamAccount ' , ' radiusprofile ' , ' shadowAccount ' ]
2016-07-26 00:54:32 +00:00
# attributes
gid = ldapdb . models . fields . IntegerField ( db_column = ' gidNumber ' )
name = ldapdb . models . fields . CharField ( db_column = ' cn ' , max_length = 200 , primary_key = True )
uid = ldapdb . models . fields . CharField ( db_column = ' uid ' , max_length = 200 )
uidNumber = ldapdb . models . fields . IntegerField ( db_column = ' uidNumber ' , unique = True )
sn = ldapdb . models . fields . CharField ( db_column = ' sn ' , max_length = 200 )
2016-07-31 03:03:07 +00:00
login_shell = ldapdb . models . fields . CharField ( db_column = ' loginShell ' , max_length = 200 , blank = True , null = True )
2016-07-26 00:54:32 +00:00
mail = ldapdb . models . fields . CharField ( db_column = ' mail ' , max_length = 200 )
given_name = ldapdb . models . fields . CharField ( db_column = ' givenName ' , max_length = 200 )
home_directory = ldapdb . models . fields . CharField ( db_column = ' homeDirectory ' , max_length = 200 )
2016-07-27 00:39:19 +00:00
display_name = ldapdb . models . fields . CharField ( db_column = ' displayName ' , max_length = 200 , blank = True , null = True )
2016-07-26 00:54:32 +00:00
dialupAccess = ldapdb . models . fields . CharField ( db_column = ' dialupAccess ' )
sambaSID = ldapdb . models . fields . IntegerField ( db_column = ' sambaSID ' , unique = True )
user_password = ldapdb . models . fields . CharField ( db_column = ' userPassword ' , max_length = 200 , blank = True , null = True )
sambat_nt_password = ldapdb . models . fields . CharField ( db_column = ' sambaNTPassword ' , max_length = 200 , blank = True , null = True )
macs = ldapdb . models . fields . ListField ( db_column = ' radiusCallingStationId ' , max_length = 200 , blank = True , null = True )
2017-06-26 20:23:58 +00:00
shadowexpire = ldapdb . models . fields . CharField ( db_column = ' shadowExpire ' , blank = True , null = True )
2016-07-26 00:54:32 +00:00
def __str__ ( self ) :
return self . name
def __unicode__ ( self ) :
return self . name
def save ( self , * args , * * kwargs ) :
self . sn = self . name
self . uid = self . name
self . sambaSID = self . uidNumber
super ( LdapUser , self ) . save ( * args , * * kwargs )
class LdapUserGroup ( ldapdb . models . Model ) :
"""
Class for representing an LDAP user entry .
"""
# LDAP meta-data
2016-07-27 00:39:19 +00:00
base_dn = LDAP [ ' base_usergroup_dn ' ]
2016-07-26 00:54:32 +00:00
object_classes = [ ' posixGroup ' ]
# attributes
gid = ldapdb . models . fields . IntegerField ( db_column = ' gidNumber ' )
members = ldapdb . models . fields . ListField ( db_column = ' memberUid ' , blank = True )
name = ldapdb . models . fields . CharField ( db_column = ' cn ' , max_length = 200 , primary_key = True )
def __str__ ( self ) :
return self . name
2016-07-31 01:36:54 +00:00
class LdapServiceUser ( ldapdb . models . Model ) :
"""
Class for representing an LDAP userservice entry .
"""
# LDAP meta-data
base_dn = LDAP [ ' base_userservice_dn ' ]
object_classes = [ ' applicationProcess ' , ' simpleSecurityObject ' ]
# attributes
name = ldapdb . models . fields . CharField ( db_column = ' cn ' , max_length = 200 , primary_key = True )
user_password = ldapdb . models . fields . CharField ( db_column = ' userPassword ' , max_length = 200 , blank = True , null = True )
2017-06-18 12:59:53 +00:00
def __str__ ( self ) :
return self . name
class LdapServiceUserGroup ( ldapdb . models . Model ) :
"""
Class for representing an LDAP userservice entry .
"""
# LDAP meta-data
base_dn = LDAP [ ' base_userservicegroup_dn ' ]
object_classes = [ ' groupOfNames ' ]
# attributes
name = ldapdb . models . fields . CharField ( db_column = ' cn ' , max_length = 200 , primary_key = True )
members = ldapdb . models . fields . ListField ( db_column = ' member ' , blank = True )
def __str__ ( self ) :
return self . name
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-10-23 23:28:11 +00:00
self . fields [ ' name ' ] . label = ' Prénom '
self . fields [ ' surname ' ] . label = ' Nom '
2016-07-04 20:45:30 +00:00
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 ' ,
2017-06-25 02:12:21 +00:00
' telephone ' ,
2016-07-08 01:12:28 +00:00
]
2017-06-25 23:29:34 +00:00
def clean_telephone ( self ) :
telephone = self . cleaned_data [ ' telephone ' ]
preferences , created = OptionalUser . objects . get_or_create ( )
if not telephone and preferences . is_tel_mandatory :
raise forms . ValidationError ( " Un numéro de téléphone valide est requis " )
return telephone
2016-07-27 00:39:19 +00:00
class EditInfoForm ( BaseInfoForm ) :
class Meta ( BaseInfoForm . Meta ) :
fields = [
' name ' ,
' surname ' ,
' pseudo ' ,
' email ' ,
' school ' ,
' comment ' ,
' room ' ,
' shell ' ,
2017-06-25 02:12:21 +00:00
' telephone ' ,
2016-07-27 00:39:19 +00:00
]
2016-12-03 23:12:50 +00:00
class InfoForm ( EditInfoForm ) :
2016-07-09 17:51:37 +00:00
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-07-31 01:36:54 +00:00
class ServiceUserForm ( ModelForm ) :
2017-06-18 12:59:53 +00:00
password = forms . CharField ( label = u ' Nouveau mot de passe ' , max_length = 255 , validators = [ MinLengthValidator ( 8 ) ] , widget = forms . PasswordInput , required = False )
2016-07-31 01:36:54 +00:00
class Meta :
model = ServiceUser
2017-06-18 12:59:53 +00:00
fields = ( ' pseudo ' , ' access_group ' )
2016-07-31 01:36:54 +00:00
2017-06-18 12:59:53 +00:00
class EditServiceUserForm ( ServiceUserForm ) :
class Meta ( ServiceUserForm . Meta ) :
2017-06-18 17:24:53 +00:00
fields = [ ' access_group ' , ' comment ' ]
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-26 00:54:32 +00:00
class ListRightForm ( ModelForm ) :
class Meta :
model = ListRight
2016-11-21 00:49:45 +00:00
fields = [ ' listright ' , ' details ' ]
2016-07-26 00:54:32 +00:00
def __init__ ( self , * args , * * kwargs ) :
super ( ListRightForm , self ) . __init__ ( * args , * * kwargs )
self . fields [ ' listright ' ] . label = ' Nom du droit/groupe '
class NewListRightForm ( ListRightForm ) :
class Meta ( ListRightForm . Meta ) :
fields = ' __all__ '
def __init__ ( self , * args , * * kwargs ) :
super ( NewListRightForm , self ) . __init__ ( * args , * * kwargs )
self . fields [ ' gid ' ] . label = ' Gid, attention, cet attribut ne doit pas être modifié après création '
class DelListRightForm ( ModelForm ) :
2017-05-27 02:55:33 +00:00
listrights = forms . ModelMultipleChoiceField ( queryset = ListRight . objects . all ( ) . select_related ( ' user ' ) , label = " Droits actuels " , widget = forms . CheckboxSelectMultiple )
2016-07-26 00:54:32 +00:00
class Meta :
exclude = [ ' listright ' , ' gid ' ]
model = ListRight
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