summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kanakarakis <ivan.kanak@gmail.com>2020-11-18 01:12:01 +0200
committerIvan Kanakarakis <ivan.kanak@gmail.com>2020-11-23 14:58:13 +0200
commit5cdd5c4ba5cba5fc41508c2866ebcb37e46c6140 (patch)
tree022ca9d78543e40578dd56bcb4be49f052fc4051
parent0e5127056a954c4099e8929c3dce7abc7abf146e (diff)
downloadpysaml2-5cdd5c4ba5cba5fc41508c2866ebcb37e46c6140.tar.gz
Formatting
Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
-rw-r--r--src/saml2/client.py125
-rw-r--r--src/saml2/client_base.py44
-rw-r--r--src/saml2/entity.py84
-rw-r--r--src/saml2/pack.py10
-rw-r--r--src/saml2/server.py36
-rw-r--r--src/saml2/sigver.py16
6 files changed, 207 insertions, 108 deletions
diff --git a/src/saml2/client.py b/src/saml2/client.py
index 11c737c1..e8990a46 100644
--- a/src/saml2/client.py
+++ b/src/saml2/client.py
@@ -40,10 +40,18 @@ class Saml2Client(Base):
""" The basic pySAML2 service provider class """
def prepare_for_authenticate(
- self, entityid=None, relay_state="",
- binding=saml2.BINDING_HTTP_REDIRECT, vorg="", nameid_format=None,
- scoping=None, consent=None, extensions=None, sign=None,
- response_binding=saml2.BINDING_HTTP_POST, **kwargs):
+ self,
+ entityid=None,
+ relay_state="",
+ binding=saml2.BINDING_HTTP_REDIRECT,
+ vorg="",
+ nameid_format=None,
+ scoping=None,
+ consent=None, extensions=None,
+ sign=None,
+ response_binding=saml2.BINDING_HTTP_POST,
+ **kwargs,
+ ):
""" Makes all necessary preparations for an authentication request.
:param entityid: The entity ID of the IdP to send the request to
@@ -61,19 +69,19 @@ class Saml2Client(Base):
:return: session id and AuthnRequest info
"""
- reqid, negotiated_binding, info = \
- self.prepare_for_negotiated_authenticate(
- entityid=entityid,
- relay_state=relay_state,
- binding=binding,
- vorg=vorg,
- nameid_format=nameid_format,
- scoping=scoping,
- consent=consent,
- extensions=extensions,
- sign=sign,
- response_binding=response_binding,
- **kwargs)
+ reqid, negotiated_binding, info = self.prepare_for_negotiated_authenticate(
+ entityid=entityid,
+ relay_state=relay_state,
+ binding=binding,
+ vorg=vorg,
+ nameid_format=nameid_format,
+ scoping=scoping,
+ consent=consent,
+ extensions=extensions,
+ sign=sign,
+ response_binding=response_binding,
+ **kwargs,
+ )
if negotiated_binding != binding:
raise ValueError(
@@ -85,9 +93,19 @@ class Saml2Client(Base):
return reqid, info
def prepare_for_negotiated_authenticate(
- self, entityid=None, relay_state="", binding=None, vorg="",
- nameid_format=None, scoping=None, consent=None, extensions=None,
- sign=None, response_binding=saml2.BINDING_HTTP_POST, **kwargs):
+ self,
+ entityid=None,
+ relay_state="",
+ binding=None,
+ vorg="",
+ nameid_format=None,
+ scoping=None,
+ consent=None,
+ extensions=None,
+ sign=None,
+ response_binding=saml2.BINDING_HTTP_POST,
+ **kwargs,
+ ):
""" Makes all necessary preparations for an authentication request
that negotiates which binding to use for authentication.
@@ -116,12 +134,18 @@ class Saml2Client(Base):
logger.info("destination to provider: %s", destination)
reqid, request = self.create_authn_request(
- destination, vorg, scoping, response_binding, nameid_format,
- consent=consent, extensions=extensions, sign=sign,
- **kwargs)
+ destination,
+ vorg,
+ scoping,
+ response_binding,
+ nameid_format,
+ consent=consent,
+ extensions=extensions,
+ sign=sign,
+ **kwargs,
+ )
_req_str = str(request)
-
logger.info("AuthNReq: %s", _req_str)
try:
@@ -129,13 +153,18 @@ class Saml2Client(Base):
except KeyError:
args = {}
- http_info = self.apply_binding(binding, _req_str, destination,
- relay_state, sign=sign, **args)
+ http_info = self.apply_binding(
+ binding,
+ _req_str,
+ destination,
+ relay_state,
+ sign=sign,
+ **args,
+ )
return reqid, binding, http_info
else:
- raise SignOnError(
- "No supported bindings available for authentication")
+ raise SignOnError("No supported bindings available for authentication")
def global_logout(self, name_id, reason="", expire=None, sign=None,
sign_alg=None, digest_alg=None):
@@ -232,43 +261,47 @@ class Saml2Client(Base):
sigalg = None
if sign:
if binding == BINDING_HTTP_REDIRECT:
- sigalg = kwargs.get(
- "sigalg", ds.DefaultSignature().get_sign_alg())
+ sigalg = kwargs.get("sigalg", ds.DefaultSignature().get_sign_alg())
# key = kwargs.get("key", self.signkey)
srequest = str(request)
else:
- srequest = self.sign(request, sign_alg=sign_alg,
- digest_alg=digest_alg)
+ srequest = self.sign(
+ request, sign_alg=sign_alg, digest_alg=digest_alg
+ )
else:
srequest = str(request)
relay_state = self._relay_state(req_id)
- http_info = self.apply_binding(binding, srequest, destination,
- relay_state, sign=sign, sigalg=sigalg)
+ http_info = self.apply_binding(
+ binding,
+ srequest,
+ destination,
+ relay_state,
+ sign=sign,
+ sigalg=sigalg,
+ )
if binding == BINDING_SOAP:
response = self.send(**http_info)
-
if response and response.status_code == 200:
not_done.remove(entity_id)
response = response.text
logger.info("Response: %s", response)
- res = self.parse_logout_request_response(response,
- binding)
+ res = self.parse_logout_request_response(response, binding)
responses[entity_id] = res
else:
logger.info("NOT OK response from %s", destination)
-
else:
- self.state[req_id] = {"entity_id": entity_id,
- "operation": "SLO",
- "entity_ids": entity_ids,
- "name_id": code(name_id),
- "reason": reason,
- "not_on_or_after": expire,
- "sign": sign}
-
+ self.state[req_id] = {
+ "entity_id": entity_id,
+ "operation": "SLO",
+ "entity_ids": entity_ids,
+ "name_id": code(name_id),
+ "reason": reason,
+ "not_on_or_after": expire,
+ "sign": sign,
+ }
responses[entity_id] = (binding, http_info)
not_done.remove(entity_id)
diff --git a/src/saml2/client_base.py b/src/saml2/client_base.py
index 41df6585..d33bbbf0 100644
--- a/src/saml2/client_base.py
+++ b/src/saml2/client_base.py
@@ -281,13 +281,25 @@ class Base(Entity):
else:
return None
- def create_authn_request(self, destination, vorg="", scoping=None,
- binding=saml2.BINDING_HTTP_POST,
- nameid_format=None,
- service_url_binding=None, message_id=0,
- consent=None, extensions=None, sign=None,
- allow_create=None, sign_prepare=False, sign_alg=None,
- digest_alg=None, requested_attributes=None, **kwargs):
+ def create_authn_request(
+ self,
+ destination,
+ vorg="",
+ scoping=None,
+ binding=BINDING_HTTP_POST,
+ nameid_format=None,
+ service_url_binding=None,
+ message_id=0,
+ consent=None,
+ extensions=None,
+ sign=None,
+ sign_prepare=False,
+ sign_alg=None,
+ digest_alg=None,
+ allow_create=None,
+ requested_attributes=None,
+ **kwargs,
+ ):
""" Creates an authentication request.
:param destination: Where the request should be sent.
@@ -302,6 +314,8 @@ class Base(Entity):
:param extensions: Possible extensions
:param sign: Whether the request should be signed or not.
:param sign_prepare: Whether the signature should be prepared or not.
+ :param sign_alg: The request signature algorithm
+ :param digest_alg: The request digest algorithm
:param allow_create: If the identity provider is allowed, in the course
of fulfilling the request, to create a new identifier to represent
the principal.
@@ -445,11 +459,11 @@ class Base(Entity):
extensions,
sign,
sign_prepare,
+ sign_alg=sign_alg,
+ digest_alg=digest_alg,
protocol_binding=binding,
scoping=scoping,
nsprefix=nsprefix,
- sign_alg=sign_alg,
- digest_alg=digest_alg,
**args,
)
else:
@@ -461,11 +475,11 @@ class Base(Entity):
extensions,
sign,
sign_prepare,
+ sign_alg=sign_alg,
+ digest_alg=digest_alg,
protocol_binding=binding,
scoping=scoping,
nsprefix=nsprefix,
- sign_alg=sign_alg,
- digest_alg=digest_alg,
**args,
)
@@ -843,10 +857,12 @@ class Base(Entity):
# The IDP publishes support for ECP by using the SOAP binding on
# SingleSignOnService
- _, location = self.pick_binding("single_sign_on_service",
- [_binding], entity_id=entityid)
+ _, location = self.pick_binding(
+ "single_sign_on_service", [_binding], entity_id=entityid
+ )
req_id, authn_req = self.create_authn_request(
- location, service_url_binding=BINDING_PAOS, **kwargs)
+ location, service_url_binding=BINDING_PAOS, **kwargs
+ )
# ----------------------------------------
# The SOAP envelope
diff --git a/src/saml2/entity.py b/src/saml2/entity.py
index 672ad6f7..af2d8ba4 100644
--- a/src/saml2/entity.py
+++ b/src/saml2/entity.py
@@ -190,8 +190,16 @@ class Entity(HTTPBase):
return Issuer(text=self.config.entityid,
format=NAMEID_FORMAT_ENTITY)
- def apply_binding(self, binding, msg_str, destination="", relay_state="",
- response=False, sign=False, **kwargs):
+ def apply_binding(
+ self,
+ binding,
+ msg_str,
+ destination="",
+ relay_state="",
+ response=False,
+ sign=None,
+ **kwargs,
+ ):
"""
Construct the necessary HTTP arguments dependent on Binding
@@ -218,19 +226,25 @@ class Entity(HTTPBase):
# info["url"] = destination
# info["method"] = "POST"
# else:
- info = self.use_http_form_post(msg_str, destination,
- relay_state, typ)
+ info = self.use_http_form_post(msg_str, destination, relay_state, typ)
info["url"] = destination
info["method"] = "POST"
elif binding == BINDING_HTTP_REDIRECT:
logger.info("HTTP REDIRECT")
sigalg = kwargs.get("sigalg")
- if sign and sigalg:
- signer = self.sec.sec_backend.get_signer(sigalg)
- else:
- signer = None
- info = self.use_http_get(msg_str, destination, relay_state, typ,
- signer=signer, **kwargs)
+ signer = (
+ self.sec.sec_backend.get_signer(sigalg)
+ if sign and sigalg
+ else None
+ )
+ info = self.use_http_get(
+ msg_str,
+ destination,
+ relay_state,
+ typ,
+ signer=signer,
+ **kwargs,
+ )
info["url"] = str(destination)
info["method"] = "GET"
elif binding == BINDING_SOAP or binding == BINDING_PAOS:
@@ -416,12 +430,19 @@ class Entity(HTTPBase):
# --------------------------------------------------------------------------
- def sign(self, msg, mid=None, to_sign=None, sign_prepare=False,
- sign_alg=None, digest_alg=None):
+ def sign(
+ self,
+ msg,
+ mid=None,
+ to_sign=None,
+ sign_prepare=False,
+ sign_alg=None,
+ digest_alg=None,
+ ):
if msg.signature is None:
- msg.signature = pre_signature_part(msg.id, self.sec.my_cert, 1,
- sign_alg=sign_alg,
- digest_alg=digest_alg)
+ msg.signature = pre_signature_part(
+ msg.id, self.sec.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg
+ )
if sign_prepare:
return msg
@@ -437,9 +458,20 @@ class Entity(HTTPBase):
logger.info("REQUEST: %s", msg)
return signed_instance_factory(msg, self.sec, to_sign)
- def _message(self, request_cls, destination=None, message_id=0,
- consent=None, extensions=None, sign=False, sign_prepare=False,
- nsprefix=None, sign_alg=None, digest_alg=None, **kwargs):
+ def _message(
+ self,
+ request_cls,
+ destination=None,
+ message_id=0,
+ consent=None,
+ extensions=None,
+ sign=False,
+ sign_prepare=False,
+ nsprefix=None,
+ sign_alg=None,
+ digest_alg=None,
+ **kwargs,
+ ):
"""
Some parameters appear in all requests so simplify by doing
it in one place
@@ -480,13 +512,17 @@ class Entity(HTTPBase):
req = self.msg_cb(req)
reqid = req.id
-
if sign:
- return reqid, self.sign(req, sign_prepare=sign_prepare,
- sign_alg=sign_alg, digest_alg=digest_alg)
- else:
- logger.info("REQUEST: %s", req)
- return reqid, req
+ signed_req = self.sign(
+ req,
+ sign_prepare=sign_prepare,
+ sign_alg=sign_alg,
+ digest_alg=digest_alg,
+ )
+ req = signed_req
+
+ logger.info("REQUEST: %s", req)
+ return reqid, req
@staticmethod
def _filter_args(instance, extensions=None, **kwargs):
diff --git a/src/saml2/pack.py b/src/saml2/pack.py
index f8fdbfcb..7b693f28 100644
--- a/src/saml2/pack.py
+++ b/src/saml2/pack.py
@@ -186,13 +186,11 @@ def http_redirect_message(message, location, relay_state="", typ="SAMLRequest",
)
args["SigAlg"] = sigalg
- string = "&".join([urlencode({k: args[k]})
- for k in _order if k in args]).encode('ascii')
- args["Signature"] = base64.b64encode(signer.sign(string))
- string = urlencode(args)
- else:
- string = urlencode(args)
+ string = "&".join(urlencode({k: args[k]}) for k in _order if k in args)
+ string_enc = string.encode('ascii')
+ args["Signature"] = base64.b64encode(signer.sign(string_enc))
+ string = urlencode(args)
glue_char = "&" if urlparse(location).query else "?"
login_url = glue_char.join([location, string])
headers = [('Location', str(login_url))]
diff --git a/src/saml2/server.py b/src/saml2/server.py
index 50250c3a..bcdbd2bb 100644
--- a/src/saml2/server.py
+++ b/src/saml2/server.py
@@ -671,18 +671,30 @@ class Server(Entity):
return args
- def create_authn_response(self, identity, in_response_to, destination,
- sp_entity_id, name_id_policy=None, userid=None,
- name_id=None, authn=None, issuer=None,
- sign_response=None, sign_assertion=None,
- encrypt_cert_advice=None,
- encrypt_cert_assertion=None,
- encrypt_assertion=None,
- encrypt_assertion_self_contained=True,
- encrypted_advice_attributes=False, pefim=False,
- sign_alg=None, digest_alg=None,
- session_not_on_or_after=None,
- **kwargs):
+ def create_authn_response(
+ self,
+ identity,
+ in_response_to,
+ destination,
+ sp_entity_id,
+ name_id_policy=None,
+ userid=None,
+ name_id=None,
+ authn=None,
+ issuer=None,
+ sign_response=None,
+ sign_assertion=None,
+ encrypt_cert_advice=None,
+ encrypt_cert_assertion=None,
+ encrypt_assertion=None,
+ encrypt_assertion_self_contained=True,
+ encrypted_advice_attributes=False,
+ pefim=False,
+ sign_alg=None,
+ digest_alg=None,
+ session_not_on_or_after=None,
+ **kwargs
+ ):
""" Constructs an AuthenticationResponse
:param identity: Information about an user
diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py
index 02daadc8..ee630340 100644
--- a/src/saml2/sigver.py
+++ b/src/saml2/sigver.py
@@ -566,8 +566,7 @@ def verify_redirect_signature(saml_msg, crypto, cert=None, sigkey=None):
try:
signer = crypto.get_signer(saml_msg['SigAlg'], sigkey)
except KeyError:
- raise Unsupported('Signature algorithm: {alg}'.format(
- alg=saml_msg['SigAlg']))
+ raise Unsupported('Signature algorithm: {alg}'.format(alg=saml_msg['SigAlg']))
else:
if saml_msg['SigAlg'] in SIGNER_ALGS:
if 'SAMLRequest' in saml_msg:
@@ -576,13 +575,18 @@ def verify_redirect_signature(saml_msg, crypto, cert=None, sigkey=None):
_order = RESP_ORDER
else:
raise Unsupported(
- 'Verifying signature on something that should not be '
- 'signed')
+ 'Verifying signature on something that should not be signed'
+ )
+
_args = saml_msg.copy()
del _args['Signature'] # everything but the signature
string = '&'.join(
- [parse.urlencode({k: _args[k]}) for k in _order if k in
- _args]).encode('ascii')
+ [
+ parse.urlencode({k: _args[k]})
+ for k in _order
+ if k in _args
+ ]
+ ).encode('ascii')
if cert:
_key = extract_rsa_key_from_x509_cert(pem_format(cert))