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>
<th>{{school.group.name}}</th>
<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>
Éditer
</a>

View file

@ -1,12 +1,14 @@
from django.views.generic import TemplateView, UpdateView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from content.models import Category
from users.models import SchoolProfile
from .models import SiteSettings
class SettingsView(TemplateView):
class SettingsView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView):
template_name = "settings/settings.html"
permission_required = 'settings.change_sitesettings'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -16,11 +18,12 @@ class SettingsView(TemplateView):
context['settings'] = True
return context
class EditSiteSettingsView(UpdateView):
class EditSiteSettingsView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
template_name = "edit.html"
model = SiteSettings
fields = '__all__'
success_url = reverse_lazy('settings:index')
permission_required = 'settings.change_sitesettings'
def get_object(self, queryset=None):
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_ROOT = os.path.join(BASE_DIR, 'static', 'media')
LOGIN_URL = "/users/login"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"

View file

@ -28,6 +28,7 @@ class SchoolInline(admin.StackedInline):
model = SchoolProfile
can_delete = False
verbose_name_plural = 'schools'
fk_name = 'admins'
# 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.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.urls import reverse
from django.dispatch import receiver
@ -10,7 +11,13 @@ class SchoolProfile(models.Model):
group = models.OneToOneField(
Group,
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):
@ -19,6 +26,36 @@ class SchoolProfile(models.Model):
def get_absolute_url(self):
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):
"""Profil d'un utilisateur"""
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)
def update_groups(sender, instance, **kwargs):
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 %}
{% 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 %}">
<i class="fa fa-edit"></i>
Éditer

View file

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