Gestion des droits des utilisateurs.

This commit is contained in:
Klafyvel 2018-03-01 11:25:34 +01:00
parent b76a93d956
commit b9ea7fba54
10 changed files with 146 additions and 16 deletions

View file

@ -48,7 +48,7 @@
<tr> <tr>
<th>{{school.group.name}}</th> <th>{{school.group.name}}</th>
<td>{{school.group.user_set.count}}</td> <td>{{school.group.user_set.count}}</td>
<td><a class="btn btn-outline-primary btn-sm" href="{% url "users:edit-school" pk=school.pk%}"> <td><a class="btn btn-outline-primary btn-sm" href="{% url "users:edit-school" pk=school.group.pk%}">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
Éditer Éditer
</a> </a>

View file

@ -1,12 +1,14 @@
from django.views.generic import TemplateView, UpdateView from django.views.generic import TemplateView, UpdateView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from content.models import Category from content.models import Category
from users.models import SchoolProfile from users.models import SchoolProfile
from .models import SiteSettings from .models import SiteSettings
class SettingsView(TemplateView): class SettingsView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView):
template_name = "settings/settings.html" template_name = "settings/settings.html"
permission_required = 'settings.change_sitesettings'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
@ -16,11 +18,12 @@ class SettingsView(TemplateView):
context['settings'] = True context['settings'] = True
return context return context
class EditSiteSettingsView(UpdateView): class EditSiteSettingsView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
template_name = "edit.html" template_name = "edit.html"
model = SiteSettings model = SiteSettings
fields = '__all__' fields = '__all__'
success_url = reverse_lazy('settings:index') success_url = reverse_lazy('settings:index')
permission_required = 'settings.change_sitesettings'
def get_object(self, queryset=None): def get_object(self, queryset=None):
obj,_ = self.model.objects.get_or_create() obj,_ = self.model.objects.get_or_create()

View file

@ -128,5 +128,6 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static', 'media') MEDIA_ROOT = os.path.join(BASE_DIR, 'static', 'media')
LOGIN_URL = "/users/login"
LOGIN_REDIRECT_URL = "/" LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/" LOGOUT_REDIRECT_URL = "/"

View file

@ -28,6 +28,7 @@ class SchoolInline(admin.StackedInline):
model = SchoolProfile model = SchoolProfile
can_delete = False can_delete = False
verbose_name_plural = 'schools' verbose_name_plural = 'schools'
fk_name = 'admins'
# Define a new User admin # Define a new User admin

View file

@ -0,0 +1,20 @@
# Generated by Django 2.0.1 on 2018-03-01 07:16
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('auth', '0009_alter_user_last_name_max_length'),
('users', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='schoolprofile',
name='admins',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='admin_of', to='auth.Group'),
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 2.0.1 on 2018-03-01 09:33
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0002_schoolprofile_admins'),
]
operations = [
migrations.AlterField(
model_name='schoolprofile',
name='group',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='school', to='auth.Group'),
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 2.0.1 on 2018-03-01 09:52
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0003_auto_20180301_0933'),
]
operations = [
migrations.AlterField(
model_name='schoolprofile',
name='group',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='school', to='auth.Group'),
),
]

View file

@ -1,5 +1,6 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.urls import reverse from django.urls import reverse
from django.dispatch import receiver from django.dispatch import receiver
@ -10,7 +11,13 @@ class SchoolProfile(models.Model):
group = models.OneToOneField( group = models.OneToOneField(
Group, Group,
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name="students" related_name="school",
)
admins = models.OneToOneField(
Group,
on_delete=models.SET_NULL,
related_name="admin_of",
null=True
) )
def __str__(self): def __str__(self):
@ -19,6 +26,36 @@ class SchoolProfile(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse("users:school", kwargs={'pk':self.pk}) return reverse("users:school", kwargs={'pk':self.pk})
def save(self, *args, **kwargs):
viewing_right, _ = Permission.objects.get_or_create(
codename='view_' + str(self.group.pk),
name='Peut voir ' + str(self.group.pk),
content_type=ContentType.objects.get_for_model(SchoolProfile)
)
if viewing_right not in self.group.permissions.all():
self.group.permissions.add(viewing_right)
self.group.save()
admins,_ = Group.objects.get_or_create(name='admins')
admins.permissions.add(viewing_right)
super().save(*args, **kwargs)
@receiver(post_save, sender=SchoolProfile)
def update_permissions_school(sender, instance, **kwargs):
instance.admins,admin_created = Group.objects.get_or_create(name=str(instance.group.pk)+'_admins')
admin_right,_ = Permission.objects.get_or_create(
codename='manage_' + str(instance.group.pk),
name="Administrateur de l'école " + str(instance.group.pk),
content_type=ContentType.objects.get_for_model(SchoolProfile)
)
admins,_ = Group.objects.get_or_create(name='admins')
admins.permissions.add(admin_right)
if admin_created:
instance.save(update_fields=['admins'])
instance.admins.permissions.add(admin_right)
instance.admins.save()
class UserProfile(models.Model): class UserProfile(models.Model):
"""Profil d'un utilisateur""" """Profil d'un utilisateur"""
school = models.ForeignKey(SchoolProfile, on_delete=models.SET_NULL, null=True, blank=True) school = models.ForeignKey(SchoolProfile, on_delete=models.SET_NULL, null=True, blank=True)
@ -28,3 +65,16 @@ class UserProfile(models.Model):
@receiver(post_save, sender=UserProfile) @receiver(post_save, sender=UserProfile)
def update_groups(sender, instance, **kwargs): def update_groups(sender, instance, **kwargs):
instance.user.groups.add(instance.school.group) instance.user.groups.add(instance.school.group)
@receiver(post_save, sender=User)
def update_permission_user(sender, instance, **kwargs):
perm,_ = Permission.objects.get_or_create(
codename='manage_'+str(instance.pk),
name='Peut administrer ' + instance.username,
content_type=ContentType.objects.get_for_model(User)
)
instance.user_permissions.add(perm)
admins,_ = Group.objects.get_or_create(name='admins')
admins.permissions.add(perm)

View file

@ -2,7 +2,7 @@
{% load bootstrap4 %} {% load bootstrap4 %}
{% block content %} {% block content %}
<h1>{{object.group.name}}</h1> <h1>{{object.name}}</h1>
<a class="btn btn-primary btn-sm" href="{% url 'users:edit-school' object.pk %}"> <a class="btn btn-primary btn-sm" href="{% url 'users:edit-school' object.pk %}">
<i class="fa fa-edit"></i> <i class="fa fa-edit"></i>
Éditer Éditer

View file

@ -1,4 +1,5 @@
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from django.views.generic import CreateView, UpdateView, DeleteView, DetailView from django.views.generic import CreateView, UpdateView, DeleteView, DetailView
from django.contrib.auth.views import LoginView, LogoutView, PasswordChangeView from django.contrib.auth.views import LoginView, LogoutView, PasswordChangeView
from django.contrib.auth.hashers import make_password from django.contrib.auth.hashers import make_password
@ -39,7 +40,7 @@ class CreateUser(CreateView):
self.object.save() self.object.save()
return r return r
class Profile(UpdateView): class Profile(LoginRequiredMixin, UpdateView):
model = User model = User
template_name = 'users/profile.html' template_name = 'users/profile.html'
fields = [ fields = [
@ -57,7 +58,7 @@ class Profile(UpdateView):
def get_success_url(self): def get_success_url(self):
return reverse( return reverse(
'users:reset_password', 'users:profile',
kwargs={'pk': self.object.pk} kwargs={'pk': self.object.pk}
) )
@ -80,7 +81,8 @@ class CreateUserProfile(CreateView):
return super(CreateUserProfile, self).form_valid(form) return super(CreateUserProfile, self).form_valid(form)
class CreateSchool(CreateView): class CreateSchool(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
permission_required = 'users.add_schoolprofile'
model = Group model = Group
fields = ['name'] fields = ['name']
template_name = 'edit.html' template_name = 'edit.html'
@ -100,11 +102,14 @@ class CreateSchool(CreateView):
return response return response
class EditSchool(UpdateView): class EditSchool(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
model = Group model = Group
fields = ['name'] fields = ['name']
template_name = 'edit.html' template_name = 'edit.html'
success_url = reverse_lazy('settings:index') queryset = Group.objects.filter(school__isnull=False)
def get_success_url(self):
return reverse('users:school', kwargs={'pk':self.object.pk})
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
@ -112,22 +117,34 @@ class EditSchool(UpdateView):
context['validate'] = "Modifier" context['validate'] = "Modifier"
return context return context
def has_permission(self):
return self.request.user.has_perm('users.manage_'+str(self.kwargs['pk']))
class DeleteSchool(DeleteView): def form_valid(self, *args, **kwargs):
r = super().form_valid(*args, **kwargs)
self.object.school.save()
return r
class DeleteSchool(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
model = Group model = Group
permission_required = 'users.delete_schoolprofile'
class School(DetailView): class School(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
model = SchoolProfile model = Group
template_name = "users/school.html" template_name = "users/school.html"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data() context = super().get_context_data()
context['contents'] = Content.objects.filter(school_owner=self.object) context['contents'] = Content.objects.filter(school_owner=self.object.school)
context['school'] = True context['school'] = True
context['members'] = User.objects.filter(userprofile__school=self.object) context['members'] = User.objects.filter(userprofile__school=self.object.school)
return context return context
def has_permission(self):
return self.request.user.has_perm('users.view_'+str(self.kwargs['pk']))
class Logout(SuccessMessageMixin, LogoutView): class Logout(SuccessMessageMixin, LogoutView):
success_message = "Vous vous êtes bien déconnecté." success_message = "Vous vous êtes bien déconnecté."