mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-22 14:13:21 +00:00
Refactor rights handling
This commit is contained in:
parent
dc37e79f14
commit
475bff14cb
@ -135,6 +135,46 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||||||
self.username = user_name
|
self.username = user_name
|
||||||
return user_name
|
return user_name
|
||||||
|
|
||||||
|
def is_owner(self, obj):
|
||||||
|
"""
|
||||||
|
Determine if the object is owned by the user
|
||||||
|
"""
|
||||||
|
# TODO: add permission scale validation, to allow some groups other than superuser to manipulate
|
||||||
|
# all objects of a class if they are in the right group
|
||||||
|
if not hasattr(obj, "owner_group"):
|
||||||
|
return False
|
||||||
|
if self.is_superuser or self.groups.filter(name=obj.owner_group.name).exists():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def can_edit(self, obj):
|
||||||
|
"""
|
||||||
|
Determine if the object can be edited by the user
|
||||||
|
"""
|
||||||
|
if not hasattr(obj, "edit_group"):
|
||||||
|
return False
|
||||||
|
if self.is_owner(obj):
|
||||||
|
return True
|
||||||
|
for g in obj.edit_group.all():
|
||||||
|
if self.groups.filter(name=g.name).exists():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def can_view(self, obj):
|
||||||
|
"""
|
||||||
|
Determine if the object can be viewed by the user
|
||||||
|
"""
|
||||||
|
if not hasattr(obj, "view_group"):
|
||||||
|
return False
|
||||||
|
if self.can_edit(obj):
|
||||||
|
return True
|
||||||
|
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):
|
class LockError(Exception):
|
||||||
"""There was a lock error on the object"""
|
"""There was a lock error on the object"""
|
||||||
pass
|
pass
|
||||||
@ -237,7 +277,7 @@ class Page(models.Model):
|
|||||||
if self.pk not in Page.lock_mutex.keys():
|
if self.pk not in Page.lock_mutex.keys():
|
||||||
# print("Page mutex does not exists")
|
# print("Page mutex does not exists")
|
||||||
return False
|
return False
|
||||||
if (timezone.now()-Page.lock_mutex[self.pk]['time']) > timedelta(seconds=5):
|
if (timezone.now()-Page.lock_mutex[self.pk]['time']) > timedelta(minutes=5):
|
||||||
# print("Lock timed out")
|
# print("Lock timed out")
|
||||||
self.unset_lock()
|
self.unset_lock()
|
||||||
return False
|
return False
|
||||||
@ -251,7 +291,7 @@ class Page(models.Model):
|
|||||||
raise AlreadyLocked("The page is already locked by someone else")
|
raise AlreadyLocked("The page is already locked by someone else")
|
||||||
Page.lock_mutex[self.pk] = {'user': user,
|
Page.lock_mutex[self.pk] = {'user': user,
|
||||||
'time': timezone.now()}
|
'time': timezone.now()}
|
||||||
print("Locking page")
|
# print("Locking page")
|
||||||
|
|
||||||
def set_lock_recursive(self, user):
|
def set_lock_recursive(self, user):
|
||||||
"""
|
"""
|
||||||
@ -264,7 +304,7 @@ class Page(models.Model):
|
|||||||
def unset_lock(self):
|
def unset_lock(self):
|
||||||
"""Always try to unlock, even if there is no lock"""
|
"""Always try to unlock, even if there is no lock"""
|
||||||
Page.lock_mutex.pop(self.pk, None)
|
Page.lock_mutex.pop(self.pk, None)
|
||||||
print("Unlocking page")
|
# print("Unlocking page")
|
||||||
|
|
||||||
def get_lock(self):
|
def get_lock(self):
|
||||||
"""
|
"""
|
||||||
@ -322,6 +362,8 @@ class PageRev(models.Model):
|
|||||||
return self.page.edit_group
|
return self.page.edit_group
|
||||||
elif attr == "view_group":
|
elif attr == "view_group":
|
||||||
return self.page.view_group
|
return self.page.view_group
|
||||||
|
elif attr == "unset_lock":
|
||||||
|
return self.page.unset_lock
|
||||||
else:
|
else:
|
||||||
return object.__getattribute__(self, attr)
|
return object.__getattribute__(self, attr)
|
||||||
|
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
{% block page %}
|
{% block page %}
|
||||||
<h3>Page</h3>
|
<h3>Page</h3>
|
||||||
<p><a href="{% url 'core:page_list' %}">Back to list</a></p>
|
<p><a href="{% url 'core:page_list' %}">Back to list</a></p>
|
||||||
{% if user.is_superuser %}
|
{% if can_edit %}
|
||||||
<p><a href="{% url 'core:page_edit' page.get_full_name %}">Edit</a></p>
|
<p><a href="{% url 'core:page_edit' page.get_full_name %}">Edit</a></p>
|
||||||
|
{% endif %}
|
||||||
|
{% if can_edit_prop %}
|
||||||
<p><a href="{% url 'core:page_prop' page.get_full_name %}">Prop</a></p>
|
<p><a href="{% url 'core:page_prop' page.get_full_name %}">Prop</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p>You're seeing the page <strong>{{ page.get_display_name }}</strong> -
|
<p>You're seeing the page <strong>{{ page.get_display_name }}</strong> -
|
||||||
|
@ -23,63 +23,40 @@ class CanEditPropMixin(View):
|
|||||||
"""
|
"""
|
||||||
def dispatch(self, request, *arg, **kwargs):
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
|
res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
|
||||||
obj = self.object
|
if self.object is None or self.request.user.is_owner(self.object):
|
||||||
user = self.request.user
|
|
||||||
if obj is None:
|
|
||||||
return res
|
return res
|
||||||
# TODO: add permission scale validation, to allow some groups other than superuser to manipulate
|
try: # Always unlock when 403
|
||||||
# all objects of a class if they are in the right group
|
|
||||||
if user.is_superuser or user.groups.filter(name=obj.owner_group.name).exists():
|
|
||||||
return res
|
|
||||||
print("Guyuy")
|
|
||||||
self.object.unset_lock()
|
self.object.unset_lock()
|
||||||
|
except: pass
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
return HttpResponseForbidden("403, Forbidden")
|
|
||||||
|
|
||||||
class CanEditMixin(CanEditPropMixin):
|
class CanEditMixin(View):
|
||||||
"""
|
"""
|
||||||
This view makes exactly the same this as its direct parent, but checks the group on the edit_group field of the
|
This view makes exactly the same this as its direct parent, but checks the group on the edit_group field of the
|
||||||
object
|
object
|
||||||
"""
|
"""
|
||||||
def dispatch(self, request, *arg, **kwargs):
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
# TODO: WIP: fix permissions with exceptions!
|
# TODO: WIP: fix permissions with exceptions!
|
||||||
try:
|
|
||||||
res = super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
|
res = super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
|
||||||
|
if self.object is None or self.request.user.can_edit(self.object):
|
||||||
return res
|
return res
|
||||||
except PermissionDenied:
|
try: # Always unlock when 403
|
||||||
pass
|
self.object.unset_lock()
|
||||||
res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
|
except: pass
|
||||||
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 res
|
|
||||||
if isinstance(obj, User) and obj == user:
|
|
||||||
return res
|
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
return HttpResponseForbidden("403, Forbidden")
|
|
||||||
|
|
||||||
class CanViewMixin(CanEditMixin):
|
class CanViewMixin(View):
|
||||||
"""
|
"""
|
||||||
This view still makes exactly the same this as its direct parent, but checks the group on the view_group field of
|
This view still makes exactly the same this as its direct parent, but checks the group on the view_group field of
|
||||||
the object
|
the object
|
||||||
"""
|
"""
|
||||||
def dispatch(self, request, *arg, **kwargs):
|
def dispatch(self, request, *arg, **kwargs):
|
||||||
try:
|
|
||||||
res = super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
|
res = super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
|
||||||
|
if self.object is None or self.request.user.can_view(self.object):
|
||||||
return res
|
return res
|
||||||
except PermissionDenied:
|
try: # Always unlock when 403
|
||||||
pass
|
self.object.unset_lock()
|
||||||
res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
|
except: pass
|
||||||
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 res
|
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
from .user import *
|
from .user import *
|
||||||
|
@ -27,6 +27,11 @@ class PageView(CanViewMixin, DetailView):
|
|||||||
context = super(PageView, self).get_context_data(**kwargs)
|
context = super(PageView, self).get_context_data(**kwargs)
|
||||||
if "page" not in context.keys():
|
if "page" not in context.keys():
|
||||||
context['new_page'] = self.kwargs['page_name']
|
context['new_page'] = self.kwargs['page_name']
|
||||||
|
if self.request.user.is_owner(self.object):
|
||||||
|
context['can_edit_prop'] = True
|
||||||
|
if self.request.user.can_edit(self.object):
|
||||||
|
context['can_edit'] = True
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
class PageHistView(CanViewMixin, DetailView):
|
class PageHistView(CanViewMixin, DetailView):
|
||||||
|
Loading…
Reference in New Issue
Block a user