def test_logout_1(self): """ one IdP/AA with BINDING_HTTP_REDIRECT on single_logout_service""" # information about the user from an IdP session_info = { "name_id": "123456", "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", "surName": "Andersson", "mail": "*****@*****.**" } } self.client.users.add_information_about_person(session_info) entity_ids = self.client.users.issuers_of_info("123456") assert entity_ids == ["urn:mace:example.com:saml:roland:idp"] resp = self.client.global_logout("123456", "Tired", in_a_while(minutes=5)) print resp assert resp assert resp[0] # a session_id assert resp[1] == '200 OK' assert resp[2] == [('Content-type', 'text/html')] assert resp[3][0] == '<head>' assert resp[3][1] == '<title>SAML 2.0 POST</title>' session_info = self.client.state[resp[0]] print session_info assert session_info["entity_id"] == entity_ids[0] assert session_info["subject_id"] == "123456" assert session_info["reason"] == "Tired" assert session_info["operation"] == "SLO" assert session_info["entity_ids"] == entity_ids assert session_info["sign"] == False
def test_logout_1(self): """ one IdP/AA logout from""" # information about the user from an IdP session_info = { "name_id": "123456", "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", "surName": "Andersson", "mail": "*****@*****.**" } } self.client.users.add_information_about_person(session_info) entity_ids = self.client.users.issuers_of_info("123456") assert entity_ids == ["urn:mace:example.com:saml:roland:idp"] resp = self.client.global_logout("123456", "Tired", in_a_while(minutes=5)) print resp assert resp assert len(resp) == 1 assert resp.keys() == entity_ids http_args = resp[entity_ids[0]] assert isinstance(http_args, dict) assert http_args["headers"] == [('Content-type', 'text/html')] info = unpack_form(http_args["data"][3]) xml_str = base64.b64decode(info["SAMLRequest"]) req = logout_request_from_string(xml_str) print req assert req.reason == "Tired"
def test_logout_3(self): """ two or more IdP/AA with BINDING_HTTP_REDIRECT""" conf = config.SPConfig() conf.load_file("server3_conf") client = Saml2Client(conf) # information about the user from an IdP session_info_authn = { "name_id": "123456", "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", "surName": "Andersson", "mail": "*****@*****.**" } } client.users.add_information_about_person(session_info_authn) session_info_aa = { "name_id": "123456", "issuer": "urn:mace:example.com:saml:roland:aa", "not_on_or_after": in_a_while(minutes=15), "ava": { "eduPersonEntitlement": "Foobar", } } client.users.add_information_about_person(session_info_aa) entity_ids = client.users.issuers_of_info("123456") assert _leq(entity_ids, [ "urn:mace:example.com:saml:roland:idp", "urn:mace:example.com:saml:roland:aa" ]) resp = client.global_logout("123456", "Tired", in_a_while(minutes=5)) print resp assert resp assert resp[0] # a session_id assert resp[1] == '200 OK' # HTTP POST assert resp[2] == [('Content-type', 'text/html')] assert resp[3][0] == '<head>' assert resp[3][1] == '<title>SAML 2.0 POST</title>' state_info = client.state[resp[0]] print state_info assert state_info["entity_id"] == entity_ids[0] assert state_info["subject_id"] == "123456" assert state_info["reason"] == "Tired" assert state_info["operation"] == "SLO" assert state_info["entity_ids"] == entity_ids assert state_info["sign"] == False
def test_logout_3(self): """ two or more IdP/AA with BINDING_HTTP_REDIRECT""" conf = config.SPConfig() conf.load_file("server3_conf") client = Saml2Client(conf) # information about the user from an IdP session_info_authn = { "name_id": "123456", "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", "surName": "Andersson", "mail": "*****@*****.**" } } client.users.add_information_about_person(session_info_authn) session_info_aa = { "name_id": "123456", "issuer": "urn:mace:example.com:saml:roland:aa", "not_on_or_after": in_a_while(minutes=15), "ava": { "eduPersonEntitlement": "Foobar", } } client.users.add_information_about_person(session_info_aa) entity_ids = client.users.issuers_of_info("123456") assert _leq(entity_ids, ["urn:mace:example.com:saml:roland:idp", "urn:mace:example.com:saml:roland:aa"]) resp = client.global_logout("123456", "Tired", in_a_while(minutes=5)) print resp assert resp assert resp[0] # a session_id assert resp[1] == '200 OK' # HTTP POST assert resp[2] == [('Content-type', 'text/html')] assert resp[3][0] == '<head>' assert resp[3][1] == '<title>SAML 2.0 POST</title>' state_info = client.state[resp[0]] print state_info assert state_info["entity_id"] == entity_ids[0] assert state_info["subject_id"] == "123456" assert state_info["reason"] == "Tired" assert state_info["operation"] == "SLO" assert state_info["entity_ids"] == entity_ids assert state_info["sign"] == False
def test_logout_2(self): """ one IdP/AA with BINDING_SOAP, can't actually send something""" conf = config.SPConfig() conf.load_file("server2_conf") client = Saml2Client(conf) # information about the user from an IdP session_info = { "name_id": "123456", "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", "surName": "Andersson", "mail": "*****@*****.**" } } client.users.add_information_about_person(session_info) entity_ids = self.client.users.issuers_of_info("123456") assert entity_ids == ["urn:mace:example.com:saml:roland:idp"] destinations = client.config.single_logout_services( entity_ids[0], BINDING_SOAP) print destinations assert destinations == ['http://localhost:8088/slo'] # Will raise an error since there is noone at the other end. raises( LogoutError, 'client.global_logout("123456", "Tired", in_a_while(minutes=5))')
def entities_desc(service, ename, base, cert_file=None, validity="", cache="", social=None, scopebase="social2saml.org"): ed = [] if cert_file: _cert = read_cert_from_file(cert_file, "pem") key_descriptor = do_key_descriptor(_cert) else: key_descriptor = None for name, desc in service.items(): if social is None or name in social: scope = shibmd.Scope(text="%s.%s" % (name, scopebase)) loc = "%s/%s" % (base, desc["saml_endpoint"]) eid = "%s/%s" % (base, desc["entity_id"]) ed.append(entity_desc(loc, key_descriptor, eid, scope=scope)) return EntitiesDescriptor( name=ename, entity_descriptor=ed, valid_until=in_a_while(hours=validity), cache_duration=cache)
def test_construct_AttributeAuthorityDescriptor(): aad = make_instance( md.AttributeAuthorityDescriptor, { "valid_until": time_util.in_a_while(30), # 30 days from now "id": "aad.example.com", "protocol_support_enumeration": SAML2_NAMESPACE, "attribute_service": {"binding": BINDING_SOAP, "location": "http://example.com:6543/saml2/aad"}, "name_id_format": [NAMEID_FORMAT_TRANSIENT], "key_descriptor": {"use": "signing", "key_info": {"key_name": "example.com"}}, }, ) print aad assert _eq( aad.keyswv(), ["valid_until", "id", "attribute_service", "name_id_format", "key_descriptor", "protocol_support_enumeration"], ) assert time_util.str_to_time(aad.valid_until) assert aad.id == "aad.example.com" assert aad.protocol_support_enumeration == SAML2_NAMESPACE assert len(aad.attribute_service) == 1 atsr = aad.attribute_service[0] assert _eq(atsr.keyswv(), ["binding", "location"]) assert atsr.binding == BINDING_SOAP assert atsr.location == "http://example.com:6543/saml2/aad" assert len(aad.name_id_format) == 1 nif = aad.name_id_format[0] assert nif.text.strip() == NAMEID_FORMAT_TRANSIENT assert len(aad.key_descriptor) == 1 kdesc = aad.key_descriptor[0] assert kdesc.use == "signing" assert kdesc.key_info.key_name[0].text.strip() == "example.com"
def entity_descriptor(confd): mycert = "".join(open(confd.cert_file).readlines()[1:-1]) entd = md.EntityDescriptor() entd.entity_id = confd.entityid if confd.valid_for: entd.valid_until = in_a_while(hours=int(confd.valid_for)) if confd.organization is not None: entd.organization = do_organization_info(confd.organization) if confd.contact_person is not None: entd.contact_person = do_contact_person_info(confd.contact_person) serves = confd.serves if not serves: raise Exception( 'No service type ("sp","idp","aa") provided in the configuration') if "sp" in serves: confd.context = "sp" entd.spsso_descriptor = do_spsso_descriptor(confd, mycert) if "idp" in serves: confd.context = "idp" entd.idpsso_descriptor = do_idpsso_descriptor(confd, mycert) if "aa" in serves: confd.context = "aa" entd.attribute_authority_descriptor = do_aa_descriptor(confd, mycert) if "pdp" in serves: confd.context = "pdp" entd.pdp_descriptor = do_pdp_descriptor(confd, mycert) return entd
def test_extend_person(self): session_info = { "name_id": nid, "issuer": IDP_OTHER, "not_on_or_after": in_a_while(minutes=15), "ava": { "eduPersonEntitlement": "Anka" } } self.population.add_information_about_person(session_info) issuers = self.population.issuers_of_info(nid) assert _eq(issuers, [IDP_ONE, IDP_OTHER]) subjects = [code(c) for c in self.population.subjects()] assert subjects == [cnid] # Are any of the sources gone stale stales = self.population.stale_sources_for_person(nid) assert stales == [] # are any of the possible sources not used or gone stale possible = [IDP_ONE, IDP_OTHER] stales = self.population.stale_sources_for_person(nid, possible) assert stales == [] (identity, stale) = self.population.get_identity(nid) assert stale == [] assert identity == {'mail': '*****@*****.**', 'givenName': 'Anders', 'surName': 'Andersson', "eduPersonEntitlement": "Anka"} info = self.population.get_info_from(nid, IDP_OTHER) assert _eq(list(info.keys()), ["not_on_or_after", "name_id", "ava"]) assert info["name_id"] == nid assert info["ava"] == {"eduPersonEntitlement": "Anka"}
def test_slo_soap(self): soon = time_util.in_a_while(days=1) sinfo = { "name_id": nid, "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": soon, "user": { "givenName": "Leo", "surName": "Laport", } } sp = client.Saml2Client(config_file="server_conf") sp.users.add_information_about_person(sinfo) req_id, logout_request = sp.create_logout_request( name_id=nid, destination="http://localhost:8088/slo", issuer_entity_id="urn:mace:example.com:saml:roland:idp", reason="I'm tired of this") #_ = s_utils.deflate_and_base64_encode("%s" % (logout_request,)) saml_soap = make_soap_enveloped_saml_thingy(logout_request) self.server.ident.close() with closing(Server("idp_soap_conf")) as idp: request = idp.parse_logout_request(saml_soap) idp.ident.close() assert request
def test_slo_http_post(self): soon = time_util.in_a_while(days=1) sinfo = { "name_id": nid, "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": soon, "user": { "givenName": "Leo", "surName": "Laport", } } self.client.users.add_information_about_person(sinfo) req_id, logout_request = self.client.create_logout_request( destination="http://localhost:8088/slop", name_id=nid, issuer_entity_id="urn:mace:example.com:saml:roland:idp", reason="I'm tired of this") _req = "%s" % logout_request intermed = base64.b64encode(_req.encode("utf8")) #saml_soap = make_soap_enveloped_saml_thingy(logout_request) request = self.server.parse_logout_request(intermed, BINDING_HTTP_POST) assert request
def test_logout_2(self): """ one IdP/AA with BINDING_SOAP, can't actually send something""" conf = config.SPConfig() conf.load_file("server2_conf") client = Saml2Client(conf) # information about the user from an IdP session_info = { "name_id": "123456", "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", "surName": "Andersson", "mail": "*****@*****.**" } } client.users.add_information_about_person(session_info) entity_ids = self.client.users.issuers_of_info("123456") assert entity_ids == ["urn:mace:example.com:saml:roland:idp"] destinations = client.config.single_logout_services(entity_ids[0], BINDING_SOAP) print destinations assert destinations == ['http://localhost:8088/slo'] # Will raise an error since there is noone at the other end. raises(LogoutError, 'client.global_logout("123456", "Tired", in_a_while(minutes=5))')
def entities_descriptor(eds, valid_for, name, ident, sign, secc): entities = md.EntitiesDescriptor(entity_descriptor=eds) if valid_for: entities.valid_until = in_a_while(hours=valid_for) if name: entities.name = name if ident: entities.id = ident if sign: if not ident: ident = sid() if not secc.key_file: raise SAMLError("If you want to do signing you should define " + "a key to sign with") if not secc.my_cert: raise SAMLError("If you want to do signing you should define " + "where your public key are") entities.signature = pre_signature_part(ident, secc.my_cert, 1) entities.id = ident xmldoc = secc.sign_statement("%s" % entities, class_name(entities)) entities = md.entities_descriptor_from_string(xmldoc) else: xmldoc = None return entities, xmldoc
def test_slo_soap(self): soon = time_util.in_a_while(days=1) sinfo = { "name_id": nid, "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": soon, "user": { "givenName": "Leo", "sn": "Laport", } } sp = client.Saml2Client(config_file="server_conf") sp.users.add_information_about_person(sinfo) req_id, logout_request = sp.create_logout_request( name_id=nid, destination="http://localhost:8088/slo", issuer_entity_id="urn:mace:example.com:saml:roland:idp", reason="I'm tired of this") #_ = s_utils.deflate_and_base64_encode("%s" % (logout_request,)) saml_soap = make_soap_enveloped_saml_thingy(logout_request) self.server.ident.close() with closing(Server("idp_soap_conf")) as idp: request = idp.parse_logout_request(saml_soap) idp.ident.close() assert request
def entity_descriptor(confd): mycert = "".join(open(confd.cert_file).readlines()[1:-1]) entd = md.EntityDescriptor() entd.entity_id = confd.entityid if confd.valid_for: entd.valid_until = in_a_while(hours=int(confd.valid_for)) if confd.organization is not None: entd.organization = do_organization_info(confd.organization) if confd.contact_person is not None: entd.contact_person = do_contact_person_info(confd.contact_person) serves = confd.serves if not serves: raise Exception('No service type ("sp","idp","aa") provided in the configuration') if "sp" in serves: confd.context = "sp" entd.spsso_descriptor = do_spsso_descriptor(confd, mycert) if "idp" in serves: confd.context = "idp" entd.idpsso_descriptor = do_idpsso_descriptor(confd, mycert) if "aa" in serves: confd.context = "aa" entd.attribute_authority_descriptor = do_aa_descriptor(confd, mycert) if "pdp" in serves: confd.context = "pdp" entd.pdp_descriptor = do_pdp_descriptor(confd, mycert) return entd
def entities_descriptor(eds, valid_for, name, ident, sign, secc): entities = md.EntitiesDescriptor(entity_descriptor=eds) if valid_for: entities.valid_until = in_a_while(hours=valid_for) if name: entities.name = name if ident: entities.id = ident if sign: if not ident: ident = sid() if not secc.key_file: raise Exception("If you want to do signing you should define " + "a key to sign with") if not secc.my_cert: raise Exception("If you want to do signing you should define " + "where your public key are") entities.signature = pre_signature_part(ident, secc.my_cert, 1) entities.id = ident xmldoc = secc.sign_statement("%s" % entities, class_name(entities)) entities = md.entities_descriptor_from_string(xmldoc) return entities
def _expiration(self, timeout, tformat="%a, %d-%b-%Y %H:%M:%S GMT"): if timeout == "now": return time_util.instant(tformat) elif timeout == "dawn": return time.strftime(tformat, time.gmtime(0)) else: # validity time should match lifetime of assertions return time_util.in_a_while(minutes=timeout, format=tformat)
def entity_descriptor(confd): mycert = None enc_cert = None if confd.cert_file is not None: mycert = [] mycert.append("".join(open(confd.cert_file).readlines()[1:-1])) if confd.additional_cert_files is not None: for _cert_file in confd.additional_cert_files: mycert.append("".join(open(_cert_file).readlines()[1:-1])) if confd.encryption_keypairs is not None: enc_cert = [] for _encryption in confd.encryption_keypairs: enc_cert.append("".join( open(_encryption["cert_file"]).readlines()[1:-1])) entd = md.EntityDescriptor() entd.entity_id = confd.entityid if confd.valid_for: entd.valid_until = in_a_while(hours=int(confd.valid_for)) if confd.organization is not None: entd.organization = do_organization_info(confd.organization) if confd.contact_person is not None: entd.contact_person = do_contact_person_info(confd.contact_person) if confd.entity_category: entd.extensions = md.Extensions() ava = [AttributeValue(text=c) for c in confd.entity_category] attr = Attribute(attribute_value=ava, name="http://macedir.org/entity-category") item = mdattr.EntityAttributes(attribute=attr) entd.extensions.add_extension_element(item) serves = confd.serves if not serves: raise SAMLError( 'No service type ("sp","idp","aa") provided in the configuration') if "sp" in serves: confd.context = "sp" entd.spsso_descriptor = do_spsso_descriptor(confd, mycert, enc_cert) if "idp" in serves: confd.context = "idp" entd.idpsso_descriptor = do_idpsso_descriptor(confd, mycert, enc_cert) if "aa" in serves: confd.context = "aa" entd.attribute_authority_descriptor = do_aa_descriptor( confd, mycert, enc_cert) if "pdp" in serves: confd.context = "pdp" entd.pdp_descriptor = do_pdp_descriptor(confd, mycert, enc_cert) if "aq" in serves: confd.context = "aq" entd.authn_authority_descriptor = do_aq_descriptor( confd, mycert, enc_cert) return entd
def entity_descriptor(confd): mycert = None enc_cert = None if confd.cert_file is not None: mycert = [] mycert.append("".join(open(confd.cert_file).readlines()[1:-1])) if confd.additional_cert_files is not None: for _cert_file in confd.additional_cert_files: mycert.append("".join(open(_cert_file).readlines()[1:-1])) if confd.encryption_keypairs is not None: enc_cert = [] for _encryption in confd.encryption_keypairs: enc_cert.append( "".join(open(_encryption["cert_file"]).readlines()[1:-1])) entd = md.EntityDescriptor() entd.entity_id = confd.entityid if confd.valid_for: entd.valid_until = in_a_while(hours=int(confd.valid_for)) if confd.organization is not None: entd.organization = do_organization_info(confd.organization) if confd.contact_person is not None: entd.contact_person = do_contact_person_info(confd.contact_person) if confd.entity_category: entd.extensions = md.Extensions() ava = [AttributeValue(text=c) for c in confd.entity_category] attr = Attribute(attribute_value=ava, name="http://macedir.org/entity-category") item = mdattr.EntityAttributes(attribute=attr) entd.extensions.add_extension_element(item) serves = confd.serves if not serves: raise SAMLError( 'No service type ("sp","idp","aa") provided in the configuration') if "sp" in serves: confd.context = "sp" entd.spsso_descriptor = do_spsso_descriptor(confd, mycert, enc_cert) if "idp" in serves: confd.context = "idp" entd.idpsso_descriptor = do_idpsso_descriptor(confd, mycert, enc_cert) if "aa" in serves: confd.context = "aa" entd.attribute_authority_descriptor = do_aa_descriptor(confd, mycert, enc_cert) if "pdp" in serves: confd.context = "pdp" entd.pdp_descriptor = do_pdp_descriptor(confd, mycert, enc_cert) if "aq" in serves: confd.context = "aq" entd.authn_authority_descriptor = do_aq_descriptor(confd, mycert, enc_cert) return entd
def test_valid_for(self, entity_desc, signature_security_context): valid_for = 4 # metadata valid for 4 hours expected_validity = in_a_while(hours=valid_for) signed_metadata = create_signed_entity_descriptor( entity_desc, signature_security_context, valid_for=valid_for) md = InMemoryMetaData(None) md.parse(signed_metadata) assert md.entity_descr.valid_until == expected_validity
def add_derek_info(sp): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Derek"], "umuselin": ["deje0001"]} session_info["issuer"] = "urn:mace:example.com:saml:idp" session_info["name_id"] = nid session_info["not_on_or_after"] = not_on_or_after # subject_id, entity_id, info, timestamp sp.users.add_information_about_person(session_info)
def not_on_or_after(self, sp_entity_id): """ When the assertion stops being valid, should not be used after this time. :param sp_entity_id: The SP entity ID :return: String representation of the time """ return in_a_while(**self.get_lifetime(sp_entity_id))
def test_valid_for(self, entity_desc, signature_security_context): valid_for = 4 # metadata valid for 4 hours expected_validity = in_a_while(hours=valid_for) signed_metadata = create_signed_entity_descriptor(entity_desc, signature_security_context, valid_for=valid_for) md = InMemoryMetaData(None) md.parse(signed_metadata) assert md.entity_descr.valid_until == expected_validity
def test_valid(): assert valid("2000-01-12T00:00:00Z") == False current_year = datetime.datetime.today().year assert valid("%d-01-12T00:00:00Z" % (current_year + 1)) == True this_instance = instant() time.sleep(1) assert valid(this_instance) == False # unless on a very fast machine :-) soon = in_a_while(seconds=10) assert valid(soon) == True
def add_derek_info(sp): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Derek"], "umuselin": ["deje0001"]} session_info["issuer"] = "https://toylan3.umdc.umu.se/shibboleth" session_info["name_id"] = "abcdefgh" session_info["not_on_or_after"] = not_on_or_after # subject_id, entity_id, info, timestamp sp.users.add_information_about_person(session_info)
def add_derek_info(sp): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Derek"], "umuselin": ["deje0001"]} session_info["issuer"] = "urn:mace:example.com:saml:idp" session_info["name_id"] = "abcdefgh" session_info["not_on_or_after"] = not_on_or_after # subject_id, entity_id, info, timestamp sp.users.add_information_about_person(session_info)
def add_derek_info(sp): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName":["Derek"], "umuselin":["deje0001"]} session_info["issuer"] = "https://toylan3.umdc.umu.se/shibboleth" session_info["name_id"] = "abcdefgh" session_info["not_on_or_after"] = not_on_or_after # subject_id, entity_id, info, timestamp sp.users.add_information_about_person(session_info)
def _expiration(timeout, tformat=None): # Wed, 06-Jun-2012 01:34:34 GMT if not tformat: tformat = "%a, %d-%b-%Y %T GMT" if timeout == "now": return time_util.instant(tformat) else: # validity time should match lifetime of assertions return time_util.in_a_while(minutes=timeout, format=tformat)
def test_set(self): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Derek"]} self.cache.set("1234", "abcd", session_info, not_on_or_after) (ava, inactive) = self.cache.get_identity("1234") assert inactive == [] assert ava.keys() == ["givenName"] assert ava["givenName"] == ["Derek"]
def test_identity(self): if self.cache is not None: not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Derek"]} self.cache.set("1234", "abcd", session_info, not_on_or_after) not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"mail": ["*****@*****.**"]} self.cache.set("1234", "xyzv", session_info, not_on_or_after) (ident, _) = self.cache.get_identity("1234") print(ident) assert len(list(ident.keys())) == 2 assert "givenName" in list(ident.keys()) assert "mail" in list(ident.keys()) assert ident["mail"] == ["*****@*****.**"] assert ident["givenName"] == ["Derek"]
def test_timeout(self): not_on_or_after = str_to_time(in_a_while(seconds=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Alex"], "surName": ["Rodriguez"]} self.cache.set("1000", "bcde", session_info, not_on_or_after) time.sleep(2) (ava, inactive) = self.cache.get_identity("1000") assert inactive == ["bcde"] assert ava == {}
def test_identity(self): if self.cache is not None: not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName":["Derek"]} self.cache.set("1234", "abcd", session_info, not_on_or_after) not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"mail":["*****@*****.**"]} self.cache.set("1234", "xyzv", session_info, not_on_or_after) (ident, _) = self.cache.get_identity("1234") print ident assert len(ident.keys()) == 2 assert "givenName" in ident.keys() assert "mail" in ident.keys() assert ident["mail"] == ["*****@*****.**"] assert ident["givenName"] == ["Derek"]
def test_receivers(self): assert _eq(self.cache.receivers("9876"), ["abcd"]) not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Ichiro"], "surName": ["Suzuki"]} self.cache.set("9876", "bcde", session_info, not_on_or_after) assert _eq(self.cache.receivers("9876"), ["abcd", "bcde"]) assert _eq(self.cache.subjects(), ["1234", "9876"])
def _expiration(timeout, tformat=None): # Wed, 06-Jun-2012 01:34:34 GMT if not tformat: tformat = '%a, %d-%b-%Y %T GMT' if timeout == "now": return time_util.instant(tformat) else: # validity time should match lifetime of assertions return time_util.in_a_while(minutes=timeout, format=tformat)
def test_set(self): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Derek"]} self.cache.set(nid[0], "abcd", session_info, not_on_or_after) (ava, inactive) = self.cache.get_identity(nid[0]) assert inactive == [] assert list(ava.keys()) == ["givenName"] assert ava["givenName"] == ["Derek"]
def test_add_ava_info(self): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"surName": ["Jeter"]} self.cache.set(nid[0], "bcde", session_info, not_on_or_after) (ava, inactive) = self.cache.get_identity(nid[0]) assert inactive == [] assert _eq(ava.keys(), ["givenName", "surName"]) assert ava["givenName"] == ["Derek"] assert ava["surName"] == ["Jeter"]
def sign_entity_descriptor(edesc, valid_for, ident, secc): if valid_for: edesc.valid_until = in_a_while(hours=valid_for) if not ident: ident = sid() edesc.signature = pre_signature_part(ident, secc.my_cert, 1) edesc.id = ident xmldoc = secc.sign_statement_using_xmlsec("%s" % edesc, class_name(edesc)) return md.entity_descriptor_from_string(xmldoc)
def test_timeout(self): not_on_or_after = str_to_time(in_a_while(seconds=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Alex"], "surName": ["Rodriguez"]} self.cache.set(nid[2], "bcde", session_info, not_on_or_after) time.sleep(2) (ava, inactive) = self.cache.get_identity(nid[2]) assert inactive == ["bcde"] assert ava == {}
def test_set_get_2(self): if self.cache is not None: not_on_or_after = str_to_time(in_a_while(seconds=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Mariano"]} # subject_id, entity_id, info, timestamp self.cache.set("1235", "abcd", session_info, not_on_or_after) time.sleep(2) raises(ToOld, 'self.cache.get("1235", "abcd")') info = self.cache.get("1235", "abcd", False) assert info != {}
def test_second_subject(self): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Ichiro"], "surName": ["Suzuki"]} self.cache.set("9876", "abcd", session_info, not_on_or_after) (ava, inactive) = self.cache.get_identity("9876") assert inactive == [] assert _eq(ava.keys(), ["givenName", "surName"]) assert ava["givenName"] == ["Ichiro"] assert ava["surName"] == ["Suzuki"] assert _eq(self.cache.subjects(), ["1234", "9876"])
def test_receivers(self): assert _eq(self.cache.receivers(nid[1]), ["abcd"]) not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Ichiro"], "surName": ["Suzuki"]} self.cache.set(nid[1], "bcde", session_info, not_on_or_after) assert _eq(self.cache.receivers(nid[1]), ["abcd", "bcde"]) assert nid_eq(self.cache.subjects(), nid[0:2])
def test_set_get_1(self): if self.cache is not None: not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName":["Derek"]} # subject_id, entity_id, info, timestamp self.cache.set("1234", "abcd", session_info, not_on_or_after) info = self.cache.get("1234", "abcd") #{u'issuer': u'', u'came from': u'', u'ava': {u'givenName': [u'Derek']}, u'session_id': -1, u'not_on_or_after': 0} ava = info["ava"] print ava assert ava.keys() == ["givenName"] assert ava["givenName"] == ["Derek"]
def test_set_get_1(self): if self.cache is not None: not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Derek"]} # subject_id, entity_id, info, timestamp self.cache.set("1234", "abcd", session_info, not_on_or_after) info = self.cache.get("1234", "abcd") #{u'issuer': u'', u'came from': u'', u'ava': {u'givenName': [u'Derek']}, u'session_id': -1, u'not_on_or_after': 0} ava = info["ava"] print(ava) assert list(ava.keys()) == ["givenName"] assert ava["givenName"] == ["Derek"]
def test_second_subject(self): not_on_or_after = str_to_time(in_a_while(days=1)) session_info = SESSION_INFO_PATTERN.copy() session_info["ava"] = {"givenName": ["Ichiro"], "surName": ["Suzuki"]} self.cache.set(nid[1], "abcd", session_info, not_on_or_after) (ava, inactive) = self.cache.get_identity(nid[1]) assert inactive == [] assert _eq(ava.keys(), ["givenName", "surName"]) assert ava["givenName"] == ["Ichiro"] assert ava["surName"] == ["Suzuki"] assert nid_eq(self.cache.subjects(), [nid[0], nid[1]])
def _expiration(timeout, tformat="%a, %d-%b-%Y %H:%M:%S GMT"): """ :param timeout: :param tformat: :return: """ if timeout == "now": return instant(tformat) elif timeout == "dawn": return strftime(tformat, gmtime(0)) else: # validity time should match lifetime of assertions return in_a_while(minutes=timeout, format=tformat)
def test_logout_1(self): """ one IdP/AA logout from""" # information about the user from an IdP session_info = { "name_id": nid, "issuer": "urn:mace:example.com:saml:roland:idp", "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", "surName": "Andersson", "mail": "*****@*****.**" } } self.client.users.add_information_about_person(session_info) entity_ids = self.client.users.issuers_of_info(nid) assert entity_ids == ["urn:mace:example.com:saml:roland:idp"] resp = self.client.global_logout(nid, "Tired", in_a_while(minutes=5)) print resp assert resp assert len(resp) == 1 assert resp.keys() == entity_ids response = resp[entity_ids[0]] assert isinstance(response, LogoutResponse)
def entity_descriptor(confd, valid_for): mycert = "".join(open(confd.cert_file).readlines()[1:-1]) # if "attribute_map_dir" in confd: # attrconverters = ac_factory(confd.attribute_map_dir) # else: # attrconverters = [AttributeConverter()] #if "attribute_maps" in confd: # (forward,backward) = parse_attribute_map(confd["attribute_maps"]) #else: # backward = {} entd = md.EntityDescriptor() entd.entity_id = confd.entityid if valid_for: entd.valid_until = in_a_while(hours=valid_for) if confd.organization is not None: entd.organization = do_organization_info(confd.organization) if confd.contact_person is not None: entd.contact_person = do_contact_person_info(confd.contact_person) serves = confd.serves() if not serves: raise Exception( 'No service type ("sp","idp","aa") provided in the configuration') if "sp" in serves: confd.context = "sp" entd.spsso_descriptor = do_sp_sso_descriptor(confd, mycert) if "idp" in serves: confd.context = "idp" entd.idpsso_descriptor = do_idp_sso_descriptor(confd, mycert) if "aa" in serves: confd.context = "aa" entd.attribute_authority_descriptor = do_aa_descriptor(confd, mycert) if "pdp" in serves: confd.context = "pdp" entd.pdp_descriptor = do_pdp_descriptor(confd, mycert) return entd
def entities_desc(service, ename, base, cert_file=None, validity="", cache="", social=None, scopebase="social2saml.org"): ed = [] if cert_file: _cert = read_cert_from_file(cert_file, "pem") key_descriptor = do_key_descriptor(_cert) else: key_descriptor = None for name, desc in service.items(): if social is None or name in social: scope = shibmd.Scope(text="%s.%s" % (name, scopebase)) loc = "%s/%s" % (base, desc["saml_endpoint"]) eid = "%s/%s" % (base, desc["entity_id"]) ed.append(entity_desc(loc, key_descriptor, eid, scope=scope)) return EntitiesDescriptor(name=ename, entity_descriptor=ed, valid_until = in_a_while(hours=validity), cache_duration=cache)
def test_construct_AttributeAuthorityDescriptor(): aad = make_instance( md.AttributeAuthorityDescriptor, { "valid_until": time_util.in_a_while(30), # 30 days from now "id": "aad.example.com", "protocol_support_enumeration": SAML2_NAMESPACE, "attribute_service": { "binding": BINDING_SOAP, "location": "http://example.com:6543/saml2/aad", }, "name_id_format": [ NAMEID_FORMAT_TRANSIENT, ], "key_descriptor": { "use": "signing", "key_info": { "key_name": "example.com", } } }) print aad assert _eq(aad.keyswv(), [ "valid_until", "id", "attribute_service", "name_id_format", "key_descriptor", "protocol_support_enumeration" ]) assert time_util.str_to_time(aad.valid_until) assert aad.id == "aad.example.com" assert aad.protocol_support_enumeration == SAML2_NAMESPACE assert len(aad.attribute_service) == 1 atsr = aad.attribute_service[0] assert _eq(atsr.keyswv(), ["binding", "location"]) assert atsr.binding == BINDING_SOAP assert atsr.location == "http://example.com:6543/saml2/aad" assert len(aad.name_id_format) == 1 nif = aad.name_id_format[0] assert nif.text.strip() == NAMEID_FORMAT_TRANSIENT assert len(aad.key_descriptor) == 1 kdesc = aad.key_descriptor[0] assert kdesc.use == "signing" assert kdesc.key_info.key_name[0].text.strip() == "example.com"
def test_add_person(self): session_info = { "name_id": nid, "issuer": IDP_ONE, "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", "surName": "Andersson", "mail": "*****@*****.**" } } self.population.add_information_about_person(session_info) issuers = self.population.issuers_of_info(nid) assert list(issuers) == [IDP_ONE] subjects = [code(c) for c in self.population.subjects()] assert subjects == [cnid] # Are any of the sources gone stale stales = self.population.stale_sources_for_person(nid) assert stales == [] # are any of the possible sources not used or gone stale possible = [IDP_ONE, IDP_OTHER] stales = self.population.stale_sources_for_person(nid, possible) assert stales == [IDP_OTHER] (identity, stale) = self.population.get_identity(nid) assert stale == [] assert identity == { 'mail': '*****@*****.**', 'givenName': 'Anders', 'surName': 'Andersson' } info = self.population.get_info_from(nid, IDP_ONE) assert sorted(list(info.keys())) == sorted( ["not_on_or_after", "name_id", "ava"]) assert info["name_id"] == nid assert info["ava"] == { 'mail': '*****@*****.**', 'givenName': 'Anders', 'surName': 'Andersson' }
def create_signed_entity_descriptor(entity_descriptor, security_context, valid_for=None): """ :param entity_descriptor: the entity descriptor to sign :param security_context: security context for the signature :param valid_for: number of hours the metadata should be valid :return: the signed XML document :type entity_descriptor: saml2.md.EntityDescriptor] :type security_context: saml2.sigver.SecurityContext :type valid_for: Optional[int] """ if valid_for: entity_descriptor.valid_until = in_a_while(hours=valid_for) entity_desc, xmldoc = sign_entity_descriptor(entity_descriptor, None, security_context) if not valid_instance(entity_desc): raise ValueError("Could not construct valid EntityDescriptor tag") return xmldoc