Skip to content

Commit 848f773

Browse files
committed
Merge remote-tracking branch 'origin/rh_wkis3' into rh_wkis3
2 parents 6596de8 + 67a6fd2 commit 848f773

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import logging
2+
from base64 import urlsafe_b64encode
3+
4+
from satosa.context import Context
5+
6+
from .base import RequestMicroService
7+
from ..exception import SATOSAConfigurationError
8+
from ..exception import SATOSAError
9+
10+
logger = logging.getLogger(__name__)
11+
12+
13+
class FilterRequester(RequestMicroService):
14+
"""
15+
Decide whether a requester is allowed to send an authentication request to the target entity based on a whitelist
16+
"""
17+
def __init__(self, config, *args, **kwargs):
18+
super().__init__(*args, **kwargs)
19+
20+
for target_entity, rules in config["rules"].items():
21+
conflicting_rules = set(rules.get("deny", [])).intersection(rules.get("allow", []))
22+
if conflicting_rules:
23+
raise SATOSAConfigurationError("Conflicting requester rules for FilterRequester,"
24+
"{} is both denied and allowed".format(conflicting_rules))
25+
26+
self.rules = {self._b64_url(k): v for k, v in config["rules"].items()}
27+
self.conf_target_entity_id = config.get('target_entity_id', None)
28+
29+
def process(self, context, data):
30+
target_entity_id = context.get_decoration(Context.KEY_TARGET_ENTITYID) or self.conf_target_entity_id
31+
if None is target_entity_id:
32+
msg_tpl = "{name} can only be used when a target entityid is set"
33+
msg = msg_tpl.format(name=self.__class__.__name__)
34+
logger.error(msg)
35+
raise SATOSAError(msg)
36+
37+
target_specific_rules = self.rules.get(target_entity_id)
38+
# default to allowing everything if there are no specific rules
39+
if not target_specific_rules:
40+
logging.debug("Requester '%s' allowed by default to target entity '%s' due to no entity specific rules",
41+
data.requester, target_entity_id)
42+
return super().process(context, data)
43+
44+
# deny rules takes precedence
45+
deny_rules = target_specific_rules.get("deny", [])
46+
if data.requester in deny_rules:
47+
logging.debug("Requester '%s' is not allowed by target entity '%s' due to deny rules '%s'", data.requester,
48+
target_entity_id, deny_rules)
49+
raise SATOSAError("Requester is not allowed by target provider")
50+
51+
allow_rules = target_specific_rules.get("allow", [])
52+
allow_all = "*" in allow_rules
53+
if data.requester in allow_rules or allow_all:
54+
logging.debug("Requester '%s' allowed by target entity '%s' due to allow rules '%s",
55+
data.requester, target_entity_id, allow_rules)
56+
return super().process(context, data)
57+
58+
logger.debug("Requester '%s' is not allowed by target entity '%s' due to final deny all rule in '%s'",
59+
data.requester, target_entity_id, deny_rules)
60+
raise SATOSAError("Requester is not allowed by target provider")

0 commit comments

Comments
 (0)