def authorize(user: User, they: RuleList): def per_role(cls): """Reads _permissions from the given class and creates rules from it.""" perms = getattr(cls, "_permissions") if perms is None or user is None: return # normalize role data type perms = {str(role): p for role, p in perms.items()} for role in user.roles: role_perms = perms.get(role.name) if role_perms is None: continue for action, check in role_perms.items(): # accept all if check == ALL or check is True: they.can(action, cls) # based on attribute values elif isinstance(check, dict): they.can(action, cls, **check) # based on check function elif hasattr(check, "__call__"): def gen_wrapper(check): def wrapper(subject): return check(subject, user) return wrapper they.can(action, cls, gen_wrapper(check)) else: they.can(action, cls, check) if user is not None: they.can(MANAGE, User, id=user.id) they.can(READ, User) they.can("READ_OWN", "Proposal") if user.is_reviewer(): # reviewers can see the list of proposals they.can(READ, "Proposal") if user.is_admin(): # admins can do everything they.can(MANAGE, ALL) # pylint: disable=import-outside-toplevel # import locally to avoid import cycle from data.models.vulnerability import Vulnerability # pylint: enable=import-outside-toplevel per_role(Vulnerability) log.debug("%s can %s", user, they)
def authorize(user: User, they: RuleList): def per_role(cls): """Reads _permissions from the given class and creates rules from it.""" perms = getattr(cls, '_permissions') if perms is None or user is None: return # normalize role data type perms = {str(role): p for role, p in perms.items()} for role in user.roles: role_perms = perms.get(role.name) if role_perms is None: continue for action, check in role_perms.items(): # accept all if check == ALL or check is True: they.can(action, cls) # based on attribute values elif isinstance(check, dict): they.can(action, cls, **check) # based on check function else: they.can(action, cls, check) if user is not None: they.can(MANAGE, User, id=user.id) they.can('READ_OWN', 'Proposal') if user.is_reviewer(): # reviewers can see the list of proposals they.can(READ, 'Proposal') if user.is_admin(): # admins can do everything they.can(MANAGE, ALL) # import locally to avoid import from data.models.vulnerability import Vulnerability per_role(Vulnerability) log.debug('%s can %s', user, they)