Clean up of users app

This commit is contained in:
Alexandre Iooss 2019-08-08 15:35:25 +02:00
parent 4049582f1e
commit ef0bd78af5
No known key found for this signature in database
GPG Key ID: 6C79278F3FCDCC02
12 changed files with 75 additions and 290 deletions

View File

@ -358,4 +358,4 @@ def history(request, object, id):
except EmptyPage: except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results. # If page is out of range (e.g. 9999), deliver last page of results.
reversions = paginator.page(paginator.num_pages) reversions = paginator.page(paginator.num_pages)
return render(request, 'med/history.html', {'reversions': reversions, 'object': object_instance}) return render(request, 'media/history.html', {'reversions': reversions, 'object': object_instance})

View File

@ -1,22 +0,0 @@
# 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.

View File

@ -7,7 +7,7 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from .models import User, Right, Adhesion, ListRight, Clef, Request from .models import Adhesion, Clef, ListRight, Request, Right, User
class RequestAdmin(admin.ModelAdmin): class RequestAdmin(admin.ModelAdmin):
@ -44,7 +44,8 @@ class IsAdherentFilter(admin.SimpleListFilter):
value = self.value() value = self.value()
if value == 'Yes': if value == 'Yes':
# Get current membership year and list all members # Get current membership year and list all members
last_adh_year = Adhesion.objects.all().order_by('annee_debut').reverse().first() last_adh_year = Adhesion.objects.all().order_by('annee_debut')\
.reverse().first()
return last_adh_year.adherent return last_adh_year.adherent
return queryset return queryset
@ -69,7 +70,8 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
""" """
Get current membership year and check if user is there Get current membership year and check if user is there
""" """
last_adh_year = Adhesion.objects.all().order_by('annee_debut').reverse().first() last_adh_year = Adhesion.objects.all().order_by('annee_debut')\
.reverse().first()
return last_adh_year and obj in last_adh_year.adherent.all() return last_adh_year and obj in last_adh_year.adherent.all()
is_adherent.boolean = True is_adherent.boolean = True

View File

@ -1,37 +0,0 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import ipaddress
from django.shortcuts import redirect
from med.settings import AUTHORIZED_IP_RANGE, AUTHORIZED_IP6_RANGE
def user_is_in_campus(function):
def wrap(request, *args, **kwargs):
if not request.user.is_authenticated:
remote_ip = get_ip(request)
if not ipaddress.ip_address(remote_ip) in ipaddress.ip_network(
AUTHORIZED_IP_RANGE) and not ipaddress.ip_address(remote_ip) in ipaddress.ip_network(
AUTHORIZED_IP6_RANGE):
return redirect("/")
return function(request, *args, **kwargs)
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap
def get_ip(request):
"""Returns the IP of the request, accounting for the possibility of being
behind a proxy.
"""
ip = request.META.get("HTTP_X_FORWARDED_FOR", None)
if ip:
# X_FORWARDED_FOR returns client1, proxy1, proxy2,...
ip = ip.split(", ")[0]
else:
ip = request.META.get("REMOTE_ADDR", "")
return ip

View File

@ -3,18 +3,25 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django import forms from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.validators import MinLengthValidator from django.core.validators import MinLengthValidator
from django.forms import ModelForm, Form from django.forms import ModelForm
from .models import Adhesion, Clef, ListRight, Right, User from .models import User
class PassForm(forms.Form): class PassForm(forms.Form):
passwd1 = forms.CharField(label=u'Nouveau mot de passe', max_length=255, validators=[MinLengthValidator(8)], passwd1 = forms.CharField(
widget=forms.PasswordInput) label=u'Nouveau mot de passe',
passwd2 = forms.CharField(label=u'Saisir à nouveau le mot de passe', max_length=255, max_length=255,
validators=[MinLengthValidator(8)], widget=forms.PasswordInput) validators=[MinLengthValidator(8)],
widget=forms.PasswordInput,
)
passwd2 = forms.CharField(
label=u'Saisir à nouveau le mot de passe',
max_length=255,
validators=[MinLengthValidator(8)],
widget=forms.PasswordInput
)
class BaseInfoForm(ModelForm): class BaseInfoForm(ModelForm):
@ -41,36 +48,3 @@ class InfoForm(BaseInfoForm):
'address', 'address',
'maxemprunt', 'maxemprunt',
] ]
class PasswordForm(ModelForm):
class Meta:
model = User
fields = ['password']
class AdhesionForm(ModelForm):
adherent = forms.ModelMultipleChoiceField(User.objects.all(), widget=forms.CheckboxSelectMultiple, required=False)
class Meta:
model = Adhesion
fields = '__all__'
class RightForm(ModelForm):
def __init__(self, *args, **kwargs):
super(RightForm, self).__init__(*args, **kwargs)
self.fields['right'].label = 'Droit'
self.fields['right'].empty_label = "Choisir un nouveau droit"
class Meta:
model = Right
fields = ['right']
class DelRightForm(Form):
rights = forms.ModelMultipleChoiceField(queryset=Right.objects.all(), widget=forms.CheckboxSelectMultiple)
def __init__(self, right, *args, **kwargs):
super(DelRightForm, self).__init__(*args, **kwargs)
self.fields['rights'].queryset = Right.objects.filter(right=right)

View File

@ -28,7 +28,8 @@ class User(AbstractUser):
) )
maxemprunt = models.IntegerField( maxemprunt = models.IntegerField(
verbose_name=_('maximum borrowed'), verbose_name=_('maximum borrowed'),
help_text=_('Maximal amount of simultaneous borrowed item authorized.'), help_text=_('Maximal amount of simultaneous borrowed item '
'authorized.'),
default=MAX_EMPRUNT, default=MAX_EMPRUNT,
) )
comment = models.CharField( comment = models.CharField(
@ -50,7 +51,8 @@ class User(AbstractUser):
@property @property
def is_adherent(self): def is_adherent(self):
last_adh_year = Adhesion.objects.all().order_by('annee_debut').reverse().first() last_adh_year = Adhesion.objects.all().order_by(
'annee_debut').reverse().first()
return last_adh_year and self in last_adh_year.adherent.all() return last_adh_year and self in last_adh_year.adherent.all()
@ -69,8 +71,8 @@ class Request(models.Model):
def save(self): def save(self):
if not self.expires_at: if not self.expires_at:
self.expires_at = timezone.now() \ self.expires_at = timezone.now()
+ datetime.timedelta(hours=REQ_EXPIRE_HRS) self.expires_at += datetime.timedelta(hours=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().save() super().save()
@ -95,7 +97,11 @@ class ListRight(models.Model):
PRETTY_NAME = "Liste des droits existants" PRETTY_NAME = "Liste des droits existants"
listright = models.CharField(max_length=255, unique=True) listright = models.CharField(max_length=255, unique=True)
details = models.CharField(help_text="Description", max_length=255, blank=True) details = models.CharField(
help_text="Description",
max_length=255,
blank=True,
)
def __str__(self): def __str__(self):
return self.listright return self.listright
@ -103,7 +109,8 @@ class ListRight(models.Model):
class Clef(models.Model): class Clef(models.Model):
nom = models.CharField(max_length=255, unique=True) nom = models.CharField(max_length=255, unique=True)
proprio = models.ForeignKey('User', on_delete=models.PROTECT, blank=True, null=True) proprio = models.ForeignKey('User', on_delete=models.PROTECT, blank=True,
null=True)
commentaire = models.CharField(max_length=255, null=True, blank=True) commentaire = models.CharField(max_length=255, null=True, blank=True)

View File

@ -8,7 +8,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
<th>Clef</th> <th>Clef</th>
<th>Propriétaire</th> <th>Propriétaire</th>
<th>Commentaire</th> <th>Commentaire</th>
<th></th>
</tr> </tr>
</thead> </thead>
{% for clef in clef_list %} {% for clef in clef_list %}
@ -16,9 +15,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
<td>{{ clef.nom }}</td> <td>{{ clef.nom }}</td>
<td>{{ clef.proprio }}</td> <td>{{ clef.proprio }}</td>
<td>{{ clef.commentaire }}</td> <td>{{ clef.commentaire }}</td>
<td class="text-right">
{% include 'buttons/history.html' with href='users:history' name='clef' id=clef.id %}
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@ -1,58 +0,0 @@
{% extends "users/sidebar.html" %}
{% comment %}
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.
{% endcomment %}
{% load bootstrap3 %}
{% block title %}Création et modification d'utilisateur{% endblock %}
{% block content %}
<h1>Gestion des droits</h1>
<form class="form" method="post">
{% csrf_token %}
<table class="table table-striped">
<thead>
<tr>
{% for key, values in userform.items %}
<th>{{ key }}</th>
{% endfor %}
</tr>
</thead>
<tr>
{% for key, values in userform.items %}
{% bootstrap_form_errors values %}
<th>{{ values.rights }}</th>
{% endfor %}
</tr>
</table>
{% bootstrap_button "Modifier" button_type="submit" icon="star" %}
</form>
<br />
<br />
<br />
{% endblock %}

View File

@ -1,40 +0,0 @@
{% extends "media/sidebar.html" %}
{% comment %}
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.
{% endcomment %}
{% load bootstrap3 %}
{% block title %}Création et modification de media{% endblock %}
{% block content %}
<form class="form" method="post">
{% csrf_token %}
<h4>Attention, voulez-vous vraiment supprimer cet objet {{ objet_name }} ( {{ objet }} ) ?</h4>
{% bootstrap_button "Confirmer" button_type="submit" icon="trash" %}
</form>
<br />
<br />
<br />
{% endblock %}

View File

@ -9,16 +9,15 @@ from . import views
app_name = 'users' app_name = 'users'
urlpatterns = [ urlpatterns = [
url(r'^new_user/$', views.new_user, name='new-user'), url(r'^new_user/$', views.new_user, name='new-user'),
url(r'^edit_info/(?P<userid>[0-9]+)$', views.edit_info, name='edit-info'), url(r'^edit_info/(?P<userid>[0-9]+)$', views.edit_info,
url(r'^password/(?P<userid>[0-9]+)$', views.password, name='password'), name='edit-info'),
url(r'^password/(?P<userid>[0-9]+)$', views.password,
name='password'),
url(r'^profil/(?P<userid>[0-9]+)$', views.profil, name='profil'), url(r'^profil/(?P<userid>[0-9]+)$', views.profil, name='profil'),
url(r'^adherer/(?P<userid>[0-9]+)$', views.adherer, name='adherer'), url(r'^adherer/(?P<userid>[0-9]+)$', views.adherer, name='adherer'),
url(r'^mon_profil/$', views.mon_profil, name='mon-profil'), url(r'^mon_profil/$', views.mon_profil, name='mon-profil'),
url(r'^index_clef/$', views.index_clef, name='index-clef'), url(r'^index_clef/$', views.index_clef, name='index-clef'),
url(r'^history/(?P<object>clef)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^history/(?P<object>adhesion)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^process/(?P<token>[a-z0-9]{32})/$', views.process, name='process'), url(r'^process/(?P<token>[a-z0-9]{32})/$', views.process, name='process'),
url(r'^history/(?P<object>user)/(?P<id>[0-9]+)$', views.history, name='history'),
url(r'^$', views.index, name='index'), url(r'^$', views.index, name='index'),
url(r'^index_ajour/$', views.index_ajour, name='index-ajour'), url(r'^index_ajour/$', views.index_ajour, name='index-ajour'),
] ]

View File

@ -5,24 +5,21 @@
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.core.mail import send_mail from django.core.mail import send_mail
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db import IntegrityError
from django.db import transaction from django.db import transaction
from django.shortcuts import get_object_or_404, render, redirect from django.shortcuts import get_object_or_404, redirect, render
from django.template import loader from django.template import loader
from django.template.context_processors import csrf from django.template.context_processors import csrf
from django.utils import timezone from django.utils import timezone
from reversion import revisions as reversion from reversion import revisions as reversion
from reversion.models import Version
from med.settings import REQ_EXPIRE_STR, EMAIL_FROM, ASSO_NAME, ASSO_EMAIL, SITE_NAME, PAGINATION_NUMBER from med.settings import ASSO_EMAIL, ASSO_NAME, EMAIL_FROM, \
PAGINATION_NUMBER, REQ_EXPIRE_STR, SITE_NAME
from media.models import Emprunt from media.models import Emprunt
from users.decorators import user_is_in_campus from users.forms import BaseInfoForm, InfoForm
from users.forms import InfoForm, BaseInfoForm, AdhesionForm
from users.forms import PassForm from users.forms import PassForm
from users.forms import RightForm, DelRightForm from users.models import Adhesion, Clef, Request, Right, User
from users.models import User, Request, ListRight, Right, Clef, Adhesion
def form(ctx, template, request): def form(ctx, template, request):
@ -48,7 +45,9 @@ def password_change_action(u_form, user, request, req=False):
def reset_passwd_mail(req, request): def reset_passwd_mail(req, request):
""" Prend en argument un request, envoie un mail de réinitialisation de mot de pass """ """
Envoie un mail de réinitialisation de mot de passe
"""
t = loader.get_template('users/email_passwd_request') t = loader.get_template('users/email_passwd_request')
c = { c = {
'name': str(req.user.first_name) + ' ' + str(req.user.last_name), 'name': str(req.user.first_name) + ' ' + str(req.user.last_name),
@ -67,7 +66,9 @@ def reset_passwd_mail(req, request):
@login_required @login_required
@permission_required('bureau') @permission_required('bureau')
def new_user(request): def new_user(request):
""" Vue de création d'un nouvel utilisateur, envoie un mail pour le mot de passe""" """
Vue de création d'un nouvel utilisateur
"""
user = BaseInfoForm(request.POST or None) user = BaseInfoForm(request.POST or None)
if user.is_valid(): if user.is_valid():
user = user.save(commit=False) user = user.save(commit=False)
@ -80,21 +81,29 @@ def new_user(request):
req.save() req.save()
reset_passwd_mail(req, request) reset_passwd_mail(req, request)
messages.success(request, messages.success(request,
"L'utilisateur %s a été crée, un mail pour l'initialisation du mot de passe a été envoyé" % user.username) "L'utilisateur %s a été crée, un mail pour "
"l'initialisation du mot de passe a été "
"envoyé" % user.username)
return redirect("/users/profil/" + str(user.id)) return redirect("/users/profil/" + str(user.id))
return form({'userform': user}, 'users/user.html', request) return form({'userform': user}, 'users/user.html', request)
@login_required @login_required
def edit_info(request, userid): def edit_info(request, userid):
""" Edite un utilisateur à partir de son id, si l'id est différent de request.user, vérifie la possession du droit admin """ """
Edite un utilisateur à partir de son id,
si l'id est différent de request.user,
vérifie la possession du droit admin
"""
try: try:
user = User.objects.get(pk=userid) user = User.objects.get(pk=userid)
except User.DoesNotExist: except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant") messages.error(request, "Utilisateur inexistant")
return redirect("/users/") return redirect("/users/")
if not request.user.has_perms(('bureau',)) and user != request.user: if not request.user.has_perms(('bureau',)) and user != request.user:
messages.error(request, "Vous ne pouvez pas modifier un autre user que vous sans droit admin") messages.error(request,
"Vous ne pouvez pas modifier un autre user que vous "
"sans droit admin")
return redirect("/users/profil/" + str(request.user.id)) return redirect("/users/profil/" + str(request.user.id))
if not request.user.has_perms(('bureau',)): if not request.user.has_perms(('bureau',)):
user = BaseInfoForm(request.POST or None, instance=user) user = BaseInfoForm(request.POST or None, instance=user)
@ -104,7 +113,8 @@ def edit_info(request, userid):
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
user.save() user.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in user.changed_data)) reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
field for field in user.changed_data))
messages.success(request, "L'user a bien été modifié") messages.success(request, "L'user a bien été modifié")
return redirect("/users/profil/" + userid) return redirect("/users/profil/" + userid)
return form({'userform': user}, 'users/user.html', request) return form({'userform': user}, 'users/user.html', request)
@ -121,7 +131,9 @@ def password(request, userid):
messages.error(request, "Utilisateur inexistant") messages.error(request, "Utilisateur inexistant")
return redirect("/users/") return redirect("/users/")
if not request.user.has_perms(('bureau',)) and user != request.user: if not request.user.has_perms(('bureau',)) and user != request.user:
messages.error(request, "Vous ne pouvez pas modifier un autre user que vous sans droit admin") messages.error(request,
"Vous ne pouvez pas modifier un autre user que vous "
"sans droit admin")
return redirect("/users/profil/" + str(request.user.id)) return redirect("/users/profil/" + str(request.user.id))
u_form = PassForm(request.POST or None) u_form = PassForm(request.POST or None)
if u_form.is_valid(): if u_form.is_valid():
@ -129,7 +141,8 @@ def password(request, userid):
return form({'userform': u_form}, 'users/user.html', request) return form({'userform': u_form}, 'users/user.html', request)
@user_is_in_campus @login_required
@permission_required('perm')
def index_clef(request): def index_clef(request):
clef_list = Clef.objects.all().order_by('nom') clef_list = Clef.objects.all().order_by('nom')
return render(request, 'users/index_clef.html', {'clef_list': clef_list}) return render(request, 'users/index_clef.html', {'clef_list': clef_list})
@ -157,7 +170,8 @@ def index(request):
@permission_required('perm') @permission_required('perm')
def index_ajour(request): def index_ajour(request):
""" Affiche l'ensemble des users, need droit admin """ """ Affiche l'ensemble des users, need droit admin """
users_list = Adhesion.objects.all().order_by('annee_debut').reverse().first().adherent.all().order_by('first_name') users_list = Adhesion.objects.all().order_by(
'annee_debut').reverse().first().adherent.all().order_by('first_name')
paginator = Paginator(users_list, PAGINATION_NUMBER) paginator = Paginator(users_list, PAGINATION_NUMBER)
page = request.GET.get('page') page = request.GET.get('page')
try: try:
@ -171,58 +185,6 @@ def index_ajour(request):
return render(request, 'users/index.html', {'users_list': users_list}) return render(request, 'users/index.html', {'users_list': users_list})
@user_is_in_campus
def history(request, object, id):
""" Affichage de l'historique : (acl, argument)
user : self, userid"""
if object == 'clef':
try:
object_instance = Clef.objects.get(pk=id)
except Clef.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
elif not request.user.is_authenticated:
messages.error(request, "Permission denied")
return redirect("/users/")
if object == 'user':
try:
object_instance = User.objects.get(pk=id)
except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
if not request.user.has_perms(('perm',)) and object_instance != request.user:
messages.error(request,
"Vous ne pouvez pas afficher l'historique d'un autre user que vous sans droit admin")
return redirect("/users/profil/" + str(request.user.id))
elif object == 'clef':
try:
object_instance = Clef.objects.get(pk=id)
except Clef.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
elif object == 'adhesion':
try:
object_instance = Adhesion.objects.get(pk=id)
except Adhesion.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
else:
messages.error(request, "Objet inconnu")
return redirect("/users/")
reversions = Version.objects.get_for_object(object_instance)
paginator = Paginator(reversions, PAGINATION_NUMBER)
page = request.GET.get('page')
try:
reversions = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
reversions = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
reversions = paginator.page(paginator.num_pages)
return render(request, 'med/history.html', {'reversions': reversions, 'object': object_instance})
@login_required @login_required
def mon_profil(request): def mon_profil(request):
return redirect("/users/profil/" + str(request.user.id)) return redirect("/users/profil/" + str(request.user.id))
@ -236,7 +198,9 @@ def profil(request, userid):
messages.error(request, "Utilisateur inexistant") messages.error(request, "Utilisateur inexistant")
return redirect("/users/") return redirect("/users/")
if not request.user.has_perms(('perm',)) and users != request.user: if not request.user.has_perms(('perm',)) and users != request.user:
messages.error(request, "Vous ne pouvez pas afficher un autre user que vous sans droit perm") messages.error(request,
"Vous ne pouvez pas afficher un autre user "
"que vous sans droit perm")
return redirect("/users/profil/" + str(request.user.id)) return redirect("/users/profil/" + str(request.user.id))
emprunts_list = Emprunt.objects.filter(user=users) emprunts_list = Emprunt.objects.filter(user=users)
list_droits = Right.objects.filter(user=users) list_droits = Right.objects.filter(user=users)
@ -259,11 +223,11 @@ def adherer(request, userid):
except User.DoesNotExist: except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant") messages.error(request, "Utilisateur inexistant")
return redirect("/users/") return redirect("/users/")
adh_annee = Adhesion.objects.all().order_by('annee_debut').reverse().first() adh_year = Adhesion.objects.all().order_by('annee_debut').reverse().first()
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():
reversion.set_user(request.user) reversion.set_user(request.user)
adh_annee.adherent.add(users) adh_year.adherent.add(users)
adh_annee.save() adh_year.save()
reversion.set_comment("Adhesion de %s" % users) reversion.set_comment("Adhesion de %s" % users)
messages.success(request, "Adhesion effectuee") messages.success(request, "Adhesion effectuee")
return redirect("/users/profil/" + userid) return redirect("/users/profil/" + userid)