Gestion des droits des utilisateurs.
This commit is contained in:
parent
b76a93d956
commit
b9ea7fba54
10 changed files with 146 additions and 16 deletions
|
@ -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>
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 = "/"
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
20
users/migrations/0002_schoolprofile_admins.py
Normal file
20
users/migrations/0002_schoolprofile_admins.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
19
users/migrations/0003_auto_20180301_0933.py
Normal file
19
users/migrations/0003_auto_20180301_0933.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
19
users/migrations/0004_auto_20180301_0952.py
Normal file
19
users/migrations/0004_auto_20180301_0952.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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é."
|
||||||
|
|
Loading…
Reference in a new issue