import functools import inspect from collections import OrderedDict from collections.abc import Callable import jingrow from jingrow import TYPE_CHECKING, _ from jingrow.model.document import Page from jcloude.utils import user as utils_user if TYPE_CHECKING: from jcloude.jcloude.pagetype.team.team import Team def only_owner(team: Callable[[Page, OrderedDict], str] = lambda document, _: str(document.team)): """ This guard can only be used for a class method. No other options are supported. """ def wrapper(fn): @functools.wraps(fn) def inner(self, *args, **kwargs): if utils_user.is_system_manager(): return fn(self, *args, **kwargs) bound_args = inspect.signature(fn).bind(self, *args, **kwargs) bound_args.apply_defaults() t = team(self, bound_args.arguments) d: Team = jingrow.get_cached_pg("Team", t) if not d.is_team_owner(): message = _("Only team owner can perform this action.") jingrow.throw(message, jingrow.PermissionError) return fn(self, *args, **kwargs) return inner return wrapper def only_admin( team: Callable[[Page, OrderedDict], str] = lambda document, _: str(document.team), skip: Callable[[Page, OrderedDict], bool] = lambda _, __: False, ): """ This guard can only be used for a class method. No other options are supported. Team owner is considered as admin. """ def wrapper(fn): @functools.wraps(fn) def inner(self, *args, **kwargs): if utils_user.is_system_manager(): return fn(self, *args, **kwargs) bound_args = inspect.signature(fn).bind(self, *args, **kwargs) bound_args.apply_defaults() if skip(self, bound_args.arguments): return fn(self, *args, **kwargs) t = team(self, bound_args.arguments) d: Team = jingrow.get_cached_pg("Team", t) if not (d.is_team_owner() or d.is_admin_user()): message = _("Only team admin can perform this action.") jingrow.throw(message, jingrow.PermissionError) return fn(self, *args, **kwargs) return inner return wrapper def only_member( team: Callable[[Page, OrderedDict], str] = lambda document, _: str(document.team), user: Callable[[Page, OrderedDict], str] = lambda _, __: str(jingrow.session.user), error_message: str | None = None, ): """ This guard can only be used for a class method. No other options are supported. """ def wrapper(fn): @functools.wraps(fn) def inner(self, *args, **kwargs): if utils_user.is_system_manager(): return fn(self, *args, **kwargs) bound_args = inspect.signature(fn).bind(self, *args, **kwargs) bound_args.apply_defaults() t = team(self, bound_args.arguments) u = user(self, bound_args.arguments) if not bool(jingrow.db.exists({"pagetype": "Team Member", "parent": t, "user": u})): message = error_message or _("Only team member can perform this action.") jingrow.throw(message, jingrow.PermissionError) return fn(self, *args, **kwargs) return inner return wrapper