def test_filter_attribute_value_assertions_2(AVA): p = Policy({ "default": { "attribute_restrictions": { "givenName": ["^R.*"], } } }) ava = filter_attribute_value_assertions(AVA[0].copy(), p.get_attribute_restrictions("")) print(ava) assert _eq(ava.keys(), []) ava = filter_attribute_value_assertions(AVA[1].copy(), p.get_attribute_restrictions("")) print(ava) assert _eq(list(ava.keys()), ["givenName"]) assert ava["givenName"] == ["Ryan"] ava = filter_attribute_value_assertions(AVA[3].copy(), p.get_attribute_restrictions("")) print(ava) assert _eq(list(ava.keys()), ["givenName"]) assert ava["givenName"] == ["Roland"]
def test_assertion_1(AVA): ava = Assertion(AVA[0]) print(ava) print(ava.__dict__) policy = Policy({ "default": { "attribute_restrictions": { "givenName": ["^R.*"], } } }) ava = ava.apply_policy("", policy) print(ava) assert _eq(list(ava.keys()), []) ava = Assertion(AVA[1].copy()) ava = ava.apply_policy("", policy) assert _eq(list(ava.keys()), ["givenName"]) assert ava["givenName"] == ["Ryan"] ava = Assertion(AVA[3].copy()) ava = ava.apply_policy("", policy) assert _eq(list(ava.keys()), ["givenName"]) assert ava["givenName"] == ["Roland"]
def test_assertion_2(): AVA = {'mail': u'*****@*****.**', 'eduPersonTargetedID': 'http://lingon.ladok.umu' '.se:8090/idp!http://lingon.ladok.umu' '.se:8088/sp!95e9ae91dbe62d35198fbbd5e1fb0976', 'displayName': u'Roland Hedberg', 'uid': 'http://roland.hedberg.myopenid.com/'} ava = Assertion(AVA) policy = Policy({ "default": { "lifetime": {"minutes": 240}, "attribute_restrictions": None, # means all I have "name_form": NAME_FORMAT_URI }, }) ava = ava.apply_policy("", policy) acs = ac_factory(full_path("attributemaps")) attribute = from_local(acs, ava, policy.get_name_form("")) assert len(attribute) == 4 names = [attr.name for attr in attribute] assert _eq(sorted(list(names)), [ 'urn:oid:0.9.2342.19200300.100.1.1', 'urn:oid:0.9.2342.19200300.100.1.3', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'urn:oid:2.16.840.1.113730.3.1.241'])
def test_assertion_with_authn_instant(): ava = {} ast = Assertion(ava) policy = Policy({ "default": { "lifetime": {"minutes": 240}, "attribute_restrictions": None, # means all I have "name_form": NAME_FORMAT_URI }, }) name_id = NameID(format=NAMEID_FORMAT_TRANSIENT, text="foobar") issuer = Issuer(text="entityid", format=NAMEID_FORMAT_ENTITY) farg = add_path( {}, ['subject', 'subject_confirmation', 'method', saml.SCM_BEARER]) add_path( farg['subject']['subject_confirmation'], ['subject_confirmation_data', 'in_response_to', 'in_response_to']) add_path( farg['subject']['subject_confirmation'], ['subject_confirmation_data', 'recipient', 'consumer_url']) msg = ast.construct( "sp_entity_id", [AttributeConverterNOOP(NAME_FORMAT_URI)], policy, issuer=issuer, authn_decl=ACD, authn_auth="authn_authn", authn_instant=1234567890, name_id=name_id, farg=farg) print(msg) assert msg.authn_statement[0].authn_instant == "2009-02-13T23:31:30Z"
def test_req_opt(): req = [ to_dict( md.RequestedAttribute( friendly_name="surname", name="urn:oid:2.5.4.4", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", is_required="true"), ONTS), to_dict( md.RequestedAttribute( friendly_name="givenname", name="urn:oid:2.5.4.42", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", is_required="true"), ONTS), to_dict( md.RequestedAttribute( friendly_name="edupersonaffiliation", name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", is_required="true"), ONTS)] opt = [ to_dict( md.RequestedAttribute( friendly_name="title", name="urn:oid:2.5.4.12", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", is_required="false"), ONTS)] policy = Policy() ava = {'givenname': 'Roland', 'sn': 'Hedberg', 'uid': 'rohe0002', 'edupersonaffiliation': 'staff'} sp_entity_id = "urn:mace:example.com:saml:curt:sp" fava = policy.filter(ava, sp_entity_id, None, req, opt) assert fava
def test_ava_filter_1(): conf = { "default": { "lifetime": {"minutes": 15}, "attribute_restrictions": None # means all I have }, "urn:mace:umu.se:saml:roland:sp": { "lifetime": {"minutes": 5}, "attribute_restrictions": { "givenName": None, "surName": None, "mail": [".*@.*\.umu\.se"], } }} r = Policy(conf) ava = {"givenName": "Derek", "surName": "Jeter", "mail": "*****@*****.**"} ava = r.filter(ava, "urn:mace:umu.se:saml:roland:sp", None, None) assert _eq(list(ava.keys()), ["givenName", "surName"]) ava = {"givenName": "Derek", "mail": "*****@*****.**"} assert _eq(sorted(list(ava.keys())), ["givenName", "mail"])
def test_ava_filter_2(): conf = { "default": { "lifetime": {"minutes": 15}, "attribute_restrictions": None # means all I have }, "urn:mace:umu.se:saml:roland:sp": { "lifetime": {"minutes": 5}, "attribute_restrictions": { "givenName": None, "sn": None, "mail": [".*@.*\.umu\.se"], } }} policy = Policy(conf) ava = {"givenName": "Derek", "sn": "Jeter", "mail": "*****@*****.**"} # mail removed because it doesn't match the regular expression _ava = policy.filter(ava, 'urn:mace:umu.se:saml:roland:sp', None, [mail], [gn, sn]) assert _eq(sorted(list(_ava.keys())), ["givenName", 'sn']) ava = {"givenName": "Derek", "sn": "Jeter"} # it wasn't there to begin with try: policy.filter(ava, 'urn:mace:umu.se:saml:roland:sp', None, [gn, sn, mail]) except MissingValue: pass
def test_filter_attribute_value_assertions_0(AVA): p = Policy({ "default": { "attribute_restrictions": { "surName": [".*berg"], } } }) ava = filter_attribute_value_assertions(AVA[3].copy(), p.get_attribute_restrictions("")) print(ava) assert list(ava.keys()) == ["surName"] assert ava["surName"] == ["Hedberg"]
def test_filter_ava(): policy = Policy({ "default": { "lifetime": {"minutes": 15}, # "attribute_restrictions": None # means all I have "entity_categories": ["swamid"] } }) ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["*****@*****.**", "*****@*****.**"], "c": ["USA"]} ava = policy.filter(ava, "https://connect.sunet.se/shibboleth", MDS) assert _eq(list(ava.keys()), ['mail', 'givenName', 'sn', 'c']) assert _eq(ava["mail"], ["*****@*****.**", "*****@*****.**"])
def test_transient_1(self): policy = Policy({ "default": { "name_form": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "nameid_format": NAMEID_FORMAT_TRANSIENT, "attribute_restrictions": { "surName": [".*berg"], } } }) nameid = self.id.construct_nameid("foobar", policy, "urn:mace:example.com:sp:1") assert _eq(nameid.keyswv(), ['text', 'format', 'sp_name_qualifier', 'name_qualifier']) assert nameid.format == NAMEID_FORMAT_TRANSIENT assert nameid.text != "foobar"
def test_filter_ava2(): policy = Policy({ "default": { "lifetime": {"minutes": 15}, # "attribute_restrictions": None # means all I have "entity_categories": ["refeds", "edugain"] } }) ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["*****@*****.**"], "c": ["USA"], "eduPersonTargetedID": "foo!bar!xyz"} ava = policy.filter(ava, "https://connect.sunet.se/shibboleth", MDS) # Mismatch, policy deals with eduGAIN, metadata says SWAMID # So only minimum should come out assert _eq(list(ava.keys()), ['eduPersonTargetedID'])
def test_lifetime_2(): conf = { "default": { "attribute_restrictions": None # means all I have }, "urn:mace:umu.se:saml:roland:sp": { "lifetime": {"minutes": 5}, "attribute_restrictions": { "givenName": None, "surName": None, "mail": [".*@.*\.umu\.se"], } }} r = Policy(conf) assert r is not None assert r.get_lifetime("urn:mace:umu.se:saml:roland:sp") == {"minutes": 5} assert r.get_lifetime("urn:mace:example.se:saml:sp") == {"hours": 1}
def test_filter_ava_4(): """ Return everything as default policy is used """ policy = Policy({ "default": { "lifetime": {"minutes": 15}, "attribute_restrictions": None # means all I have }, "urn:mace:example.com:saml:roland:sp": { "lifetime": {"minutes": 5}, "attribute_restrictions": { "mail": [".*@example\.com$"], } }}) ava = {"givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**", "*****@*****.**"]} # No restrictions apply ava = policy.filter(ava, "urn:mace:example.com:saml:curt:sp", [], []) assert _eq(sorted(list(ava.keys())), ['mail', 'givenName', 'surName']) assert _eq(ava["mail"], ["*****@*****.**", "*****@*****.**"])
def test_persistent_1(self): policy = Policy({ "default": { "name_form": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "nameid_format": NAMEID_FORMAT_PERSISTENT, "attribute_restrictions": { "surName": [".*berg"], } } }) nameid = self.id.construct_nameid("foobar", policy, "urn:mace:example.com:sp:1") assert _eq(nameid.keyswv(), ['format', 'text', 'sp_name_qualifier', 'name_qualifier']) assert nameid.sp_name_qualifier == "urn:mace:example.com:sp:1" assert nameid.format == NAMEID_FORMAT_PERSISTENT id = self.id.find_local_id(nameid) assert id == "foobar"
def test_vo_2(self): policy = Policy({ "default": { "name_form": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "nameid_format": NAMEID_FORMAT_PERSISTENT, "attribute_restrictions": { "surName": [".*berg"], } } }) name_id_policy = samlp.name_id_policy_from_string(NAME_ID_POLICY_2) nameid = self.id.construct_nameid("foobar", policy, 'http://vo.example.org/design', name_id_policy) assert _eq(nameid.keyswv(), ['text', 'sp_name_qualifier', 'format', 'name_qualifier']) assert nameid.sp_name_qualifier == 'http://vo.example.org/design' assert nameid.format == NAMEID_FORMAT_PERSISTENT assert nameid.text != "foobar01"
def test_filter_ava_3(): """ Only example.com mail addresses returned """ policy = Policy({ "default": { "lifetime": {"minutes": 15}, "attribute_restrictions": None # means all I have }, "urn:mace:example.com:saml:roland:sp": { "lifetime": {"minutes": 5}, "attribute_restrictions": { "mail": [".*@example\.com$"], } }}) ava = {"givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**", "*****@*****.**"]} # No restrictions apply ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", [], []) assert _eq(list(ava.keys()), ["mail"]) assert ava["mail"] == ["*****@*****.**"]
def test_filter_ava3(): policy = Policy({ "default": { "lifetime": {"minutes": 15}, # "attribute_restrictions": None # means all I have "entity_categories": ["swamid"] } }) mds = MetadataStore(ATTRCONV, sec_config, disable_ssl_certificate_validation=True) mds.imp([{"class": "saml2_tophat.mdstore.MetaDataFile", "metadata": [(full_path("entity_cat_sfs_hei.xml"),)]}]) ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["*****@*****.**"], "c": ["USA"], "eduPersonTargetedID": "foo!bar!xyz", "norEduPersonNIN": "19800101134"} ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", mds) assert _eq(list(ava.keys()), ['eduPersonTargetedID', "norEduPersonNIN"])
def test_ava_filter_dont_fail(): conf = { "default": { "lifetime": {"minutes": 15}, "attribute_restrictions": None, # means all I have "fail_on_missing_requested": False }, "urn:mace:umu.se:saml:roland:sp": { "lifetime": {"minutes": 5}, "attribute_restrictions": { "givenName": None, "surName": None, "mail": [".*@.*\.umu\.se"], }, "fail_on_missing_requested": False }} policy = Policy(conf) ava = {"givenName": "Derek", "surName": "Jeter", "mail": "*****@*****.**"} # mail removed because it doesn't match the regular expression # So it should fail if the 'fail_on_ ...' flag wasn't set _ava = policy.filter(ava, 'urn:mace:umu.se:saml:roland:sp', None, [mail], [gn, sn]) assert _ava ava = {"givenName": "Derek", "surName": "Jeter"} # it wasn't there to begin with _ava = policy.filter(ava, 'urn:mace:umu.se:saml:roland:sp', None, [gn, sn, mail]) assert _ava
def load_complex(self, cnf, typ="", metadata_construction=False): try: self.setattr(typ, "policy", Policy(cnf["policy"])) except KeyError: pass # for srv, spec in cnf["service"].items(): # try: # self.setattr(srv, "policy", # Policy(cnf["service"][srv]["policy"])) # except KeyError: # pass try: try: acs = ac_factory(cnf["attribute_map_dir"]) except KeyError: acs = ac_factory() if not acs: raise ConfigurationError( "No attribute converters, something is wrong!!") _acs = self.getattr("attribute_converters", typ) if _acs: _acs.extend(acs) else: self.setattr(typ, "attribute_converters", acs) except KeyError: pass if not metadata_construction: try: self.setattr(typ, "metadata", self.load_metadata(cnf["metadata"])) except KeyError: pass
def test_filter_ava_0(): policy = Policy( { "default": { "lifetime": {"minutes": 15}, "attribute_restrictions": None # means all I have }, "urn:mace:example.com:saml:roland:sp": { "lifetime": {"minutes": 5}, } } ) ava = {"givenName": ["Derek"], "surName": ["Jeter"], "mail": ["*****@*****.**"]} # No restrictions apply ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", [], []) assert _eq(sorted(list(ava.keys())), ["givenName", "mail", "surName"]) assert ava["givenName"] == ["Derek"] assert ava["surName"] == ["Jeter"] assert ava["mail"] == ["*****@*****.**"]
def test_filter_attribute_value_assertions_1(AVA): p = Policy({ "default": { "attribute_restrictions": { "surName": None, "givenName": [".*er.*"], } } }) ava = filter_attribute_value_assertions(AVA[0].copy(), p.get_attribute_restrictions("")) print(ava) assert _eq(ava.keys(), ["givenName", "surName"]) assert ava["surName"] == ["Jeter"] assert ava["givenName"] == ["Derek"] ava = filter_attribute_value_assertions(AVA[1].copy(), p.get_attribute_restrictions("")) print(ava) assert _eq(list(ava.keys()), ["surName"]) assert ava["surName"] == ["Howard"]
def test_vo_1(self): policy = Policy({ "default": { "name_form": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "nameid_format": NAMEID_FORMAT_PERSISTENT, "attribute_restrictions": { "surName": [".*berg"], } } }) name_id_policy = samlp.name_id_policy_from_string(NAME_ID_POLICY_1) print(name_id_policy) nameid = self.id.construct_nameid("foobar", policy, 'http://vo.example.org/biomed', name_id_policy) print(nameid) assert _eq(nameid.keyswv(), ['text', 'sp_name_qualifier', 'format', 'name_qualifier']) assert nameid.sp_name_qualifier == 'http://vo.example.org/biomed' assert nameid.format == NAMEID_FORMAT_PERSISTENT # we want to *NOT* keep the user identifier in the nameid node assert nameid.text != "foobar"
def test_assertion_with_noop_attribute_conv(): ava = {"urn:oid:2.5.4.4": "Roland", "urn:oid:2.5.4.42": "Hedberg"} ast = Assertion(ava) policy = Policy({ "default": { "lifetime": {"minutes": 240}, "attribute_restrictions": None, # means all I have "name_form": NAME_FORMAT_URI }, }) name_id = NameID(format=NAMEID_FORMAT_TRANSIENT, text="foobar") issuer = Issuer(text="entityid", format=NAMEID_FORMAT_ENTITY) farg = add_path( {}, ['subject', 'subject_confirmation', 'method', saml.SCM_BEARER]) add_path( farg['subject']['subject_confirmation'], ['subject_confirmation_data', 'in_response_to', 'in_response_to']) add_path( farg['subject']['subject_confirmation'], ['subject_confirmation_data', 'recipient', 'consumer_url']) msg = ast.construct( "sp_entity_id", [AttributeConverterNOOP(NAME_FORMAT_URI)], policy, issuer=issuer, farg=farg, authn_decl=ACD, name_id=name_id, authn_auth="authn_authn") print(msg) for attr in msg.attribute_statement[0].attribute: assert attr.name_format == NAME_FORMAT_URI assert len(attr.attribute_value) == 1 if attr.name == "urn:oid:2.5.4.42": assert attr.attribute_value[0].text == "Hedberg" elif attr.name == "urn:oid:2.5.4.4": assert attr.attribute_value[0].text == "Roland"
def create_attribute_response(self, identity, in_response_to, destination, sp_entity_id, userid="", name_id=None, status=None, issuer=None, sign_assertion=False, sign_response=False, attributes=None, sign_alg=None, digest_alg=None, farg=None, **kwargs): """ Create an attribute assertion response. :param identity: A dictionary with attributes and values that are expected to be the bases for the assertion in the response. :param in_response_to: The session identifier of the request :param destination: The URL which should receive the response :param sp_entity_id: The entity identifier of the SP :param userid: A identifier of the user :param name_id: The identifier of the subject :param status: The status of the response :param issuer: The issuer of the response :param sign_assertion: Whether the assertion should be signed or not :param sign_response: Whether the whole response should be signed :param attributes: :param kwargs: To catch extra keyword arguments :return: A response instance """ policy = self.config.getattr("policy", "aa") if not name_id and userid: try: name_id = self.ident.construct_nameid(userid, policy, sp_entity_id) logger.warning("Unspecified NameID format") except Exception: pass to_sign = [] if identity: farg = self.update_farg(in_response_to, sp_entity_id, farg=farg) _issuer = self._issuer(issuer) ast = Assertion(identity) if policy: ast.apply_policy(sp_entity_id, policy, self.metadata) else: policy = Policy() if attributes: restr = restriction_from_attribute_spec(attributes) ast = filter_attribute_value_assertions(ast) assertion = ast.construct(sp_entity_id, self.config.attribute_converters, policy, issuer=_issuer, name_id=name_id, farg=farg['assertion']) if sign_assertion: assertion.signature = pre_signature_part(assertion.id, self.sec.my_cert, 1, sign_alg=sign_alg, digest_alg=digest_alg) # Just the assertion or the response and the assertion ? to_sign = [(class_name(assertion), assertion.id)] kwargs['sign_assertion'] = True kwargs["assertion"] = assertion if sp_entity_id: kwargs['sp_entity_id'] = sp_entity_id return self._response(in_response_to, destination, status, issuer, sign_response, to_sign, sign_alg=sign_alg, digest_alg=digest_alg, **kwargs)
def setup_assertion(self, authn, sp_entity_id, in_response_to, consumer_url, name_id, policy, _issuer, authn_statement, identity, best_effort, sign_response, farg=None, session_not_on_or_after=None, **kwargs): """ Construct and return the Assertion :param authn: Authentication information :param sp_entity_id: :param in_response_to: The ID of the request this is an answer to :param consumer_url: The recipient of the assertion :param name_id: The NameID of the subject :param policy: Assertion policies :param _issuer: Issuer of the statement :param authn_statement: An AuthnStatement instance :param identity: Identity information about the Subject :param best_effort: Even if not the SPs demands can be met send a response. :param sign_response: Sign the response, only applicable if ErrorResponse :param kwargs: Extra keyword arguments :return: An Assertion instance """ ast = Assertion(identity) ast.acs = self.config.getattr("attribute_converters", "idp") if policy is None: policy = Policy() try: ast.apply_policy(sp_entity_id, policy, self.metadata) except MissingValue as exc: if not best_effort: return self.create_error_response(in_response_to, consumer_url, exc, sign_response) farg = self.update_farg(in_response_to, consumer_url, farg) if authn: # expected to be a dictionary # Would like to use dict comprehension but ... authn_args = dict([(AUTHN_DICT_MAP[k], v) for k, v in authn.items() if k in AUTHN_DICT_MAP]) authn_args.update(kwargs) assertion = ast.construct( sp_entity_id, self.config.attribute_converters, policy, issuer=_issuer, farg=farg['assertion'], name_id=name_id, session_not_on_or_after=session_not_on_or_after, **authn_args) elif authn_statement: # Got a complete AuthnStatement assertion = ast.construct(sp_entity_id, self.config.attribute_converters, policy, issuer=_issuer, authn_statem=authn_statement, farg=farg['assertion'], name_id=name_id, **kwargs) else: assertion = ast.construct( sp_entity_id, self.config.attribute_converters, policy, issuer=_issuer, farg=farg['assertion'], name_id=name_id, session_not_on_or_after=session_not_on_or_after, **kwargs) return assertion