Source code for arpoc.ac.conflict_resolution

"""
Conflict Resolution Module for ARPOC.

Provides functions to use to evaluate how Policies and Policy Sets
combine the results of the rules they use.

Every resolver should inherit from ConflictResolution.

"""
from enum import Enum
from typing import Callable, Dict, Optional

from .common import Effects


[docs]class ConflictResolution: """ Base Class for all ConflictResolution Objects. Normally a child-class should just implement the update method """ def __init__(self) -> None: self._results: Dict[str, Optional[Effects]] = dict() self._break: bool = False self._effect: Optional[Effects] = None def __str__(self) -> str: return "Effect: {}\nBreak:{}\nResults:{}".format( self._results, self._break, self._effect)
[docs] def update(self, entity_id: str, result: Optional[Effects]) -> None: assert isinstance( result, Effects ) or result is None, "type was: %s, expected: None, Effects" % type( result) self._results[entity_id] = result
[docs] def check_break(self) -> bool: return self._break
[docs] def get_effect(self) -> Optional[Effects]: return self._effect
[docs]class AnyOfAny(ConflictResolution): """ Resolver that grants access as soon as a returned True """
[docs] def update(self, entity_id: str, result: Optional[Effects]) -> None: super().update(entity_id, result) if self._effect is None and result == Effects.DENY: self._effect = Effects.DENY if result == Effects.GRANT: self._break = True self._effect = Effects.GRANT
[docs]class And(ConflictResolution): """ Resolver that grants access only if all rules returned True """
[docs] def update(self, entity_id: str, result: Optional[Effects]) -> None: super().update(entity_id, result) if result == Effects.GRANT and self._effect is None: self._effect = Effects.GRANT if result == Effects.DENY: self._break = True self._effect = Effects.DENY
cr_switcher: Dict[str, Callable] = { "ANY": AnyOfAny, "AND": And, }