Source code for pyechonext.permissions

from abc import ABC, abstractmethod
from typing import Any, Dict, List, Set, Tuple, Type


[docs] class AbstractPermission(ABC): """ This class describes an abstract permission. """ @abstractmethod def __str__(self): """Returns a string representation of the object. Raises: NotImplementedError: abstract method """ raise NotImplementedError()
[docs] class Permission(AbstractPermission): """ This class describes a permission. """
[docs] def __init__(self, name: str): """Initialize a permission Args: name (str): permission name """ self.name: str = name
def __str__(self) -> str: """Returns a string representation of the object. Returns: str: permission name """ return self.name
[docs] class AbstractRole(ABC): """ This class describes an abstract role. """
[docs] @abstractmethod def has_permission(self, permission: Type[AbstractPermission]) -> bool: """Determines if permission Args: permission (AbstractPermission): permission object Raises: NotImplementedError: abstract method Returns: bool: true is has, false otherwise """ raise NotImplementedError()
[docs] @abstractmethod def get_permissions(self) -> Set[AbstractPermission]: """Get list of permissions Raises: NotImplementedError: abstract method Returns: Set[AbstractPermission]: set with abstract permissions """ raise NotImplementedError()
[docs] @abstractmethod def get_name(self) -> str: """Get the role name Raises: NotImplementedError: abstract method Returns: str: role name """ raise NotImplementedError()
[docs] class Role(AbstractRole): """ This class describes a role. """
[docs] def __init__(self, name: str): """Constructs a new instance Args: name (str): role name """ self.name = name self.permissions: Set[AbstractPermission] = set()
[docs] def add_permission(self, permission: AbstractPermission): """Add a permission Args: permission (AbstractPermission): permission object """ self.permissions.add(permission)
[docs] def remove_permission(self, permission: AbstractPermission): """Remove a permission Args: permission (AbstractPermission): permission object """ self.permissions.discard(permission)
[docs] def has_permission(self, permission: AbstractPermission) -> bool: """Determines if permission Args: permission (AbstractPermission): permission object bool: true is has, false otherwise """ return permission in self.permissions
[docs] def get_permissions(self) -> Set[AbstractPermission]: """Get list of permissions Returns: Set[AbstractPermission]: set with abstract permissions """ return self.permissions
[docs] def get_name(self) -> str: """Get the role name Returns: str: role name """ return self.name
[docs] class User: """ This class describes an user. """
[docs] def __init__(self, username: str, attributes: Dict[str, Any] = {}): """Constructs a new instance Args: username (str): name of user attributes (Dict[str, Any], optional): attributes for user. Defaults to {}. """ self.username: str = username self.roles: Set[AbstractRole] = set() self.attributes: Dict[str, Any] = attributes
[docs] def add_role(self, role: AbstractRole): """Adds a role Args: role (AbstractRole): role object """ self.roles.add(role)
[docs] def remove_role(self, role: AbstractRole): """Remove a role Args: role (Type[AbstractRole]): role object """ self.roles.discard(role)
[docs] def has_permission(self, permission: AbstractPermission) -> bool: """Determines if permission Args: permission (Type[AbstractPermission]): permission object Returns: bool: true is has, false otherwise """ perms = [str(perm) for p in self.roles for perm in p.permissions] return str(permission) in perms
[docs] def get_roles(self) -> Set[AbstractRole]: """Get roles Returns: Set[AbstractRole]: roles set """ return self.roles
[docs] def get_username(self) -> str: """Get username Returns: str: username """ return self.username
[docs] class Resource: """ This class describes a resource. """
[docs] def __init__(self, name: str): """Constructs a new resource Args: name (str): resource name """ self.name = name
def __str__(self) -> str: """Returns a string representation of the object. Returns: str: resource name """ return self.name
[docs] class AccessControlRule: """ This class describes an access control rule. """
[docs] def __init__( self, role: Type[AbstractRole], permission: Type[AbstractPermission], resource: Type[Resource], allowed: bool, ): """Constructs a new instance Args: role (Type[AbstractRole]): role object permission (Type[AbstractPermission]): permission object resource (Type[Resource]): resource object allowed (bool): allowed status """ self.role: Type[AbstractRole] = role self.permission: Type[AbstractPermission] = permission self.resource: Type[Resource] = resource self.allowed: bool = allowed
[docs] def applies_to( self, user: User, resource: Type[Resource], permission: Type[AbstractPermission] ) -> bool: """Applies to user Args: user (User): user resource (Type[Resource]): resource permission (Type[AbstractPermission]): permissions Returns: bool: true if is applies, false otherwise """ return ( self.role in user.get_roles() and self.resource == resource and str(self.permission) == str(permission) )
def __str__(self): """Returns a string representation of the object. Returns: str: rule name """ return f"Rule {self.role} {self.permission} {self.resource} {self.allowed}"
[docs] class Policy: """ This class describes a policy. """
[docs] def __init__(self): """ Constructs a new instance. """ self.rules: List[AccessControlRule] = []
[docs] def add_rule(self, rule: AccessControlRule): """Add a new rule Args: rule (AccessControlRule): new rule """ self.rules.append(rule)
[docs] def evaluate( self, user: User, resource: Type[Resource], permission: Type[AbstractPermission] ) -> bool: """Evaluate policty access Args: user (User): user object resource (Resource): resource permission (AbstractPermission): permission Returns: bool: true is allowed, false otherwise """ for rule in self.rules: if rule.applies_to(user, resource, permission): return rule.allowed return False
[docs] class AttributeBasedPolicy(Policy): """ This class describes an attribute based policy. """
[docs] def __init__(self, conditions: Dict[str, Any]): """Constructs a new instance Args: conditions (Dict[str, Any]): conditions dictionary """ super().__init__() self.conditions = conditions
[docs] def evaluate( self, user: User, resource: Type[Resource], permission: Type[AbstractPermission] ) -> bool: """Evaluate policy access Args: user (User): user model resource (Resource): resource model permission (AbstractPermission): permission model Returns: bool: evaluation status """ for condition, value in self.conditions.items(): if user.attributes.get(condition, None) is None: continue return super().evaluate(user, resource, permission)
[docs] class AgeRestrictionsABP(Policy): """ This class describes an age restrictions abp. """
[docs] def __init__(self, conditions: Dict[str, Any], rules: List[AccessControlRule]): """Initialize a Age Policy Args: conditions (Dict[str, Any]): conditions rules (List[AccessControlRule]): rules list """ super().__init__() self.conditions = conditions self.rules += rules
[docs] def evaluate( self, user: User, resource: Type[Resource], permission: Type[AbstractPermission] ) -> bool: """Evaluate policy access Args: user (User): user object resource (Resource): resource object permission (AbstractPermission): permission object Returns: bool: evaluation status """ for condition, value in self.conditions.items(): if user.attributes.get(condition, 0) < value: return False return super().evaluate(user, resource, permission)
[docs] class PermissionChecker(ABC): """ This class describes a permission checker. """
[docs] @abstractmethod def check( self, user: User, resource: Type[Resource], permission: Type[AbstractPermission] ) -> bool: """Check permissions for user Args: user (User): user object resource (Resource): resource object permission (AbstractPermission): permission object Raises: NotImplementedError: abstract method Returns: bool: true is valid, false otherwise """ raise NotImplementedError()
[docs] class DefaultPermissionChecker(PermissionChecker): """ This class describes a default permission checker. """
[docs] def __init__(self, policy: Policy): """Initialize a checker Args: policy (Policy): policy for checkr """ self.policy: Policy = policy
[docs] def check( self, user: User, resource: Type[Resource], permission: Type[AbstractPermission] ) -> bool: """Check user permissions Args: user (User): user object resource (Resource): resource object permission (AbstractPermission): permissions object Returns: bool: true is valid, false otherwise """ if user.has_permission(permission): return self.policy.evaluate(user, resource, permission) return False
[docs] class AbstractController(ABC): """ This class describes a abstract controller. """
[docs] @abstractmethod def __init__(self, permission_checker: PermissionChecker): """Constructs a new instance Args: permission_checker (PermissionChecker): permission checker class """ pass
[docs] @abstractmethod def check( self, current_user: User, resource: Type[Resource], permission: Permission ) -> bool: """Check permissions for user Args: current_user (User): user object resource (Resource): resource object permission (Permission): permission object Raises: NotImplementedError: abstractmethod Returns: bool: true is valid, otherwise false """ raise NotImplementedError()
[docs] class UserController(AbstractController): """ Controls the data flow into an user object and updates the view whenever data changes. """
[docs] def __init__(self, permission_checker: PermissionChecker): """Constructs a new instance Args: permission_checker (PermissionChecker): permission checker class """ self.permission_checker = permission_checker
[docs] def check( self, current_user: User, resource: Type[Resource], permission: Permission ) -> bool: """Check permissions for user Args: current_user (User): current user object resource (Resource): resource object permission (Permission): user permission Returns: bool: True is valid, false otherwise """ return self.permission_checker.check(current_user, resource, permission)
[docs] def view_users(self, current_user: User, resource: Type[Resource]) -> Tuple[str]: """View users by current user and resource Args: current_user (User): current user object resource (Resource): resource object Returns: Tuple[str]: data """ if not self.permission_checker.check( current_user, resource, Permission("view_users") ): return ("403 Forbidden", "You do not have permission to view users.") return ("200 OK", "User edit form")
[docs] def edit_users(self, current_user: User, resource: Type[Resource]) -> Tuple[str]: """Edit users with current user and resource Args: current_user (User): user object resource (Resource): resource object Returns: Tuple[str]: data """ if not self.permission_checker.check( current_user, resource, Permission("edit_users") ): return ("403 Forbidden", "You do not have permission to edit users.") return ("200 OK", "User edit form")