Skip to content

Commit d007ed6

Browse files
Merge pull request #174 from skoranda/idp_metadata_assertion
Encapsulate context internal data - add SP metadata and target entity id
2 parents 91469d6 + 59507b9 commit d007ed6

File tree

6 files changed

+47
-19
lines changed

6 files changed

+47
-19
lines changed

src/satosa/backends/saml2.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import satosa.util as util
1818
from satosa.base import SAMLBaseModule
1919
from satosa.base import SAMLEIDASBaseModule
20+
from satosa.context import Context
2021
from .base import BackendModule
2122
from ..exception import SATOSAAuthenticationError
2223
from ..internal_data import (InternalResponse,
@@ -92,15 +93,13 @@ def start_auth(self, context, internal_req):
9293
if len(idps) == 1 and "mdq" not in self.config["sp_config"]["metadata"]:
9394
return self.authn_request(context, idps[0])
9495

95-
try:
96-
# find mirrored entity id
97-
entity_id = context.internal_data["mirror.target_entity_id"]
98-
except KeyError:
99-
# redirect to discovery server
96+
entity_id = context.get_decoration(
97+
Context.KEY_MIRROR_TARGET_ENTITYID)
98+
if None is entity_id:
10099
return self.disco_query()
101-
else:
102-
entity_id = urlsafe_b64decode(entity_id).decode("utf-8")
103-
return self.authn_request(context, entity_id)
100+
101+
entity_id = urlsafe_b64decode(entity_id).decode("utf-8")
102+
return self.authn_request(context, entity_id)
104103

105104
def disco_query(self):
106105
"""
@@ -230,6 +229,8 @@ def authn_response(self, context, binding):
230229
"State did not match relay state for state", context.state)
231230
raise SATOSAAuthenticationError(context.state, "State did not match relay state")
232231

232+
context.decorate(Context.KEY_BACKEND_METADATA_STORE, self.sp.metadata)
233+
233234
del context.state[self.name]
234235
return self.auth_callback_func(context, self._translate_response(authn_response, context.state))
235236

src/satosa/context.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
"""
2-
Holds methods for sending internal data through the satosa proxy
3-
"""
41
from .exception import SATOSAError
52

63

@@ -11,10 +8,15 @@ class SATOSABadContextError(SATOSAError):
118
pass
129

1310

11+
"""
12+
Holds methods for sending internal data through the satosa proxy
13+
"""
1414
class Context(object):
1515
"""
1616
Holds information about the current request.
1717
"""
18+
KEY_BACKEND_METADATA_STORE = 'metadata_store'
19+
KEY_MIRROR_TARGET_ENTITYID = 'mirror_target_entity_id'
1820

1921
def __init__(self):
2022
self._path = None
@@ -60,3 +62,19 @@ def path(self, p):
6062
elif p.startswith('/'):
6163
raise ValueError("path can't start with '/'")
6264
self._path = p
65+
66+
def decorate(self, key, value):
67+
"""
68+
Add information to the context
69+
"""
70+
71+
self.internal_data[key] = value
72+
return self
73+
74+
def get_decoration(self, key):
75+
"""
76+
Retrieve information from the context
77+
"""
78+
79+
value = self.internal_data.get(key)
80+
return value

src/satosa/frontends/saml2.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from saml2.server import Server
1717

1818
from satosa.base import SAMLBaseModule
19+
from satosa.context import Context
1920
from .base import FrontendModule
2021
from ..internal_data import InternalRequest, UserIdHashType
2122
from ..logging_util import satosa_logging
@@ -503,7 +504,7 @@ def _load_idp_dynamic_endpoints(self, context):
503504
:return: An idp server
504505
"""
505506
target_entity_id = context.path.split("/")[1]
506-
context.internal_data["mirror.target_entity_id"] = target_entity_id
507+
context.decorate(Context.KEY_MIRROR_TARGET_ENTITYID, target_entity_id)
507508
idp_conf_file = self._load_endpoints_to_config(context.target_backend, target_entity_id)
508509
idp_config = IdPConfig().load(idp_conf_file, metadata_construction=False)
509510
return Server(config=idp_config)

src/satosa/micro_services/custom_routing.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import logging
22
from base64 import urlsafe_b64encode
33

4+
from satosa.context import Context
5+
46
from .base import RequestMicroService
57
from ..exception import SATOSAConfigurationError
68
from ..exception import SATOSAError
@@ -56,9 +58,9 @@ def _b64_url(self, data):
5658
return urlsafe_b64encode(data.encode("utf-8")).decode("utf-8")
5759

5860
def process(self, context, data):
59-
try:
60-
target_entity_id = context.internal_data["mirror.target_entity_id"]
61-
except KeyError:
61+
target_entity_id = context.get_decoration(
62+
Context.KEY_MIRROR_TARGET_ENTITYID)
63+
if None is target_entity_id:
6264
logger.error("DecideIfRequesterIsAllowed can only be used with SAMLMirrorFrontend")
6365
raise SATOSAError("DecideIfRequesterIsAllowed can only be used with SAMLMirrorFrontend")
6466

tests/satosa/backends/test_saml2.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,12 @@ def test_full_flow(self, context, idp_conf, sp_conf):
141141
assert context.state[test_state_key] == "my_state"
142142
self.assert_authn_response(internal_resp)
143143

144-
def test_start_auth_redirects_directly_to_mirrored_idp(self, context, idp_conf):
145-
context.internal_data["mirror.target_entity_id"] = urlsafe_b64encode(
146-
idp_conf["entityid"].encode("utf-8")).decode("utf-8")
144+
def test_start_auth_redirects_directly_to_mirrored_idp(
145+
self, context, idp_conf):
146+
entityid = idp_conf["entityid"]
147+
entityid_bytes = entityid.encode("utf-8")
148+
entityid_b64_str = urlsafe_b64encode(entityid_bytes).decode("utf-8")
149+
context.decorate(Context.KEY_MIRROR_TARGET_ENTITYID, entityid_b64_str)
147150

148151
resp = self.samlbackend.start_auth(context, InternalRequest(None, None))
149152
self.assert_redirect_to_idp(resp, idp_conf)

tests/satosa/micro_services/test_custom_routing.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44

5+
from satosa.context import Context
56
from satosa.exception import SATOSAError, SATOSAConfigurationError
67
from satosa.internal_data import InternalRequest
78
from satosa.micro_services.custom_routing import DecideIfRequesterIsAllowed
@@ -11,7 +12,9 @@
1112

1213
@pytest.fixture
1314
def target_context(context):
14-
context.internal_data["mirror.target_entity_id"] = urlsafe_b64encode(TARGET_ENTITY.encode("utf-8")).decode("utf-8")
15+
entityid_bytes = TARGET_ENTITY.encode("utf-8")
16+
entityid_b64_str = urlsafe_b64encode(entityid_bytes).decode("utf-8")
17+
context.decorate(Context.KEY_MIRROR_TARGET_ENTITYID, entityid_b64_str)
1518
return context
1619

1720

0 commit comments

Comments
 (0)