Skip to content

Commit 6c8e086

Browse files
author
Roland Hedberg
committed
Merge branch 'master' of github.com:rohe/pysaml2
2 parents c857134 + 75ae22e commit 6c8e086

File tree

3 files changed

+82
-59
lines changed

3 files changed

+82
-59
lines changed

src/saml2/client_base.py

Lines changed: 72 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,16 @@ class Base(Entity):
8989
""" The basic pySAML2 service provider class """
9090

9191
def __init__(self, config=None, identity_cache=None, state_cache=None,
92-
virtual_organization="", config_file=""):
92+
virtual_organization="", config_file="", msg_cb=None):
9393
"""
9494
:param config: A saml2.config.Config instance
9595
:param identity_cache: Where the class should store identity information
9696
:param state_cache: Where the class should keep state information
9797
:param virtual_organization: A specific virtual organization
9898
"""
9999

100-
Entity.__init__(self, "sp", config, config_file, virtual_organization)
100+
Entity.__init__(self, "sp", config, config_file, virtual_organization,
101+
msg_cb=msg_cb)
101102

102103
self.users = Population(identity_cache)
103104
self.lock = threading.Lock()
@@ -150,7 +151,8 @@ def _sso_location(self, entityid=None, binding=BINDING_HTTP_REDIRECT):
150151
raise IdpUnspecified("Too many IdPs to choose from: %s" % eids)
151152

152153
try:
153-
srvs = self.metadata.single_sign_on_service(list(eids.keys())[0], binding)
154+
srvs = self.metadata.single_sign_on_service(list(eids.keys())[0],
155+
binding)
154156
return destinations(srvs)[0]
155157
except IndexError:
156158
raise IdpUnspecified("No IdP to send to given the premises")
@@ -186,7 +188,7 @@ def add_vo_information_about_user(self, name_id):
186188
ava = self.users.get_identity(name_id)[0]
187189
return ava
188190

189-
#noinspection PyUnusedLocal
191+
# noinspection PyUnusedLocal
190192
@staticmethod
191193
def is_session_valid(_session_id):
192194
""" Place holder. Supposed to check if the session is still valid.
@@ -201,11 +203,12 @@ def service_urls(self, binding=BINDING_HTTP_POST):
201203
return None
202204

203205
def create_authn_request(self, destination, vorg="", scoping=None,
204-
binding=saml2.BINDING_HTTP_POST,
205-
nameid_format=None,
206-
service_url_binding=None, message_id=0,
207-
consent=None, extensions=None, sign=None,
208-
allow_create=False, sign_prepare=False, sign_alg=None, digest_alg=None, **kwargs):
206+
binding=saml2.BINDING_HTTP_POST,
207+
nameid_format=None,
208+
service_url_binding=None, message_id=0,
209+
consent=None, extensions=None, sign=None,
210+
allow_create=False, sign_prepare=False, sign_alg=None,
211+
digest_alg=None, **kwargs):
209212
""" Creates an authentication request.
210213
211214
:param destination: Where the request should be sent.
@@ -244,7 +247,7 @@ def create_authn_request(self, destination, vorg="", scoping=None,
244247
except KeyError:
245248
try:
246249
args["assertion_consumer_service_index"] = str(kwargs[
247-
"assertion_consumer_service_index"])
250+
"assertion_consumer_service_index"])
248251
del kwargs["assertion_consumer_service_index"]
249252
except KeyError:
250253
if service_url_binding is None:
@@ -281,7 +284,6 @@ def create_authn_request(self, destination, vorg="", scoping=None,
281284
raise ValueError("%s or wrong type expected %s" % (_item,
282285
param))
283286

284-
285287
try:
286288
args["name_id_policy"] = kwargs["name_id_policy"]
287289
del kwargs["name_id_policy"]
@@ -303,7 +305,6 @@ def create_authn_request(self, destination, vorg="", scoping=None,
303305
# NameIDPolicy can only have one format specified
304306
nameid_format = nameid_format[0]
305307

306-
307308
name_id_policy = samlp.NameIDPolicy(allow_create=allow_create,
308309
format=nameid_format)
309310

@@ -334,24 +335,28 @@ def create_authn_request(self, destination, vorg="", scoping=None,
334335
sign = self.authn_requests_signed
335336

336337
if (sign and self.sec.cert_handler.generate_cert()) or \
337-
client_crt is not None:
338+
client_crt is not None:
338339
with self.lock:
339340
self.sec.cert_handler.update_cert(True, client_crt)
340341
if client_crt is not None:
341342
sign_prepare = True
342343
return self._message(AuthnRequest, destination, message_id,
343344
consent, extensions, sign, sign_prepare,
344345
protocol_binding=binding,
345-
scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args)
346+
scoping=scoping, nsprefix=nsprefix,
347+
sign_alg=sign_alg, digest_alg=digest_alg,
348+
**args)
346349
return self._message(AuthnRequest, destination, message_id, consent,
347350
extensions, sign, sign_prepare,
348351
protocol_binding=binding,
349-
scoping=scoping, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg, **args)
352+
scoping=scoping, nsprefix=nsprefix,
353+
sign_alg=sign_alg, digest_alg=digest_alg, **args)
350354

351355
def create_attribute_query(self, destination, name_id=None,
352-
attribute=None, message_id=0, consent=None,
353-
extensions=None, sign=False, sign_prepare=False, sign_alg=None, digest_alg=None,
354-
**kwargs):
356+
attribute=None, message_id=0, consent=None,
357+
extensions=None, sign=False, sign_prepare=False, sign_alg=None,
358+
digest_alg=None,
359+
**kwargs):
355360
""" Constructs an AttributeQuery
356361
357362
:param destination: To whom the query should be sent
@@ -407,15 +412,16 @@ def create_attribute_query(self, destination, name_id=None,
407412

408413
return self._message(AttributeQuery, destination, message_id, consent,
409414
extensions, sign, sign_prepare, subject=subject,
410-
attribute=attribute, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg)
415+
attribute=attribute, nsprefix=nsprefix,
416+
sign_alg=sign_alg, digest_alg=digest_alg)
411417

412418
# MUST use SOAP for
413419
# AssertionIDRequest, SubjectQuery,
414420
# AuthnQuery, AttributeQuery, or AuthzDecisionQuery
415421
def create_authz_decision_query(self, destination, action,
416-
evidence=None, resource=None, subject=None,
417-
message_id=0, consent=None, extensions=None,
418-
sign=None, sign_alg=None, digest_alg=None, **kwargs):
422+
evidence=None, resource=None, subject=None,
423+
message_id=0, consent=None, extensions=None,
424+
sign=None, sign_alg=None, digest_alg=None, **kwargs):
419425
""" Creates an authz decision query.
420426
421427
:param destination: The IdP endpoint
@@ -433,15 +439,16 @@ def create_authz_decision_query(self, destination, action,
433439
return self._message(AuthzDecisionQuery, destination, message_id,
434440
consent, extensions, sign, action=action,
435441
evidence=evidence, resource=resource,
436-
subject=subject, sign_alg=sign_alg, digest_alg=digest_alg, **kwargs)
442+
subject=subject, sign_alg=sign_alg,
443+
digest_alg=digest_alg, **kwargs)
437444

438445
def create_authz_decision_query_using_assertion(self, destination,
439-
assertion, action=None,
440-
resource=None,
441-
subject=None, message_id=0,
442-
consent=None,
443-
extensions=None,
444-
sign=False, nsprefix=None):
446+
assertion, action=None,
447+
resource=None,
448+
subject=None, message_id=0,
449+
consent=None,
450+
extensions=None,
451+
sign=False, nsprefix=None):
445452
""" Makes an authz decision query based on a previously received
446453
Assertion.
447454
@@ -466,9 +473,9 @@ def create_authz_decision_query_using_assertion(self, destination,
466473
_action = None
467474

468475
return self.create_authz_decision_query(
469-
destination, _action, saml.Evidence(assertion=assertion),
470-
resource, subject, message_id=message_id, consent=consent,
471-
extensions=extensions, sign=sign, nsprefix=nsprefix)
476+
destination, _action, saml.Evidence(assertion=assertion),
477+
resource, subject, message_id=message_id, consent=consent,
478+
extensions=extensions, sign=sign, nsprefix=nsprefix)
472479

473480
@staticmethod
474481
def create_assertion_id_request(assertion_id_refs, **kwargs):
@@ -484,8 +491,9 @@ def create_assertion_id_request(assertion_id_refs, **kwargs):
484491
return 0, assertion_id_refs[0]
485492

486493
def create_authn_query(self, subject, destination=None, authn_context=None,
487-
session_index="", message_id=0, consent=None,
488-
extensions=None, sign=False, nsprefix=None, sign_alg=None, digest_alg=None):
494+
session_index="", message_id=0, consent=None,
495+
extensions=None, sign=False, nsprefix=None, sign_alg=None,
496+
digest_alg=None):
489497
"""
490498
491499
:param subject: The subject its all about as a <Subject> instance
@@ -502,14 +510,15 @@ def create_authn_query(self, subject, destination=None, authn_context=None,
502510
extensions, sign, subject=subject,
503511
session_index=session_index,
504512
requested_authn_context=authn_context,
505-
nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg)
513+
nsprefix=nsprefix, sign_alg=sign_alg,
514+
digest_alg=digest_alg)
506515

507516
def create_name_id_mapping_request(self, name_id_policy,
508-
name_id=None, base_id=None,
509-
encrypted_id=None, destination=None,
510-
message_id=0, consent=None,
511-
extensions=None, sign=False,
512-
nsprefix=None, sign_alg=None, digest_alg=None):
517+
name_id=None, base_id=None,
518+
encrypted_id=None, destination=None,
519+
message_id=0, consent=None,
520+
extensions=None, sign=False,
521+
nsprefix=None, sign_alg=None, digest_alg=None):
513522
"""
514523
515524
:param name_id_policy:
@@ -531,31 +540,37 @@ def create_name_id_mapping_request(self, name_id_policy,
531540
return self._message(NameIDMappingRequest, destination, message_id,
532541
consent, extensions, sign,
533542
name_id_policy=name_id_policy, name_id=name_id,
534-
nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg)
543+
nsprefix=nsprefix, sign_alg=sign_alg,
544+
digest_alg=digest_alg)
535545
elif base_id:
536546
return self._message(NameIDMappingRequest, destination, message_id,
537547
consent, extensions, sign,
538548
name_id_policy=name_id_policy, base_id=base_id,
539-
nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg)
549+
nsprefix=nsprefix, sign_alg=sign_alg,
550+
digest_alg=digest_alg)
540551
else:
541552
return self._message(NameIDMappingRequest, destination, message_id,
542553
consent, extensions, sign,
543554
name_id_policy=name_id_policy,
544-
encrypted_id=encrypted_id, nsprefix=nsprefix, sign_alg=sign_alg, digest_alg=digest_alg)
555+
encrypted_id=encrypted_id, nsprefix=nsprefix,
556+
sign_alg=sign_alg, digest_alg=digest_alg)
545557

546558
# ======== response handling ===========
547559

548560
def parse_authn_request_response(self, xmlstr, binding, outstanding=None,
549-
outstanding_certs=None):
561+
outstanding_certs=None):
550562
""" Deal with an AuthnResponse
551563
552564
:param xmlstr: The reply as a xml string
553565
:param binding: Which binding that was used for the transport
554566
:param outstanding: A dictionary with session IDs as keys and
555567
the original web request from the user before redirection
556568
as values.
557-
:param only_identity_in_encrypted_assertion: Must exist an assertion that is not encrypted that contains all
558-
other information like subject and authentication statement.
569+
:param only_identity_in_encrypted_assertion: Must exist an assertion
570+
that is not encrypted that contains all
571+
other information like
572+
subject and
573+
authentication statement.
559574
:return: An response.AuthnResponse or None
560575
"""
561576

@@ -576,7 +591,7 @@ def parse_authn_request_response(self, xmlstr, binding, outstanding=None,
576591
"entity_id": self.config.entityid,
577592
"attribute_converters": self.config.attribute_converters,
578593
"allow_unknown_attributes":
579-
self.config.allow_unknown_attributes,
594+
self.config.allow_unknown_attributes,
580595
}
581596
try:
582597
resp = self._parse_response(xmlstr, AuthnResponse,
@@ -594,20 +609,22 @@ def parse_authn_request_response(self, xmlstr, binding, outstanding=None,
594609
if resp is None:
595610
return None
596611
elif isinstance(resp, AuthnResponse):
597-
if resp.assertion is not None and len(resp.response.encrypted_assertion) == 0:
612+
if resp.assertion is not None and len(
613+
resp.response.encrypted_assertion) == 0:
598614
self.users.add_information_about_person(resp.session_info())
599615
logger.info("--- ADDED person info ----")
600616
pass
601617
else:
602-
logger.error("Response type not supported: %s", saml2.class_name(resp))
618+
logger.error("Response type not supported: %s",
619+
saml2.class_name(resp))
603620
return resp
604621

605622
# ------------------------------------------------------------------------
606623
# SubjectQuery, AuthnQuery, RequestedAuthnContext, AttributeQuery,
607624
# AuthzDecisionQuery all get Response as response
608625

609626
def parse_authz_decision_query_response(self, response,
610-
binding=BINDING_SOAP):
627+
binding=BINDING_SOAP):
611628
""" Verify that the response is OK
612629
"""
613630
kwargs = {"entity_id": self.config.entityid,
@@ -658,7 +675,7 @@ def parse_name_id_mapping_request_response(self, txt, binding=BINDING_SOAP):
658675
# ------------------- ECP ------------------------------------------------
659676

660677
def create_ecp_authn_request(self, entityid=None, relay_state="",
661-
sign=False, **kwargs):
678+
sign=False, **kwargs):
662679
""" Makes an authentication request.
663680
664681
:param entityid: The entity ID of the IdP to send the request to
@@ -710,7 +727,7 @@ def create_ecp_authn_request(self, entityid=None, relay_state="",
710727
_, location = self.pick_binding("single_sign_on_service",
711728
[_binding], entity_id=entityid)
712729
req_id, authn_req = self.create_authn_request(
713-
location, service_url_binding=BINDING_PAOS, **kwargs)
730+
location, service_url_binding=BINDING_PAOS, **kwargs)
714731

715732
# ----------------------------------------
716733
# The SOAP envelope
@@ -730,8 +747,8 @@ def parse_ecp_authn_response(self, txt, outstanding=None):
730747

731748
_relay_state = None
732749
for item in rdict["header"]:
733-
if item.c_tag == "RelayState" and\
734-
item.c_namespace == ecp.NAMESPACE:
750+
if item.c_tag == "RelayState" and \
751+
item.c_namespace == ecp.NAMESPACE:
735752
_relay_state = item
736753

737754
response = self.parse_authn_request_response(rdict["body"],
@@ -805,7 +822,7 @@ def create_discovery_service_request(url, entity_id, **kwargs):
805822

806823
@staticmethod
807824
def parse_discovery_service_response(url="", query="",
808-
returnIDParam="entityID"):
825+
returnIDParam="entityID"):
809826
"""
810827
Deal with the response url from a Discovery Service
811828

src/saml2/entity.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def create_artifact(entity_id, message_handle, endpoint_index=0):
124124

125125
class Entity(HTTPBase):
126126
def __init__(self, entity_type, config=None, config_file="",
127-
virtual_organization=""):
127+
virtual_organization="", msg_cb=None):
128128
self.entity_type = entity_type
129129
self.users = None
130130

@@ -177,6 +177,8 @@ def __init__(self, entity_type, config=None, config_file="",
177177
else:
178178
self.sourceid = {}
179179

180+
self.msg_cb = msg_cb
181+
180182
def _issuer(self, entityid=None):
181183
""" Return an Issuer instance """
182184
if entityid:
@@ -465,7 +467,6 @@ def _message(self, request_cls, destination=None, message_id=0,
465467
kwargs[key] = val
466468

467469
req = request_cls(**kwargs)
468-
reqid = req.id
469470

470471
if destination:
471472
req.destination = destination
@@ -479,6 +480,11 @@ def _message(self, request_cls, destination=None, message_id=0,
479480
if nsprefix:
480481
req.register_prefix(nsprefix)
481482

483+
if self.msg_cb:
484+
req = self.msg_cb(req)
485+
486+
reqid = req.id
487+
482488
if sign:
483489
return reqid, self.sign(req, sign_prepare=sign_prepare,
484490
sign_alg=sign_alg, digest_alg=digest_alg)

src/saml2/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ class Server(Entity):
7474
""" A class that does things that IdPs or AAs do """
7575

7676
def __init__(self, config_file="", config=None, cache=None, stype="idp",
77-
symkey=""):
78-
Entity.__init__(self, stype, config, config_file)
77+
symkey="", msg_cb=None):
78+
Entity.__init__(self, stype, config, config_file, msg_cb=msg_cb)
7979
self.eptid = None
8080
self.init_config(stype)
8181
self.cache = cache

0 commit comments

Comments
 (0)