mirror of
				https://github.com/ae-utbm/sith.git
				synced 2025-10-31 00:53:08 +00:00 
			
		
		
		
	Refactor rights handling
This commit is contained in:
		| @@ -135,6 +135,46 @@ class User(AbstractBaseUser, PermissionsMixin): | ||||
|         self.username = 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): | ||||
|     """There was a lock error on the object""" | ||||
|     pass | ||||
| @@ -237,7 +277,7 @@ class Page(models.Model): | ||||
|         if self.pk not in Page.lock_mutex.keys(): | ||||
|             # print("Page mutex does not exists") | ||||
|             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") | ||||
|             self.unset_lock() | ||||
|             return False | ||||
| @@ -251,7 +291,7 @@ class Page(models.Model): | ||||
|             raise AlreadyLocked("The page is already locked by someone else") | ||||
|         Page.lock_mutex[self.pk] = {'user': user, | ||||
|                                     'time': timezone.now()} | ||||
|         print("Locking page") | ||||
|         # print("Locking page") | ||||
|  | ||||
|     def set_lock_recursive(self, user): | ||||
|         """ | ||||
| @@ -264,7 +304,7 @@ class Page(models.Model): | ||||
|     def unset_lock(self): | ||||
|         """Always try to unlock, even if there is no lock""" | ||||
|         Page.lock_mutex.pop(self.pk, None) | ||||
|         print("Unlocking page") | ||||
|         # print("Unlocking page") | ||||
|  | ||||
|     def get_lock(self): | ||||
|         """ | ||||
| @@ -322,6 +362,8 @@ class PageRev(models.Model): | ||||
|             return self.page.edit_group | ||||
|         elif attr == "view_group": | ||||
|             return self.page.view_group | ||||
|         elif attr == "unset_lock": | ||||
|             return self.page.unset_lock | ||||
|         else: | ||||
|             return object.__getattribute__(self, attr) | ||||
|  | ||||
|   | ||||
| @@ -3,8 +3,10 @@ | ||||
| {% block page %} | ||||
|     <h3>Page</h3> | ||||
|     <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> | ||||
|     {% endif %} | ||||
|     {% if can_edit_prop %} | ||||
|         <p><a href="{% url 'core:page_prop' page.get_full_name %}">Prop</a></p> | ||||
|     {% endif %} | ||||
|     <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): | ||||
|         res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs) | ||||
|         obj = self.object | ||||
|         user = self.request.user | ||||
|         if obj is None: | ||||
|         if self.object is None or self.request.user.is_owner(self.object): | ||||
|             return res | ||||
|         # 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 user.is_superuser or user.groups.filter(name=obj.owner_group.name).exists(): | ||||
|             return res | ||||
|         print("Guyuy") | ||||
|         self.object.unset_lock() | ||||
|         try: # Always unlock when 403 | ||||
|             self.object.unset_lock() | ||||
|         except: pass | ||||
|         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 | ||||
|     object | ||||
|     """ | ||||
|     def dispatch(self, request, *arg, **kwargs): | ||||
|         # TODO: WIP: fix permissions with exceptions! | ||||
|         try: | ||||
|             res = super(CanEditMixin, self).dispatch(request, *arg, **kwargs) | ||||
|             return res | ||||
|         except PermissionDenied: | ||||
|             pass | ||||
|         res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs) | ||||
|         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: | ||||
|         res = super(CanEditMixin, self).dispatch(request, *arg, **kwargs) | ||||
|         if self.object is None or self.request.user.can_edit(self.object): | ||||
|             return res | ||||
|         try: # Always unlock when 403 | ||||
|             self.object.unset_lock() | ||||
|         except: pass | ||||
|         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 | ||||
|     the object | ||||
|     """ | ||||
|     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 | ||||
|         except PermissionDenied: | ||||
|             pass | ||||
|         res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs) | ||||
|         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 | ||||
|         try: # Always unlock when 403 | ||||
|             self.object.unset_lock() | ||||
|         except: pass | ||||
|         raise PermissionDenied | ||||
|  | ||||
| from .user import * | ||||
|   | ||||
| @@ -27,6 +27,11 @@ class PageView(CanViewMixin, DetailView): | ||||
|         context = super(PageView, self).get_context_data(**kwargs) | ||||
|         if "page" not in context.keys(): | ||||
|             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 | ||||
|  | ||||
| class PageHistView(CanViewMixin, DetailView): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user