8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2025-01-11 02:34:28 +00:00

[users] PEP8 on main files

This commit is contained in:
Alexandre Iooss 2018-10-28 15:32:31 +01:00
parent a9ec23c260
commit 05dc3fd800
8 changed files with 193 additions and 187 deletions

View file

@ -27,6 +27,7 @@ Here are defined some functions to check acl on the application.
""" """
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
def can_view(user): def can_view(user):
"""Check if an user can view the application. """Check if an user can view the application.
@ -40,4 +41,3 @@ def can_view(user):
can = user.has_module_perms('users') can = user.has_module_perms('users')
return can, None if can else _("You don't have the right to view this" return can, None if can else _("You don't have the right to view this"
" application.") " application.")

View file

@ -28,10 +28,16 @@ où on fait appel à UserChange et ServiceUserChange, forms custom
from __future__ import unicode_literals from __future__ import unicode_literals
from django.contrib import admin from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import Group
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from .forms import (
UserChangeForm,
UserCreationForm,
ServiceUserChangeForm,
ServiceUserCreationForm
)
from .models import ( from .models import (
User, User,
EMailAddress, EMailAddress,
@ -49,12 +55,6 @@ from .models import (
LdapServiceUserGroup, LdapServiceUserGroup,
LdapUserGroup LdapUserGroup
) )
from .forms import (
UserChangeForm,
UserCreationForm,
ServiceUserChangeForm,
ServiceUserCreationForm
)
class LdapUserAdmin(admin.ModelAdmin): class LdapUserAdmin(admin.ModelAdmin):
@ -147,10 +147,10 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
'Personal info', 'Personal info',
{ {
'fields': 'fields':
('surname', 'email', 'school', 'shell', 'uid_number') ('surname', 'email', 'school', 'shell', 'uid_number')
} }
), ),
('Permissions', {'fields': ('is_admin', )}), ('Permissions', {'fields': ('is_admin',)}),
) )
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user. # overrides get_fieldsets to use this attribute when creating a user.
@ -167,7 +167,7 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
'is_admin', 'is_admin',
'password1', 'password1',
'password2' 'password2'
) )
} }
), ),
) )

View file

@ -34,25 +34,21 @@ Modification, creation de :
from __future__ import unicode_literals from __future__ import unicode_literals
from django import forms from django import forms
from django.forms import ModelForm, Form
from django.contrib.auth.forms import ReadOnlyPasswordHashField from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.validators import MinLengthValidator
from django.utils import timezone
from django.contrib.auth.models import Group, Permission from django.contrib.auth.models import Group, Permission
from django.utils.translation import ugettext_lazy as _ from django.core.validators import MinLengthValidator
from django.forms import ModelForm, Form
from django.utils import timezone
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from machines.models import Interface, Machine, Nas from machines.models import Interface, Nas
from topologie.models import Port
from preferences.models import OptionalUser
from re2o.utils import remove_user_room, get_input_formats_help_text
from re2o.mixins import FormRevMixin
from re2o.field_permissions import FieldPermissionFormMixin
from preferences.models import GeneralOption from preferences.models import GeneralOption
from preferences.models import OptionalUser
from .widgets import DateTimePicker from re2o.field_permissions import FieldPermissionFormMixin
from re2o.mixins import FormRevMixin
from re2o.utils import remove_user_room
from topologie.models import Port
from .models import ( from .models import (
User, User,
ServiceUser, ServiceUser,
@ -65,6 +61,7 @@ from .models import (
Adherent, Adherent,
Club Club
) )
from .widgets import DateTimePicker
class PassForm(FormRevMixin, FieldPermissionFormMixin, forms.ModelForm): class PassForm(FormRevMixin, FieldPermissionFormMixin, forms.ModelForm):
@ -108,7 +105,7 @@ class PassForm(FormRevMixin, FieldPermissionFormMixin, forms.ModelForm):
"""Verifie si il y a lieu que le mdp self est correct""" """Verifie si il y a lieu que le mdp self est correct"""
if not self.instance.check_password( if not self.instance.check_password(
self.cleaned_data.get("selfpasswd") self.cleaned_data.get("selfpasswd")
): ):
raise forms.ValidationError(_("The current password is incorrect.")) raise forms.ValidationError(_("The current password is incorrect."))
return return
@ -310,6 +307,7 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
"""Formulaire de base d'edition d'un user. Formulaire de base, utilisé """Formulaire de base d'edition d'un user. Formulaire de base, utilisé
pour l'edition de self par self ou un cableur. On formate les champs pour l'edition de self par self ou un cableur. On formate les champs
avec des label plus jolis""" avec des label plus jolis"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(AdherentForm, self).__init__(*args, prefix=prefix, **kwargs) super(AdherentForm, self).__init__(*args, prefix=prefix, **kwargs)
@ -328,8 +326,8 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
return self.cleaned_data.get('email').lower() return self.cleaned_data.get('email').lower()
else: else:
raise forms.ValidationError( raise forms.ValidationError(
_("You can't use a {} address.").format( _("You can't use a {} address.").format(
OptionalUser.objects.first().local_email_domain)) OptionalUser.objects.first().local_email_domain))
class Meta: class Meta:
model = Adherent model = Adherent
@ -344,7 +342,6 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
'room', 'room',
] ]
def clean_telephone(self): def clean_telephone(self):
"""Verifie que le tel est présent si 'option est validée """Verifie que le tel est présent si 'option est validée
dans preferences""" dans preferences"""
@ -368,16 +365,17 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
remove_user_room(self.cleaned_data.get('room')) remove_user_room(self.cleaned_data.get('room'))
return return
class AdherentCreationForm(AdherentForm): class AdherentCreationForm(AdherentForm):
"""Formulaire de création d'un user. """Formulaire de création d'un user.
AdherentForm auquel on ajoute une checkbox afin d'éviter les AdherentForm auquel on ajoute une checkbox afin d'éviter les
doublons d'utilisateurs""" doublons d'utilisateurs"""
# Champ permettant d'éviter au maxium les doublons d'utilisateurs # Champ permettant d'éviter au maxium les doublons d'utilisateurs
former_user_check_info = _("If you already have an account, please use it. "\ former_user_check_info = _("If you already have an account, please use it. "
+ "If your lost access to it, please consider "\ "If your lost access to it, please consider "
+ "using the forgotten password button on the "\ "using the forgotten password button on the "
+ "login page or contacting support.") "login page or contacting support.")
former_user_check = forms.BooleanField(required=True, help_text=former_user_check_info) former_user_check = forms.BooleanField(required=True, help_text=former_user_check_info)
former_user_check.label = _("I certifie that I have not had an account before") former_user_check.label = _("I certifie that I have not had an account before")
@ -389,14 +387,16 @@ class AdherentCreationForm(AdherentForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(AdherentCreationForm, self).__init__(*args, **kwargs) super(AdherentCreationForm, self).__init__(*args, **kwargs)
class AdherentEditForm(AdherentForm): class AdherentEditForm(AdherentForm):
"""Formulaire d'édition d'un user. """Formulaire d'édition d'un user.
AdherentForm incluant la modification des champs gpg et shell""" AdherentForm incluant la modification des champs gpg et shell"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(AdherentEditForm, self).__init__(*args, **kwargs) super(AdherentEditForm, self).__init__(*args, **kwargs)
self.fields['gpg_fingerprint'].widget.attrs['placeholder'] = _("Leave empty if you don't have any GPG key.") self.fields['gpg_fingerprint'].widget.attrs['placeholder'] = _("Leave empty if you don't have any GPG key.")
if 'shell' in self.fields: if 'shell' in self.fields:
self.fields['shell'].empty_label = _("Default shell") self.fields['shell'].empty_label = _("Default shell")
def clean_gpg_fingerprint(self): def clean_gpg_fingerprint(self):
"""Format the GPG fingerprint""" """Format the GPG fingerprint"""
@ -419,10 +419,12 @@ class AdherentEditForm(AdherentForm):
'gpg_fingerprint' 'gpg_fingerprint'
] ]
class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
"""Formulaire de base d'edition d'un user. Formulaire de base, utilisé """Formulaire de base d'edition d'un user. Formulaire de base, utilisé
pour l'edition de self par self ou un cableur. On formate les champs pour l'edition de self par self ou un cableur. On formate les champs
avec des label plus jolis""" avec des label plus jolis"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(ClubForm, self).__init__(*args, prefix=prefix, **kwargs) super(ClubForm, self).__init__(*args, prefix=prefix, **kwargs)
@ -462,6 +464,7 @@ class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
class ClubAdminandMembersForm(FormRevMixin, ModelForm): class ClubAdminandMembersForm(FormRevMixin, ModelForm):
"""Permet d'éditer la liste des membres et des administrateurs """Permet d'éditer la liste des membres et des administrateurs
d'un club""" d'un club"""
class Meta: class Meta:
model = Club model = Club
fields = ['administrators', 'members'] fields = ['administrators', 'members']
@ -478,6 +481,7 @@ class ClubAdminandMembersForm(FormRevMixin, ModelForm):
class PasswordForm(FormRevMixin, ModelForm): class PasswordForm(FormRevMixin, ModelForm):
""" Formulaire de changement brut de mot de passe. """ Formulaire de changement brut de mot de passe.
Ne pas utiliser sans traitement""" Ne pas utiliser sans traitement"""
class Meta: class Meta:
model = User model = User
fields = ['password', 'pwd_ntlm'] fields = ['password', 'pwd_ntlm']
@ -499,7 +503,7 @@ class ServiceUserForm(FormRevMixin, ModelForm):
class Meta: class Meta:
model = ServiceUser model = ServiceUser
fields = ('pseudo', 'access_group','comment') fields = ('pseudo', 'access_group', 'comment')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
@ -516,12 +520,14 @@ class ServiceUserForm(FormRevMixin, ModelForm):
class EditServiceUserForm(ServiceUserForm): class EditServiceUserForm(ServiceUserForm):
"""Formulaire d'edition de base d'un service user. Ne permet """Formulaire d'edition de base d'un service user. Ne permet
d'editer que son group d'acl et son commentaire""" d'editer que son group d'acl et son commentaire"""
class Meta(ServiceUserForm.Meta): class Meta(ServiceUserForm.Meta):
fields = ['access_group', 'comment'] fields = ['access_group', 'comment']
class StateForm(FormRevMixin, ModelForm): class StateForm(FormRevMixin, ModelForm):
""" Changement de l'état d'un user""" """ Changement de l'état d'un user"""
class Meta: class Meta:
model = User model = User
fields = ['state'] fields = ['state']
@ -552,6 +558,7 @@ class GroupForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
class SchoolForm(FormRevMixin, ModelForm): class SchoolForm(FormRevMixin, ModelForm):
"""Edition, creation d'un école""" """Edition, creation d'un école"""
class Meta: class Meta:
model = School model = School
fields = ['name'] fields = ['name']
@ -564,6 +571,7 @@ class SchoolForm(FormRevMixin, ModelForm):
class ShellForm(FormRevMixin, ModelForm): class ShellForm(FormRevMixin, ModelForm):
"""Edition, creation d'un école""" """Edition, creation d'un école"""
class Meta: class Meta:
model = ListShell model = ListShell
fields = ['shell'] fields = ['shell']
@ -595,6 +603,7 @@ class ListRightForm(FormRevMixin, ModelForm):
class NewListRightForm(ListRightForm): class NewListRightForm(ListRightForm):
"""Ajout d'un groupe/list de droit """ """Ajout d'un groupe/list de droit """
class Meta(ListRightForm.Meta): class Meta(ListRightForm.Meta):
fields = ('name', 'unix_name', 'gid', 'critical', 'permissions', fields = ('name', 'unix_name', 'gid', 'critical', 'permissions',
'details') 'details')
@ -641,6 +650,7 @@ class DelSchoolForm(Form):
class BanForm(FormRevMixin, ModelForm): class BanForm(FormRevMixin, ModelForm):
"""Creation, edition d'un objet bannissement""" """Creation, edition d'un objet bannissement"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(BanForm, self).__init__(*args, prefix=prefix, **kwargs) super(BanForm, self).__init__(*args, prefix=prefix, **kwargs)
@ -650,11 +660,12 @@ class BanForm(FormRevMixin, ModelForm):
class Meta: class Meta:
model = Ban model = Ban
exclude = ['user'] exclude = ['user']
widgets = {'date_end':DateTimePicker} widgets = {'date_end': DateTimePicker}
class WhitelistForm(FormRevMixin, ModelForm): class WhitelistForm(FormRevMixin, ModelForm):
"""Creation, edition d'un objet whitelist""" """Creation, edition d'un objet whitelist"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(WhitelistForm, self).__init__(*args, prefix=prefix, **kwargs) super(WhitelistForm, self).__init__(*args, prefix=prefix, **kwargs)
@ -664,11 +675,12 @@ class WhitelistForm(FormRevMixin, ModelForm):
class Meta: class Meta:
model = Whitelist model = Whitelist
exclude = ['user'] exclude = ['user']
widgets = {'date_end':DateTimePicker} widgets = {'date_end': DateTimePicker}
class EMailAddressForm(FormRevMixin, ModelForm): class EMailAddressForm(FormRevMixin, ModelForm):
"""Create and edit a local email address""" """Create and edit a local email address"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(EMailAddressForm, self).__init__(*args, prefix=prefix, **kwargs) super(EMailAddressForm, self).__init__(*args, prefix=prefix, **kwargs)
@ -685,6 +697,7 @@ class EMailAddressForm(FormRevMixin, ModelForm):
class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
"""Edit email-related settings""" """Edit email-related settings"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(EmailSettingsForm, self).__init__(*args, prefix=prefix, **kwargs) super(EmailSettingsForm, self).__init__(*args, prefix=prefix, **kwargs)
@ -699,12 +712,12 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
return self.cleaned_data.get('email').lower() return self.cleaned_data.get('email').lower()
else: else:
raise forms.ValidationError( raise forms.ValidationError(
_("You can't use a {} address.").format( _("You can't use a {} address.").format(
OptionalUser.objects.first().local_email_domain)) OptionalUser.objects.first().local_email_domain))
class Meta: class Meta:
model = User model = User
fields = ['email','local_email_enabled', 'local_email_redirect'] fields = ['email', 'local_email_enabled', 'local_email_redirect']
class InitialRegisterForm(forms.Form): class InitialRegisterForm(forms.Form):
@ -721,7 +734,9 @@ class InitialRegisterForm(forms.Form):
port = Port.objects.filter(switch__interface__ipv4__ipv4=switch_ip, port=switch_port).first() port = Port.objects.filter(switch__interface__ipv4__ipv4=switch_ip, port=switch_port).first()
# If a port exists, checking there is a room AND radius # If a port exists, checking there is a room AND radius
if port: if port:
if port.get_port_profile.radius_type != 'NO' and port.get_port_profile.radius_mode == 'STRICT' and hasattr(port, 'room'): if (port.get_port_profile.radius_type != 'NO'
and port.get_port_profile.radius_mode == 'STRICT'
and hasattr(port, 'room')):
# Requesting user is not in this room ? # Requesting user is not in this room ?
if self.user.room != port.room: if self.user.room != port.room:
self.new_room = port.room self.new_room = port.room

View file

@ -42,50 +42,45 @@ models sql classiques. Seuls certains champs essentiels sont
dupliqués. dupliqués.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
import re
import uuid
import datetime import datetime
import re
import sys import sys
import traceback
import uuid
from django.db import models import ldapdb.models.fields
from django.db.models import Q
from django import forms from django import forms
from django.forms import ValidationError
from django.db.models.signals import post_save, post_delete, m2m_changed
from django.dispatch import receiver
from django.utils.functional import cached_property
from django.template import Context, loader
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.db import transaction
from django.utils import timezone
from django.contrib.auth.models import ( from django.contrib.auth.models import (
AbstractBaseUser, AbstractBaseUser,
BaseUserManager, BaseUserManager,
PermissionsMixin, PermissionsMixin,
Group Group
) )
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
import traceback from django.db import models
from django.db import transaction
from django.db.models import Q
from django.db.models.signals import post_save, post_delete, m2m_changed
from django.dispatch import receiver
from django.forms import ValidationError
from django.template import Context, loader
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from reversion import revisions as reversion from reversion import revisions as reversion
import ldapdb.models
import ldapdb.models.fields
from re2o.settings import LDAP, GID_RANGES, UID_RANGES
from re2o.login import hashNT
from re2o.field_permissions import FieldPermissionModelMixin
from re2o.mixins import AclMixin, RevMixin
from cotisations.models import Cotisation, Facture, Paiement, Vente from cotisations.models import Cotisation, Facture, Paiement, Vente
from machines.models import Domain, Interface, Machine, regen from machines.models import Domain, Interface, Machine, regen
from preferences.models import GeneralOption, AssoOption, OptionalUser from preferences.models import GeneralOption, AssoOption, OptionalUser
from preferences.models import OptionalMachine, MailMessageOption from preferences.models import OptionalMachine, MailMessageOption
from re2o.field_permissions import FieldPermissionModelMixin
from re2o.login import hashNT
from re2o.mixins import AclMixin, RevMixin
from re2o.settings import LDAP, GID_RANGES, UID_RANGES
# Utilitaires généraux # Utilitaires généraux
@ -93,8 +88,8 @@ from preferences.models import OptionalMachine, MailMessageOption
def linux_user_check(login): def linux_user_check(login):
""" Validation du pseudo pour respecter les contraintes unix""" """ Validation du pseudo pour respecter les contraintes unix"""
UNIX_LOGIN_PATTERN = re.compile("^[a-zA-Z][a-zA-Z0-9-]*[$]?$") unix_login_pattern = re.compile("^[a-zA-Z][a-zA-Z0-9-]*[$]?$")
return UNIX_LOGIN_PATTERN.match(login) return unix_login_pattern.match(login)
def linux_user_validator(login): def linux_user_validator(login):
@ -117,7 +112,7 @@ def get_fresh_user_uid():
used_uids = list(User.objects.values_list('uid_number', flat=True)) used_uids = list(User.objects.values_list('uid_number', flat=True))
except: except:
used_uids = [] used_uids = []
free_uids = [id for id in uids if id not in used_uids] free_uids = [uid for uid in uids if uid not in used_uids]
return min(free_uids) return min(free_uids)
@ -128,7 +123,7 @@ def get_fresh_gid():
int(max(GID_RANGES['posix'])) int(max(GID_RANGES['posix']))
)) ))
used_gids = list(ListRight.objects.values_list('gid', flat=True)) used_gids = list(ListRight.objects.values_list('gid', flat=True))
free_gids = [id for id in gids if id not in used_gids] free_gids = [gid for gid in gids if gid not in used_gids]
return min(free_gids) return min(free_gids)
@ -296,7 +291,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
@cached_property @cached_property
def get_mail(self): def get_mail(self):
"""Return the mail address choosen by the user""" """Return the mail address choosen by the user"""
if not OptionalUser.get_cached_value('local_email_accounts_enabled') or not self.local_email_enabled or self.local_email_redirect: if (not OptionalUser.get_cached_value('local_email_accounts_enabled')
or not self.local_email_enabled or self.local_email_redirect):
return str(self.email) return str(self.email)
else: else:
return str(self.emailaddress_set.get(local_part=self.pseudo.lower())) return str(self.emailaddress_set.get(local_part=self.pseudo.lower()))
@ -336,7 +332,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
def set_active(self): def set_active(self):
"""Enable this user if he subscribed successfully one time before""" """Enable this user if he subscribed successfully one time before"""
if self.state == self.STATE_NOT_YET_ACTIVE: if self.state == self.STATE_NOT_YET_ACTIVE:
if self.facture_set.filter(valid=True).filter(Q(vente__type_cotisation='All') | Q(vente__type_cotisation='Adhesion')).exists(): if self.facture_set.filter(valid=True).filter(
Q(vente__type_cotisation='All') | Q(vente__type_cotisation='Adhesion')).exists():
self.state = self.STATE_ACTIVE self.state = self.STATE_ACTIVE
self.save() self.save()
@ -502,7 +499,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
) )
).aggregate( ).aggregate(
total=models.Sum( total=models.Sum(
models.F('prix')*models.F('number'), models.F('prix') * models.F('number'),
output_field=models.DecimalField() output_field=models.DecimalField()
) )
)['total'] or 0 )['total'] or 0
@ -511,7 +508,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
name="solde" name="solde"
).aggregate( ).aggregate(
total=models.Sum( total=models.Sum(
models.F('prix')*models.F('number'), models.F('prix') * models.F('number'),
output_field=models.DecimalField() output_field=models.DecimalField()
) )
)['total'] or 0 )['total'] or 0
@ -587,20 +584,20 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
user_ldap.dialupAccess = str(self.has_access()) user_ldap.dialupAccess = str(self.has_access())
user_ldap.home_directory = self.home_directory user_ldap.home_directory = self.home_directory
user_ldap.mail = self.get_mail user_ldap.mail = self.get_mail
user_ldap.given_name = self.surname.lower() + '_'\ user_ldap.given_name = self.surname.lower() + '_' \
+ self.name.lower()[:3] + self.name.lower()[:3]
user_ldap.gid = LDAP['user_gid'] user_ldap.gid = LDAP['user_gid']
if '{SSHA}' in self.password or '{SMD5}' in self.password: if '{SSHA}' in self.password or '{SMD5}' in self.password:
# We remove the extra $ added at import from ldap # We remove the extra $ added at import from ldap
user_ldap.user_password = self.password[:6] + \ user_ldap.user_password = self.password[:6] + \
self.password[7:] self.password[7:]
elif '{crypt}' in self.password: elif '{crypt}' in self.password:
# depending on the length, we need to remove or not a $ # depending on the length, we need to remove or not a $
if len(self.password) == 41: if len(self.password) == 41:
user_ldap.user_password = self.password user_ldap.user_password = self.password
else: else:
user_ldap.user_password = self.password[:7] + \ user_ldap.user_password = self.password[:7] + \
self.password[8:] self.password[8:]
user_ldap.sambat_nt_password = self.pwd_ntlm.upper() user_ldap.sambat_nt_password = self.pwd_ntlm.upper()
if self.get_shell: if self.get_shell:
@ -632,7 +629,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
def notif_inscription(self): def notif_inscription(self):
""" Prend en argument un objet user, envoie un mail de bienvenue """ """ Prend en argument un objet user, envoie un mail de bienvenue """
template = loader.get_template('users/email_welcome') template = loader.get_template('users/email_welcome')
mailmessageoptions, _created = MailMessageOption\ mailmessageoptions, _created = MailMessageOption \
.objects.get_or_create() .objects.get_or_create()
context = Context({ context = Context({
'nom': self.get_full_name(), 'nom': self.get_full_name(),
@ -688,7 +685,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
une machine inconnue sur le compte de l'user""" une machine inconnue sur le compte de l'user"""
all_interfaces = self.user_interfaces(active=False) all_interfaces = self.user_interfaces(active=False)
if all_interfaces.count() > OptionalMachine.get_cached_value( if all_interfaces.count() > OptionalMachine.get_cached_value(
'max_lambdauser_interfaces' 'max_lambdauser_interfaces'
): ):
return False, _("Maximum number of registered machines reached.") return False, _("Maximum number of registered machines reached.")
if not nas_type: if not nas_type:
@ -714,7 +711,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
domain.save() domain.save()
self.notif_auto_newmachine(interface_cible) self.notif_auto_newmachine(interface_cible)
except Exception as error: except Exception as error:
return False, traceback.format_exc() return False, traceback.format_exc()
return interface_cible, "Ok" return interface_cible, "Ok"
def notif_auto_newmachine(self, interface): def notif_auto_newmachine(self, interface):
@ -741,7 +738,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
def set_password(self, password): def set_password(self, password):
""" A utiliser de préférence, set le password en hash courrant et """ A utiliser de préférence, set le password en hash courrant et
dans la version ntlm""" dans la version ntlm"""
super().set_password(password) super(User).set_password(password)
self.pwd_ntlm = hashNT(password) self.pwd_ntlm = hashNT(password)
return return
@ -853,7 +850,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
the right to change a state the right to change a state
""" """
if not ((self.pk == user_request.pk and OptionalUser.get_cached_value('self_change_room')) if not ((self.pk == user_request.pk and OptionalUser.get_cached_value('self_change_room'))
or user_request.has_perm('users.change_user')): or user_request.has_perm('users.change_user')):
return False, _("Permission required to change the room.") return False, _("Permission required to change the room.")
else: else:
return True, None return True, None
@ -879,16 +876,15 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
the right to change a shell the right to change a shell
""" """
if not ((self.pk == user_request.pk and OptionalUser.get_cached_value('self_change_shell')) if not ((self.pk == user_request.pk and OptionalUser.get_cached_value('self_change_shell'))
or user_request.has_perm('users.change_user_shell')): or user_request.has_perm('users.change_user_shell')):
return False, _("Permission required to change the shell.") return False, _("Permission required to change the shell.")
else: else:
return True, None return True, None
@staticmethod @staticmethod
def can_change_local_email_redirect(user_request, *_args, **_kwargs): def can_change_local_email_redirect(*_args, **_kwargs):
""" Check if a user can change local_email_redirect. """ Check if a user can change local_email_redirect.
:param user_request: The user who request
:returns: a message and a boolean which is True if the user has :returns: a message and a boolean which is True if the user has
the right to change a redirection the right to change a redirection
""" """
@ -898,7 +894,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
) )
@staticmethod @staticmethod
def can_change_local_email_enabled(user_request, *_args, **_kwargs): def can_change_local_email_enabled(*_args, **_kwargs):
""" Check if a user can change internal address. """ Check if a user can change internal address.
:param user_request: The user who request :param user_request: The user who request
@ -1014,8 +1010,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""Check if this pseudo is already used by any mailalias. """Check if this pseudo is already used by any mailalias.
Better than raising an error in post-save and catching it""" Better than raising an error in post-save and catching it"""
if (EMailAddress.objects if (EMailAddress.objects
.filter(local_part=self.pseudo.lower()).exclude(user_id=self.id) .filter(local_part=self.pseudo.lower()).exclude(user_id=self.id)
): ):
raise ValidationError("This pseudo is already in use.") raise ValidationError("This pseudo is already in use.")
if not self.local_email_enabled and not self.email: if not self.local_email_enabled and not self.email:
raise ValidationError( raise ValidationError(
@ -1027,8 +1023,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
if self.local_email_redirect and not self.email: if self.local_email_redirect and not self.email:
raise ValidationError( raise ValidationError(
{'local_email_redirect': ( {'local_email_redirect': (
_("You can't redirect your local emails if no external email" _("You can't redirect your local emails if no external email"
" address has been set.")), } " address has been set.")), }
) )
def __str__(self): def __str__(self):
@ -1399,7 +1395,6 @@ class ListShell(RevMixin, AclMixin, models.Model):
verbose_name = _("shell") verbose_name = _("shell")
verbose_name_plural = _("shells") verbose_name_plural = _("shells")
def get_pretty_name(self): def get_pretty_name(self):
"""Return the canonical name of the shell""" """Return the canonical name of the shell"""
return self.shell.split("/")[-1] return self.shell.split("/")[-1]
@ -1586,14 +1581,14 @@ class Request(models.Model):
created_at = models.DateTimeField(auto_now_add=True, editable=False) created_at = models.DateTimeField(auto_now_add=True, editable=False)
expires_at = models.DateTimeField() expires_at = models.DateTimeField()
def save(self): def save(self, **kwargs):
if not self.expires_at: if not self.expires_at:
self.expires_at = (timezone.now() + self.expires_at = (timezone.now() +
datetime.timedelta( datetime.timedelta(
hours=GeneralOption.get_cached_value( hours=GeneralOption.get_cached_value(
'req_expire_hrs' 'req_expire_hrs'
) )
)) ))
if not self.token: if not self.token:
self.token = str(uuid.uuid4()).replace('-', '') # remove hyphens self.token = str(uuid.uuid4()).replace('-', '') # remove hyphens
super(Request, self).save() super(Request, self).save()
@ -1682,7 +1677,7 @@ class LdapUser(ldapdb.models.Model):
self.sn = self.name self.sn = self.name
self.uid = self.name self.uid = self.name
self.sambaSID = self.uidNumber self.sambaSID = self.uidNumber
super(LdapUser, self).save(*args, **kwargs) super(LdapUser, self).save()
class LdapUserGroup(ldapdb.models.Model): class LdapUserGroup(ldapdb.models.Model):
@ -1856,7 +1851,7 @@ class EMailAddress(RevMixin, AclMixin, models.Model):
if user_request == self.user: if user_request == self.user:
return True, None return True, None
return False, _("You don't have the right to delete another user's" return False, _("You don't have the right to delete another user's"
" local email account") " local email account")
def can_edit(self, user_request, *_args, **_kwargs): def can_edit(self, user_request, *_args, **_kwargs):
"""Check if a user can edit the alias """Check if a user can edit the alias
@ -1885,4 +1880,3 @@ class EMailAddress(RevMixin, AclMixin, models.Model):
if "@" in self.local_part: if "@" in self.local_part:
raise ValidationError(_("The local part must not contain @.")) raise ValidationError(_("The local part must not contain @."))
super(EMailAddress, self).clean(*args, **kwargs) super(EMailAddress, self).clean(*args, **kwargs)

View file

@ -27,6 +27,7 @@ Serializers for the User app
""" """
from rest_framework import serializers from rest_framework import serializers
from users.models import Club, Adherent from users.models import Club, Adherent

View file

@ -23,13 +23,9 @@
The tests for the Users module. The tests for the Users module.
""" """
import os.path
from django.test import TestCase from django.test import TestCase
from django.conf import settings
from . import models
import volatildap from . import models
class SchoolTestCase(TestCase): class SchoolTestCase(TestCase):
@ -84,4 +80,3 @@ class LdapServiceUserTestCase(TestCase):
user_password="{SSHA}AbCdEfGhIjKlMnOpQrStUvWxYz987654" user_password="{SSHA}AbCdEfGhIjKlMnOpQrStUvWxYz987654"
) )
self.assertEqual(g.name, 'users_test_ldapserviceuser') self.assertEqual(g.name, 'users_test_ldapserviceuser')

View file

@ -36,30 +36,24 @@ des whitelist, des services users et des écoles
from __future__ import unicode_literals from __future__ import unicode_literals
from django.urls import reverse
from django.shortcuts import get_object_or_404, render, redirect
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.db.models import ProtectedError, Count, Max
from django.utils import timezone
from django.db import transaction from django.db import transaction
from django.db.models import ProtectedError, Count, Max
from django.http import HttpResponse from django.http import HttpResponse
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.views.decorators.csrf import csrf_exempt from django.shortcuts import get_object_or_404, render, redirect
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer from rest_framework.renderers import JSONRenderer
from reversion import revisions as reversion from reversion import revisions as reversion
from cotisations.models import Facture, Paiement from cotisations.models import Facture, Paiement
from cotisations.utils import find_payment_method
from machines.models import Machine from machines.models import Machine
from preferences.models import OptionalUser, GeneralOption, AssoOption from preferences.models import OptionalUser, GeneralOption, AssoOption
from re2o.views import form
from re2o.utils import (
all_has_access,
SortTable,
re2o_paginator
)
from re2o.acl import ( from re2o.acl import (
can_create, can_create,
can_edit, can_edit,
@ -69,22 +63,13 @@ from re2o.acl import (
can_view_all, can_view_all,
can_change can_change
) )
from cotisations.utils import find_payment_method from re2o.utils import (
from topologie.models import Port all_has_access,
from .serializers import MailingSerializer, MailingMemberSerializer SortTable,
from .models import ( re2o_paginator
User,
Ban,
Whitelist,
School,
ListRight,
Request,
ServiceUser,
Adherent,
Club,
ListShell,
EMailAddress,
) )
from re2o.views import form
from topologie.models import Port
from .forms import ( from .forms import (
BanForm, BanForm,
WhitelistForm, WhitelistForm,
@ -109,6 +94,20 @@ from .forms import (
GroupForm, GroupForm,
InitialRegisterForm InitialRegisterForm
) )
from .models import (
User,
Ban,
Whitelist,
School,
ListRight,
Request,
ServiceUser,
Adherent,
Club,
ListShell,
EMailAddress,
)
from .serializers import MailingSerializer, MailingMemberSerializer
@can_create(Adherent) @can_create(Adherent)
@ -116,8 +115,8 @@ def new_user(request):
""" Vue de création d'un nouvel utilisateur, """ Vue de création d'un nouvel utilisateur,
envoie un mail pour le mot de passe""" envoie un mail pour le mot de passe"""
user = AdherentCreationForm(request.POST or None, user=request.user) user = AdherentCreationForm(request.POST or None, user=request.user)
GTU_sum_up = GeneralOption.get_cached_value('GTU_sum_up') gtu_sum_up = GeneralOption.get_cached_value('GTU_sum_up')
GTU = GeneralOption.get_cached_value('GTU') gtu = GeneralOption.get_cached_value('GTU')
if user.is_valid(): if user.is_valid():
user = user.save() user = user.save()
user.reset_passwd_mail(request) user.reset_passwd_mail(request)
@ -130,8 +129,8 @@ def new_user(request):
return form( return form(
{ {
'userform': user, 'userform': user,
'GTU_sum_up': GTU_sum_up, 'GTU_sum_up': gtu_sum_up,
'GTU': GTU, 'GTU': gtu,
'showCGU': True, 'showCGU': True,
'action_name': _("Commit") 'action_name': _("Commit")
}, },
@ -560,7 +559,7 @@ def del_emailaddress(request, emailaddress, **_kwargs):
return redirect(reverse( return redirect(reverse(
'users:profil', 'users:profil',
kwargs={'userid': str(emailaddress.user.id)} kwargs={'userid': str(emailaddress.user.id)}
)) ))
return form( return form(
{'objet': emailaddress, 'objet_name': 'emailaddress'}, {'objet': emailaddress, 'objet_name': 'emailaddress'},
'users/delete.html', 'users/delete.html',
@ -584,7 +583,7 @@ def edit_email_settings(request, user_instance, **_kwargs):
return redirect(reverse( return redirect(reverse(
'users:profil', 'users:profil',
kwargs={'userid': str(user_instance.id)} kwargs={'userid': str(user_instance.id)}
)) ))
return form( return form(
{'userform': email_settings, {'userform': email_settings,
'showCGU': False, 'showCGU': False,
@ -909,28 +908,28 @@ def index_listright(request):
""" Affiche l'ensemble des droits""" """ Affiche l'ensemble des droits"""
rights = {} rights = {}
for right in (ListRight.objects for right in (ListRight.objects
.order_by('name') .order_by('name')
.prefetch_related('permissions') .prefetch_related('permissions')
.prefetch_related('user_set') .prefetch_related('user_set')
.prefetch_related('user_set__facture_set__vente_set__cotisation') .prefetch_related('user_set__facture_set__vente_set__cotisation')
): ):
rights[right] = (right.user_set rights[right] = (right.user_set
.annotate(action_number=Count('revision'), .annotate(action_number=Count('revision'),
last_seen=Max('revision__date_created'), last_seen=Max('revision__date_created'),
end_adhesion=Max('facture__vente__cotisation__date_end')) end_adhesion=Max('facture__vente__cotisation__date_end'))
) )
superusers = (User.objects superusers = (User.objects
.filter(is_superuser=True) .filter(is_superuser=True)
.annotate(action_number=Count('revision'), .annotate(action_number=Count('revision'),
last_seen=Max('revision__date_created'), last_seen=Max('revision__date_created'),
end_adhesion=Max('facture__vente__cotisation__date_end')) end_adhesion=Max('facture__vente__cotisation__date_end'))
) )
return render( return render(
request, request,
'users/index_listright.html', 'users/index_listright.html',
{ {
'rights': rights, 'rights': rights,
'superusers' : superusers, 'superusers': superusers,
} }
) )
@ -960,10 +959,10 @@ def mon_profil(request):
@can_view(User) @can_view(User)
def profil(request, users, **_kwargs): def profil(request, users, **_kwargs):
""" Affiche un profil, self or cableur, prend un userid en argument """ """ Affiche un profil, self or cableur, prend un userid en argument """
machines = Machine.objects.filter(user=users).select_related('user')\ machines = Machine.objects.filter(user=users).select_related('user') \
.prefetch_related('interface_set__domain__extension')\ .prefetch_related('interface_set__domain__extension') \
.prefetch_related('interface_set__ipv4__ip_type__extension')\ .prefetch_related('interface_set__ipv4__ip_type__extension') \
.prefetch_related('interface_set__type')\ .prefetch_related('interface_set__type') \
.prefetch_related('interface_set__domain__related_domain__extension') .prefetch_related('interface_set__domain__related_domain__extension')
machines = SortTable.sort( machines = SortTable.sort(
machines, machines,
@ -1003,8 +1002,8 @@ def profil(request, users, **_kwargs):
user_solde = False user_solde = False
else: else:
user_solde = ( user_solde = (
balance is not None balance is not None
and balance.can_credit_balance(request.user) and balance.can_credit_balance(request.user)
) )
return render( return render(
request, request,
@ -1083,18 +1082,21 @@ def process_passwd(request, req):
request request
) )
@login_required @login_required
def initial_register(request): def initial_register(request):
switch_ip = request.GET.get('switch_ip', None) switch_ip = request.GET.get('switch_ip', None)
switch_port = request.GET.get('switch_port', None) switch_port = request.GET.get('switch_port', None)
client_mac = request.GET.get('client_mac', None) client_mac = request.GET.get('client_mac', None)
u_form = InitialRegisterForm(request.POST or None, user=request.user, switch_ip=switch_ip, switch_port=switch_port, client_mac=client_mac) u_form = InitialRegisterForm(request.POST or None, user=request.user, switch_ip=switch_ip, switch_port=switch_port,
client_mac=client_mac)
if not u_form.fields: if not u_form.fields:
messages.error(request, _("Incorrect URL, or already registered device")) messages.error(request, _("Incorrect URL, or already registered device"))
return redirect(reverse( return redirect(reverse(
'users:profil', 'users:profil',
kwargs={'userid': str(request.user.id)} kwargs={'userid': str(request.user.id)}
)) ))
port = None # TODO: local variable initialized only if condition succeed
if switch_ip and switch_port: if switch_ip and switch_port:
port = Port.objects.filter(switch__interface__ipv4__ipv4=switch_ip, port=switch_port).first() port = Port.objects.filter(switch__interface__ipv4__ipv4=switch_ip, port=switch_port).first()
if u_form.is_valid(): if u_form.is_valid():
@ -1184,9 +1186,8 @@ def ml_club_members(request, ml_name):
messages.error(request, _("The mailing list doesn't exist.")) messages.error(request, _("The mailing list doesn't exist."))
return redirect(reverse('index')) return redirect(reverse('index'))
members = ( members = (
club.administrators.all().values('email').distinct() | club.administrators.all().values('email').distinct() |
club.members.all().values('email').distinct() club.members.all().values('email').distinct()
) )
seria = MailingMemberSerializer(members, many=True) seria = MailingMemberSerializer(members, many=True)
return JSONResponse(seria.data) return JSONResponse(seria.data)

View file

@ -1,18 +1,17 @@
from django.forms.widgets import Input from django.conf import settings
from django.forms.utils import flatatt from django.forms.utils import flatatt
from django.utils.safestring import mark_safe from django.forms.widgets import Input
from django.template import Context, Template from django.template import Context
from django.template.loader import get_template from django.template.loader import get_template
from django.conf import settings from django.utils.dates import (
from django.utils.translation import ugettext_lazy as _, get_language_bidi WEEKDAYS,
from django.utils.dates import ( WEEKDAYS_ABBR,
WEEKDAYS, MONTHS,
WEEKDAYS_ABBR, MONTHS_3
MONTHS,
MONTHS_3,
MONTHS_AP,
MONTHS_ALT
) )
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _, get_language_bidi
def list2str(str_iterable): def list2str(str_iterable):
""" """
@ -22,29 +21,30 @@ def list2str(str_iterable):
:returns: A representation of the iterable as a list (e.g '["a", "b"]') :returns: A representation of the iterable as a list (e.g '["a", "b"]')
""" """
return '["' + '", "'.join(str_iterable) + '"]' return '["' + '", "'.join(str_iterable) + '"]'
class DateTimePicker(Input): class DateTimePicker(Input):
is_localized = False is_localized = False
def render(self, name, value, attrs=None):
super().render(name, value, attrs) def render(self, name, value, attrs=None, **kwargs):
super(DateTimePicker).render(name, value, attrs)
flat_attrs = flatatt(attrs) flat_attrs = flatatt(attrs)
context = Context({ context = Context({
'name': name, 'name': name,
'attrs': flat_attrs, 'attrs': flat_attrs,
'id': attrs['id'], 'id': attrs['id'],
'closeText': _("Close"), 'closeText': _("Close"),
'currentText': _("Today"), 'currentText': _("Today"),
'dayNames': mark_safe(list2str((str(item[1]) for item in WEEKDAYS.items()))), 'dayNames': mark_safe(list2str((str(item[1]) for item in WEEKDAYS.items()))),
'dayNamesMin': mark_safe(list2str((str(item[1]) for item in WEEKDAYS_ABBR.items()))), 'dayNamesMin': mark_safe(list2str((str(item[1]) for item in WEEKDAYS_ABBR.items()))),
'dayNamesShort': mark_safe(list2str((str(item[1]) for item in WEEKDAYS_ABBR.items()))), 'dayNamesShort': mark_safe(list2str((str(item[1]) for item in WEEKDAYS_ABBR.items()))),
'firstDay': mark_safe('"' + str(WEEKDAYS[settings.FIRST_DAY_OF_WEEK]) + '"'), 'firstDay': mark_safe('"' + str(WEEKDAYS[settings.FIRST_DAY_OF_WEEK]) + '"'),
'isRTL': str(get_language_bidi()).lower(), 'isRTL': str(get_language_bidi()).lower(),
'monthNames': mark_safe(list2str((str(item[1]) for item in MONTHS.items()))), 'monthNames': mark_safe(list2str((str(item[1]) for item in MONTHS.items()))),
'monthNamesShort': mark_safe(list2str((str(item[1]) for item in MONTHS_3.items()))), 'monthNamesShort': mark_safe(list2str((str(item[1]) for item in MONTHS_3.items()))),
'nextText': mark_safe('"' + str(_('Next')) + '"'), 'nextText': mark_safe('"' + str(_('Next')) + '"'),
'prevText': mark_safe('"' + str(_('Previous')) + '"'), 'prevText': mark_safe('"' + str(_('Previous')) + '"'),
'weekHeader': mark_safe('"' + str(_('Wk')) + '"' ), 'weekHeader': mark_safe('"' + str(_('Wk')) + '"'),
}) })
template = get_template('users/datetimepicker.html') template = get_template('users/datetimepicker.html')
return template.render(context) return template.render(context)