8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-25 00:13:45 +00:00

Merge branch 'asso_users' into 'master'

Asso users

See merge request federez/re2o!41
This commit is contained in:
Gabriel Detraz 2017-11-24 19:43:26 +01:00
commit 4ac51db31a
11 changed files with 249 additions and 39 deletions

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-11-21 04:42
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0023_auto_20171015_2033'),
]
operations = [
migrations.AddField(
model_name='optionaluser',
name='all_can_create',
field=models.BooleanField(default=False, help_text="Tous les users peuvent en créer d'autres"),
),
]

View file

@ -42,6 +42,10 @@ class OptionalUser(models.Model):
default=0
)
gpg_fingerprint = models.BooleanField(default=True)
all_can_create = models.BooleanField(
default=False,
help_text="Tous les users peuvent en créer d'autres",
)
def clean(self):
"""Creation du mode de paiement par solde"""

View file

@ -52,6 +52,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td>{{ useroptions.solde_negatif }}</td>
{% endif %}
</tr>
<tr>
<th>Creations d'users par tous</th>
<td>{{ useroptions.all_can_create }}</td>
</tr>
</table>
<h4>Préférences machines</h4>
{% if is_bureau %}

View file

@ -379,6 +379,18 @@ class FullClubForm(ClubForm):
]
class ClubAdminandMembersForm(ModelForm):
"""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__)
super(ClubAdminandMembersForm, self).__init__(*args, prefix=prefix, **kwargs)
class PasswordForm(ModelForm):
""" Formulaire de changement brut de mot de passe.
Ne pas utiliser sans traitement"""

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-11-20 02:17
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0059_auto_20171025_1854'),
]
operations = [
migrations.AddField(
model_name='club',
name='administrators',
field=models.ManyToManyField(blank=True, related_name='club_administrator', to='users.Adherent'),
),
migrations.AddField(
model_name='club',
name='members',
field=models.ManyToManyField(blank=True, related_name='club_members', to='users.Adherent'),
),
]

View file

@ -60,7 +60,10 @@ 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 AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import (
AbstractBaseUser,
BaseUserManager
)
from django.core.validators import RegexValidator
from reversion import revisions as reversion
@ -755,6 +758,28 @@ class User(AbstractBaseUser):
num += 1
return composed_pseudo(num)
def can_create(user):
options, _created = OptionalUser.objects.get_or_create()
if options.all_can_create:
return True
else:
return user.has_perms(('cableur',))
def can_edit(self, user):
if self.is_class_club and user.is_class_adherent:
return self == user or user.has_perms(('cableur',)) or\
user.adherent in self.club.administrators.all()
else:
return self == user or user.has_perms(('cableur',))
def can_view(self, user):
if self.is_class_club and user.is_class_adherent:
return self == user or user.has_perms(('cableur',)) or\
user.adherent in self.club.administrators.all() or\
user.adherent in self.club.members.all()
else:
return self == user or user.has_perms(('cableur',))
def __str__(self):
return self.pseudo
@ -771,6 +796,7 @@ class Adherent(User):
pass
class Club(User):
PRETTY_NAME = "Clubs"
room = models.ForeignKey(
@ -779,6 +805,17 @@ class Club(User):
blank=True,
null=True
)
administrators = models.ManyToManyField(
blank=True,
to='users.Adherent',
related_name='club_administrator'
)
members = models.ManyToManyField(
blank=True,
to='users.Adherent',
related_name='club_members'
)
pass

View file

@ -141,21 +141,61 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td>{{ user.shell }}</td>
{% endif %}
</table>
<h2>Machines :</h2>
{% if user.is_class_club %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-club-admin-members' user.club.id %}">
<i class="glyphicon glyphicon-lock"></i>
Gérer admin et membres
</a>
<h3>Administrateurs du club</h3>
<table class="table table-striped">
<thead>
<tr>
<th>Nom</th>
<th>Prenom</th>
<th>Pseudo</th>
</tr>
</thead>
{% for admin in user.club.administrators.all %}
<tr>
<td>{{ admin.surname }}</td>
<td>{{ admin.name }}</td>
<td>{{ admin.pseudo }}</td>
</tr>
{% endfor %}
</table>
<h3>Membres</h3>
<table class="table table-striped">
<thead>
<tr>
<th>Nom</th>
<th>Prenom</th>
<th>Pseudo</th>
</tr>
</thead>
{% for admin in user.club.members.all %}
<tr>
<td>{{ admin.surname }}</td>
<td>{{ admin.name }}</td>
<td>{{ admin.pseudo }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
<h2>Machines</h2>
<h4><a class="btn btn-primary btn-sm" role="button" href="{% url 'machines:new-machine' user.id %}"><i class="glyphicon glyphicon-phone"></i> Ajouter une machine</a></h4>
{% if machines_list %}
{% include "machines/aff_machines.html" with machines_list=machines_list %}
{% else %}
<p>Aucune machine</p>
{% endif %}
<h2>Cotisations :</h2>
<h2>Cotisations</h2>
{% if is_cableur %}<h4><a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:new-facture' user.id %}"><i class="glyphicon glyphicon-piggy-bank"></i> Ajouter une cotisation</a> {% if user_solde %}<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:credit-solde' user.id %}"><i class="glyphicon glyphicon-piggy-bank"></i> Modifier le solde</a>{% endif%}</h4>{% endif%}
{% if facture_list %}
{% include "cotisations/aff_cotisations.html" with facture_list=facture_list %}
{% else %}
<p>Aucune facture</p>
{% endif %}
<h2>Bannissements :</h2>
<h2>Bannissements</h2>
{% if is_bofh %}<h4><a class="btn btn-primary btn-sm" role="button" href="{% url 'users:add-ban' user.id %}"><i class="glyphicon glyphicon-pushpin"></i> Ajouter un bannissement</a></h4>{% endif %}
{% if ban_list %}
{% include "users/aff_bans.html" with ban_list=ban_list %}

View file

@ -25,22 +25,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block sidebar %}
{% if is_cableur %}
<a class="list-group-item list-group-item-success" href="{% url "users:new-user" %}">
<i class="glyphicon glyphicon-plus"></i>
Créer un adhérent
</a>
{% if is_cableur %}
<a class="list-group-item list-group-item-success" href="{% url "users:new-club" %}">
<i class="glyphicon glyphicon-plus"></i>
Créer un club/association
</a>
<a class="list-group-item list-group-item-info" href="{% url "users:index" %}">
<i class="glyphicon glyphicon-list"></i>
Adherents
{% endif %}
<a class="list-group-item list-group-item-success" href="{% url "users:new-user" %}">
<i class="glyphicon glyphicon-plus"></i>
Créer un adhérent
</a>
<a class="list-group-item list-group-item-info" href="{% url "users:index-clubs" %}">
<i class="glyphicon glyphicon-list"></i>
Clubs
Clubs et assos
</a>
{% if is_cableur %}
<a class="list-group-item list-group-item-info" href="{% url "users:index" %}">
<i class="glyphicon glyphicon-list"></i>
Adherents
</a>
<a class="list-group-item list-group-item-info" href="{% url "users:index-ban" %}">
<i class="glyphicon glyphicon-list"></i>

View file

@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<form class="form" method="post">
{% csrf_token %}
{% massive_bootstrap_form userform 'room,school' %}
{% massive_bootstrap_form userform 'room,school,administrators,members' %}
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
</form>
<br />

View file

@ -33,6 +33,11 @@ urlpatterns = [
url(r'^new_user/$', views.new_user, name='new-user'),
url(r'^new_club/$', views.new_club, name='new-club'),
url(r'^edit_info/(?P<userid>[0-9]+)$', views.edit_info, name='edit-info'),
url(
r'^edit_club_admin_members/(?P<clubid>[0-9]+)$',
views.edit_club_admin_members,
name='edit-club-admin-members'
),
url(r'^state/(?P<userid>[0-9]+)$', views.state, name='state'),
url(r'^password/(?P<userid>[0-9]+)$', views.password, name='password'),
url(r'^new_serviceuser/$', views.new_serviceuser, name='new-serviceuser'),

View file

@ -40,7 +40,7 @@ from django.shortcuts import get_object_or_404, render, redirect
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.db.models import ProtectedError
from django.db.models import ProtectedError, Q
from django.db import IntegrityError
from django.utils import timezone
from django.db import transaction
@ -53,14 +53,40 @@ from rest_framework.renderers import JSONRenderer
from reversion.models import Version
from reversion import revisions as reversion
from users.serializers import MailSerializer
from users.models import User, Right, Ban, Whitelist, School, ListRight
from users.models import Request, ServiceUser, Adherent, Club
from users.forms import DelRightForm, BanForm, WhitelistForm, DelSchoolForm
from users.forms import DelListRightForm, NewListRightForm, FullAdherentForm
from users.forms import StateForm, FullClubForm
from users.forms import RightForm, SchoolForm, EditServiceUserForm
from users.forms import ServiceUserForm, ListRightForm, AdherentForm, ClubForm
from users.forms import MassArchiveForm, PassForm, ResetPasswordForm
from users.models import (
User,
Right,
Ban,
Whitelist,
School,
ListRight,
Request,
ServiceUser,
Adherent,
Club
)
from users.forms import (
DelRightForm,
BanForm,
WhitelistForm,
DelSchoolForm,
DelListRightForm,
NewListRightForm,
FullAdherentForm,
StateForm,
FullClubForm,
RightForm,
SchoolForm,
EditServiceUserForm,
ServiceUserForm,
ListRightForm,
AdherentForm,
ClubForm,
MassArchiveForm,
PassForm,
ResetPasswordForm,
ClubAdminandMembersForm
)
from cotisations.models import Facture
from machines.models import Machine
from preferences.models import OptionalUser, GeneralOption
@ -85,10 +111,15 @@ def password_change_action(u_form, user, request, req=False):
@login_required
@permission_required('cableur')
def new_user(request):
""" Vue de création d'un nouvel utilisateur,
envoie un mail pour le mot de passe"""
if not User.can_create(request.user):
messages.error(request, "Vous ne pouvez pas accéder à ce menu")
return redirect(reverse(
'users:profil',
kwargs={'userid':str(request.user.id)}
))
user = AdherentForm(request.POST or None)
if user.is_valid():
user = user.save(commit=False)
@ -128,6 +159,37 @@ def new_club(request):
return form({'userform': club}, 'users/user.html', request)
@login_required
def edit_club_admin_members(request, clubid):
"""Vue d'edition de la liste des users administrateurs et
membres d'un club"""
try:
club_instance = Club.objects.get(pk=clubid)
except Club.DoesNotExist:
messages.error(request, "Club inexistant")
return redirect(reverse('users:index'))
if not club_instance.can_edit(request.user):
messages.error(request, "Vous ne pouvez pas accéder à ce menu")
return redirect(reverse(
'users:profil',
kwargs={'userid':str(request.user.id)}
))
club = ClubAdminandMembersForm(request.POST or None, instance=club_instance)
if club.is_valid():
with transaction.atomic(), reversion.create_revision():
club.save()
reversion.set_user(request.user)
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
field for field in club.changed_data
))
messages.success(request, "Le club a bien été modifié")
return redirect(reverse(
'users:profil',
kwargs={'userid':str(club_instance.id)}
))
return form({'userform': club}, 'users/user.html', request)
def select_user_edit_form(request, user):
"""Fonction de choix du bon formulaire, en fonction de:
- droit
@ -156,9 +218,8 @@ def edit_info(request, userid):
except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect(reverse('users:index'))
if not request.user.has_perms(('cableur',)) and user != request.user:
messages.error(request, "Vous ne pouvez pas modifier un autre\
user que vous sans droit cableur")
if not user.can_edit(request.user):
messages.error(request, "Vous ne pouvez pas accéder à ce menu")
return redirect(reverse(
'users:profil',
kwargs={'userid':str(request.user.id)}
@ -221,9 +282,8 @@ def password(request, userid):
except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect(reverse('users'))
if not request.user.has_perms(('cableur',)) and user != request.user:
messages.error(request, "Vous ne pouvez pas modifier un\
autre user que vous sans droit cableur")
if not user.can_edit(request.user):
messages.error(request, "Vous ne pouvez pas accéder à ce menu")
return redirect(reverse(
'users:profil',
kwargs={'userid':str(request.user.id)}
@ -664,12 +724,16 @@ def index(request):
@login_required
@permission_required('cableur')
def index_clubs(request):
""" Affiche l'ensemble des clubs, need droit cableur """
options, _created = GeneralOption.objects.get_or_create()
pagination_number = options.pagination_number
clubs_list = Club.objects.select_related('room')
if not request.user.has_perms(('cableur',)):
clubs_list = Club.objects.filter(
Q(administrators=request.user.adherent) | Q(members=request.user.adherent)
).distinct().select_related('room')
else:
clubs_list = Club.objects.select_related('room')
clubs_list = SortTable.sort(
clubs_list,
request.GET.get('col'),
@ -795,10 +859,8 @@ def history(request, object_name, object_id):
except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect(reverse('users:index'))
if not request.user.has_perms(('cableur',)) and\
object_instance != request.user:
messages.error(request, "Vous ne pouvez pas afficher\
l'historique d'un autre user que vous sans droit cableur")
if not object_instance.can_view(request.user):
messages.error(request, "Vous ne pouvez pas afficher ce menu")
return redirect(reverse(
'users:profil',
kwargs={'userid':str(request.user.id)}
@ -889,9 +951,8 @@ def profil(request, userid):
except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect(reverse('users:index'))
if not request.user.has_perms(('cableur',)) and users != request.user:
messages.error(request, "Vous ne pouvez pas afficher un autre user\
que vous sans droit cableur")
if not users.can_view(request.user):
messages.error(request, "Vous ne pouvez pas accéder à ce menu")
return redirect(reverse(
'users:profil',
kwargs={'userid':str(request.user.id)}