forms.py 27.5 KB
Newer Older
1
# -*- mode: python; coding: utf-8 -*-
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 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.
chirac's avatar
chirac committed
23 24
"""
Definition des forms pour l'application users.
25

chirac's avatar
chirac committed
26 27 28 29 30 31 32
Modification, creation de :
    - un user (informations personnelles)
    - un bannissement
    - le mot de passe d'un user
    - une whiteliste
    - un user de service
"""
33

34
from __future__ import unicode_literals
35 36

from django import forms
37
from django.forms import ModelForm, Form
38
from django.contrib.auth.forms import ReadOnlyPasswordHashField
Gabriel Detraz's avatar
Gabriel Detraz committed
39
from django.core.validators import MinLengthValidator
40
from django.utils import timezone
41
from django.contrib.auth.models import Group, Permission
42
from django.utils.translation import ugettext_lazy as _
erdnaxe's avatar
erdnaxe committed
43
from django.utils.safestring import mark_safe
44

45 46
from machines.models import Interface, Machine, Nas
from topologie.models import Port
chirac's avatar
chirac committed
47
from preferences.models import OptionalUser
48 49
from re2o.utils import remove_user_room
from re2o.base import get_input_formats_help_text
50 51 52
from re2o.mixins import FormRevMixin
from re2o.field_permissions import FieldPermissionFormMixin

edpibu's avatar
edpibu committed
53 54
from preferences.models import GeneralOption

root's avatar
root committed
55 56
from .widgets import DateTimePicker

57 58 59 60 61 62
from .models import (
    User,
    ServiceUser,
    School,
    ListRight,
    Whitelist,
63
    EMailAddress,
64 65 66 67 68
    ListShell,
    Ban,
    Adherent,
    Club
)
69

70

71
class PassForm(FormRevMixin, FieldPermissionFormMixin, forms.ModelForm):
chirac's avatar
chirac committed
72 73 74
    """Formulaire de changement de mot de passe. Verifie que les 2
    nouveaux mots de passe renseignés sont identiques et respectent
    une norme"""
75
    selfpasswd = forms.CharField(
76
        label=_("Current password"),
77 78 79
        max_length=255,
        widget=forms.PasswordInput
    )
chirac's avatar
chirac committed
80
    passwd1 = forms.CharField(
81
        label=_("New password"),
chirac's avatar
chirac committed
82 83 84 85 86
        max_length=255,
        validators=[MinLengthValidator(8)],
        widget=forms.PasswordInput
    )
    passwd2 = forms.CharField(
87
        label=_("New password confirmation"),
chirac's avatar
chirac committed
88 89 90 91
        max_length=255,
        validators=[MinLengthValidator(8)],
        widget=forms.PasswordInput
    )
92

93 94 95 96
    class Meta:
        model = User
        fields = []

97
    def clean_passwd2(self):
chirac's avatar
chirac committed
98
        """Verifie que passwd1 et 2 sont identiques"""
99 100 101 102
        # Check that the two password entries match
        password1 = self.cleaned_data.get("passwd1")
        password2 = self.cleaned_data.get("passwd2")
        if password1 and password2 and password1 != password2:
103
            raise forms.ValidationError(
104
                _("The new passwords don't match.")
105
            )
106
        return password2
107

108 109
    def clean_selfpasswd(self):
        """Verifie si il y a lieu que le mdp self est correct"""
110
        if not self.instance.check_password(
111 112
                self.cleaned_data.get("selfpasswd")
            ):
113
            raise forms.ValidationError(_("The current password is incorrect."))
114 115 116 117 118 119
        return

    def save(self, commit=True):
        """Changement du mot de passe"""
        user = super(PassForm, self).save(commit=False)
        user.set_password(self.cleaned_data.get("passwd1"))
120
        user.set_active()
121 122
        user.save()

chirac's avatar
chirac committed
123

124
class UserCreationForm(FormRevMixin, forms.ModelForm):
125
    """A form for creating new users. Includes all the required
chirac's avatar
chirac committed
126 127 128 129 130 131
    fields, plus a repeated password.

    Formulaire pour la création d'un user. N'est utilisé que pour
    l'admin, lors de la creation d'un user par admin. Inclu tous les
    champs obligatoires"""
    password1 = forms.CharField(
132
        label=_("Password"),
chirac's avatar
chirac committed
133 134 135 136 137
        widget=forms.PasswordInput,
        validators=[MinLengthValidator(8)],
        max_length=255
    )
    password2 = forms.CharField(
138
        label=_("Password confirmation"),
chirac's avatar
chirac committed
139 140 141 142
        widget=forms.PasswordInput,
        validators=[MinLengthValidator(8)],
        max_length=255
    )
143
    is_admin = forms.BooleanField(label=_("Is admin"))
144

145
    def __init__(self, *args, **kwargs):
146
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
147 148
        super(UserCreationForm, self).__init__(*args, prefix=prefix, **kwargs)

149 150 151 152
    def clean_email(self):
        if not OptionalUser.objects.first().local_email_domain in self.cleaned_data.get('email'):
            return self.cleaned_data.get('email').lower()
        else:
153 154
            raise forms.ValidationError(_("You can't use an internal address"
                                          " as your external address."))
155

156
    class Meta:
157
        model = Adherent
158
        fields = ('pseudo', 'surname', 'email')
159 160

    def clean_password2(self):
chirac's avatar
chirac committed
161
        """Verifie que password1 et 2 sont identiques"""
162 163 164 165
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
166
            raise forms.ValidationError(_("The passwords don't match."))
167 168 169 170 171 172 173 174 175 176
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        user.save()
        user.is_admin = self.cleaned_data.get("is_admin")
        return user

chirac's avatar
chirac committed
177

178
class ServiceUserCreationForm(FormRevMixin, forms.ModelForm):
chirac's avatar
chirac committed
179
    """A form for creating new users. Includes all the required
chirac's avatar
chirac committed
180 181 182 183 184
    fields, plus a repeated password.

    Formulaire pour la creation de nouveaux serviceusers.
    Requiert seulement un mot de passe; et un pseudo"""
    password1 = forms.CharField(
185
        label=_("Password"),
chirac's avatar
chirac committed
186 187 188 189 190
        widget=forms.PasswordInput,
        min_length=8,
        max_length=255
    )
    password2 = forms.CharField(
191
        label=_("Password confirmation"),
chirac's avatar
chirac committed
192 193 194 195
        widget=forms.PasswordInput,
        min_length=8,
        max_length=255
    )
chirac's avatar
chirac committed
196

197
    def __init__(self, *args, **kwargs):
198
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
chirac's avatar
chirac committed
199 200 201 202 203
        super(ServiceUserCreationForm, self).__init__(
            *args,
            prefix=prefix,
            **kwargs
        )
204

chirac's avatar
chirac committed
205 206 207 208 209
    class Meta:
        model = ServiceUser
        fields = ('pseudo',)

    def clean_password2(self):
chirac's avatar
chirac committed
210
        """Verifie que password1 et 2 sont indentiques"""
chirac's avatar
chirac committed
211 212 213 214
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
215
            raise forms.ValidationError(_("The passwords don't match."))
chirac's avatar
chirac committed
216 217 218 219 220 221 222 223
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(ServiceUserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        user.save()
        return user
224

chirac's avatar
chirac committed
225

226
class UserChangeForm(FormRevMixin, forms.ModelForm):
227 228 229
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
chirac's avatar
chirac committed
230 231

    Formulaire pour la modification d'un user coté admin
232 233
    """
    password = ReadOnlyPasswordHashField()
234
    is_admin = forms.BooleanField(label=_("Is admin"), required=False)
235 236

    class Meta:
237
        model = Adherent
238
        fields = ('pseudo', 'password', 'surname', 'email')
239 240

    def __init__(self, *args, **kwargs):
241
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
242
        super(UserChangeForm, self).__init__(*args, prefix=prefix, **kwargs)
243
        print(_("User is admin: %s") % kwargs['instance'].is_admin)
244 245 246
        self.initial['is_admin'] = kwargs['instance'].is_admin

    def clean_password(self):
chirac's avatar
chirac committed
247
        """Dummy fun"""
248 249 250 251 252 253 254 255 256 257 258 259
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserChangeForm, self).save(commit=False)
        user.is_admin = self.cleaned_data.get("is_admin")
        if commit:
            user.save()
        return user
chirac's avatar
chirac committed
260

chirac's avatar
chirac committed
261

262
class ServiceUserChangeForm(FormRevMixin, forms.ModelForm):
chirac's avatar
chirac committed
263 264 265
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
chirac's avatar
chirac committed
266 267

    Formulaire pour l'edition des service users coté admin
chirac's avatar
chirac committed
268 269 270
    """
    password = ReadOnlyPasswordHashField()

271
    def __init__(self, *args, **kwargs):
272
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
chirac's avatar
chirac committed
273 274 275 276 277
        super(ServiceUserChangeForm, self).__init__(
            *args,
            prefix=prefix,
            **kwargs
        )
278

chirac's avatar
chirac committed
279 280 281 282 283
    class Meta:
        model = ServiceUser
        fields = ('pseudo',)

    def clean_password(self):
chirac's avatar
chirac committed
284
        """Dummy fun"""
chirac's avatar
chirac committed
285 286
        return self.initial["password"]

chirac's avatar
chirac committed
287

chirac's avatar
chirac committed
288
class ResetPasswordForm(forms.Form):
chirac's avatar
chirac committed
289 290
    """Formulaire de demande de reinitialisation de mot de passe,
    mdp oublié"""
291
    pseudo = forms.CharField(label=_("Username"), max_length=255)
chirac's avatar
chirac committed
292
    email = forms.EmailField(max_length=255)
293

chirac's avatar
chirac committed
294

295
class MassArchiveForm(forms.Form):
chirac's avatar
chirac committed
296 297 298
    """Formulaire d'archivage des users inactif. Prend en argument
    du formulaire la date de depart avant laquelle archiver les
    users"""
299 300 301
    date = forms.DateTimeField(help_text='%d/%m/%y')

    def clean(self):
chirac's avatar
chirac committed
302
        cleaned_data = super(MassArchiveForm, self).clean()
303 304
        date = cleaned_data.get("date")
        if date:
305
            if date > timezone.now():
306 307 308
                raise forms.ValidationError(_("Impossible to archive users"
                                              " whose end access date is in"
                                              " the future."))
chirac's avatar
chirac committed
309

310

311
class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
chirac's avatar
chirac committed
312 313 314
    """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
    avec des label plus jolis"""
315
    def __init__(self, *args, **kwargs):
316
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
317
        super(AdherentForm, self).__init__(*args, prefix=prefix, **kwargs)
318 319 320 321 322
        self.fields['name'].label = _("First name")
        self.fields['surname'].label = _("Surname")
        self.fields['email'].label = _("Email address")
        self.fields['school'].label = _("School")
        self.fields['comment'].label = _("Comment")
323 324 325
        if 'room' in self.fields:
            self.fields['room'].label = _("Room")
            self.fields['room'].empty_label = _("No room")
326
        self.fields['school'].empty_label = _("Select a school")
327

328
    class Meta:
329
        model = Adherent
330 331 332 333
        fields = [
            'name',
            'surname',
            'pseudo',
334
            'email',
335 336
            'school',
            'comment',
337
            'telephone',
338
            'room',
339 340
        ]

341 342 343 344 345 346 347 348 349 350 351 352 353
    force = forms.BooleanField(
        label=_("Force the move?"),
        initial=False,
        required=False
    )

    def clean_email(self):
        if not OptionalUser.objects.first().local_email_domain in self.cleaned_data.get('email'):
            return self.cleaned_data.get('email').lower()
        else:
            raise forms.ValidationError(
                    _("You can't use a {} address.").format(
                        OptionalUser.objects.first().local_email_domain))
354

355
    def clean_telephone(self):
chirac's avatar
chirac committed
356 357
        """Verifie que le tel est présent si 'option est validée
        dans preferences"""
358
        telephone = self.cleaned_data['telephone']
359
        if not telephone and OptionalUser.get_cached_value('is_tel_mandatory'):
chirac's avatar
chirac committed
360
            raise forms.ValidationError(
361
                _("A valid telephone number is required.")
chirac's avatar
chirac committed
362
            )
363 364
        return telephone

365 366 367 368
    def clean_force(self):
        """On supprime l'ancien user de la chambre si et seulement si la
        case est cochée"""
        if self.cleaned_data.get('force', False):
369
            remove_user_room(self.cleaned_data.get('room'))
370
        return
chirac's avatar
chirac committed
371

372

373 374 375 376 377
class AdherentCreationForm(AdherentForm):
    """Formulaire de création d'un user.
    AdherentForm auquel on ajoute une checkbox afin d'éviter les
    doublons d'utilisateurs"""

edpibu's avatar
edpibu committed
378 379 380 381 382 383
    # Champ permettant d'éviter au maxium les doublons d'utilisateurs
    former_user_check_info = _("If you already have an account, please use it. "\
                           + "If your lost access to it, please consider "\
                           + "using the forgotten password button on the "\
                           + "login page or contacting support.")
    former_user_check = forms.BooleanField(required=True, help_text=former_user_check_info)
384
    former_user_check.label = _("I certify that I have not had an account before")
385

edpibu's avatar
edpibu committed
386 387
    # Checkbox for GTU
    gtu_check = forms.BooleanField(required=True)
Hugo LEVY-FALK's avatar
Hugo LEVY-FALK committed
388 389
    #gtu_check.label = mark_safe("{} <a href='/media/{}' download='CGU'>{}</a>{}".format(
    #    _("I commit to accept the"), GeneralOption.get_cached_value('GTU'), _("General Terms of Use"), _(".")))
edpibu's avatar
edpibu committed
390

391 392 393 394 395 396 397 398 399 400 401 402 403 404
    class Meta:
        model = Adherent
        fields = [
            'name',
            'surname',
            'pseudo',
            'email',
            'school',
            'comment',
            'telephone',
            'room',
            'state',
        ]

edpibu's avatar
edpibu committed
405 406
    def __init__(self, *args, **kwargs):
        super(AdherentCreationForm, self).__init__(*args, **kwargs)
407 408 409 410

class AdherentEditForm(AdherentForm):
    """Formulaire d'édition d'un user.
    AdherentForm incluant la modification des champs gpg et shell"""
411
    def __init__(self, *args, **kwargs):
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
       super(AdherentEditForm, self).__init__(*args, **kwargs)
       self.fields['gpg_fingerprint'].widget.attrs['placeholder'] = _("Leave empty if you don't have any GPG key.")
       if 'shell' in self.fields:
           self.fields['shell'].empty_label = _("Default shell")

    class Meta:
        model = Adherent
        fields = [
            'name',
            'surname',
            'pseudo',
            'email',
            'school',
            'comment',
            'telephone',
            'room',
            'shell',
            'gpg_fingerprint'
        ]
431

432
class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
433 434 435 436 437
    """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
    avec des label plus jolis"""
    def __init__(self, *args, **kwargs):
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
438
        super(ClubForm, self).__init__(*args, prefix=prefix, **kwargs)
439 440 441
        self.fields['surname'].label = _("Name")
        self.fields['school'].label = _("School")
        self.fields['comment'].label = _("Comment")
442
        self.fields['email'].label = _("Email address")
443 444 445
        if 'room' in self.fields:
            self.fields['room'].label = _("Room")
            self.fields['room'].empty_label = _("No room")
446 447
        self.fields['school'].empty_label = _("Select a school")
        self.fields['mailing'].label = _("Use a mailing list")
448 449 450 451 452 453 454 455 456

    class Meta:
        model = Club
        fields = [
            'surname',
            'pseudo',
            'school',
            'comment',
            'room',
Gabriel Detraz's avatar
Gabriel Detraz committed
457
            'email',
458
            'telephone',
459
            'email',
460
            'shell',
461
            'mailing'
462 463 464 465 466 467
        ]

    def clean_telephone(self):
        """Verifie que le tel est présent si 'option est validée
        dans preferences"""
        telephone = self.cleaned_data['telephone']
468
        if not telephone and OptionalUser.get_cached_value('is_tel_mandatory'):
469
            raise forms.ValidationError(
470
                _("A valid telephone number is required.")
471 472 473 474
            )
        return telephone


475
class ClubAdminandMembersForm(FormRevMixin, ModelForm):
476 477 478 479 480 481 482 483
    """Permet d'éditer la liste des membres et des administrateurs
    d'un club"""
    class Meta:
        model = Club
        fields = ['administrators', 'members']

    def __init__(self, *args, **kwargs):
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
484 485 486 487 488
        super(ClubAdminandMembersForm, self).__init__(
            *args,
            prefix=prefix,
            **kwargs
        )
489 490


491
class PasswordForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
492 493
    """ Formulaire de changement brut de mot de passe.
    Ne pas utiliser sans traitement"""
494 495 496 497
    class Meta:
        model = User
        fields = ['password', 'pwd_ntlm']

498
    def __init__(self, *args, **kwargs):
499
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
500 501
        super(PasswordForm, self).__init__(*args, prefix=prefix, **kwargs)

chirac's avatar
chirac committed
502

503
class ServiceUserForm(FormRevMixin, ModelForm):
504 505
    """Service user creation
    force initial password set"""
chirac's avatar
chirac committed
506
    password = forms.CharField(
507
        label=_("New password"),
chirac's avatar
chirac committed
508 509 510
        max_length=255,
        validators=[MinLengthValidator(8)],
        widget=forms.PasswordInput,
511
        required=True
chirac's avatar
chirac committed
512
    )
513 514 515

    class Meta:
        model = ServiceUser
516
        fields = ('pseudo', 'access_group','comment')
517

518
    def __init__(self, *args, **kwargs):
519
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
520 521
        super(ServiceUserForm, self).__init__(*args, prefix=prefix, **kwargs)

522
    def save(self, commit=True):
523
        """Password change"""
524 525 526 527 528
        user = super(ServiceUserForm, self).save(commit=False)
        if self.cleaned_data['password']:
            user.set_password(self.cleaned_data.get("password"))
        user.save()

chirac's avatar
chirac committed
529

530
class EditServiceUserForm(ServiceUserForm):
chirac's avatar
chirac committed
531 532
    """Formulaire d'edition de base d'un service user. Ne permet
    d'editer que son group d'acl et son commentaire"""
533 534 535 536 537 538 539 540
    password = forms.CharField(
        label=_("New password"),
        max_length=255,
        validators=[MinLengthValidator(8)],
        widget=forms.PasswordInput,
        required=False
    )

541
    class Meta(ServiceUserForm.Meta):
chirac's avatar
chirac committed
542 543
        fields = ['access_group', 'comment']

544

545
class StateForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
546
    """ Changement de l'état d'un user"""
547 548 549 550
    class Meta:
        model = User
        fields = ['state']

551
    def __init__(self, *args, **kwargs):
552
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
553 554
        super(StateForm, self).__init__(*args, prefix=prefix, **kwargs)

555 556 557 558 559 560
    def save(self, commit=True):
        user = super(StateForm, self).save(commit=False)
        if self.cleaned_data['state']:
            user.state=self.cleaned_data.get('state')
            user.state_sync()
        user.save()
561

Hugo LEVY-FALK's avatar
Hugo LEVY-FALK committed
562
class GroupForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
563 564 565 566 567 568 569 570 571
    """ Gestion des groupes d'un user"""
    groups = forms.ModelMultipleChoiceField(
        Group.objects.all(),
        widget=forms.CheckboxSelectMultiple,
        required=False
    )

    class Meta:
        model = User
572
        fields = ['is_superuser', 'groups']
573 574 575 576

    def __init__(self, *args, **kwargs):
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
        super(GroupForm, self).__init__(*args, prefix=prefix, **kwargs)
Hugo LEVY-FALK's avatar
Hugo LEVY-FALK committed
577
        if 'is_superuser' in self.fields:
578
            self.fields['is_superuser'].label = _("Superuser")
579 580


581
class SchoolForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
582
    """Edition, creation d'un école"""
583 584 585 586 587
    class Meta:
        model = School
        fields = ['name']

    def __init__(self, *args, **kwargs):
588
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
589
        super(SchoolForm, self).__init__(*args, prefix=prefix, **kwargs)
590
        self.fields['name'].label = _("School")
591

chirac's avatar
chirac committed
592

593
class ShellForm(FormRevMixin, ModelForm):
594 595 596 597 598 599 600 601
    """Edition, creation d'un école"""
    class Meta:
        model = ListShell
        fields = ['shell']

    def __init__(self, *args, **kwargs):
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
        super(ShellForm, self).__init__(*args, prefix=prefix, **kwargs)
602
        self.fields['shell'].label = _("Shell name")
603 604


605
class ListRightForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
606
    """Edition, d'un groupe , équivalent à un droit
607
    Ne permet pas d'editer le gid, car il sert de primary key"""
608
    permissions = forms.ModelMultipleChoiceField(
609
        Permission.objects.all().select_related('content_type'),
610 611 612 613
        widget=forms.CheckboxSelectMultiple,
        required=False
    )

614 615
    class Meta:
        model = ListRight
616
        fields = ('name', 'unix_name', 'critical', 'permissions', 'details')
617 618

    def __init__(self, *args, **kwargs):
619
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
620
        super(ListRightForm, self).__init__(*args, prefix=prefix, **kwargs)
621
        self.fields['unix_name'].label = _("Name of the group of rights")
622

chirac's avatar
chirac committed
623

624
class NewListRightForm(ListRightForm):
chirac's avatar
chirac committed
625
    """Ajout d'un groupe/list de droit """
626
    class Meta(ListRightForm.Meta):
627 628
        fields = ('name', 'unix_name', 'gid', 'critical', 'permissions',
                  'details')
629 630 631

    def __init__(self, *args, **kwargs):
        super(NewListRightForm, self).__init__(*args, **kwargs)
632 633
        self.fields['gid'].label = _("GID. Warning: this field must not be"
                                     " edited after creation.")
chirac's avatar
chirac committed
634

635

636
class DelListRightForm(Form):
chirac's avatar
chirac committed
637 638
    """Suppression d'un ou plusieurs groupes"""
    listrights = forms.ModelMultipleChoiceField(
639
        queryset=ListRight.objects.none(),
640
        label=_("Current groups of rights"),
chirac's avatar
chirac committed
641 642 643
        widget=forms.CheckboxSelectMultiple
    )

644 645 646 647
    def __init__(self, *args, **kwargs):
        instances = kwargs.pop('instances', None)
        super(DelListRightForm, self).__init__(*args, **kwargs)
        if instances:
648
            self.fields['listrights'].queryset = instances
649
        else:
650
            self.fields['listrights'].queryset = ListRight.objects.all()
651

652

653
class DelSchoolForm(Form):
chirac's avatar
chirac committed
654 655
    """Suppression d'une ou plusieurs écoles"""
    schools = forms.ModelMultipleChoiceField(
656
        queryset=School.objects.none(),
657
        label=_("Current schools"),
chirac's avatar
chirac committed
658 659 660
        widget=forms.CheckboxSelectMultiple
    )

661
    def __init__(self, *args, **kwargs):
662
        instances = kwargs.pop('instances', None)
663
        super(DelSchoolForm, self).__init__(*args, **kwargs)
664 665 666 667
        if instances:
            self.fields['schools'].queryset = instances
        else:
            self.fields['schools'].queryset = School.objects.all()
668

669

670
class BanForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
671
    """Creation, edition d'un objet bannissement"""
672
    def __init__(self, *args, **kwargs):
673
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
674
        super(BanForm, self).__init__(*args, prefix=prefix, **kwargs)
675
        self.fields['date_end'].label = _("End date")
676
        self.fields['date_end'].localize = False
677 678 679 680

    class Meta:
        model = Ban
        exclude = ['user']
681
        widgets = {'date_end':DateTimePicker}
682 683


684
class WhitelistForm(FormRevMixin, ModelForm):
chirac's avatar
chirac committed
685
    """Creation, edition d'un objet whitelist"""
686
    def __init__(self, *args, **kwargs):
687
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
688
        super(WhitelistForm, self).__init__(*args, prefix=prefix, **kwargs)
689
        self.fields['date_end'].label = _("End date")
root's avatar
root committed
690
        self.fields['date_end'].localize = False
691 692 693 694

    class Meta:
        model = Whitelist
        exclude = ['user']
root's avatar
root committed
695
        widgets = {'date_end':DateTimePicker}
696 697


698 699
class EMailAddressForm(FormRevMixin, ModelForm):
    """Create and edit a local email address"""
700 701
    def __init__(self, *args, **kwargs):
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
702
        super(EMailAddressForm, self).__init__(*args, prefix=prefix, **kwargs)
703 704
        self.fields['local_part'].label = _("Local part of the email address")
        self.fields['local_part'].help_text = _("Can't contain @")
705

706 707
    def clean_local_part(self):
        return self.cleaned_data.get('local_part').lower()
708 709

    class Meta:
710
        model = EMailAddress
711
        exclude = ['user']
712

713 714 715

class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
    """Edit email-related settings"""
716 717
    def __init__(self, *args, **kwargs):
        prefix = kwargs.pop('prefix', self.Meta.model.__name__)
718
        super(EmailSettingsForm, self).__init__(*args, prefix=prefix, **kwargs)
719
        self.fields['email'].label = _("Main email address")
720
        if 'local_email_redirect' in self.fields:
721
            self.fields['local_email_redirect'].label = _("Redirect local emails")
722
        if 'local_email_enabled' in self.fields:
723
            self.fields['local_email_enabled'].label = _("Use local emails")
724

725 726 727 728
    def clean_email(self):
        if not OptionalUser.objects.first().local_email_domain in self.cleaned_data.get('email'):
            return self.cleaned_data.get('email').lower()
        else:
729 730 731
            raise forms.ValidationError(
                    _("You can't use a {} address.").format(
                        OptionalUser.objects.first().local_email_domain))
732

733
    class Meta:
734
        model = User
735
        fields = ['email','local_email_enabled', 'local_email_redirect']
736

737 738 739 740 741 742 743 744 745 746 747 748 749 750 751

class InitialRegisterForm(forms.Form):
    register_room = forms.BooleanField(required=False)
    register_machine = forms.BooleanField(required=False)

    def __init__(self, *args, **kwargs):
        switch_ip = kwargs.pop('switch_ip')
        switch_port = kwargs.pop('switch_port')
        client_mac = kwargs.pop('client_mac')
        self.user = kwargs.pop('user')
        if switch_ip and switch_port:
            # Looking for a port
            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 port:
752
                if port.get_port_profile.radius_type != 'NO' and port.get_port_profile.radius_mode == 'STRICT' and hasattr(port, 'room'):
753 754 755 756 757 758 759 760 761 762
                    # Requesting user is not in this room ?
                    if self.user.room != port.room:
                        self.new_room = port.room
        if client_mac and switch_ip:
            # If this interface doesn't already exists
            if not Interface.objects.filter(mac_address=client_mac):
                self.mac_address = client_mac
                self.nas_type = Nas.objects.filter(nas_type__interface__ipv4__ipv4=switch_ip).first()
        super(InitialRegisterForm, self).__init__(*args, **kwargs)
        if hasattr(self, 'new_room'):
763
            self.fields['register_room'].label = _("This room is my room")
764 765 766
        else:
            self.fields.pop('register_room')
        if hasattr(self, 'mac_address'):
767
            self.fields['register_machine'].label = _("This new connected device is mine")
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786
        else:
            self.fields.pop('register_machine')

    def clean_register_room(self):
        if self.cleaned_data['register_room']:
            if self.user.is_class_adherent:
                remove_user_room(self.new_room)
                user = self.user.adherent
                user.room = self.new_room
                user.save()
            if self.user.is_class_club:
                user = self.user.club
                user.room = self.new_room
                user.save()

    def clean_register_machine(self):
        if self.cleaned_data['register_machine']:
            if self.mac_address and self.nas_type:
                self.user.autoregister_machine(self.mac_address, self.nas_type)