def test_no_resources(self): resources = { "idp-metadata": False, "sp-private-key": False, "sp-signing-keyinfo": False } self.patch_object(keystone_saml_mellon.hookenv, 'resource_get', side_effect=FakeResourceGet(resources)) ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.idp_metadata, None) self.assertEqual(ksmca._validation_errors, {"idp-metadata": ksmca.IDP_METADATA_NOT_PROVIDED}) self.assertEqual(ksmca.sp_signing_keyinfo, None) self.assertEqual( ksmca._validation_errors, { "idp-metadata": ksmca.IDP_METADATA_NOT_PROVIDED, "sp-signing-keyinfo": ksmca.SP_SIGNING_KEYINFO_NOT_PROVIDED }) self.assertEqual(ksmca.sp_private_key, None) self.assertEqual( ksmca._validation_errors, { "idp-metadata": ksmca.IDP_METADATA_NOT_PROVIDED, "sp-signing-keyinfo": ksmca.SP_SIGNING_KEYINFO_NOT_PROVIDED, "sp-private-key": ksmca.SP_PRIVATE_KEY_NOT_PROVIDED })
def test_sp_private_key(self): self.os.path.exists.return_value = True ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() # Valid Key self.sp_private_key_pem = (""" -----BEGIN RSA PRIVATE KEY----- MIIBPAIBAAJBANLUtlT9JMQ/RcGEipW6MBtUoFBGMOclUmOpP1BbaFJoBn19J0UG STj29M9nDLDRdfP0O/JiisG6ejxmO0A0xTsCAwEAAQJBAKT0IKRmW3ngN2etl/CF +FWp5LRp9qEjJk8rgIoSupCdvuT0Q6XLk/ygHeiBYcKTf2pT/PWjQxg1pD7So5K8 YcECIQD5SKfItJ5YC9mD+6H28UqQATPehRPhQEEFIl/lJCrFgwIhANiC14XvcuWc xMy1Lcc5lFkrB+b+oWVKJyMpNTHgXivpAiEAqh0FurZfNDBp8GJgpbcFrf3UGq7v 4RBLDqjljeY/decCIEk3/lDCCFYULQ2ZW9Da7Qs2nSaGB+isKg4e+mlSmiY5AiEA lAoUNjDHWBOlyXziqZiufMURqbPPbRkEjWwN8G2r15A= -----END RSA PRIVATE KEY----- """) self.file.read.return_value = self.sp_private_key_pem self.assertEqual(ksmca.sp_private_key, self.sp_private_key_pem) self.open.assert_called_with(self.resources["sp-private-key"]) # Invalid Key ksmca._sp_private_key = None self.file.read.return_value = "INVALID PEM KEY" self.assertEqual(ksmca.sp_private_key, '') self.assertEqual(ksmca._validation_errors, {"sp-private-key": ksmca.SP_PRIVATE_KEY_INVALID})
def test_idp_metadata_url(self): self.test_config.update( {'idp-metadata-url': 'https://samltest.id/saml/idp'}) self.patch_object(keystone_saml_mellon.hookenv, 'config', side_effect=FakeConfig(self.test_config)) resources = { "idp-metadata": False, "sp-private-key": False, "sp-signing-keyinfo": False } self.patch_object(keystone_saml_mellon.hookenv, 'resource_get', side_effect=FakeResourceGet(resources)) response = mock.MagicMock() idp_meta_xml = ( "<?xml version='1.0' encoding='UTF-8'?>" "<EntityDescriptor entityID='https://samltest.id/saml/idp'> " "</EntityDescriptor>") response.read.return_value = idp_meta_xml.encode('utf-8') self.patch_object(keystone_saml_mellon.urllib.request, 'urlopen', return_value=response) ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() # Valid XML self.assertEqual(ksmca.idp_metadata, idp_meta_xml) # Invalid XML response = mock.MagicMock() response.read.return_value = "foobar42".encode('utf-8') self.patch_object(keystone_saml_mellon.urllib.request, 'urlopen', return_value=response) ksmca._idp_metadata = None self.assertEqual(ksmca.idp_metadata, None) self.assertEqual(ksmca._validation_errors, {"idp-metadata": ksmca.IDP_METADATA_INVALID}) # Invalid URL self.patch_object(keystone_saml_mellon.urllib.request, 'urlopen', side_effect=urllib.error.URLError('invalid URL')) self.assertEqual(ksmca.idp_metadata, None) self.assertEqual( ksmca._validation_errors, {"idp-metadata": ksmca.IDP_METADATA_URL_ERROR + ': invalid URL'})
def test_idp_metadata(self): self.os.path.exists.return_value = True ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() # Valid XML self.idp_metadata_xml = ( "<?xml version='1.0' encoding='UTF-8'?>" "<EntityDescriptor entityID='https://samltest.id/saml/idp'> " "</EntityDescriptor>") self.file.read.return_value = self.idp_metadata_xml self.assertEqual(ksmca.idp_metadata, self.idp_metadata_xml) self.open.assert_called_with(self.resources["idp-metadata"], 'r', encoding='utf-8') # Invalid XML ksmca._idp_metadata = None self.file.read.return_value = "INVALID XML" self.assertEqual(ksmca.idp_metadata, None) self.assertEqual(ksmca._validation_errors, {"idp-metadata": ksmca.IDP_METADATA_INVALID})
def test_sp_signing_keyinfo(self): self.os.path.exists.return_value = True ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() # Valid XML self.sp_signing_keyinfo_xml = ( "<?xml version='1.0' encoding='UTF-8'?>" "<ds:KeyInfo xmlns:ds='http://www.w3.org/2000/09/xmldsig#'>" "<ds:X509Data> <ds:X509Certificate> </ds:X509Certificate>" "</ds:X509Data> </ds:KeyInfo>") self.file.read.return_value = self.sp_signing_keyinfo_xml self.assertEqual(ksmca.sp_signing_keyinfo, self.sp_signing_keyinfo_xml) self.open.assert_called_with(self.resources["sp-signing-keyinfo"]) # Inalid XML ksmca._sp_signing_keyinfo = None self.file.read.return_value = "INVALID XML" self.assertEqual(ksmca.sp_signing_keyinfo, "") self.assertEqual( ksmca._validation_errors, {"sp-signing-keyinfo": ksmca.SP_SIGNING_KEYINFO_INVALID})
def test_supported_nameid_formats(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.supported_nameid_formats, self.nameid_formats.split(","))
def test_mellon_subject_confirmation_data_address_check(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.mellon_subject_confirmation_data_address_check, 'Off')
def test_sp_logout_path(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.sp_logout_path, '{}/logout'.format(ksmca.mellon_endpoint_path))
def test_remote_id_attribute(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.remote_id_attribute, "MELLON_IDP")
def test_websso_auth_idp_protocol_path(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual( ksmca.websso_auth_idp_protocol_path, ('/v3/auth/OS-FEDERATION/identity_providers/{}/protocols/{}/websso' .format(self.idp_name, self.protocol_name)))
def test_sp_auth_path(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.sp_auth_path, '{}/auth'.format(ksmca.sp_protocol_path))
def test_sp_protocol_path(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual( ksmca.sp_protocol_path, '{}/protocols/{}'.format(ksmca.sp_idp_path, self.protocol_name))
def test_sp_idp_path(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual( ksmca.sp_idp_path, '/v3/OS-FEDERATION/identity_providers/{}'.format(self.idp_name))
def test_sp_private_key_file(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.sp_private_key_file, keystone_saml_mellon.SP_PRIVATE_KEY)
def test_sp_metadata_file(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.sp_metadata_file, keystone_saml_mellon.SP_METADATA)
def test_sp_post_response_path(self): ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() self.assertEqual(ksmca.sp_post_response_path, '{}/postResponse'.format(ksmca.mellon_endpoint_path))
def test_validation_errors(self): errors = {"idp-metadata": "Bad XML"} ksmca = keystone_saml_mellon.KeystoneSAMLMellonConfigurationAdapter() ksmca._validation_errors = errors self.assertEqual(ksmca.validation_errors, errors)