added new tests category between "pre" and "post: "mid". added new test cases

This commit is contained in:
rhoerbe
2014-08-11 14:52:14 +02:00
parent b16009dc69
commit 95ffb58b5b
4 changed files with 162 additions and 57 deletions

View File

@@ -213,6 +213,28 @@ class CheckSpHttpResponseOK(Error):
return res return res
class CheckSpHttpResponse500(Error):
""" Checks that the SP's HTTP response status is >= 500. This is useful
to check if the SP correctly flags errors such as an invalid signature
"""
cid = "check-sp-http-response-500"
msg = "SP does not return a HTTP 5xx status when it shold do so."
def _func(self, conv):
_response = conv.last_response
_content = conv.last_response.content
res = {}
if _response.status_code < 500:
self._status = self.status
self._message = self.msg
#res["content"] = _content #too big + charset converstion needed
res["url"] = conv.position
res["http_status"] = _response.status_code
return res
class MissingRedirect(CriticalError): class MissingRedirect(CriticalError):
""" At this point in the flow a redirect back to the client was expected. """ At this point in the flow a redirect back to the client was expected.
""" """

View File

@@ -282,13 +282,6 @@ class Conversation():
:param resp_flow: The flow to prepare the response :param resp_flow: The flow to prepare the response
:return: The SP's HTTP response on receiving the SAML response :return: The SP's HTTP response on receiving the SAML response
""" """
# make sure I got the request I expected
assert isinstance(self.saml_request.message, req._class)
try:
self.test_sequence(req.tests["post"])
except KeyError:
pass
# Pick information from the request that should be in the response # Pick information from the request that should be in the response
args = self.instance.response_args(self.saml_request.message, args = self.instance.response_args(self.saml_request.message,
@@ -381,7 +374,7 @@ class Conversation():
self._log_response(self.last_response) self._log_response(self.last_response)
def do_flow(self, flow): def do_flow(self, flow, mid_tests):
""" """
Solicited or 'un-solicited' flows. Solicited or 'un-solicited' flows.
@@ -392,6 +385,12 @@ class Conversation():
self.wb_send_GET_startpage() self.wb_send_GET_startpage()
self.intermit(flow[0]._interaction) self.intermit(flow[0]._interaction)
self.parse_saml_message() self.parse_saml_message()
# make sure I got the request I expected
assert isinstance(self.saml_request.message, flow[1]._class)
try:
self.test_sequence(mid_tests)
except KeyError:
pass
self.send_idp_response(flow[1], flow[2]) self.send_idp_response(flow[1], flow[2])
if len(flow) == 4: if len(flow) == 4:
self.handle_result(flow[3]) self.handle_result(flow[3])
@@ -399,6 +398,7 @@ class Conversation():
self.handle_result() self.handle_result()
def do_sequence_and_tests(self, oper, tests=None): def do_sequence_and_tests(self, oper, tests=None):
self.current_oper = oper
try: try:
self.test_sequence(tests["pre"]) self.test_sequence(tests["pre"])
except KeyError: except KeyError:
@@ -406,7 +406,7 @@ class Conversation():
for flow in oper: for flow in oper:
try: try:
self.do_flow(flow) self.do_flow(flow, tests["mid"])
except InteractionNeeded: except InteractionNeeded:
self.test_output.append({"status": INTERACTION, self.test_output.append({"status": INTERACTION,
"message": "see detail log for response content", "message": "see detail log for response content",

View File

@@ -3,7 +3,7 @@ import logging
import re import re
import sys import sys
from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT
from saml2test.check import Check from saml2test.check import Check
from saml2test.check import ERROR, INFORMATION, WARNING from saml2test.check import ERROR, INFORMATION, WARNING
from saml2test import check from saml2test import check
@@ -86,6 +86,15 @@ class VerifyDigestAlgorithm(Check):
if request.signature: if request.signature:
if not self._digest_algo(request.signature, _algs): if not self._digest_algo(request.signature, _algs):
return {} return {}
elif conv._binding == BINDING_HTTP_REDIRECT:
self._message = "no digest with redirect binding"
self._status = INFORMATION
return {}
elif conv._binding == BINDING_HTTP_POST:
self._message = "cannot verify digest algorithm: request not signed"
self._status = WARNING
return {}
return {} return {}
@@ -204,6 +213,29 @@ class VerifyEchopageContents(Check):
return False return False
class SetResponseAndAssertionSignaturesFalse(Check):
""" Prepare config to suppress signatures of both response and assertion"""
cid = "set-response-and-assertion-signature-false"
msg = "Prepare config to suppress signatures of both response and assertion"
def _func(self, conv):
conv.json_config['args']['AuthnResponse']['sign_assertion'] = 'never'
conv.json_config['args']['AuthnResponse']['sign_response'] = 'never'
self._status = INFORMATION
return {}
#class SetInvalidIdpKey(Check):
# """ Prepare config to set IDP signing key to some useless key"""
# cid = "set-idp-key-invalid"
# msg = "Prepare config to set IDP signing key invalid"
#
# def _func(self, conv):
# conv.instance.sec.cert_file = conv.instance.config.invalid_idp_cert_file
# conv.instance.sec.key_file = conv.instance.config.invalid_idp_key_file
# return {}
# ============================================================================= # =============================================================================

View File

@@ -11,9 +11,11 @@ from saml2.saml import SCM_SENDER_VOUCHES
from saml2.saml import ConditionAbstractType_ from saml2.saml import ConditionAbstractType_
from saml2.samlp import STATUS_AUTHN_FAILED from saml2.samlp import STATUS_AUTHN_FAILED
from saml2.time_util import in_a_while, a_while_ago from saml2.time_util import in_a_while, a_while_ago
from sp_test.check import VerifyAuthnRequest, VerifyDigestAlgorithm, \
VerifySignatureAlgorithm, VerifyIfRequestIsSigned
from sp_test import check from sp_test import check
from sp_test.check import VerifyAuthnRequest, VerifyDigestAlgorithm
from sp_test.check import VerifySignatureAlgorithm, VerifyIfRequestIsSigned
from sp_test.check import SetResponseAndAssertionSignaturesFalse
from saml2test.check import CheckSpHttpResponseOK, CheckSpHttpResponse500
from saml2test import ip_addresses from saml2test import ip_addresses
__author__ = 'rolandh' __author__ = 'rolandh'
@@ -83,9 +85,8 @@ class Request(object):
response = "" response = ""
_class = None _class = None
tests = {"pre": [], tests = {"pre": [],
"post": [VerifyAuthnRequest, "mid": [VerifyAuthnRequest],
VerifyDigestAlgorithm, "post": []}
VerifySignatureAlgorithm,]}
def __init__(self): def __init__(self):
pass pass
@@ -171,13 +172,19 @@ class AuthnResponse_without_SubjectConfirmationData_2(AuthnResponse):
class AuthnResponse_rnd_Response_inresponseto(AuthnResponse): class AuthnResponse_rnd_Response_inresponseto(AuthnResponse):
def pre_processing(self, message, **kwargs): def pre_processing(self, message, **kwargs):
message.in_response_to = rndstr(16) message.in_response_to = "invalid_rand_" + rndstr(6)
return message return message
class AuthnResponse_rnd_Response_assertion_inresponseto(AuthnResponse): class AuthnResponse_rnd_Response_assertion_inresponseto(AuthnResponse):
def pre_processing(self, message, **kwargs): def pre_processing(self, message, **kwargs):
message.assertion.in_response_to = rndstr(16) message.assertion.in_response_to = "invalid_rand_" + rndstr(6)
return message
class AuthnResponse_Response_no_inresponse(AuthnResponse):
def pre_processing(self, message, **kwargs):
message.in_response_to = None
return message return message
@@ -367,25 +374,60 @@ PHASES = {
"login_redirect": (Login, AuthnRequest, AuthnResponse_redirect), "login_redirect": (Login, AuthnRequest, AuthnResponse_redirect),
} }
# Each operation defines 4 flows and 3 sets of tests, in chronological order:
# test "pre": executes before anything is sent to the SP
# flow 0: Start conversation flow
# flow 1: SAML request flow
# test "mid": executes after receiving the SAML request
# flow 2: SAML response flow
# flow 3: check SP response after authentication
# test "post": executes after finals response has been received from SP
OPERATIONS = { OPERATIONS = {
'sp-00': { 'sp-00': {
"name": 'Basic Login test', "name": 'Basic Login test expect HTTP 200 result',
"descr": 'GET startpage from SP, verify authentication request, verify ' "descr": 'WebSSO verify authentication request, verify '
'HTTP-Response after sending the SAML response', 'HTTP-Response after sending the SAML response',
"sequence": [(Login, AuthnRequest, AuthnResponse, None)], "sequence": [(Login, AuthnRequest, AuthnResponse, CheckSpHttpResponseOK)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'sp-01': { 'sp-01': {
"name": 'Login & echo page verification test', "name": 'Login OK & echo page verification test',
"descr": 'Same as SP-00, then check if result page is displayed', "descr": 'Same as SP-00, then check if result page is displayed',
"sequence": [(Login, AuthnRequest, AuthnResponse, check.VerifyEchopageContents)], "sequence": [(Login, AuthnRequest, AuthnResponse, check.VerifyEchopageContents)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'sp-02': { 'sp-02': {
"name": 'Require AuthnRequest to be signed', "name": 'Require AuthnRequest to be signed',
"descr": 'Same as SP-00, and check if a request signature can be found', "descr": 'Same as SP-00, and check if a request signature can be found',
"sequence": [(Login, AuthnRequest, AuthnResponse, None)], "sequence": [(Login, AuthnRequest, AuthnResponse, None)],
"tests": {"pre": [], "post": [VerifyIfRequestIsSigned]} "tests": {"pre": [], "mid": [VerifyIfRequestIsSigned], "post": []}
},
'sp-03': {
"name": 'Reject unsigned reponse/assertion',
"descr": 'Check if SP flags missing signature with HTTP 500',
"sequence": [(Login, AuthnRequest, AuthnResponse, CheckSpHttpResponse500)],
"tests": {"pre": [SetResponseAndAssertionSignaturesFalse], "mid": [], "post": []}
},
'sp-04': { # test-case specific code in sp_test/__init__
"name": 'Reject siganture with invalid IDP key',
"descr": 'IDP-key for otherwise valid signature not in metadata - expect HTTP 500 result',
"sequence": [(Login, AuthnRequest, AuthnResponse, CheckSpHttpResponse500)],
"tests": {"pre": [], "mid": [], "post": []}
},
'sp-05': {
"name": 'Verify digest algorithm',
"descr": 'Trigger WebSSO AuthnRequest and verify that the used '
'digest algorithm was one from the approved set.',
"sequence": [(Login, AuthnRequest, AuthnResponse, None)],
"tests": {"pre": [], "mid": [VerifyDigestAlgorithm], "post": []}
},
'sp-06': {
"name": 'Verify signature algorithm',
"descr": 'Trigger WebSSO AuthnRequest and verify that the used '
'signature algorithm was one from the approved set.',
"sequence": [(Login, AuthnRequest, AuthnResponse, None)],
"tests": {"pre": [], "mid": [VerifySignatureAlgorithm], "post": []}
}, },
'sp-08': { 'sp-08': {
"name": "SP should accept a Response without a " "name": "SP should accept a Response without a "
@@ -394,37 +436,37 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_without_SubjectConfirmationData_2, AuthnResponse_without_SubjectConfirmationData_2,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL02': { 'FL02': {
"name": 'Verify various aspects of the generated AuthnRequest message', "name": 'Verify various aspects of the generated AuthnRequest message',
"descr": 'Basic Login test', "descr": 'Basic Login test',
"sequence": [], "sequence": [],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL03': { 'FL03': {
"name": "SP should not accept a Response as valid, when the StatusCode" "name": "SP should not accept a Response as valid, when the StatusCode"
" is not success", " is not success",
"sequence": [(Login, AuthnRequest, ErrorResponse, check.ErrorResponse)], "sequence": [(Login, AuthnRequest, ErrorResponse, check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL04': { 'FL04': {
"name": "SP should accept a NameID with Format: persistent", "name": "SP should accept a NameID with Format: persistent",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_NameIDformat_persistent, None)], AuthnResponse_NameIDformat_persistent, None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL05': { 'FL05': {
"name": "SP should accept a NameID with Format: e-mail", "name": "SP should accept a NameID with Format: e-mail",
"sequence": [(Login, AuthnRequest, AuthnResponse_NameIDformat_email, "sequence": [(Login, AuthnRequest, AuthnResponse_NameIDformat_email,
None)], None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL06': { 'FL06': {
"name": "Do SP work with unknown NameID Format, such as : foo", "name": "Do SP work with unknown NameID Format, such as : foo",
"sequence": [(Login, AuthnRequest, AuthnResponse_NameIDformat_foo, "sequence": [(Login, AuthnRequest, AuthnResponse_NameIDformat_foo,
None)], None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL07': { 'FL07': {
"name": "SP should accept a Response without a " "name": "SP should accept a Response without a "
@@ -432,7 +474,7 @@ OPERATIONS = {
"is SCM_SENDER_VOUCHES", "is SCM_SENDER_VOUCHES",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_without_SubjectConfirmationData_1, None)], AuthnResponse_without_SubjectConfirmationData_1, None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL09': { 'FL09': {
"name": "SP should not accept a response InResponseTo " "name": "SP should not accept a response InResponseTo "
@@ -440,7 +482,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_rnd_Response_inresponseto, AuthnResponse_rnd_Response_inresponseto,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL10': { 'FL10': {
"name": "SP should not accept an assertion InResponseTo " "name": "SP should not accept an assertion InResponseTo "
@@ -448,22 +490,31 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_rnd_Response_assertion_inresponseto, AuthnResponse_rnd_Response_assertion_inresponseto,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
},
'FL11': {
"name": "Does the SP allow the InResponseTo attribute to be missing"
"from the Response element?",
"sequence": [(Login, AuthnRequest,
AuthnResponse_Response_no_inresponse,
check.ErrorResponse)],
"tests": {"pre": [], "mid": [], "post": []}
}, },
'FL12': { 'FL12': {
"name": "Do the SP allow the InResponseTo attribute to be missing" "name": "Does the SP allow the InResponseTo attribute to be missing"
"from the SubjectConfirmationData element?", "from the SubjectConfirmationData element?"
"(Test is questionable - review)", # TODO
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_SubjectConfirmationData_no_inresponse, AuthnResponse_SubjectConfirmationData_no_inresponse,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL13': { 'FL13': {
"name": "SP should not accept a broken DestinationURL attribute", "name": "SP should not accept a broken DestinationURL attribute",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_broken_destination, AuthnResponse_broken_destination,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
# New untested # New untested
'FL14a': { 'FL14a': {
@@ -471,14 +522,14 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_broken_destination, AuthnResponse_broken_destination,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL14b': { 'FL14b': {
"name": "SP should not accept missing Recipient attribute", "name": "SP should not accept missing Recipient attribute",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_missing_Recipient, AuthnResponse_missing_Recipient,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL20': { 'FL20': {
"name": "Accept a Response with a SubjectConfirmationData elements " "name": "Accept a Response with a SubjectConfirmationData elements "
@@ -486,7 +537,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_correct_recipient_address, AuthnResponse_correct_recipient_address,
None)], None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL21': { 'FL21': {
"name": "Accept a Response with a SubjectConfirmationData elements " "name": "Accept a Response with a SubjectConfirmationData elements "
@@ -494,7 +545,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_incorrect_recipient_address, AuthnResponse_incorrect_recipient_address,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL22': { 'FL22': {
"name": "Accept a Response with two SubjectConfirmationData elements" "name": "Accept a Response with two SubjectConfirmationData elements"
@@ -502,7 +553,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_2_recipients_me_last, AuthnResponse_2_recipients_me_last,
None)], None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL23': { 'FL23': {
"name": "Accept a Response with two SubjectConfirmationData elements" "name": "Accept a Response with two SubjectConfirmationData elements"
@@ -510,14 +561,14 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_2_recipients_me_first, AuthnResponse_2_recipients_me_first,
None)], None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL26': { 'FL26': {
"name": "Reject an assertion containing an unknown Condition.", "name": "Reject an assertion containing an unknown Condition.",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_unknown_condition, AuthnResponse_unknown_condition,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL27': { 'FL27': {
"name": "Reject a Response with a Condition with a NotBefore in the " "name": "Reject a Response with a Condition with a NotBefore in the "
@@ -525,7 +576,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_future_NotBefore, AuthnResponse_future_NotBefore,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL28': { 'FL28': {
"name": "Reject a Response with a Condition with a NotOnOrAfter in " "name": "Reject a Response with a Condition with a NotOnOrAfter in "
@@ -533,7 +584,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_future_NotBefore, AuthnResponse_future_NotBefore,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL29': { 'FL29': {
"name": "Reject a Response with a SubjectConfirmationData@NotOnOrAfter " "name": "Reject a Response with a SubjectConfirmationData@NotOnOrAfter "
@@ -541,7 +592,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_past_SubjectConfirmationData_NotOnOrAfter, AuthnResponse_past_SubjectConfirmationData_NotOnOrAfter,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL24': { 'FL24': {
"name": "Reject a Response with a SubjectConfirmationData@NotBefore " "name": "Reject a Response with a SubjectConfirmationData@NotBefore "
@@ -549,7 +600,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_future_SubjectConfirmationData_NotBefore, AuthnResponse_future_SubjectConfirmationData_NotBefore,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL30': { 'FL30': {
"name": "Reject a Response with an AuthnStatement where " "name": "Reject a Response with an AuthnStatement where "
@@ -557,28 +608,28 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_past_AuthnStatement_SessionNotOnOrAfter, AuthnResponse_past_AuthnStatement_SessionNotOnOrAfter,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL31': { 'FL31': {
"name": "Reject a Response with an AuthnStatement missing", "name": "Reject a Response with an AuthnStatement missing",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_missing_AuthnStatement, AuthnResponse_missing_AuthnStatement,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL32': { 'FL32': {
"name": "Reject an IssueInstant far (24 hours) into the future", "name": "Reject an IssueInstant far (24 hours) into the future",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_missing_AuthnStatement, AuthnResponse_missing_AuthnStatement,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL33': { 'FL33': {
"name": "Reject an IssueInstant far (24 hours) into the past", "name": "Reject an IssueInstant far (24 hours) into the past",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_missing_AuthnStatement, AuthnResponse_missing_AuthnStatement,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL34': { 'FL34': {
"name": "Accept xs:datetime with millisecond precision " "name": "Accept xs:datetime with millisecond precision "
@@ -586,7 +637,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_datetime_millisecond, AuthnResponse_datetime_millisecond,
None)], None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL36': { 'FL36': {
"name": "Reject a Response with a Condition with a empty set of " "name": "Reject a Response with a Condition with a empty set of "
@@ -594,14 +645,14 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_AudienceRestriction_no_audience, AuthnResponse_AudienceRestriction_no_audience,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL37': { 'FL37': {
"name": "Reject a Response with a Condition with a wrong Audience.", "name": "Reject a Response with a Condition with a wrong Audience.",
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_AudienceRestriction_wrong_audience, AuthnResponse_AudienceRestriction_wrong_audience,
check.ErrorResponse)], check.ErrorResponse)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL38': { 'FL38': {
"name": "Accept a Response with a Condition with an additional " "name": "Accept a Response with a Condition with an additional "
@@ -609,7 +660,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_AudienceRestriction_prepended_audience, AuthnResponse_AudienceRestriction_prepended_audience,
None)], None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
'FL39': { 'FL39': {
"name": "Accept a Response with a Condition with an additional " "name": "Accept a Response with a Condition with an additional "
@@ -617,7 +668,7 @@ OPERATIONS = {
"sequence": [(Login, AuthnRequest, "sequence": [(Login, AuthnRequest,
AuthnResponse_AudienceRestriction_appended_audience, AuthnResponse_AudienceRestriction_appended_audience,
None)], None)],
"tests": {"pre": [], "post": []} "tests": {"pre": [], "mid": [], "post": []}
}, },
} }