mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-30 23:39:54 +01:00 
			
		
		
		
	The memoization doesn't work when objects don't have a primary key.
This commit is contained in:
		| @@ -61,7 +61,7 @@ class MembershipTable(tables.Table): | |||||||
|  |  | ||||||
|     def render_club(self, value): |     def render_club(self, value): | ||||||
|         s = value.name |         s = value.name | ||||||
|         if PermissionBackend().has_perm(get_current_authenticated_user(), "member.view_club", value): |         if PermissionBackend.check_perm(get_current_authenticated_user(), "member.view_club", value): | ||||||
|             s = format_html("<a href={url}>{name}</a>", |             s = format_html("<a href={url}>{name}</a>", | ||||||
|                             url=reverse_lazy('member:club_detail', kwargs={"pk": value.pk}), name=s) |                             url=reverse_lazy('member:club_detail', kwargs={"pk": value.pk}), name=s) | ||||||
|  |  | ||||||
| @@ -86,7 +86,7 @@ class MembershipTable(tables.Table): | |||||||
|                         date_end=datetime.now().date(), |                         date_end=datetime.now().date(), | ||||||
|                         fee=0, |                         fee=0, | ||||||
|                     ) |                     ) | ||||||
|                     if PermissionBackend().has_perm(get_current_authenticated_user(), |                     if PermissionBackend.check_perm(get_current_authenticated_user(), | ||||||
|                                                     "member:add_membership", empty_membership):  # If the user has right |                                                     "member:add_membership", empty_membership):  # If the user has right | ||||||
|                         t = format_html(t + ' <a class="btn btn-warning" href="{url}">{text}</a>', |                         t = format_html(t + ' <a class="btn btn-warning" href="{url}">{text}</a>', | ||||||
|                                         url=reverse_lazy('member:club_renew_membership', |                                         url=reverse_lazy('member:club_renew_membership', | ||||||
| @@ -96,7 +96,7 @@ class MembershipTable(tables.Table): | |||||||
|     def render_roles(self, record): |     def render_roles(self, record): | ||||||
|         roles = record.roles.all() |         roles = record.roles.all() | ||||||
|         s = ", ".join(str(role) for role in roles) |         s = ", ".join(str(role) for role in roles) | ||||||
|         if PermissionBackend().has_perm(get_current_authenticated_user(), "member.change_membership_roles", record): |         if PermissionBackend.check_perm(get_current_authenticated_user(), "member.change_membership_roles", record): | ||||||
|             s = format_html("<a href='" + str(reverse_lazy("member:club_manage_roles", kwargs={"pk": record.pk})) |             s = format_html("<a href='" + str(reverse_lazy("member:club_manage_roles", kwargs={"pk": record.pk})) | ||||||
|                             + "'>" + s + "</a>") |                             + "'>" + s + "</a>") | ||||||
|         return s |         return s | ||||||
|   | |||||||
| @@ -299,7 +299,7 @@ class ClubDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): | |||||||
|         context = super().get_context_data(**kwargs) |         context = super().get_context_data(**kwargs) | ||||||
|  |  | ||||||
|         club = context["club"] |         club = context["club"] | ||||||
|         if PermissionBackend().has_perm(self.request.user, "member.change_club_membership_start", club): |         if PermissionBackend.check_perm(self.request.user, "member.change_club_membership_start", club): | ||||||
|             club.update_membership_dates() |             club.update_membership_dates() | ||||||
|  |  | ||||||
|         club_transactions = Transaction.objects.all().filter(Q(source=club.note) | Q(destination=club.note))\ |         club_transactions = Transaction.objects.all().filter(Q(source=club.note) | Q(destination=club.note))\ | ||||||
|   | |||||||
| @@ -114,8 +114,16 @@ class PermissionBackend(ModelBackend): | |||||||
|             query = query | perm.query |             query = query | perm.query | ||||||
|         return query |         return query | ||||||
|  |  | ||||||
|  |     @staticmethod | ||||||
|     @memoize |     @memoize | ||||||
|     def has_perm(self, user_obj, perm, obj=None): |     def check_perm(user_obj, perm, obj=None): | ||||||
|  |         """ | ||||||
|  |         Check is the given user has the permission over a given object. | ||||||
|  |         The result is then memoized. | ||||||
|  |         Exception: for add permissions, since the object is not hashable since it doesn't have any | ||||||
|  |         primary key, the result is not memoized. Moreover, the right could change | ||||||
|  |         (e.g. for a transaction, the balance of the user could change) | ||||||
|  |         """ | ||||||
|         if user_obj is None or isinstance(user_obj, AnonymousUser): |         if user_obj is None or isinstance(user_obj, AnonymousUser): | ||||||
|             return False |             return False | ||||||
|  |  | ||||||
| @@ -134,10 +142,13 @@ class PermissionBackend(ModelBackend): | |||||||
|         perm_field = perm[2] if len(perm) == 3 else None |         perm_field = perm[2] if len(perm) == 3 else None | ||||||
|         ct = ContentType.objects.get_for_model(obj) |         ct = ContentType.objects.get_for_model(obj) | ||||||
|         if any(permission.applies(obj, perm_type, perm_field) |         if any(permission.applies(obj, perm_type, perm_field) | ||||||
|                for permission in self.permissions(user_obj, ct, perm_type)): |                for permission in PermissionBackend.permissions(user_obj, ct, perm_type)): | ||||||
|             return True |             return True | ||||||
|         return False |         return False | ||||||
|  |  | ||||||
|  |     def has_perm(self, user_obj, perm, obj=None): | ||||||
|  |         return PermissionBackend.check_perm(user_obj, perm, obj) | ||||||
|  |  | ||||||
|     def has_module_perms(self, user_obj, app_label): |     def has_module_perms(self, user_obj, app_label): | ||||||
|         return False |         return False | ||||||
|  |  | ||||||
|   | |||||||
| @@ -49,7 +49,10 @@ def memoize(f): | |||||||
|             # lru_cache makes the job of memoization |             # lru_cache makes the job of memoization | ||||||
|             # We store only the 512 latest data per session. It has to be enough. |             # We store only the 512 latest data per session. It has to be enough. | ||||||
|             sess_funs[sess_key] = lru_cache(512)(f) |             sess_funs[sess_key] = lru_cache(512)(f) | ||||||
|         return sess_funs[sess_key](*args, **kwargs) |         try: | ||||||
|  |             return sess_funs[sess_key](*args, **kwargs) | ||||||
|  |         except TypeError:  # For add permissions, objects are not hashable (not yet created). Don't memoize this case. | ||||||
|  |             return f(*args, **kwargs) | ||||||
|  |  | ||||||
|     func.func_name = f.__name__ |     func.func_name = f.__name__ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ class StrongDjangoObjectPermissions(DjangoObjectPermissions): | |||||||
|  |  | ||||||
|         perms = self.get_required_object_permissions(request.method, model_cls) |         perms = self.get_required_object_permissions(request.method, model_cls) | ||||||
|         # if not user.has_perms(perms, obj): |         # if not user.has_perms(perms, obj): | ||||||
|         if not all(PermissionBackend().has_perm(user, perm, obj) for perm in perms): |         if not all(PermissionBackend.check_perm(user, perm, obj) for perm in perms): | ||||||
|             # If the user does not have permissions we need to determine if |             # If the user does not have permissions we need to determine if | ||||||
|             # they have read permissions to see 403, or not, and simply see |             # they have read permissions to see 403, or not, and simply see | ||||||
|             # a 404 response. |             # a 404 response. | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ def pre_save_object(sender, instance, **kwargs): | |||||||
|         # We check if the user can change the model |         # We check if the user can change the model | ||||||
|  |  | ||||||
|         # If the user has all right on a model, then OK |         # If the user has all right on a model, then OK | ||||||
|         if PermissionBackend().has_perm(user, app_label + ".change_" + model_name, instance): |         if PermissionBackend.check_perm(user, app_label + ".change_" + model_name, instance): | ||||||
|             return |             return | ||||||
|  |  | ||||||
|         # In the other case, we check if he/she has the right to change one field |         # In the other case, we check if he/she has the right to change one field | ||||||
| @@ -56,11 +56,11 @@ def pre_save_object(sender, instance, **kwargs): | |||||||
|             # If the field wasn't modified, no need to check the permissions |             # If the field wasn't modified, no need to check the permissions | ||||||
|             if old_value == new_value: |             if old_value == new_value: | ||||||
|                 continue |                 continue | ||||||
|             if not PermissionBackend().has_perm(user, app_label + ".change_" + model_name + "_" + field_name, instance): |             if not PermissionBackend.check_perm(user, app_label + ".change_" + model_name + "_" + field_name, instance): | ||||||
|                 raise PermissionDenied |                 raise PermissionDenied | ||||||
|     else: |     else: | ||||||
|         # We check if the user has right to add the object |         # We check if the user has right to add the object | ||||||
|         has_perm = PermissionBackend().has_perm(user, app_label + ".add_" + model_name, instance) |         has_perm = PermissionBackend.check_perm(user, app_label + ".add_" + model_name, instance) | ||||||
|  |  | ||||||
|         if not has_perm: |         if not has_perm: | ||||||
|             raise PermissionDenied |             raise PermissionDenied | ||||||
| @@ -87,5 +87,5 @@ def pre_delete_object(instance, **kwargs): | |||||||
|     model_name = model_name_full[1] |     model_name = model_name_full[1] | ||||||
|  |  | ||||||
|     # We check if the user has rights to delete the object |     # We check if the user has rights to delete the object | ||||||
|     if not PermissionBackend().has_perm(user, app_label + ".delete_" + model_name, instance): |     if not PermissionBackend.check_perm(user, app_label + ".delete_" + model_name, instance): | ||||||
|         raise PermissionDenied |         raise PermissionDenied | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ def model_list(model_name, t="view"): | |||||||
|  |  | ||||||
|  |  | ||||||
| def has_perm(perm, obj): | def has_perm(perm, obj): | ||||||
|     return PermissionBackend().has_perm(get_current_authenticated_user(), perm, obj) |     return PermissionBackend.check_perm(get_current_authenticated_user(), perm, obj) | ||||||
|  |  | ||||||
|  |  | ||||||
| def can_create_transaction(): | def can_create_transaction(): | ||||||
| @@ -77,7 +77,7 @@ def can_create_transaction(): | |||||||
|         amount=0, |         amount=0, | ||||||
|         reason="Check permissions", |         reason="Check permissions", | ||||||
|     ) |     ) | ||||||
|     session["can_create_transaction"] = PermissionBackend().has_perm(user, "note.add_transaction", empty_transaction) |     session["can_create_transaction"] = PermissionBackend.check_perm(user, "note.add_transaction", empty_transaction) | ||||||
|     return session.get("can_create_transaction") == 1 |     return session.get("can_create_transaction") == 1 | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user