diff --git a/settings/templates/settings/settings.html b/settings/templates/settings/settings.html index c42dd06..d09b3a1 100644 --- a/settings/templates/settings/settings.html +++ b/settings/templates/settings/settings.html @@ -48,7 +48,7 @@ {{school.group.name}} {{school.group.user_set.count}} - + Éditer diff --git a/settings/views.py b/settings/views.py index 47b5c1e..4f63b6c 100644 --- a/settings/views.py +++ b/settings/views.py @@ -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() diff --git a/site_tps/settings.py b/site_tps/settings.py index 83b6128..b9a472c 100644 --- a/site_tps/settings.py +++ b/site_tps/settings.py @@ -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 = "/" diff --git a/users/admin.py b/users/admin.py index 419505c..465315b 100644 --- a/users/admin.py +++ b/users/admin.py @@ -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 diff --git a/users/migrations/0002_schoolprofile_admins.py b/users/migrations/0002_schoolprofile_admins.py new file mode 100644 index 0000000..bbd050c --- /dev/null +++ b/users/migrations/0002_schoolprofile_admins.py @@ -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'), + ), + ] diff --git a/users/migrations/0003_auto_20180301_0933.py b/users/migrations/0003_auto_20180301_0933.py new file mode 100644 index 0000000..3a6468a --- /dev/null +++ b/users/migrations/0003_auto_20180301_0933.py @@ -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'), + ), + ] diff --git a/users/migrations/0004_auto_20180301_0952.py b/users/migrations/0004_auto_20180301_0952.py new file mode 100644 index 0000000..1055782 --- /dev/null +++ b/users/migrations/0004_auto_20180301_0952.py @@ -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'), + ), + ] diff --git a/users/models.py b/users/models.py index 079d0cf..ec56f4c 100644 --- a/users/models.py +++ b/users/models.py @@ -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) + diff --git a/users/templates/users/school.html b/users/templates/users/school.html index 78eab74..a39b58e 100644 --- a/users/templates/users/school.html +++ b/users/templates/users/school.html @@ -2,7 +2,7 @@ {% load bootstrap4 %} {% block content %} -

{{object.group.name}}

+

{{object.name}}

Éditer diff --git a/users/views.py b/users/views.py index a6b8a6f..02adf52 100644 --- a/users/views.py +++ b/users/views.py @@ -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'])) + + def form_valid(self, *args, **kwargs): + r = super().form_valid(*args, **kwargs) + self.object.school.save() + return r + -class DeleteSchool(DeleteView): +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é."