本文整理汇总了Python中saml2.s_utils.decode_base64_and_inflate函数的典型用法代码示例。如果您正苦于以下问题:Python decode_base64_and_inflate函数的具体用法?Python decode_base64_and_inflate怎么用?Python decode_base64_and_inflate使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了decode_base64_and_inflate函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: unravel
def unravel(txt, binding, msgtype="response"):
"""
Will unpack the received text. Depending on the context the original
response may have been transformed before transmission.
:param txt:
:param binding:
:param msgtype:
:return:
"""
#logger.debug("unravel '%s'" % txt)
if binding not in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST,
BINDING_SOAP, BINDING_URI, BINDING_HTTP_ARTIFACT,
None]:
raise ValueError("Don't know how to handle '%s'" % binding)
else:
try:
if binding == BINDING_HTTP_REDIRECT:
xmlstr = decode_base64_and_inflate(txt)
elif binding == BINDING_HTTP_POST:
xmlstr = base64.b64decode(txt)
elif binding == BINDING_SOAP:
func = getattr(soap,
"parse_soap_enveloped_saml_%s" % msgtype)
xmlstr = func(txt)
elif binding == BINDING_HTTP_ARTIFACT:
xmlstr = base64.b64decode(txt)
else:
xmlstr = txt
except Exception:
raise UnravelError()
return xmlstr
示例2: test_logout
def test_logout(self):
settings.SAML_CONFIG = conf.create_conf(
sp_host='sp.example.com',
idp_hosts=['idp.example.com'],
metadata_file='remote_metadata_one_idp.xml',
)
self.do_login()
response = self.client.get('/logout/')
self.assertEquals(response.status_code, 302)
location = response['Location']
url = urlparse.urlparse(location)
self.assertEquals(url.hostname, 'idp.example.com')
self.assertEquals(url.path,
'/simplesaml/saml2/idp/SingleLogoutService.php')
params = urlparse.parse_qs(url.query)
self.assert_('SAMLRequest' in params)
saml_request = params['SAMLRequest'][0]
expected_request26 = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">58bcc81ea14700f66aeb707a0eff1360</saml:NameID></samlp:LogoutRequest>"""
expected_request27 = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID></samlp:LogoutRequest>"""
self.assertSAMLRequestsEquals(decode_base64_and_inflate(saml_request),
{'2.6': expected_request26,
'2.7': expected_request27})
示例3: test_login_several_idps
def test_login_several_idps(self):
settings.SAML_CONFIG = conf.create_conf(sp_host='sp.example.com',
idp_hosts=['idp1.example.com',
'idp2.example.com',
'idp3.example.com'])
response = self.client.get('/login/')
# a WAYF page should be displayed
self.assertContains(response, 'Where are you from?', status_code=200)
for i in range(1, 4):
link = '/login/?idp=https://idp%d.example.com/simplesaml/saml2/idp/metadata.php&next=/'
self.assertContains(response, link % i)
# click on the second idp
response = self.client.get('/login/', {
'idp': 'https://idp2.example.com/simplesaml/saml2/idp/metadata.php',
'next': '/',
})
self.assertEquals(response.status_code, 302)
location = response['Location']
url = urlparse.urlparse(location)
self.assertEquals(url.hostname, 'idp2.example.com')
self.assertEquals(url.path, '/simplesaml/saml2/idp/SSOService.php')
params = urlparse.parse_qs(url.query)
self.assert_('SAMLRequest' in params)
self.assert_('RelayState' in params)
saml_request = params['SAMLRequest'][0]
expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:AuthnRequest AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp2.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" ProviderName="Test SP" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" /></samlp:AuthnRequest>"""
xml = decode_base64_and_inflate(saml_request)
self.assertSAMLRequestsEquals(expected_request, xml)
示例4: test_logout_service_global
def test_logout_service_global(self):
settings.SAML_CONFIG = conf.create_conf(sp_host='sp.example.com',
idp_hosts=['idp.example.com'])
self.do_login()
# now simulate a global logout process initiated by another SP
subject_id = views._get_subject_id(self.client.session)
instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
saml_request = '<samlp:LogoutRequest ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>' % (
instant, subject_id)
response = self.client.get('/ls/', {
'SAMLRequest': deflate_and_base64_encode(saml_request),
})
self.assertEquals(response.status_code, 302)
location = response['Location']
url = urlparse.urlparse(location)
self.assertEquals(url.hostname, 'idp.example.com')
self.assertEquals(url.path,
'/simplesaml/saml2/idp/SingleLogoutService.php')
params = urlparse.parse_qs(url.query)
self.assert_('SAMLResponse' in params)
saml_response = params['SAMLResponse'][0]
expected_response = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutResponse Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="_9961abbaae6d06d251226cb25e38bf8f468036e57e" IssueInstant="2010-09-05T09:10:12Z" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>"""
xml = decode_base64_and_inflate(saml_response)
self.assertSAMLRequestsEquals(expected_response, xml)
示例5: test_inflate_then_deflate
def test_inflate_then_deflate():
txt = """Selma Lagerlöf (1858-1940) was born in Östra Emterwik, Värmland,
Sweden. She was brought up on Mårbacka, the family estate, which she did
not leave until 1881, when she went to a teachers' college at Stockholm"""
interm = utils.deflate_and_base64_encode(txt)
bis = utils.decode_base64_and_inflate(interm)
assert bis == txt
示例6: test_Saml_authenticate
def test_Saml_authenticate(self):
# modifying config in this test, make copy so as not to effect
# following tests.
tmp_sp_config = copy.deepcopy(sp_config)
# test signed authentication request
with self.app.test_request_context('/',
method='GET'):
sp = auth.Saml(tmp_sp_config)
resp = sp.authenticate(next_url='/next')
self.assertEqual(resp.status_code, 302)
self.assert_('SAMLRequest' in resp.headers['Location'])
url = urlparse.urlparse(resp.headers['Location'])
self.assertEqual(url.hostname, 'sso.example.com')
self.assertEqual(url.path, '/idp/sso')
params = urlparse.parse_qs(url.query)
self.assert_('SAMLRequest' in params)
self.assertEqual(params['RelayState'], ['/next'])
authn = samlp.authn_request_from_string(
decode_base64_and_inflate(params['SAMLRequest'][0]))
self.assertEqual(authn.destination,
'https://sso.example.com/idp/sso')
self.assertEqual(authn.assertion_consumer_service_url,
'https://foo.example.com/sp/acs')
self.assertEqual(authn.protocol_binding, BINDING_HTTP_POST)
self.assertIsNotNone(authn.signature)
self.assertEqual(session['_saml_outstanding_queries'],
{authn.id: '/next'})
# test un-signed authentication request
with self.app.test_request_context('/',
method='GET'):
tmp_sp_config['key_file'] = None
tmp_sp_config['service']['sp']['authn_requests_signed'] = None
sp = auth.Saml(tmp_sp_config)
resp = sp.authenticate(next_url='/next')
self.assertEqual(resp.status_code, 302)
self.assert_('SAMLRequest' in resp.headers['Location'])
url = urlparse.urlparse(resp.headers['Location'])
params = urlparse.parse_qs(url.query)
authn = samlp.authn_request_from_string(
decode_base64_and_inflate(params['SAMLRequest'][0]))
self.assertIsNone(authn.signature)
示例7: logout_response
def logout_response(self, xmlstr, log=None, binding=BINDING_SOAP):
""" Deal with a LogoutResponse
:param xmlstr: The response as a xml string
:param log: logging function
:param binding: What type of binding this message came through.
:return: None if the reply doesn't contain a valid SAML LogoutResponse,
otherwise the reponse if the logout was successful and None if it
was not.
"""
response = None
if log is None:
log = self.logger
if xmlstr:
try:
# expected return address
return_addr = self.config.endpoint("single_logout_service",
binding=binding)[0]
except Exception:
if log:
log.info("Not supposed to handle this!")
return None
try:
response = LogoutResponse(self.sec, return_addr, debug=self.debug,
log=log)
except Exception, exc:
if log:
log.info("%s" % exc)
return None
if binding == BINDING_HTTP_REDIRECT:
xmlstr = decode_base64_and_inflate(xmlstr)
elif binding == BINDING_HTTP_POST:
xmlstr = base64.b64decode(xmlstr)
if log:
log.debug("XMLSTR: %s" % xmlstr)
response = response.loads(xmlstr, False)
if response:
response = response.verify()
if not response:
return None
if log:
log.debug(response)
return self.handle_logout_response(response, log)
示例8: test_authenticate
def test_authenticate(self):
print self.client.config.idps()
id, response = self.client.do_authenticate(
"urn:mace:example.com:saml:roland:idp",
"http://www.example.com/relay_state")
assert response[0] == "Location"
o = urlparse(response[1])
qdict = parse_qs(o.query)
assert _leq(qdict.keys(), ['SAMLRequest', 'RelayState'])
saml_request = decode_base64_and_inflate(qdict["SAMLRequest"][0])
print saml_request
authnreq = samlp.authn_request_from_string(saml_request)
示例9: do
def do(self, message, binding, relay_state="", mtype="response"):
try:
txt = decode_base64_and_inflate(message)
is_logout_request = 'LogoutRequest' in txt.split('>', 1)[0]
except: # TODO: parse the XML correctly
is_logout_request = False
if is_logout_request:
self.sp.parse_logout_request(message, binding)
else:
self.sp.parse_logout_request_response(message, binding)
return finish_logout(self.environ, self.start_response)
示例10: http_redirect_logout_request
def http_redirect_logout_request(self, get, subject_id, log=None):
""" Deal with a LogoutRequest received through HTTP redirect
:param get: The request as a dictionary
:param subject_id: the id of the current logged user
:return: a tuple with a list of header tuples (presently only location)
and a status which will be True in case of success or False
otherwise.
"""
headers = []
success = False
if log is None:
log = self.logger
try:
saml_request = get['SAMLRequest']
except KeyError:
return None
if saml_request:
xml = decode_base64_and_inflate(saml_request)
request = samlp.logout_request_from_string(xml)
if log:
log.debug(request)
if request.name_id.text == subject_id:
status = samlp.STATUS_SUCCESS
success = self.local_logout(subject_id)
else:
status = samlp.STATUS_REQUEST_DENIED
response, destination = self .make_logout_response(
request.issuer.text,
request.id,
status)
if log:
log.info("RESPONSE: {0:>s}".format(response))
if 'RelayState' in get:
rstate = get['RelayState']
else:
rstate = ""
(headers, _body) = http_redirect_message(str(response),
destination,
rstate, 'SAMLResponse')
return headers, success
示例11: test_login_one_idp
def test_login_one_idp(self):
# monkey patch SAML configuration
settings.SAML_CONFIG = conf.create_conf(
sp_host='sp.example.com',
idp_hosts=['idp.example.com'],
metadata_file='remote_metadata_one_idp.xml',
)
response = self.client.get(reverse('saml2_login'))
self.assertEquals(response.status_code, 302)
location = response['Location']
url = urlparse(location)
self.assertEquals(url.hostname, 'idp.example.com')
self.assertEquals(url.path, '/simplesaml/saml2/idp/SSOService.php')
params = parse_qs(url.query)
self.assert_('SAMLRequest' in params)
self.assert_('RelayState' in params)
saml_request = params['SAMLRequest'][0]
if PY_VERSION < (2, 7):
expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:AuthnRequest AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
elif PY_VERSION < (3,):
expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
else:
expected_request = """<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
self.assertSAMLRequestsEquals(
decode_base64_and_inflate(saml_request).decode('utf-8'),
expected_request)
# if we set a next arg in the login view, it is preserverd
# in the RelayState argument
next = '/another-view/'
response = self.client.get(reverse('saml2_login'), {'next': next})
self.assertEquals(response.status_code, 302)
location = response['Location']
url = urlparse(location)
self.assertEquals(url.hostname, 'idp.example.com')
self.assertEquals(url.path, '/simplesaml/saml2/idp/SSOService.php')
params = parse_qs(url.query)
self.assert_('SAMLRequest' in params)
self.assert_('RelayState' in params)
self.assertEquals(params['RelayState'][0], next)
示例12: test_Saml_handle_logout_request
def test_Saml_handle_logout_request(self):
not_on_or_after = time.time()+3600
identity = {'id-1': {
'https://sso.example.com/idp/metadata': (
not_on_or_after, {
'authn_info': [],
'name_id': 'id-1',
'not_on_or_after': not_on_or_after,
'came_from': '/next',
'ava': {'uid': ['123456']}
}
)
}}
state = {
'entity_ids': ['https://sso.example.com/idp/metadata'],
'subject_id': 'id-1',
'return_to': '/next'
}
# modifying config in this test, make copy so as not to effect
# following tests.
tmp_sp_config = copy.deepcopy(sp_config)
# create a response to assert upon
sp = auth.Saml(tmp_sp_config)
logout_request = create_logout_request('id-1',
destination='https://foo.example.com/sp/slo',
issuer_entity_id='https://sso.example.com/idp/metadata',
req_entity_id='https://sso.example.com/idp/metadata')
# test SAMLRequest logout
with self.app.test_request_context('/',
method='GET',
query_string=dict(
SAMLRequest=deflate_and_base64_encode(str(logout_request)),
RelayState=deflate_and_base64_encode(logout_request.id))):
# first need to be logged in, let's pretend
session['_saml_identity'] = identity
session['_saml_subject_id'] = 'id-1'
session['_saml_state'] = {logout_request.id: state}
success, resp = sp.handle_logout(request, next_url='/next')
self.assertTrue(success)
self.assertEqual(resp.status_code, 302)
self.assert_("SAMLResponse" in resp.headers['Location'])
url = urlparse.urlparse(resp.headers['Location'])
params = urlparse.parse_qs(url.query)
self.assert_('SAMLResponse' in params)
logout = samlp.logout_response_from_string(
decode_base64_and_inflate(params['SAMLResponse'][0]))
self.assertEqual(logout.status.status_code.value,
'urn:oasis:names:tc:SAML:2.0:status:Success')
self.assertEqual(logout.destination, 'https://sso.example.com/idp/slo')
示例13: unravel
def unravel(self, txt, binding, msgtype="response"):
#logger.debug("unravel '%s'" % txt)
if binding == BINDING_HTTP_REDIRECT:
xmlstr = decode_base64_and_inflate(txt)
elif binding == BINDING_HTTP_POST:
xmlstr = base64.b64decode(txt)
elif binding == BINDING_SOAP:
func = getattr(soap, "parse_soap_enveloped_saml_%s" % msgtype)
xmlstr = func(txt)
elif binding == BINDING_URI or binding is None:
xmlstr = txt
else:
raise ValueError("Don't know how to handle '%s'" % binding)
return xmlstr
示例14: _loads
def _loads(self, xmldata, decode=True):
if decode:
logger.debug("Expected to decode and inflate xml data")
decoded_xml = s_utils.decode_base64_and_inflate(xmldata)
else:
decoded_xml = xmldata
# own copy
self.xmlstr = decoded_xml[:]
logger.info("xmlstr: %s" % (self.xmlstr,))
try:
self.message = self.signature_check(decoded_xml)
except TypeError:
raise
except Exception, excp:
logger.info("EXCEPTION: %s", excp)
示例15: test_logout_service_local
def test_logout_service_local(self):
settings.SAML_CONFIG = conf.create_conf(
sp_host='sp.example.com',
idp_hosts=['idp.example.com'],
metadata_file='remote_metadata_one_idp.xml',
)
self.do_login()
response = self.client.get(reverse('saml2_logout'))
self.assertEquals(response.status_code, 302)
location = response['Location']
url = urlparse(location)
self.assertEquals(url.hostname, 'idp.example.com')
self.assertEquals(url.path,
'/simplesaml/saml2/idp/SingleLogoutService.php')
params = parse_qs(url.query)
self.assert_('SAMLRequest' in params)
saml_request = params['SAMLRequest'][0]
if PY_VERSION < (2, 7):
expected_request = """<?xml version='1.0' encoing='UTF-8'?>
<samlp:LogoutRequest Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">58bcc81ea14700f66aeb707a0eff1360</saml:NameID></samlp:LogoutRequest>"""
elif PY_VERSION < (3,):
expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
else:
expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
self.assertSAMLRequestsEquals(decode_base64_and_inflate(saml_request).decode('utf-8'),
expected_request)
# now simulate a logout response sent by the idp
request_id = re.findall(r' ID="(.*?)" ', xml)[0]
instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
saml_response = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://sp.example.com/saml2/ls/" ID="a140848e7ce2bce834d7264ecdde0151" InResponseTo="%s" IssueInstant="%s" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status></samlp:LogoutResponse>""" % (
request_id, instant)
response = self.client.get(reverse('saml2_ls'), {
'SAMLResponse': deflate_and_base64_encode(saml_response),
})
self.assertContains(response, "Logged out", status_code=200)
self.assertEquals(self.client.session.keys(), [])