WIP: Improve many views and a bit user permissions (idea for class scale perm)

This commit is contained in:
Skia 2015-12-08 17:22:50 +01:00
parent 475bff14cb
commit e3cbe70319
10 changed files with 116 additions and 13 deletions

View File

@ -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'},
),
]

View File

@ -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'},
),
]

View File

@ -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'},
),
]

View File

@ -72,6 +72,9 @@ class User(AbstractBaseUser, PermissionsMixin):
class Meta: class Meta:
verbose_name = _('user') verbose_name = _('user')
verbose_name_plural = _('users') verbose_name_plural = _('users')
permissions = (
("change_prop_user", "Can change the user's properties (groups, ...)"),
)
def get_absolute_url(self): def get_absolute_url(self):
""" """
@ -139,11 +142,14 @@ class User(AbstractBaseUser, PermissionsMixin):
""" """
Determine if the object is owned by the user 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 # 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"): if not hasattr(obj, "owner_group"):
return False 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 True
return False return False
@ -158,6 +164,8 @@ class User(AbstractBaseUser, PermissionsMixin):
for g in obj.edit_group.all(): for g in obj.edit_group.all():
if self.groups.filter(name=g.name).exists(): if self.groups.filter(name=g.name).exists():
return True return True
if isinstance(obj, User) and obj == self:
return True
return False return False
def can_view(self, obj): def can_view(self, obj):
@ -171,8 +179,6 @@ class User(AbstractBaseUser, PermissionsMixin):
for g in obj.view_group.all(): for g in obj.view_group.all():
if self.groups.filter(name=g.name).exists(): if self.groups.filter(name=g.name).exists():
return True return True
if isinstance(obj, User) and obj == self:
return True
return False return False
class LockError(Exception): class LockError(Exception):
@ -212,7 +218,6 @@ class Page(models.Model):
class Meta: class Meta:
unique_together = ('name', 'parent') unique_together = ('name', 'parent')
permissions = ( permissions = (
#("can_edit", "Can edit the page"),
("can_view", "Can view the page"), ("can_view", "Can view the page"),
) )

View File

@ -10,12 +10,20 @@
{% block header %} {% block header %}
{% if user.is_authenticated %}Hello, {{ user.username }}!{% endif %} {% if user.is_authenticated %}Hello, {{ user.username }}!{% endif %}
<ul> <ul>
{% if not user.is_authenticated %}
<li><a href="{% url 'core:register' %}">Register</a></li> <li><a href="{% url 'core:register' %}">Register</a></li>
<li><a href="{% url 'core:login' %}">Login</a></li> <li><a href="{% url 'core:login' %}">Login</a></li>
{% else %}
<li><a href="{% url 'core:logout' %}">Logout</a></li> <li><a href="{% url 'core:logout' %}">Logout</a></li>
{% endif %}
</ul>
{% if user.is_authenticated %}
<ul>
<li><a href="{% url 'core:user_profile' user.id %}">Profile</a></li>
<li><a href="{% url 'core:user_list' %}">Users</a></li> <li><a href="{% url 'core:user_list' %}">Users</a></li>
<li><a href="{% url 'core:page_list' %}">Pages</a></li> <li><a href="{% url 'core:page_list' %}">Pages</a></li>
</ul> </ul>
{% endif %}
{% endblock %} {% endblock %}
</header> </header>

View File

@ -8,12 +8,18 @@
<h3>User Profile</h3> <h3>User Profile</h3>
<p><a href="{% url 'core:user_list' %}">Back to list</a></p> <p><a href="{% url 'core:user_list' %}">Back to list</a></p>
{% if user.is_superuser or user.id == profile.id %} {{ perms.core }}
<ul> <ul>
<li><a href="{% url 'core:user_edit' profile.id %}">Edit</a></li> {% if user.id == profile.id %}
<li><a href="{% url 'core:user_groups' profile.id %}">Groups</a></li> <li><a href="{% url 'core:user_tools' %}">Tools</a></li>
</ul>
{% endif %} {% endif %}
{% if perms.core.change_user or user.id == profile.id %}
<li><a href="{% url 'core:user_edit' profile.id %}">Edit</a></li>
{% endif %}
{% if perms.core.change_prop_user %}
<li><a href="{% url 'core:user_groups' profile.id %}">Groups</a></li>
{% endif %}
</ul>
<p> <p>
You're seeing the profile of <strong>{{ profile.get_full_name }}</strong><br/> You're seeing the profile of <strong>{{ profile.get_full_name }}</strong><br/>

View File

@ -0,0 +1,20 @@
{% extends "core/base.html" %}
{% block title %}
{{ user.get_display_name }}'s tools
{% endblock %}
{% block content %}
<h3>User Tools</h3>
<p><a href="{% url 'core:user_profile' user.id %}">Back to profile</a></p>
<ul>
{% if perms.core.add_group %}
<li><a href="{% url 'core:group_list' %}">Groups</a></li>
{% endif %}
</ul>
{% endblock %}

View File

@ -3,10 +3,9 @@ from django.conf.urls import url, include
from core.views import * from core.views import *
urlpatterns = [ urlpatterns = [
#url('^', include('django.contrib.auth.urls')),
url(r'^$', index, name='index'), url(r'^$', index, name='index'),
# Login and co
url(r'^login/$', login, name='login'), url(r'^login/$', login, name='login'),
url(r'^logout/$', logout, name='logout'), url(r'^logout/$', logout, name='logout'),
url(r'^password_change/$', password_change, name='password_change'), 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'^reset/done/$', password_reset_complete, name='password_reset_complete'),
url(r'^register$', register, name='register'), url(r'^register$', register, name='register'),
# Group handling
url(r'^group/$', GroupListView.as_view(), name='group_list'), url(r'^group/$', GroupListView.as_view(), name='group_list'),
url(r'^group/(?P<group_id>[0-9]+)/$', GroupEditView.as_view(), name='group_edit'), url(r'^group/(?P<group_id>[0-9]+)/$', GroupEditView.as_view(), name='group_edit'),
# User views
url(r'^user/$', UserListView.as_view(), name='user_list'), url(r'^user/$', UserListView.as_view(), name='user_list'),
url(r'^user/(?P<user_id>[0-9]+)/$', UserView.as_view(), name='user_profile'), url(r'^user/(?P<user_id>[0-9]+)/$', UserView.as_view(), name='user_profile'),
url(r'^user/(?P<user_id>[0-9]+)/edit$', UserUpdateProfileView.as_view(), name='user_edit'), url(r'^user/(?P<user_id>[0-9]+)/edit$', UserUpdateProfileView.as_view(), name='user_edit'),
url(r'^user/(?P<user_id>[0-9]+)/groups$', UserUpdateGroupsView.as_view(), name='user_groups'), url(r'^user/(?P<user_id>[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/$', PageListView.as_view(), name='page_list'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/edit$', PageEditView.as_view(), name='page_edit'), url(r'^page/(?P<page_name>[a-z0-9/]*)/edit$', PageEditView.as_view(), name='page_edit'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/prop$', PagePropView.as_view(), name='page_prop'), url(r'^page/(?P<page_name>[a-z0-9/]*)/prop$', PagePropView.as_view(), name='page_prop'),

View File

@ -27,10 +27,12 @@ class UserGroupsForm(forms.ModelForm):
required_css_class = 'required' required_css_class = 'required'
class Meta: class Meta:
model = User model = User
fields = ['groups', 'user_permissions',] fields = ['edit_group', 'view_group', 'groups', 'user_permissions',]
widgets = { widgets = {
'groups': CheckboxSelectMultiple, 'groups': CheckboxSelectMultiple,
'user_permissions': CheckboxSelectMultiple, 'user_permissions': CheckboxSelectMultiple,
'edit_group': CheckboxSelectMultiple,
'view_group': CheckboxSelectMultiple,
} }
class PagePropForm(forms.ModelForm): class PagePropForm(forms.ModelForm):

View File

@ -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.contrib.auth import logout as auth_logout, views
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.views.generic.edit import UpdateView from django.views.generic.edit import UpdateView
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView, TemplateView
import logging import logging
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin
@ -120,3 +120,8 @@ class UserUpdateGroupsView(CanEditPropMixin, UpdateView):
template_name = "core/user_groups.html" template_name = "core/user_groups.html"
form_class = UserGroupsForm form_class = UserGroupsForm
class UserToolsView(TemplateView):
"""
Displays the logged user's tools
"""
template_name = "core/user_tools.html"