mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-25 18:44:23 +00:00
Implement generic right checking for any View with the right parents
This commit is contained in:
parent
b19ec084b6
commit
5c9e5a24ab
23
core/migrations/0008_auto_20151127_1007.py
Normal file
23
core/migrations/0008_auto_20151127_1007.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('core', '0007_auto_20151126_1613'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='page',
|
||||||
|
name='view_group',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='page',
|
||||||
|
name='view_group',
|
||||||
|
field=models.ManyToManyField(default=1, to='core.Group', related_name='viewable_pages'),
|
||||||
|
),
|
||||||
|
]
|
23
core/migrations/0009_auto_20151127_1007.py
Normal file
23
core/migrations/0009_auto_20151127_1007.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('core', '0008_auto_20151127_1007'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='page',
|
||||||
|
name='edit_group',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='page',
|
||||||
|
name='edit_group',
|
||||||
|
field=models.ManyToManyField(to='core.Group', related_name='editable_pages', default=1),
|
||||||
|
),
|
||||||
|
]
|
@ -154,9 +154,11 @@ class Page(models.Model):
|
|||||||
# playing with a Page object, use get_full_name() instead!
|
# playing with a Page object, use get_full_name() instead!
|
||||||
full_name = models.CharField(_('page name'), max_length=255, blank=True)
|
full_name = models.CharField(_('page name'), max_length=255, blank=True)
|
||||||
|
|
||||||
|
# TODO: Rightable abstract class from which every object with right needed will be able to be child of
|
||||||
|
# Put thoses 3 attributes there
|
||||||
owner_group = models.ForeignKey(Group, related_name="owned_pages", default=1)
|
owner_group = models.ForeignKey(Group, related_name="owned_pages", default=1)
|
||||||
edit_group = models.ForeignKey(Group, related_name="editable_pages", default=1)
|
edit_group = models.ManyToManyField(Group, related_name="editable_pages", default=1)
|
||||||
view_group = models.ForeignKey(Group, related_name="viewable_pages", default=1)
|
view_group = models.ManyToManyField(Group, related_name="viewable_pages", default=1)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('name', 'parent')
|
unique_together = ('name', 'parent')
|
||||||
|
@ -1,4 +1,65 @@
|
|||||||
|
|
||||||
|
from django.http import HttpResponseForbidden
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from django.views.generic.base import View
|
||||||
|
|
||||||
|
# TODO: see models.py's TODO!
|
||||||
|
class CanEditPropMixin(View):
|
||||||
|
"""
|
||||||
|
This view is made to protect any child view that would be showing some properties of an object that are restricted
|
||||||
|
to only the owner group of the given object.
|
||||||
|
In other word, you can make a view with this view as parent, and it would be retricted to the users that are in the
|
||||||
|
object's owner_group
|
||||||
|
"""
|
||||||
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
|
res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
|
||||||
|
obj = self.object
|
||||||
|
user = self.request.user
|
||||||
|
if obj is None:
|
||||||
|
return res
|
||||||
|
if user.is_superuser or user.groups.filter(name=obj.owner_group.name).exists():
|
||||||
|
return res
|
||||||
|
return HttpResponseForbidden("403, Forbidden")
|
||||||
|
|
||||||
|
class CanEditMixin(CanEditPropMixin):
|
||||||
|
"""
|
||||||
|
This view makes exactly the same this as its direct parent, but checks the group on the edit_group field of the
|
||||||
|
object
|
||||||
|
"""
|
||||||
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
|
res = super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
|
||||||
|
if res.status_code != 403:
|
||||||
|
return res
|
||||||
|
obj = self.object
|
||||||
|
user = self.request.user
|
||||||
|
if obj is None:
|
||||||
|
return res
|
||||||
|
for g in obj.edit_group.all():
|
||||||
|
if user.groups.filter(name=g.name).exists():
|
||||||
|
return super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
|
||||||
|
return HttpResponseForbidden("403, Forbidden")
|
||||||
|
|
||||||
|
class CanViewMixin(CanEditMixin):
|
||||||
|
"""
|
||||||
|
This view still makes exactly the same this as its direct parent, but checks the group on the view_group field of
|
||||||
|
the object
|
||||||
|
"""
|
||||||
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
|
res = super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
|
||||||
|
if res.status_code != 403:
|
||||||
|
return res
|
||||||
|
obj = self.object
|
||||||
|
user = self.request.user
|
||||||
|
if obj is None:
|
||||||
|
return res
|
||||||
|
for g in obj.view_group.all():
|
||||||
|
if user.groups.filter(name=g.name).exists():
|
||||||
|
return super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
|
||||||
|
raise PermissionDenied
|
||||||
|
return HttpResponseForbidden("403, Forbidden")
|
||||||
|
|
||||||
from .user import *
|
from .user import *
|
||||||
from .page import *
|
from .page import *
|
||||||
from .site import *
|
from .site import *
|
||||||
from .group import *
|
from .group import *
|
||||||
|
|
||||||
|
@ -33,6 +33,17 @@ class UserGroupsForm(forms.ModelForm):
|
|||||||
'user_permissions': CheckboxSelectMultiple,
|
'user_permissions': CheckboxSelectMultiple,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PagePropForm(forms.ModelForm):
|
||||||
|
error_css_class = 'error'
|
||||||
|
required_css_class = 'required'
|
||||||
|
class Meta:
|
||||||
|
model = Page
|
||||||
|
fields = ['parent', 'name', 'owner_group', 'edit_group', 'view_group', ]
|
||||||
|
widgets = {
|
||||||
|
'edit_group': CheckboxSelectMultiple,
|
||||||
|
'view_group': CheckboxSelectMultiple,
|
||||||
|
}
|
||||||
|
|
||||||
class GroupEditForm(forms.ModelForm):
|
class GroupEditForm(forms.ModelForm):
|
||||||
error_css_class = 'error'
|
error_css_class = 'error'
|
||||||
required_css_class = 'required'
|
required_css_class = 'required'
|
||||||
|
@ -6,6 +6,8 @@ from django.contrib.auth.decorators import login_required, permission_required
|
|||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
|
|
||||||
from core.models import Page
|
from core.models import Page
|
||||||
|
from core.views.forms import PagePropForm
|
||||||
|
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin
|
||||||
|
|
||||||
class PageListView(ListView):
|
class PageListView(ListView):
|
||||||
model = Page
|
model = Page
|
||||||
@ -14,12 +16,23 @@ class PageListView(ListView):
|
|||||||
context = super(PageListView, self).get_context_data(**kwargs)
|
context = super(PageListView, self).get_context_data(**kwargs)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
class PageView(DetailView):
|
# Define some right management callable for user_passes_test
|
||||||
model = Page
|
def user_can_view(as_view):
|
||||||
|
def guy(*arg, **kwargs):
|
||||||
|
res = self.as_view(*arg, **kwargs)
|
||||||
|
|
||||||
@method_decorator(permission_required('core.can_view'))
|
user = self.request.user
|
||||||
def dispatch(self, *args, **kwargs):
|
obj = self.page
|
||||||
return super(PageView, self).dispatch(*args, **kwargs)
|
for g in obj.view_group.all():
|
||||||
|
if g in user.groups.all():
|
||||||
|
print("Allowed")
|
||||||
|
return res
|
||||||
|
print("Not allowed")
|
||||||
|
return res
|
||||||
|
return guy
|
||||||
|
|
||||||
|
class PageView(CanViewMixin, DetailView):
|
||||||
|
model = Page
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
|
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
|
||||||
@ -34,14 +47,11 @@ class PageView(DetailView):
|
|||||||
context['new_page'] = self.kwargs['page_name']
|
context['new_page'] = self.kwargs['page_name']
|
||||||
return context
|
return context
|
||||||
|
|
||||||
class PagePropView(UpdateView):
|
class PagePropView(CanEditPropMixin, UpdateView):
|
||||||
model = Page
|
model = Page
|
||||||
fields = ['parent', 'name', 'owner_group', 'edit_group', 'view_group', ]
|
form_class = PagePropForm
|
||||||
template_name_suffix = '_prop'
|
template_name_suffix = '_prop'
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(PagePropView, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
page_name = self.kwargs['page_name']
|
page_name = self.kwargs['page_name']
|
||||||
p = Page.get_page_by_full_name(page_name)
|
p = Page.get_page_by_full_name(page_name)
|
||||||
@ -66,7 +76,7 @@ class PagePropView(UpdateView):
|
|||||||
context['new_page'] = self.kwargs['page_name']
|
context['new_page'] = self.kwargs['page_name']
|
||||||
return context
|
return context
|
||||||
|
|
||||||
class PageEditView(UpdateView):
|
class PageEditView(CanEditMixin, UpdateView):
|
||||||
model = Page
|
model = Page
|
||||||
fields = ['title', 'content',]
|
fields = ['title', 'content',]
|
||||||
template_name_suffix = '_edit'
|
template_name_suffix = '_edit'
|
||||||
|
Loading…
Reference in New Issue
Block a user