Merge branch 'master' of github.com:rohe/pysaml2

This commit is contained in:
Roland Hedberg
2016-09-22 08:54:29 +03:00
15 changed files with 134 additions and 77 deletions

2
.gitignore vendored
View File

@@ -31,6 +31,8 @@ tmp*
*.tmpl *.tmpl
*.iml *.iml
_build/ _build/
.cache
*.swp
example/idp3/htdocs/login.mako example/idp3/htdocs/login.mako

View File

@@ -270,6 +270,19 @@ idp/aa
Directives that are specific to an IdP or AA service instance Directives that are specific to an IdP or AA service instance
sign_assertion
""""""""""""""
Specifies if the IdP should sign the assertion in an authentication response
or not. Can be True or False. Default is False.
sign_response
"""""""""""""
Specifies if the IdP should sign the authentication response or not. Can be
True or False. Default is False.
policy policy
"""""" """"""
@@ -419,7 +432,7 @@ Indicates if this SP wants the IdP to send the assertions signed. This
sets the WantAssertionsSigned attribute of the SPSSODescriptor node sets the WantAssertionsSigned attribute of the SPSSODescriptor node
of the metadata so the IdP will know this SP preference. of the metadata so the IdP will know this SP preference.
Valid values are True or False. Default value is True. Valid values are True or False. Default value is False.
Example:: Example::

View File

@@ -42,7 +42,7 @@ def get_algorithm_support(xmlsec):
pof.wait() pof.wait()
if not p_err: if not p_err:
p = p_out.split('\n') p = p_out.splitlines()
algs = [x.strip('"') for x in p[1].split(',')] algs = [x.strip('"') for x in p[1].split(',')]
digest = [] digest = []
signing = [] signing = []

View File

@@ -615,7 +615,7 @@ def _authn_context_decl_ref(decl_ref, authn_auth=None):
def authn_statement(authn_class=None, authn_auth=None, def authn_statement(authn_class=None, authn_auth=None,
authn_decl=None, authn_decl_ref=None, authn_instant="", authn_decl=None, authn_decl_ref=None, authn_instant="",
subject_locality=""): subject_locality="", session_not_on_or_after=None):
""" """
Construct the AuthnStatement Construct the AuthnStatement
:param authn_class: Authentication Context Class reference :param authn_class: Authentication Context Class reference
@@ -639,6 +639,7 @@ def authn_statement(authn_class=None, authn_auth=None,
saml.AuthnStatement, saml.AuthnStatement,
authn_instant=_instant, authn_instant=_instant,
session_index=sid(), session_index=sid(),
session_not_on_or_after=session_not_on_or_after,
authn_context=_authn_context_class_ref( authn_context=_authn_context_class_ref(
authn_class, authn_auth)) authn_class, authn_auth))
elif authn_decl: elif authn_decl:
@@ -646,19 +647,22 @@ def authn_statement(authn_class=None, authn_auth=None,
saml.AuthnStatement, saml.AuthnStatement,
authn_instant=_instant, authn_instant=_instant,
session_index=sid(), session_index=sid(),
session_not_on_or_after=session_not_on_or_after,
authn_context=_authn_context_decl(authn_decl, authn_auth)) authn_context=_authn_context_decl(authn_decl, authn_auth))
elif authn_decl_ref: elif authn_decl_ref:
res = factory( res = factory(
saml.AuthnStatement, saml.AuthnStatement,
authn_instant=_instant, authn_instant=_instant,
session_index=sid(), session_index=sid(),
session_not_on_or_after=session_not_on_or_after,
authn_context=_authn_context_decl_ref(authn_decl_ref, authn_context=_authn_context_decl_ref(authn_decl_ref,
authn_auth)) authn_auth))
else: else:
res = factory( res = factory(
saml.AuthnStatement, saml.AuthnStatement,
authn_instant=_instant, authn_instant=_instant,
session_index=sid()) session_index=sid(),
session_not_on_or_after=session_not_on_or_after)
if subject_locality: if subject_locality:
res.subject_locality = saml.SubjectLocality(text=subject_locality) res.subject_locality = saml.SubjectLocality(text=subject_locality)
@@ -719,7 +723,7 @@ class Assertion(dict):
authn_class=None, authn_auth=None, authn_decl=None, authn_class=None, authn_auth=None, authn_decl=None,
encrypt=None, sec_context=None, authn_decl_ref=None, encrypt=None, sec_context=None, authn_decl_ref=None,
authn_instant="", subject_locality="", authn_statem=None, authn_instant="", subject_locality="", authn_statem=None,
name_id=None): name_id=None, session_not_on_or_after=None):
""" Construct the Assertion """ Construct the Assertion
:param sp_entity_id: The entityid of the SP :param sp_entity_id: The entityid of the SP
@@ -770,7 +774,8 @@ class Assertion(dict):
_authn_statement = authn_statement(authn_class, authn_auth, _authn_statement = authn_statement(authn_class, authn_auth,
authn_decl, authn_decl_ref, authn_decl, authn_decl_ref,
authn_instant, authn_instant,
subject_locality) subject_locality,
session_not_on_or_after=session_not_on_or_after)
else: else:
_authn_statement = None _authn_statement = None

View File

@@ -61,7 +61,7 @@ MAP = {
DEF+'eduPersonScopedAffiliation': 'eduPersonScopedAffiliation', DEF+'eduPersonScopedAffiliation': 'eduPersonScopedAffiliation',
DEF+'eduPersonTargetedID': 'eduPersonTargetedID', DEF+'eduPersonTargetedID': 'eduPersonTargetedID',
DEF+'eduPersonAssurance': 'eduPersonAssurance', DEF+'eduPersonAssurance': 'eduPersonAssurance',
DEF+'eduPersonUniqueID': 'eduPersonUniqueID', DEF+'eduPersonUniqueId': 'eduPersonUniqueId',
DEF+'eduPersonOrcid': 'eduPersonOrcid', DEF+'eduPersonOrcid': 'eduPersonOrcid',
DEF+'email': 'email', DEF+'email': 'email',
DEF+'emailAddress': 'emailAddress', DEF+'emailAddress': 'emailAddress',
@@ -228,7 +228,7 @@ MAP = {
'eduPersonScopedAffiliation': DEF+'eduPersonScopedAffiliation', 'eduPersonScopedAffiliation': DEF+'eduPersonScopedAffiliation',
'eduPersonTargetedID': DEF+'eduPersonTargetedID', 'eduPersonTargetedID': DEF+'eduPersonTargetedID',
'eduPersonAssurance': DEF+'eduPersonAssurance', 'eduPersonAssurance': DEF+'eduPersonAssurance',
'eduPersonUniqueID': DEF+'eduPersonUniqueID', 'eduPersonUniqueId': DEF+'eduPersonUniqueId',
'eduPersonOrcid': DEF+'eduPersonOrcid', 'eduPersonOrcid': DEF+'eduPersonOrcid',
'email': DEF+'email', 'email': DEF+'email',
'emailAddress': DEF+'emailAddress', 'emailAddress': DEF+'emailAddress',

View File

@@ -19,19 +19,19 @@ MAP = {
EDUCOURSE_OID+'1': 'eduCourseOffering', EDUCOURSE_OID+'1': 'eduCourseOffering',
EDUCOURSE_OID+'2': 'eduCourseMember', EDUCOURSE_OID+'2': 'eduCourseMember',
EDUPERSON_OID+'1': 'eduPersonAffiliation', EDUPERSON_OID+'1': 'eduPersonAffiliation',
EDUPERSON_OID+'2': 'eduPersonEntitlement', EDUPERSON_OID+'2': 'eduPersonNickname',
EDUPERSON_OID+'3': 'eduPersonNickname', EDUPERSON_OID+'3': 'eduPersonOrgDN',
EDUPERSON_OID+'4': 'eduPersonOrgDN', EDUPERSON_OID+'4': 'eduPersonOrgUnitDN',
EDUPERSON_OID+'5': 'eduPersonOrgUnitDN', EDUPERSON_OID+'5': 'eduPersonPrimaryAffiliation',
EDUPERSON_OID+'6': 'eduPersonPrimaryAffiliation', EDUPERSON_OID+'6': 'eduPersonPrincipalName',
EDUPERSON_OID+'7': 'eduPersonPrimaryOrgUnitDN', EDUPERSON_OID+'7': 'eduPersonEntitlement',
EDUPERSON_OID+'8': 'eduPersonPrincipalName', EDUPERSON_OID+'8': 'eduPersonPrimaryOrgUnitDN',
EDUPERSON_OID+'9': 'eduPersonPrincipalName', EDUPERSON_OID+'9': 'eduPersonScopedAffiliation',
EDUPERSON_OID+'10': 'eduPersonScopedAffiliation', EDUPERSON_OID+'10': 'eduPersonTargetedID',
EDUPERSON_OID+'11': 'eduPersonTargetedID', EDUPERSON_OID+'11': 'eduPersonAssurance',
EDUPERSON_OID+'12': 'eduPersonAssurance', EDUPERSON_OID+'12': 'eduPersonPrincipalNamePrior',
EDUPERSON_OID+'13': 'eduPersonUniqueID', EDUPERSON_OID+'13': 'eduPersonUniqueId',
EDUPERSON_OID+'14': 'eduPersonOrcid', EDUPERSON_OID+'16': 'eduPersonOrcid',
LDAPGVAT_OID+'1': 'PVP-GID', LDAPGVAT_OID+'1': 'PVP-GID',
LDAPGVAT_OID+'149': 'PVP-BPK', LDAPGVAT_OID+'149': 'PVP-BPK',
LDAPGVAT_OID+'153': 'PVP-OU-OKZ', LDAPGVAT_OID+'153': 'PVP-OU-OKZ',
@@ -179,19 +179,19 @@ MAP = {
'eduCourseMember': EDUCOURSE_OID+'2', 'eduCourseMember': EDUCOURSE_OID+'2',
'eduCourseOffering': EDUCOURSE_OID+'1', 'eduCourseOffering': EDUCOURSE_OID+'1',
'eduPersonAffiliation': EDUPERSON_OID+'1', 'eduPersonAffiliation': EDUPERSON_OID+'1',
'eduPersonEntitlement': EDUPERSON_OID+'2', 'eduPersonEntitlement': EDUPERSON_OID+'7',
'eduPersonNickname': EDUPERSON_OID+'3', 'eduPersonNickname': EDUPERSON_OID+'2',
'eduPersonOrgDN': EDUPERSON_OID+'4', 'eduPersonOrgDN': EDUPERSON_OID+'3',
'eduPersonOrgUnitDN': EDUPERSON_OID+'5', 'eduPersonOrgUnitDN': EDUPERSON_OID+'4',
'eduPersonPrimaryAffiliation': EDUPERSON_OID+'6', 'eduPersonPrimaryAffiliation': EDUPERSON_OID+'5',
'eduPersonPrimaryOrgUnitDN': EDUPERSON_OID+'7', 'eduPersonPrimaryOrgUnitDN': EDUPERSON_OID+'8',
'eduPersonPrincipalName': EDUPERSON_OID+'8', 'eduPersonPrincipalName': EDUPERSON_OID+'6',
'eduPersonPrincipalNamePrior': EDUPERSON_OID+'9', 'eduPersonPrincipalNamePrior': EDUPERSON_OID+'12',
'eduPersonScopedAffiliation': EDUPERSON_OID+'10', 'eduPersonScopedAffiliation': EDUPERSON_OID+'9',
'eduPersonTargetedID': EDUPERSON_OID+'11', 'eduPersonTargetedID': EDUPERSON_OID+'10',
'eduPersonAssurance': EDUPERSON_OID+'12', 'eduPersonAssurance': EDUPERSON_OID+'11',
'eduPersonUniqueID': EDUPERSON_OID+'13', 'eduPersonUniqueId': EDUPERSON_OID+'13',
'eduPersonOrcid': EDUPERSON_OID+'14', 'eduPersonOrcid': EDUPERSON_OID+'16',
'email': PKCS_9+'1', 'email': PKCS_9+'1',
'employeeNumber': NETSCAPE_LDAP+'3', 'employeeNumber': NETSCAPE_LDAP+'3',
'employeeType': NETSCAPE_LDAP+'4', 'employeeType': NETSCAPE_LDAP+'4',

View File

@@ -11,19 +11,19 @@ MAP = {
"identifier": "urn:mace:shibboleth:1.0:attributeNamespace:uri", "identifier": "urn:mace:shibboleth:1.0:attributeNamespace:uri",
'fro': { 'fro': {
EDUPERSON_OID+'1': 'eduPersonAffiliation', EDUPERSON_OID+'1': 'eduPersonAffiliation',
EDUPERSON_OID+'2': 'eduPersonEntitlement', EDUPERSON_OID+'2': 'eduPersonNickname',
EDUPERSON_OID+'3': 'eduPersonNickname', EDUPERSON_OID+'3': 'eduPersonOrgDN',
EDUPERSON_OID+'4': 'eduPersonOrgDN', EDUPERSON_OID+'4': 'eduPersonOrgUnitDN',
EDUPERSON_OID+'5': 'eduPersonOrgUnitDN', EDUPERSON_OID+'5': 'eduPersonPrimaryAffiliation',
EDUPERSON_OID+'6': 'eduPersonPrimaryAffiliation', EDUPERSON_OID+'6': 'eduPersonPrincipalName',
EDUPERSON_OID+'7': 'eduPersonPrimaryOrgUnitDN', EDUPERSON_OID+'7': 'eduPersonEntitlement',
EDUPERSON_OID+'8': 'eduPersonPrincipalName', EDUPERSON_OID+'8': 'eduPersonPrimaryOrgUnitDN',
EDUPERSON_OID+'9': 'eduPersonPrincipalNamePrior', EDUPERSON_OID+'9': 'eduPersonScopedAffiliation',
EDUPERSON_OID+'10': 'eduPersonScopedAffiliation', EDUPERSON_OID+'10': 'eduPersonTargetedID',
EDUPERSON_OID+'11': 'eduPersonTargetedID', EDUPERSON_OID+'11': 'eduPersonAssurance',
EDUPERSON_OID+'12': 'eduPersonAssurance', EDUPERSON_OID+'12': 'eduPersonPrincipalNamePrior',
EDUPERSON_OID+'13': 'eduPersonUniqueID', EDUPERSON_OID+'13': 'eduPersonUniqueId',
EDUPERSON_OID+'14': 'eduPersonOrcid', EDUPERSON_OID+'16': 'eduPersonOrcid',
NETSCAPE_LDAP+'1': 'carLicense', NETSCAPE_LDAP+'1': 'carLicense',
NETSCAPE_LDAP+'2': 'departmentNumber', NETSCAPE_LDAP+'2': 'departmentNumber',
NETSCAPE_LDAP+'3': 'employeeNumber', NETSCAPE_LDAP+'3': 'employeeNumber',
@@ -114,19 +114,19 @@ MAP = {
'dnQualifier': X500ATTR+'46', 'dnQualifier': X500ATTR+'46',
'domainComponent': UCL_DIR_PILOT+'25', 'domainComponent': UCL_DIR_PILOT+'25',
'eduPersonAffiliation': EDUPERSON_OID+'1', 'eduPersonAffiliation': EDUPERSON_OID+'1',
'eduPersonEntitlement': EDUPERSON_OID+'2', 'eduPersonEntitlement': EDUPERSON_OID+'7',
'eduPersonNickname': EDUPERSON_OID+'3', 'eduPersonNickname': EDUPERSON_OID+'2',
'eduPersonOrgDN': EDUPERSON_OID+'4', 'eduPersonOrgDN': EDUPERSON_OID+'3',
'eduPersonOrgUnitDN': EDUPERSON_OID+'5', 'eduPersonOrgUnitDN': EDUPERSON_OID+'4',
'eduPersonPrimaryAffiliation': EDUPERSON_OID+'6', 'eduPersonPrimaryAffiliation': EDUPERSON_OID+'5',
'eduPersonPrimaryOrgUnitDN': EDUPERSON_OID+'7', 'eduPersonPrimaryOrgUnitDN': EDUPERSON_OID+'8',
'eduPersonPrincipalName': EDUPERSON_OID+'8', 'eduPersonPrincipalName': EDUPERSON_OID+'6',
'eduPersonPrincipalNamePrior': EDUPERSON_OID+'9', 'eduPersonPrincipalNamePrior': EDUPERSON_OID+'12',
'eduPersonScopedAffiliation': EDUPERSON_OID+'10', 'eduPersonScopedAffiliation': EDUPERSON_OID+'9',
'eduPersonTargetedID': EDUPERSON_OID+'11', 'eduPersonTargetedID': EDUPERSON_OID+'10',
'eduPersonAssurance': EDUPERSON_OID+'12', 'eduPersonAssurance': EDUPERSON_OID+'11',
'eduPersonUniqueID': EDUPERSON_OID+'13', 'eduPersonUniqueId': EDUPERSON_OID+'13',
'eduPersonOrcid': EDUPERSON_OID+'14', 'eduPersonOrcid': EDUPERSON_OID+'16',
'email': PKCS_9+'1', 'email': PKCS_9+'1',
'emailAddress': PKCS_9+'1', 'emailAddress': PKCS_9+'1',
'employeeNumber': NETSCAPE_LDAP+'3', 'employeeNumber': NETSCAPE_LDAP+'3',

View File

@@ -902,6 +902,9 @@ class MetadataStore(MetaData):
elif typ == "loader": elif typ == "loader":
key = args[1] key = args[1]
_md = MetaDataLoader(self.attrc, args[1], **_args) _md = MetaDataLoader(self.attrc, args[1], **_args)
elif typ == "mdq":
key = args[1]
_md = MetaDataMDX(args[1])
else: else:
raise SAMLError("Unknown metadata type '%s'" % typ) raise SAMLError("Unknown metadata type '%s'" % typ)
_md.load() _md.load()
@@ -992,10 +995,7 @@ class MetadataStore(MetaData):
try: try:
srvs = _md[entity_id][typ] srvs = _md[entity_id][typ]
except KeyError: except KeyError:
return None continue
if not srvs:
return srvs
res = [] res = []
for srv in srvs: for srv in srvs:
@@ -1005,6 +1005,8 @@ class MetadataStore(MetaData):
res.append(elem) res.append(elem)
return res return res
return None
def ext_service(self, entity_id, typ, service, binding=None): def ext_service(self, entity_id, typ, service, binding=None):
known_entity = False known_entity = False
for key, _md in self.metadata.items(): for key, _md in self.metadata.items():

View File

@@ -326,7 +326,8 @@ class Server(Entity):
def setup_assertion(self, authn, sp_entity_id, in_response_to, consumer_url, def setup_assertion(self, authn, sp_entity_id, in_response_to, consumer_url,
name_id, policy, _issuer, authn_statement, identity, name_id, policy, _issuer, authn_statement, identity,
best_effort, sign_response, farg=None, **kwargs): best_effort, sign_response, farg=None,
session_not_on_or_after=None, **kwargs):
""" """
Construct and return the Assertion Construct and return the Assertion
@@ -370,17 +371,20 @@ class Server(Entity):
assertion = ast.construct( assertion = ast.construct(
sp_entity_id, self.config.attribute_converters, policy, sp_entity_id, self.config.attribute_converters, policy,
issuer=_issuer, farg=farg['assertion'], name_id=name_id, issuer=_issuer, farg=farg['assertion'], name_id=name_id,
session_not_on_or_after=session_not_on_or_after,
**authn_args) **authn_args)
elif authn_statement: # Got a complete AuthnStatement elif authn_statement: # Got a complete AuthnStatement
assertion = ast.construct( assertion = ast.construct(
sp_entity_id, self.config.attribute_converters, policy, sp_entity_id, self.config.attribute_converters, policy,
issuer=_issuer, authn_statem=authn_statement, issuer=_issuer, authn_statem=authn_statement,
farg=farg['assertion'], name_id=name_id, **kwargs) farg=farg['assertion'], name_id=name_id,
**kwargs)
else: else:
assertion = ast.construct( assertion = ast.construct(
sp_entity_id, self.config.attribute_converters, policy, sp_entity_id, self.config.attribute_converters, policy,
issuer=_issuer, farg=farg['assertion'], name_id=name_id, issuer=_issuer, farg=farg['assertion'], name_id=name_id,
session_not_on_or_after=session_not_on_or_after,
**kwargs) **kwargs)
return assertion return assertion
@@ -394,7 +398,7 @@ class Server(Entity):
encrypt_assertion_self_contained=False, encrypt_assertion_self_contained=False,
encrypted_advice_attributes=False, encrypted_advice_attributes=False,
pefim=False, sign_alg=None, digest_alg=None, pefim=False, sign_alg=None, digest_alg=None,
farg=None): farg=None, session_not_on_or_after=None):
""" Create a response. A layer of indirection. """ Create a response. A layer of indirection.
:param in_response_to: The session identifier of the request :param in_response_to: The session identifier of the request
@@ -455,7 +459,7 @@ class Server(Entity):
assertion = self.setup_assertion( assertion = self.setup_assertion(
authn, sp_entity_id, in_response_to, consumer_url, name_id, authn, sp_entity_id, in_response_to, consumer_url, name_id,
policy, _issuer, authn_statement, [], True, sign_response, policy, _issuer, authn_statement, [], True, sign_response,
farg=farg) farg=farg, session_not_on_or_after=session_not_on_or_after)
assertion.advice = saml.Advice() assertion.advice = saml.Advice()
# assertion.advice.assertion_id_ref.append(saml.AssertionIDRef()) # assertion.advice.assertion_id_ref.append(saml.AssertionIDRef())
@@ -465,7 +469,8 @@ class Server(Entity):
assertion = self.setup_assertion( assertion = self.setup_assertion(
authn, sp_entity_id, in_response_to, consumer_url, name_id, authn, sp_entity_id, in_response_to, consumer_url, name_id,
policy, _issuer, authn_statement, identity, True, policy, _issuer, authn_statement, identity, True,
sign_response, farg=farg) sign_response, farg=farg,
session_not_on_or_after=session_not_on_or_after)
to_sign = [] to_sign = []
if not encrypt_assertion: if not encrypt_assertion:
@@ -681,6 +686,7 @@ class Server(Entity):
encrypt_assertion_self_contained=True, encrypt_assertion_self_contained=True,
encrypted_advice_attributes=False, pefim=False, encrypted_advice_attributes=False, pefim=False,
sign_alg=None, digest_alg=None, sign_alg=None, digest_alg=None,
session_not_on_or_after=None,
**kwargs): **kwargs):
""" Constructs an AuthenticationResponse """ Constructs an AuthenticationResponse
@@ -741,11 +747,13 @@ class Server(Entity):
return self._authn_response( return self._authn_response(
in_response_to, destination, sp_entity_id, identity, in_response_to, destination, sp_entity_id, identity,
authn=_authn, issuer=issuer, pefim=pefim, authn=_authn, issuer=issuer, pefim=pefim,
sign_alg=sign_alg, digest_alg=digest_alg, **args) sign_alg=sign_alg, digest_alg=digest_alg,
session_not_on_or_after=session_not_on_or_after, **args)
return self._authn_response( return self._authn_response(
in_response_to, destination, sp_entity_id, identity, in_response_to, destination, sp_entity_id, identity,
authn=_authn, issuer=issuer, pefim=pefim, sign_alg=sign_alg, authn=_authn, issuer=issuer, pefim=pefim, sign_alg=sign_alg,
digest_alg=digest_alg, **args) digest_alg=digest_alg,
session_not_on_or_after=session_not_on_or_after, **args)
except MissingValue as exc: except MissingValue as exc:
return self.create_error_response(in_response_to, destination, return self.create_error_response(in_response_to, destination,
@@ -756,13 +764,15 @@ class Server(Entity):
name_id_policy=None, userid=None, name_id_policy=None, userid=None,
name_id=None, authn=None, authn_decl=None, name_id=None, authn=None, authn_decl=None,
issuer=None, sign_response=False, issuer=None, sign_response=False,
sign_assertion=False, **kwargs): sign_assertion=False,
session_not_on_or_after=None, **kwargs):
return self.create_authn_response(identity, in_response_to, destination, return self.create_authn_response(identity, in_response_to, destination,
sp_entity_id, name_id_policy, userid, sp_entity_id, name_id_policy, userid,
name_id, authn, issuer, name_id, authn, issuer,
sign_response, sign_assertion, sign_response, sign_assertion,
authn_decl=authn_decl) authn_decl=authn_decl,
session_not_on_or_after=session_not_on_or_after)
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
def create_assertion_id_request_response(self, assertion_id, sign=False, def create_assertion_id_request_response(self, assertion_id, sign=False,

View File

@@ -586,7 +586,7 @@ def parse_xmlsec_output(output):
:param output: The output from Popen :param output: The output from Popen
:return: A boolean; True if the command was a success otherwise False :return: A boolean; True if the command was a success otherwise False
""" """
for line in output.split("\n"): for line in output.splitlines():
if line == "OK": if line == "OK":
return True return True
elif line == "FAIL": elif line == "FAIL":

View File

@@ -91,7 +91,7 @@ def validate_on_or_after(not_on_or_after, slack):
nooa = calendar.timegm(time_util.str_to_time(not_on_or_after)) nooa = calendar.timegm(time_util.str_to_time(not_on_or_after))
if now > nooa + slack: if now > nooa + slack:
raise ResponseLifetimeExceed( raise ResponseLifetimeExceed(
"Can't use it, it's too old %d > %d".format(now - slack, nooa)) "Can't use it, it's too old %d > %d" % (now - slack, nooa))
return nooa return nooa
else: else:
return False return False

View File

@@ -86,7 +86,7 @@ def test_filter_on_attributes_without_friendly_name():
"eduPersonAffiliation": "test", "eduPersonAffiliation": "test",
"extra": "foo"} "extra": "foo"}
eptid = to_dict( eptid = to_dict(
Attribute(name="urn:oid:1.3.6.1.4.1.5923.1.1.1.11", Attribute(name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10",
name_format=NAME_FORMAT_URI), ONTS) name_format=NAME_FORMAT_URI), ONTS)
ep_affiliation = to_dict( ep_affiliation = to_dict(
Attribute(name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1", Attribute(name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1",

View File

@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import datetime import datetime
import re import re
from collections import OrderedDict
from future.backports.urllib.parse import quote_plus from future.backports.urllib.parse import quote_plus
@@ -455,5 +456,16 @@ def test_metadata_extension_algsupport():
mdf = mds.metadata[full_path("uu.xml")] mdf = mds.metadata[full_path("uu.xml")]
assert mds assert mds
def test_extension():
mds = MetadataStore(ATTRCONV, None)
# use ordered dict to force expected entity to be last
metadata = OrderedDict()
metadata["1"] = {"entity1": {}}
metadata["2"] = {"entity2": {"idpsso_descriptor": [{"extensions": {"extension_elements": [{"__class__": "test"}]}}]}}
mds.metadata = metadata
assert mds.extension("entity2", "idpsso_descriptor", "test")
if __name__ == "__main__": if __name__ == "__main__":
test_metadata_extension_algsupport() test_metadata_extension_algsupport()

View File

@@ -540,6 +540,19 @@ def test_sha256_signing():
assert s assert s
def test_xmlsec_output_line_parsing():
output1 = "prefix\nOK\npostfix"
assert sigver.parse_xmlsec_output(output1)
output2 = "prefix\nFAIL\npostfix"
raises(sigver.XmlsecError, sigver.parse_xmlsec_output, output2)
output3 = "prefix\r\nOK\r\npostfix"
assert sigver.parse_xmlsec_output(output3)
output4 = "prefix\r\nFAIL\r\npostfix"
raises(sigver.XmlsecError, sigver.parse_xmlsec_output, output4)
if __name__ == "__main__": if __name__ == "__main__":
# t = TestSecurity() # t = TestSecurity()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
from saml2.sigver import _get_xmlsec_cryptobackend from saml2.sigver import _get_xmlsec_cryptobackend
from saml2.sigver import SecurityContext from saml2.sigver import SecurityContext
from saml2.httpbase import HTTPBase from saml2.httpbase import HTTPBase