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,
}