From e3cbe703199db5cfebb80b55e0aecd5f8a84bf97 Mon Sep 17 00:00:00 2001 From: Skia Date: Tue, 8 Dec 2015 17:22:50 +0100 Subject: [PATCH] WIP: Improve many views and a bit user permissions (idea for class scale perm) --- core/migrations/0018_auto_20151208_1558.py | 18 ++++++++++++++++++ core/migrations/0019_auto_20151208_1604.py | 18 ++++++++++++++++++ core/migrations/0020_auto_20151208_1621.py | 18 ++++++++++++++++++ core/models.py | 15 ++++++++++----- core/templates/core/base.html | 8 ++++++++ core/templates/core/user_detail.html | 14 ++++++++++---- core/templates/core/user_tools.html | 20 ++++++++++++++++++++ core/urls.py | 7 +++++-- core/views/forms.py | 4 +++- core/views/user.py | 7 ++++++- 10 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 core/migrations/0018_auto_20151208_1558.py create mode 100644 core/migrations/0019_auto_20151208_1604.py create mode 100644 core/migrations/0020_auto_20151208_1621.py create mode 100644 core/templates/core/user_tools.html diff --git a/core/migrations/0018_auto_20151208_1558.py b/core/migrations/0018_auto_20151208_1558.py new file mode 100644 index 00000000..fefc5881 --- /dev/null +++ b/core/migrations/0018_auto_20151208_1558.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0017_auto_20151203_1530'), + ] + + operations = [ + migrations.AlterModelOptions( + name='user', + options={'permissions': (('can_change_prop', "Can change the user's properties (groups, ...)"),), 'verbose_name': 'user', 'verbose_name_plural': 'users'}, + ), + ] diff --git a/core/migrations/0019_auto_20151208_1604.py b/core/migrations/0019_auto_20151208_1604.py new file mode 100644 index 00000000..8d8b98ae --- /dev/null +++ b/core/migrations/0019_auto_20151208_1604.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0018_auto_20151208_1558'), + ] + + operations = [ + migrations.AlterModelOptions( + name='user', + options={'permissions': (('change_prop', "Can change the user's properties (groups, ...)"),), 'verbose_name_plural': 'users', 'verbose_name': 'user'}, + ), + ] diff --git a/core/migrations/0020_auto_20151208_1621.py b/core/migrations/0020_auto_20151208_1621.py new file mode 100644 index 00000000..6f3b2777 --- /dev/null +++ b/core/migrations/0020_auto_20151208_1621.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0019_auto_20151208_1604'), + ] + + operations = [ + migrations.AlterModelOptions( + name='user', + options={'verbose_name_plural': 'users', 'permissions': (('change_prop_user', "Can change the user's properties (groups, ...)"),), 'verbose_name': 'user'}, + ), + ] diff --git a/core/models.py b/core/models.py index 16b7289d..b030b6e3 100644 --- a/core/models.py +++ b/core/models.py @@ -72,6 +72,9 @@ class User(AbstractBaseUser, PermissionsMixin): class Meta: verbose_name = _('user') verbose_name_plural = _('users') + permissions = ( + ("change_prop_user", "Can change the user's properties (groups, ...)"), + ) def get_absolute_url(self): """ @@ -139,11 +142,14 @@ class User(AbstractBaseUser, PermissionsMixin): """ Determine if the object is owned by the user """ - # TODO: add permission scale validation, to allow some groups other than superuser to manipulate + # TODO: add permission (class) scale validation, to allow some groups other than superuser to manipulate # all objects of a class if they are in the right group + # example: something like user.has_perm("change_"+obj.__class__) if not hasattr(obj, "owner_group"): return False - if self.is_superuser or self.groups.filter(name=obj.owner_group.name).exists(): + print(str(obj.__class__)) + print(str(obj.__class__).lower().split('.')[-1]) + if self.is_superuser or self.groups.filter(name=obj.owner_group.name).exists() or self.has_perm("change_prop_"+str(obj.__class__).lower().split('.')[-1]): return True return False @@ -158,6 +164,8 @@ class User(AbstractBaseUser, PermissionsMixin): for g in obj.edit_group.all(): if self.groups.filter(name=g.name).exists(): return True + if isinstance(obj, User) and obj == self: + return True return False def can_view(self, obj): @@ -171,8 +179,6 @@ class User(AbstractBaseUser, PermissionsMixin): for g in obj.view_group.all(): if self.groups.filter(name=g.name).exists(): return True - if isinstance(obj, User) and obj == self: - return True return False class LockError(Exception): @@ -212,7 +218,6 @@ class Page(models.Model): class Meta: unique_together = ('name', 'parent') permissions = ( - #("can_edit", "Can edit the page"), ("can_view", "Can view the page"), ) diff --git a/core/templates/core/base.html b/core/templates/core/base.html index cbb7b8a2..eeec42e9 100644 --- a/core/templates/core/base.html +++ b/core/templates/core/base.html @@ -10,12 +10,20 @@ {% block header %} {% if user.is_authenticated %}Hello, {{ user.username }}!{% endif %} + {% if user.is_authenticated %} + + {% endif %} {% endblock %} diff --git a/core/templates/core/user_detail.html b/core/templates/core/user_detail.html index dcc4649f..685cd80c 100644 --- a/core/templates/core/user_detail.html +++ b/core/templates/core/user_detail.html @@ -8,12 +8,18 @@

User Profile

Back to list

-{% if user.is_superuser or user.id == profile.id %} +{{ perms.core }} +{% if user.id == profile.id %} +
  • Tools
  • {% endif %} +{% if perms.core.change_user or user.id == profile.id %} +
  • Edit
  • +{% endif %} +{% if perms.core.change_prop_user %} +
  • Groups
  • +{% endif %} +

    You're seeing the profile of {{ profile.get_full_name }}
    diff --git a/core/templates/core/user_tools.html b/core/templates/core/user_tools.html new file mode 100644 index 00000000..670e75dd --- /dev/null +++ b/core/templates/core/user_tools.html @@ -0,0 +1,20 @@ +{% extends "core/base.html" %} + +{% block title %} + {{ user.get_display_name }}'s tools +{% endblock %} + +{% block content %} +

    User Tools

    +

    Back to profile

    + + + +{% endblock %} + + + diff --git a/core/urls.py b/core/urls.py index 280bf7e1..4bea6ed8 100644 --- a/core/urls.py +++ b/core/urls.py @@ -3,10 +3,9 @@ from django.conf.urls import url, include from core.views import * urlpatterns = [ - #url('^', include('django.contrib.auth.urls')), - url(r'^$', index, name='index'), + # Login and co url(r'^login/$', login, name='login'), url(r'^logout/$', logout, name='logout'), url(r'^password_change/$', password_change, name='password_change'), @@ -17,14 +16,18 @@ urlpatterns = [ url(r'^reset/done/$', password_reset_complete, name='password_reset_complete'), url(r'^register$', register, name='register'), + # Group handling url(r'^group/$', GroupListView.as_view(), name='group_list'), url(r'^group/(?P[0-9]+)/$', GroupEditView.as_view(), name='group_edit'), + # User views url(r'^user/$', UserListView.as_view(), name='user_list'), url(r'^user/(?P[0-9]+)/$', UserView.as_view(), name='user_profile'), url(r'^user/(?P[0-9]+)/edit$', UserUpdateProfileView.as_view(), name='user_edit'), url(r'^user/(?P[0-9]+)/groups$', UserUpdateGroupsView.as_view(), name='user_groups'), + url(r'^user/tools/$', UserToolsView.as_view(), name='user_tools'), + # Page views url(r'^page/$', PageListView.as_view(), name='page_list'), url(r'^page/(?P[a-z0-9/]*)/edit$', PageEditView.as_view(), name='page_edit'), url(r'^page/(?P[a-z0-9/]*)/prop$', PagePropView.as_view(), name='page_prop'), diff --git a/core/views/forms.py b/core/views/forms.py index 145e91ef..3f6397f8 100644 --- a/core/views/forms.py +++ b/core/views/forms.py @@ -27,10 +27,12 @@ class UserGroupsForm(forms.ModelForm): required_css_class = 'required' class Meta: model = User - fields = ['groups', 'user_permissions',] + fields = ['edit_group', 'view_group', 'groups', 'user_permissions',] widgets = { 'groups': CheckboxSelectMultiple, 'user_permissions': CheckboxSelectMultiple, + 'edit_group': CheckboxSelectMultiple, + 'view_group': CheckboxSelectMultiple, } class PagePropForm(forms.ModelForm): diff --git a/core/views/user.py b/core/views/user.py index 177e423a..fefed81d 100644 --- a/core/views/user.py +++ b/core/views/user.py @@ -3,7 +3,7 @@ from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth import logout as auth_logout, views from django.core.urlresolvers import reverse from django.views.generic.edit import UpdateView -from django.views.generic import ListView, DetailView +from django.views.generic import ListView, DetailView, TemplateView import logging from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin @@ -120,3 +120,8 @@ class UserUpdateGroupsView(CanEditPropMixin, UpdateView): template_name = "core/user_groups.html" form_class = UserGroupsForm +class UserToolsView(TemplateView): + """ + Displays the logged user's tools + """ + template_name = "core/user_tools.html"