diff --git a/setup.py b/setup.py index 902b0df..a0f6767 100755 --- a/setup.py +++ b/setup.py @@ -73,7 +73,7 @@ setup( packages=['saml2', 'xmldsig', 'xmlenc', 's2repoze', 's2repoze.plugins', "saml2/profile", "saml2/schema", "saml2/extension", - "saml2/attributemaps"], + "saml2/attributemaps", "saml2/authn_context"], package_dir={'': 'src'}, package_data={'': ['xml/*.xml']}, diff --git a/src/saml2/__init__.py b/src/saml2/__init__.py index eb1efdb..4320e62 100644 --- a/src/saml2/__init__.py +++ b/src/saml2/__init__.py @@ -670,12 +670,20 @@ class SamlBase(ExtensionContainer): return self + def clear_text(self): + if self.text: + _text = self.text.strip() + if _text == "": + self.text = None + def __eq__(self, other): try: assert isinstance(other, SamlBase) except AssertionError: return False + self.clear_text() + other.clear_text() if len(self.keyswv()) != len(other.keyswv()): return False diff --git a/src/saml2/authn_context/__init__.py b/src/saml2/authn_context/__init__.py index 47d8772..e746a8f 100644 --- a/src/saml2/authn_context/__init__.py +++ b/src/saml2/authn_context/__init__.py @@ -34,10 +34,13 @@ class Authn(object): if spec.authn_context_class_ref: _endpspec[spec.authn_context_class_ref.text] = target elif spec.authn_context_decl: - _endpspec[ - spec.authn_context_decl.c_namespace] = spec.authn_context_decl + key = spec.authn_context_decl.c_namespace + try: + _endpspec[key].append((spec.authn_context_decl, target)) + except KeyError: + _endpspec[key] = [(spec.authn_context_decl, target)] - def pick(self, endpoint, authn_context): + def pick(self, endpoint, req_authn_context): """ Given which endpoint the request came in over and what authentication context is defined find out where to send the user next. @@ -45,4 +48,24 @@ class Authn(object): :param endpoint: The service endpoint URL :param authn_context: An AuthnContext instance :return: An URL - """ \ No newline at end of file + """ + + try: + _endpspec = self.db[endpoint] + except KeyError: + self.db[endpoint] = {} + _endpspec = self.db[endpoint] + + if req_authn_context.authn_context_class_ref: + return _endpspec[req_authn_context.authn_context_class_ref.text] + elif req_authn_context.authn_context_decl: + key = req_authn_context.authn_context_decl.c_namespace + for spec, target in _endpspec[key]: + if self.match(req_authn_context, spec): + return target + + def match(self, requested, provided): + if requested == provided: + return True + else: + return False \ No newline at end of file diff --git a/tests/test_77_authn_context.py b/tests/test_77_authn_context.py new file mode 100644 index 0000000..ee36ce8 --- /dev/null +++ b/tests/test_77_authn_context.py @@ -0,0 +1,29 @@ +__author__ = 'rolandh' + +ex1 = """ + + + + + + + +""" + +from saml2.authn_context import pword + + +def test_passwd(): + length = pword.Length(min="4") + restricted_password = pword.RestrictedPassword(length=length) + authenticator = pword.Authenticator(restricted_password=restricted_password) + authn_method = pword.AuthnMethod(authenticator=authenticator) + inst = pword.AuthenticationContextDeclaration(authn_method=authn_method) + + inst2 = pword.authentication_context_declaration_from_string(ex1) + + assert inst == inst2 + +if __name__ == "__main__": + test_passwd() \ No newline at end of file