Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
assert a._get_saml_doc_etree(fake_data) is None
@patch('samlauthenticator.samlauthenticator.b64decode')
def test_not_valid_xml(self, mock_b64decode):
a = SAMLAuthenticator()
fake_data = {a.login_post_field: 'this string isn\'t important'}
mock_b64decode.return_value = 'bad xml string'
assert a._get_saml_doc_etree(fake_data) is None
class TestValidSamlResponse(unittest.TestCase):
response_etree = etree.fromstring(test_constants.sample_response_xml)
metadata_etree = etree.fromstring(test_constants.sample_metadata_xml)
verified_signed_xml = XMLVerifier().verify(response_etree, x509_cert=test_constants.x509_cert).signed_xml
@patch('samlauthenticator.samlauthenticator.datetime')
def test_valid_saml_auth(self, mock_datetime):
mock_datetime.now.return_value = datetime(2019, 4, 9, 21, 35, 0, tzinfo=timezone.utc)
mock_datetime.strptime = datetime.strptime
a = SAMLAuthenticator()
signed_xml = a._verify_saml_signature(self.metadata_etree, self.response_etree)
assert etree.tostring(signed_xml) == etree.tostring(self.verified_signed_xml)
response_is_valid, signed_xml = a._test_valid_saml_response(self.metadata_etree, self.response_etree)
assert response_is_valid
# Check the signed xml is the subset of the xml that is returned by signxml
# Export the SignedObject as an XML string.
buff = StringIO.StringIO()
signed_object.export(buff, 1, pretty_print=True)
signed_object_xml = buff.getvalue()
except Exception, err:
raise OpenADRInterfaceException('Error exporting the SignedObject: {}'.format(err), None)
if self.security_level == 'high':
try:
signature_lxml, signed_object_lxml = self.calculate_signature(signed_object_xml)
except Exception, err:
raise OpenADRInterfaceException('Error signing the SignedObject: {}'.format(err), None)
payload_lxml = self.payload_element(signature_lxml, signed_object_lxml)
try:
# Verify that the payload, with signature, is well-formed and can be validated.
signxml.XMLVerifier().verify(payload_lxml, ca_pem_file=VTN_CA_CERT_FILENAME)
except Exception, err:
raise OpenADRInterfaceException('Error verifying the SignedObject: {}'.format(err), None)
else:
signed_object_lxml = etree_.fromstring(signed_object_xml)
payload_lxml = self.payload_element(None, signed_object_lxml)
if self.log_xml:
_log.debug('VEN PAYLOAD:')
_log.debug('\n{}'.format(etree_.tostring(payload_lxml, pretty_print=True)))
# Post payload XML to the VTN as an HTTP request. Return the VTN's response, if any.
endpoint = self.vtn_address + (self.oadr_current_service or POLL)
try:
payload_xml = etree_.tostring(payload_lxml)
# OADR rule 53: If simple HTTP mode is used, send the following headers: Host, Content-Length, Content-Type.
# The EPRI VTN server responds with a 400 "bad request" if a "Host" header is sent.
def parse_signed(self, xml_tree: XmlNode, certificate: X509) -> XmlNode:
"""
Replaces all parameters with only the signed parameters. You should
provide an x509 certificate obtained out-of-band, usually via the
SAML metadata. Otherwise the signed data will be verified with only
the certificate provided in the request. This is INSECURE and
more-or-less only useful for testing.
"""
return XMLVerifier().verify(xml_tree, x509_cert=certificate).signed_xml
def _verify_saml_signature(self, saml_metadata, decoded_saml_doc):
xpath_with_namespaces = self._make_xpath_builder()
find_cert = xpath_with_namespaces('//ds:KeyInfo/ds:X509Data/ds:X509Certificate/text()')
cert_value = None
try:
cert_value = find_cert(saml_metadata)[0]
except Exception as e:
self.log.warning('Could not get cert value from saml metadata')
self._log_exception_error(e)
return None
signed_xml = None
try:
signed_xml = XMLVerifier().verify(decoded_saml_doc, x509_cert=cert_value).signed_xml
except Exception as e:
self.log.warning('Failed to verify signature on SAML Response')
self._log_exception_error(e)
return signed_xml
def parse_signed(self, x509_cert: str = None):
"""
Replaces all parameters with only the signed parameters. You should
provide an x509 certificate obtained out-of-band, usually via the
SAML metadata. Otherwise the signed data will be verified with only
the certificate provided in the request. This is INSECURE and
more-or-less only useful for testing.
:param x509_cert:
:return:
"""
self._assert_xml_tree()
self.xml_tree = XMLVerifier().verify(self.xml_tree, x509_cert=x509_cert).signed_xml
self._signed_data = True