def testAddX509KeyDescriptors(self): """ Tests the addX509KeyDescriptors method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() metadata = OneLogin_Saml2_Metadata.builder(sp_data) self.assertNotIn('<md:KeyDescriptor use="signing"', metadata) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata) metadata_without_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, None) self.assertNotIn('<md:KeyDescriptor use="signing"', metadata_without_descriptors) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata_without_descriptors) metadata_without_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, '') self.assertNotIn('<md:KeyDescriptor use="signing"', metadata_without_descriptors) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata_without_descriptors) cert_path = settings.get_cert_path() cert = self.file_contents(join(cert_path, 'sp.crt')) metadata_with_descriptors = compat.to_string(OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, cert)) self.assertIn('<md:KeyDescriptor use="signing"', metadata_with_descriptors) self.assertIn('<md:KeyDescriptor use="encryption"', metadata_with_descriptors) self.assertRaisesRegexp(Exception, 'Error parsing metadata', OneLogin_Saml2_Metadata.add_x509_key_descriptors, '', cert) base_path = dirname(dirname(dirname(dirname(__file__)))) unparsed_metadata = self.file_contents(join(base_path, 'data', 'metadata', 'unparsed_metadata.xml')) self.assertRaisesRegexp(Exception, 'Error parsing metadata', OneLogin_Saml2_Metadata.add_x509_key_descriptors, unparsed_metadata, cert)
def testAddX509KeyDescriptors(self): """ Tests the addX509KeyDescriptors method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() metadata = OneLogin_Saml2_Metadata.builder(sp_data) self.assertNotIn('<md:KeyDescriptor use="signing"', metadata) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata) metadata_without_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, None) self.assertNotIn('<md:KeyDescriptor use="signing"', metadata_without_descriptors) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata_without_descriptors) metadata_without_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, '') self.assertNotIn('<md:KeyDescriptor use="signing"', metadata_without_descriptors) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata_without_descriptors) cert_path = settings.get_cert_path() cert = self.file_contents(join(cert_path, 'sp.crt')) metadata_with_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, cert) self.assertIn('<md:KeyDescriptor use="signing"', metadata_with_descriptors) self.assertIn('<md:KeyDescriptor use="encryption"', metadata_with_descriptors) with self.assertRaisesRegexp(Exception, 'Error parsing metadata'): OneLogin_Saml2_Metadata.add_x509_key_descriptors('', cert) base_path = dirname(dirname(dirname(dirname(__file__)))) unparsed_metadata = self.file_contents(join(base_path, 'data', 'metadata', 'unparsed_metadata.xml')) with self.assertRaisesRegexp(Exception, 'Error parsing metadata'): metadata_with_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(unparsed_metadata, cert)
def testBuilderAttributeConsumingService(self): settings = OneLogin_Saml2_Settings(self.loadSettingsJSON('settings4.json')) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], None, None, contacts, organization ) self.assertIn('xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"', metadata) self.assertIn('<md:AttributeConsumingService index="1" isDefault="false"><md:ServiceName \ xml:lang="en">Test Service</md:ServiceName><md:ServiceDescription xml:lang="en">Test Service\ </md:ServiceDescription><md:RequestedAttribute Name="urn:oid:2.5.4.42" \ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="givenName" \ isRequired="false"/><md:RequestedAttribute Name="urn:oid:2.5.4.4" \ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="sn" \ isRequired="false"/><md:RequestedAttribute Name="urn:oid:2.16.840.1.113730.3.1.241" \ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="displayName" \ isRequired="false"/><md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.3" \ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="mail" \ isRequired="false"/><md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.1" \ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="uid" \ isRequired="false"/></md:AttributeConsumingService>', metadata)
def testBuilderAttributeConsumingService(self): settings = OneLogin_Saml2_Settings(self.loadSettingsJSON("settings4.json")) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security["authnRequestsSigned"], security["wantAssertionsSigned"], None, None, contacts, organization, ) self.assertIn( """ <md:AttributeConsumingService index="1"> <md:ServiceName xml:lang="en">Test Service</md:ServiceName> <md:ServiceDescription xml:lang="en">Test Service</md:ServiceDescription> <md:RequestedAttribute Name="urn:oid:2.5.4.42" FriendlyName="givenName" /> <md:RequestedAttribute Name="urn:oid:2.5.4.4" FriendlyName="sn" /> <md:RequestedAttribute Name="urn:oid:2.16.840.1.113730.3.1.241" FriendlyName="displayName" /> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.3" FriendlyName="mail" /> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.1" FriendlyName="uid" /> </md:AttributeConsumingService>""", metadata, )
def testSignMetadata(self): """ Tests the signMetadata method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'] ) self.assertIsNotNone(metadata) cert_path = settings.get_cert_path() key = self.file_contents(join(cert_path, 'sp.key')) cert = self.file_contents(join(cert_path, 'sp.crt')) signed_metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert) self.assertIn('<md:SPSSODescriptor', signed_metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata) self.assertIn('AuthnRequestsSigned="false"', signed_metadata) self.assertIn('WantAssertionsSigned="false"', signed_metadata) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata) self.assertIn('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>', signed_metadata) self.assertIn('<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>', signed_metadata) self.assertIn('<ds:Reference', signed_metadata) self.assertIn('<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>', signed_metadata) with self.assertRaisesRegexp(Exception, 'Empty string supplied as input'): OneLogin_Saml2_Metadata.sign_metadata('', key, cert) signed_metadata_2 = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert, OneLogin_Saml2_Constants.RSA_SHA256, OneLogin_Saml2_Constants.SHA384) self.assertIn('<md:SPSSODescriptor', signed_metadata_2) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata_2) self.assertIn('AuthnRequestsSigned="false"', signed_metadata_2) self.assertIn('WantAssertionsSigned="false"', signed_metadata_2) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata_2) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata_2) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata_2) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata_2) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata_2) self.assertIn('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata_2) self.assertIn('<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>', signed_metadata_2) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>', signed_metadata_2) self.assertIn('<ds:Reference', signed_metadata_2) self.assertIn('<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>', signed_metadata_2)
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self.__sp, self.__security['authnRequestsSigned'], self.__security['wantAssertionsSigned'], None, None, self.get_contacts(), self.get_organization() ) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, cert) # Sign metadata if 'signMetadata' in self.__security and self.__security['signMetadata'] is not False: if self.__security['signMetadata'] is True: key_file_name = 'sp.key' cert_file_name = 'sp.crt' else: if ('keyFileName' not in self.__security['signMetadata'] or 'certFileName' not in self.__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX ) key_file_name = self.__security['signMetadata']['keyFileName'] cert_file_name = self.__security['signMetadata']['certFileName'] key_metadata_file = self.__paths['cert'] + key_file_name cert_metadata_file = self.__paths['cert'] + cert_file_name if not exists(key_metadata_file): raise OneLogin_Saml2_Error( 'Private key file not found: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file ) if not exists(cert_metadata_file): raise OneLogin_Saml2_Error( 'Public cert file not found: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file ) f_metadata_key = open(key_metadata_file, 'r') key_metadata = f_metadata_key.read() f_metadata_key.close() f_metadata_cert = open(cert_metadata_file, 'r') cert_metadata = f_metadata_cert.read() f_metadata_cert.close() metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key_metadata, cert_metadata) return metadata
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self.__sp, self.__security['authnRequestsSigned'], self.__security['wantAssertionsSigned'], None, None, self.get_contacts(), self.get_organization()) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert) # Sign metadata if 'signMetadata' in self.__security and self.__security[ 'signMetadata'] is not False: if self.__security['signMetadata'] is True: key_file_name = 'sp.key' cert_file_name = 'sp.crt' else: if ('keyFileName' not in self.__security['signMetadata'] or 'certFileName' not in self.__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX) key_file_name = self.__security['signMetadata']['keyFileName'] cert_file_name = self.__security['signMetadata'][ 'certFileName'] key_metadata_file = self.__paths['cert'] + key_file_name cert_metadata_file = self.__paths['cert'] + cert_file_name if not exists(key_metadata_file): raise OneLogin_Saml2_Error( 'Private key file not found: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file) if not exists(cert_metadata_file): raise OneLogin_Saml2_Error( 'Public cert file not found: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file) f_metadata_key = open(key_metadata_file, 'r') key_metadata = f_metadata_key.read() f_metadata_key.close() f_metadata_cert = open(cert_metadata_file, 'r') cert_metadata = f_metadata_cert.read() f_metadata_cert.close() metadata = OneLogin_Saml2_Metadata.sign_metadata( metadata, key_metadata, cert_metadata) return metadata
def get(self): logging.info("Initiating SAML 2.0 Metadata get.") settings = yield Query(self.settings["database"], "Settings").find_one() saml_settings = Saml2MetadataHandler.get_saml_settings(settings) self.set_header('Content-Type', 'text/xml') self.write(OneLogin_Saml2_Metadata.builder( sp=saml_settings['sp'], authnsign=saml_settings['security']['authnRequestsSigned'], wsign=saml_settings['security']['wantAssertionsSigned']) ) self.flush()
def testSignMetadata(self): """ Tests the signMetadata method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security["authnRequestsSigned"], security["wantAssertionsSigned"] ) self.assertIsNotNone(metadata) cert_path = settings.get_cert_path() key = self.file_contents(join(cert_path, "sp.key")) cert = self.file_contents(join(cert_path, "sp.crt")) signed_metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert) self.assertIn("<md:SPSSODescriptor", signed_metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata) self.assertIn('AuthnRequestsSigned="false"', signed_metadata) self.assertIn('WantAssertionsSigned="false"', signed_metadata) self.assertIn( '<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata ) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata) self.assertIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata ) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata) self.assertIn( "<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>", signed_metadata ) self.assertIn( '<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata, ) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>', signed_metadata) self.assertIn("<ds:Reference", signed_metadata) self.assertIn("<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>", signed_metadata) try: OneLogin_Saml2_Metadata.sign_metadata("", key, cert) self.assertTrue(False) except Exception as e: self.assertIn("Empty string supplied as input", e.message)
def get(self): logging.info("Initiating SAML 2.0 Metadata get.") settings = yield Query(self.settings["database"], "Settings").find_one() saml_settings = Saml2MetadataHandler.get_saml_settings(settings) self.set_header('Content-Type', 'text/xml') self.write( OneLogin_Saml2_Metadata.builder( sp=saml_settings['sp'], authnsign=saml_settings['security']['authnRequestsSigned'], wsign=saml_settings['security']['wantAssertionsSigned'])) self.flush()
def testSurName(self): settingsDict = self.loadSettingsJSON() settingsDict['contactPerson']['technical']['surName'] = 'Surname' settings = OneLogin_Saml2_Settings(settingsDict) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], None, None, contacts, organization) self.assertIn('<md:SurName>Surname</md:SurName>', metadata)
def testBuilderAttributeConsumingServiceWithMultipleAttributeValue(self): settings = OneLogin_Saml2_Settings(self.loadSettingsJSON('settings5.json')) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], None, None, contacts, organization ) self.assertIn(""" <md:AttributeConsumingService index="1"> <md:ServiceName xml:lang="en">Test Service</md:ServiceName> <md:ServiceDescription xml:lang="en">Test Service</md:ServiceDescription> <md:RequestedAttribute Name="userType" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">userType</saml:AttributeValue> <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">admin</saml:AttributeValue> </md:RequestedAttribute> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.1" FriendlyName="uid" /> </md:AttributeConsumingService>""", metadata)
def testBuilderAttributeConsumingService(self): settings = OneLogin_Saml2_Settings(self.loadSettingsJSON('settings4.json')) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], None, None, contacts, organization ) self.assertIn(""" <md:AttributeConsumingService index="1"> <md:ServiceName xml:lang="en">Test Service</md:ServiceName> <md:ServiceDescription xml:lang="en">Test Service</md:ServiceDescription> <md:RequestedAttribute Name="urn:oid:2.5.4.42" FriendlyName="givenName" /> <md:RequestedAttribute Name="urn:oid:2.5.4.4" FriendlyName="sn" /> <md:RequestedAttribute Name="urn:oid:2.16.840.1.113730.3.1.241" FriendlyName="displayName" /> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.3" FriendlyName="mail" /> <md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.1" FriendlyName="uid" /> </md:AttributeConsumingService>""", metadata)
def testAddX509KeyDescriptors(self): """ Tests the addX509KeyDescriptors method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() metadata = OneLogin_Saml2_Metadata.builder(sp_data) self.assertNotIn('<md:KeyDescriptor use="signing"', metadata) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata) metadata_without_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, None) self.assertNotIn('<md:KeyDescriptor use="signing"', metadata_without_descriptors) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata_without_descriptors) metadata_without_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, "") self.assertNotIn('<md:KeyDescriptor use="signing"', metadata_without_descriptors) self.assertNotIn('<md:KeyDescriptor use="encryption"', metadata_without_descriptors) cert_path = settings.get_cert_path() cert = self.file_contents(join(cert_path, "sp.crt")) metadata_with_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, cert) self.assertIn('<md:KeyDescriptor use="signing"', metadata_with_descriptors) self.assertIn('<md:KeyDescriptor use="encryption"', metadata_with_descriptors) try: OneLogin_Saml2_Metadata.add_x509_key_descriptors("", cert) self.assertTrue(False) except Exception as e: self.assertIn("Error parsing metadata", e.message) base_path = dirname(dirname(dirname(dirname(__file__)))) unparsed_metadata = self.file_contents(join(base_path, "data", "metadata", "unparsed_metadata.xml")) try: metadata_with_descriptors = OneLogin_Saml2_Metadata.add_x509_key_descriptors(unparsed_metadata, cert) self.assertFalse(True) except Exception as e: self.assertIn("Error parsing metadata", e.message)
def testSignMetadata(self): """ Tests the signMetadata method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned']) self.assertIsNotNone(metadata) cert_path = settings.get_cert_path() key = self.file_contents(join(cert_path, 'sp.key')) cert = self.file_contents(join(cert_path, 'sp.crt')) signed_metadata = compat.to_string( OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert)) self.assertTrue( OneLogin_Saml2_Utils.validate_metadata_sign(signed_metadata, cert)) self.assertIn('<md:SPSSODescriptor', signed_metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata) self.assertIn('ID="ONELOGIN_', signed_metadata) self.assertIn('AuthnRequestsSigned="false"', signed_metadata) self.assertIn('WantAssertionsSigned="false"', signed_metadata) self.assertIn( '<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata) self.assertIn( 'Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata) self.assertIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata) self.assertIn( ' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata) self.assertIn( '<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata) self.assertIn( '<ds:SignedInfo>\n<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata) self.assertIn( '<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>', signed_metadata) self.assertIn( '<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>', signed_metadata) self.assertIn('<ds:Reference', signed_metadata) self.assertIn('<ds:KeyInfo>\n<ds:X509Data>\n<ds:X509Certificate>', signed_metadata) with self.assertRaises(Exception) as context: OneLogin_Saml2_Metadata.sign_metadata('', key, cert) exception = context.exception self.assertIn("Empty string supplied as input", str(exception)) signed_metadata_2 = compat.to_string( OneLogin_Saml2_Metadata.sign_metadata( metadata, key, cert, OneLogin_Saml2_Constants.RSA_SHA256, OneLogin_Saml2_Constants.SHA384)) self.assertTrue( OneLogin_Saml2_Utils.validate_metadata_sign( signed_metadata_2, cert)) self.assertIn('<md:SPSSODescriptor', signed_metadata_2) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata_2) self.assertIn('ID="ONELOGIN_', signed_metadata_2) self.assertIn('AuthnRequestsSigned="false"', signed_metadata_2) self.assertIn('WantAssertionsSigned="false"', signed_metadata_2) self.assertIn( '<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata_2) self.assertIn( 'Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata_2) self.assertIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata_2) self.assertIn( ' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata_2) self.assertIn( '<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata_2) self.assertIn( '<ds:SignedInfo>\n<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata_2) self.assertIn( '<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>', signed_metadata_2) self.assertIn( '<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>', signed_metadata_2) self.assertIn('<ds:Reference', signed_metadata_2) self.assertIn('<ds:KeyInfo>\n<ds:X509Data>\n<ds:X509Certificate>', signed_metadata_2) root = OneLogin_Saml2_XML.to_etree(signed_metadata_2) first_child = OneLogin_Saml2_XML.query(root, '/md:EntityDescriptor/*[1]')[0] self.assertEqual('{http://www.w3.org/2000/09/xmldsig#}Signature', first_child.tag)
def testBuilder(self): """ Tests the builder method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], None, None, contacts, organization ) self.assertIsNotNone(metadata) self.assertIn('<md:SPSSODescriptor', metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', metadata) self.assertIn('AuthnRequestsSigned="false"', metadata) self.assertIn('WantAssertionsSigned="false"', metadata) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', metadata) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', metadata) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', metadata) self.assertIn('Location="http://stuff.com/endpoints/endpoints/sls.php"', metadata) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified</md:NameIDFormat>', metadata) self.assertIn('<md:OrganizationName xml:lang="en-US">sp_test</md:OrganizationName>', metadata) self.assertIn('<md:ContactPerson contactType="technical">', metadata) self.assertIn('<md:GivenName>technical_name</md:GivenName>', metadata) security['authnRequestsSigned'] = True security['wantAssertionsSigned'] = True del sp_data['singleLogoutService']['url'] metadata2 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'] ) self.assertIsNotNone(metadata2) self.assertIn('<md:SPSSODescriptor', metadata2) self.assertIn('AuthnRequestsSigned="true"', metadata2) self.assertIn('WantAssertionsSigned="true"', metadata2) self.assertNotIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', metadata2) self.assertNotIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', metadata2) metadata3 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], '2014-10-01T11:04:29Z', 'PT1412593469S', contacts, organization ) self.assertIsNotNone(metadata3) self.assertIn('<md:SPSSODescriptor', metadata3) self.assertIn('cacheDuration="PT1412593469S"', metadata3) self.assertIn('validUntil="2014-10-01T11:04:29Z"', metadata3)
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self.__sp, self.__security['authnRequestsSigned'], self.__security['wantAssertionsSigned'], self.__security['metadataValidUntil'], self.__security['metadataCacheDuration'], self.get_contacts(), self.get_organization() ) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors(metadata, cert) # Sign metadata if 'signMetadata' in self.__security and self.__security['signMetadata'] is not False: if self.__security['signMetadata'] is True: # Use the SP's normal key to sign the metadata: if not cert: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP public key certificate.', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND ) cert_metadata = cert key_metadata = self.get_sp_key() if not key_metadata: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP private key.', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND ) else: # Use a custom key to sign the metadata: if ('keyFileName' not in self.__security['signMetadata'] or 'certFileName' not in self.__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX ) key_file_name = self.__security['signMetadata']['keyFileName'] cert_file_name = self.__security['signMetadata']['certFileName'] key_metadata_file = self.__paths['cert'] + key_file_name cert_metadata_file = self.__paths['cert'] + cert_file_name try: with open(key_metadata_file, 'r') as f_metadata_key: key_metadata = f_metadata_key.read() except IOError: raise OneLogin_Saml2_Error( 'Private key file not readable: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file ) try: with open(cert_metadata_file, 'r') as f_metadata_cert: cert_metadata = f_metadata_cert.read() except IOError: raise OneLogin_Saml2_Error( 'Public cert file not readable: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file ) metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key_metadata, cert_metadata) return metadata
def testBuilder(self): """ Tests the builder method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], None, None, contacts, organization ) self.assertIsNotNone(metadata) self.assertIn('<md:SPSSODescriptor', metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', metadata) self.assertIn('AuthnRequestsSigned="false"', metadata) self.assertIn('WantAssertionsSigned="false"', metadata) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', metadata) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', metadata) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', metadata) self.assertIn('Location="http://stuff.com/endpoints/endpoints/sls.php"', metadata) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', metadata) self.assertIn('<md:OrganizationName xml:lang="en-US">sp_test</md:OrganizationName>', metadata) self.assertIn('<md:ContactPerson contactType="technical">', metadata) self.assertIn('<md:GivenName>technical_name</md:GivenName>', metadata) security['authnRequestsSigned'] = True security['wantAssertionsSigned'] = True del sp_data['singleLogoutService']['url'] metadata2 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'] ) self.assertIsNotNone(metadata2) self.assertIn('<md:SPSSODescriptor', metadata2) self.assertIn('AuthnRequestsSigned="true"', metadata2) self.assertIn('WantAssertionsSigned="true"', metadata2) self.assertNotIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', metadata2) self.assertNotIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', metadata2) metadata3 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], '2014-10-01T11:04:29Z', 'P1Y', contacts, organization ) self.assertIsNotNone(metadata3) self.assertIn('<md:SPSSODescriptor', metadata3) self.assertIn('cacheDuration="P1Y"', metadata3) self.assertIn('validUntil="2014-10-01T11:04:29Z"', metadata3) # Test no validUntil, only cacheDuration: metadata4 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], '', 86400 * 10, # 10 days contacts, organization ) self.assertIsNotNone(metadata4) self.assertIn('<md:SPSSODescriptor', metadata4) self.assertIn('cacheDuration="PT864000S"', metadata4) self.assertNotIn('validUntil', metadata4) # Test no cacheDuration, only validUntil: metadata5 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], '2014-10-01T11:04:29Z', '', contacts, organization ) self.assertIsNotNone(metadata5) self.assertIn('<md:SPSSODescriptor', metadata5) self.assertNotIn('cacheDuration', metadata5) self.assertIn('validUntil="2014-10-01T11:04:29Z"', metadata5) datetime_value = datetime.now() metadata6 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], datetime_value, 'P1Y', contacts, organization ) self.assertIsNotNone(metadata5) self.assertIn('<md:SPSSODescriptor', metadata6) self.assertIn('cacheDuration="P1Y"', metadata6) parsed_datetime = strftime(r'%Y-%m-%dT%H:%M:%SZ', datetime_value.timetuple()) self.assertIn('validUntil="%s"' % parsed_datetime, metadata6)
def testBuilder(self): """ Tests the builder method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], None, None, contacts, organization) self.assertIsNotNone(metadata) self.assertIn('<md:SPSSODescriptor', metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', metadata) self.assertIn('AuthnRequestsSigned="false"', metadata) self.assertIn('WantAssertionsSigned="false"', metadata) self.assertIn( '<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', metadata) self.assertIn( 'Location="http://stuff.com/endpoints/endpoints/acs.php"', metadata) self.assertIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', metadata) self.assertIn( 'Location="http://stuff.com/endpoints/endpoints/sls.php"', metadata) self.assertIn( '<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified</md:NameIDFormat>', metadata) self.assertIn( '<md:OrganizationName xml:lang="en-US">sp_test</md:OrganizationName>', metadata) self.assertIn('<md:ContactPerson contactType="technical">', metadata) self.assertIn('<md:GivenName>technical_name</md:GivenName>', metadata) security['authnRequestsSigned'] = True security['wantAssertionsSigned'] = True del sp_data['singleLogoutService'] metadata2 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned']) self.assertIsNotNone(metadata2) self.assertIn('<md:SPSSODescriptor', metadata2) self.assertIn('AuthnRequestsSigned="true"', metadata2) self.assertIn('WantAssertionsSigned="true"', metadata2) self.assertNotIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', metadata2) self.assertNotIn( ' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', metadata2) metadata3 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], '2014-10-01T11:04:29Z', 'PT1412593469S', contacts, organization) self.assertIsNotNone(metadata3) self.assertIn('<md:SPSSODescriptor', metadata3) self.assertIn('cacheDuration="PT1412593469S"', metadata3) self.assertIn('validUntil="2014-10-01T11:04:29Z"', metadata3)
def testSignMetadata(self): """ Tests the signMetadata method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'] ) self.assertIsNotNone(metadata) cert_path = settings.get_cert_path() key = self.file_contents(join(cert_path, 'sp.key')) cert = self.file_contents(join(cert_path, 'sp.crt')) signed_metadata = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert) self.assertTrue(OneLogin_Saml2_Utils.validate_metadata_sign(signed_metadata, cert)) self.assertIn('<md:SPSSODescriptor', signed_metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata) self.assertIn('ID="ONELOGIN_', signed_metadata) self.assertIn('AuthnRequestsSigned="false"', signed_metadata) self.assertIn('WantAssertionsSigned="false"', signed_metadata) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata) self.assertIn('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>', signed_metadata) self.assertIn('<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>', signed_metadata) self.assertIn('<ds:Reference', signed_metadata) self.assertIn('<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>', signed_metadata) with self.assertRaisesRegexp(Exception, 'Empty string supplied as input'): OneLogin_Saml2_Metadata.sign_metadata('', key, cert) signed_metadata_2 = OneLogin_Saml2_Metadata.sign_metadata(metadata, key, cert, OneLogin_Saml2_Constants.RSA_SHA256, OneLogin_Saml2_Constants.SHA384) self.assertTrue(OneLogin_Saml2_Utils.validate_metadata_sign(signed_metadata_2, cert)) self.assertIn('<md:SPSSODescriptor', signed_metadata_2) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', signed_metadata_2) self.assertIn('ID="ONELOGIN_', signed_metadata_2) self.assertIn('AuthnRequestsSigned="false"', signed_metadata_2) self.assertIn('WantAssertionsSigned="false"', signed_metadata_2) self.assertIn('<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', signed_metadata_2) self.assertIn('Location="http://stuff.com/endpoints/endpoints/acs.php"', signed_metadata_2) self.assertIn('<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', signed_metadata_2) self.assertIn(' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', signed_metadata_2) self.assertIn('<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', signed_metadata_2) self.assertIn('<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>', signed_metadata_2) self.assertIn('<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>', signed_metadata_2) self.assertIn('<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>', signed_metadata_2) self.assertIn('<ds:Reference', signed_metadata_2) self.assertIn('<ds:KeyInfo><ds:X509Data>\n<ds:X509Certificate>', signed_metadata_2)
def testBuilder(self): """ Tests the builder method of the OneLogin_Saml2_Metadata """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) sp_data = settings.get_sp_data() security = settings.get_security_data() organization = settings.get_organization() contacts = settings.get_contacts() metadata = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], None, None, contacts, organization) self.assertIsNotNone(metadata) self.assertIn('<md:SPSSODescriptor', metadata) self.assertIn('entityID="http://stuff.com/endpoints/metadata.php"', metadata) self.assertIn('AuthnRequestsSigned="false"', metadata) self.assertIn('WantAssertionsSigned="false"', metadata) self.assertIn( '<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"', metadata) self.assertIn( 'Location="http://stuff.com/endpoints/endpoints/acs.php"', metadata) self.assertIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', metadata) self.assertIn( 'Location="http://stuff.com/endpoints/endpoints/sls.php"', metadata) self.assertIn( '<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>', metadata) self.assertIn( '<md:OrganizationName xml:lang="en-US">sp_test</md:OrganizationName>', metadata) self.assertIn('<md:ContactPerson contactType="technical">', metadata) self.assertIn('<md:GivenName>technical_name</md:GivenName>', metadata) security['authnRequestsSigned'] = True security['wantAssertionsSigned'] = True del sp_data['singleLogoutService']['url'] metadata2 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned']) self.assertIsNotNone(metadata2) self.assertIn('<md:SPSSODescriptor', metadata2) self.assertIn('AuthnRequestsSigned="true"', metadata2) self.assertIn('WantAssertionsSigned="true"', metadata2) self.assertNotIn( '<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"', metadata2) self.assertNotIn( ' Location="http://stuff.com/endpoints/endpoints/sls.php"/>', metadata2) metadata3 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], '2014-10-01T11:04:29Z', 'P1Y', contacts, organization) self.assertIsNotNone(metadata3) self.assertIn('<md:SPSSODescriptor', metadata3) self.assertIn('cacheDuration="P1Y"', metadata3) self.assertIn('validUntil="2014-10-01T11:04:29Z"', metadata3) # Test no validUntil, only cacheDuration: metadata4 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], '', 86400 * 10, # 10 days contacts, organization) self.assertIsNotNone(metadata4) self.assertIn('<md:SPSSODescriptor', metadata4) self.assertIn('cacheDuration="PT864000S"', metadata4) self.assertNotIn('validUntil', metadata4) # Test no cacheDuration, only validUntil: metadata5 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], '2014-10-01T11:04:29Z', '', contacts, organization) self.assertIsNotNone(metadata5) self.assertIn('<md:SPSSODescriptor', metadata5) self.assertNotIn('cacheDuration', metadata5) self.assertIn('validUntil="2014-10-01T11:04:29Z"', metadata5) datetime_value = datetime.now() metadata6 = OneLogin_Saml2_Metadata.builder( sp_data, security['authnRequestsSigned'], security['wantAssertionsSigned'], datetime_value, 'P1Y', contacts, organization) self.assertIsNotNone(metadata5) self.assertIn('<md:SPSSODescriptor', metadata6) self.assertIn('cacheDuration="P1Y"', metadata6) parsed_datetime = strftime(r'%Y-%m-%dT%H:%M:%SZ', datetime_value.timetuple()) self.assertIn('validUntil="%s"' % parsed_datetime, metadata6)
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self.__sp, self.__security['authnRequestsSigned'], self.__security['wantAssertionsSigned'], self.__security['metadataValidUntil'], self.__security['metadataCacheDuration'], self.get_contacts(), self.get_organization()) add_encryption = self.__security[ 'wantNameIdEncrypted'] or self.__security['wantAssertionsEncrypted'] cert_new = self.get_sp_cert_new() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert_new, add_encryption) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert, add_encryption) # Sign metadata if 'signMetadata' in self.__security and self.__security[ 'signMetadata'] is not False: if self.__security['signMetadata'] is True: # Use the SP's normal key to sign the metadata: if not cert: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP public key certificate.', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND) cert_metadata = cert key_metadata = self.get_sp_key() if not key_metadata: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP private key.', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND) else: # Use a custom key to sign the metadata: if ('keyFileName' not in self.__security['signMetadata'] or 'certFileName' not in self.__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX) key_file_name = self.__security['signMetadata']['keyFileName'] cert_file_name = self.__security['signMetadata'][ 'certFileName'] key_metadata_file = self.__paths['cert'] + key_file_name cert_metadata_file = self.__paths['cert'] + cert_file_name try: with open(key_metadata_file, 'r') as f_metadata_key: key_metadata = f_metadata_key.read() except IOError: raise OneLogin_Saml2_Error( 'Private key file not readable: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file) try: with open(cert_metadata_file, 'r') as f_metadata_cert: cert_metadata = f_metadata_cert.read() except IOError: raise OneLogin_Saml2_Error( 'Public cert file not readable: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file) signature_algorithm = self.__security['signatureAlgorithm'] digest_algorithm = self.__security['digestAlgorithm'] metadata = OneLogin_Saml2_Metadata.sign_metadata( metadata, key_metadata, cert_metadata, signature_algorithm, digest_algorithm) return metadata
def get_sp_metadata(self): """ Gets the SP metadata. The XML representation. :returns: SP metadata (xml) :rtype: string """ metadata = OneLogin_Saml2_Metadata.builder( self._OneLogin_Saml2_Settings__sp, self._OneLogin_Saml2_Settings__security['authnRequestsSigned'], self._OneLogin_Saml2_Settings__security['wantAssertionsSigned'], self._OneLogin_Saml2_Settings__security['metadataValidUntil'], self._OneLogin_Saml2_Settings__security['metadataCacheDuration'], self.get_contacts(), self.get_organization()) ##### SP SPid patch ## mapping xml tag tagMapping = { "md0:AssertionConsumerService": 'assertionConsumerService', "md0:AttributeConsumingService": 'attributeConsumingService', "md0:ServiceName": 'serviceName', "md0:ServiceDescription": 'serviceDescription', "md0:RequestedAttribute": 'requestedAttributes', "md1:AttributeValue": 'attributeValue' } ## edit meta data ns = { 'md0': OneLogin_Saml2_Constants.NS_MD, 'md1': OneLogin_Saml2_Constants.NS_SAML } xml.etree.ElementTree.register_namespace( 'md0', OneLogin_Saml2_Constants.NS_MD) xml.etree.ElementTree.register_namespace( 'md1', OneLogin_Saml2_Constants.NS_SAML) parsedMetadata = xml.etree.ElementTree.fromstring(metadata) SPSSODescriptor = parsedMetadata.find('md0:SPSSODescriptor', ns) if not self._OneLogin_Saml2_Settings__security[ 'putMetadataCacheDuration']: parsedMetadata.attrib.pop('cacheDuration') if not self._OneLogin_Saml2_Settings__security['putMetadataValidUntil']: parsedMetadata.attrib.pop('validUntil') ## fix AssertionConsumerService index 0 assertionConsumerService = SPSSODescriptor.find( 'md0:AssertionConsumerService', ns) assertionConsumerService.attrib['index'] = '0' assertionConsumerService.set('isDefault', 'true') ## fix AttributeConsumingService index 0 attributeConsumingService = SPSSODescriptor.find( 'md0:AttributeConsumingService', ns) attributeConsumingService.attrib['index'] = '0' attributeConsumingService.find('md0:ServiceName', ns).attrib[ '{http://www.w3.org/XML/1998/namespace}lang'] = self._OneLogin_Saml2_Settings__sp[ 'lang'] attributeConsumingService.find('md0:ServiceDescription', ns).attrib[ '{http://www.w3.org/XML/1998/namespace}lang'] = self._OneLogin_Saml2_Settings__sp[ 'lang'] ## add other AssertionConsumerService try: for index, value1 in enumerate(self._OneLogin_Saml2_Settings__sp[ 'otherAssertionConsumerService']): #indexValue = str(index+1) tag = "md0:AssertionConsumerService" element = xml.etree.ElementTree.Element( tag, attrib={ 'Location': value1[tagMapping[tag]]['url'], 'Binding': value1[tagMapping[tag]]['binding'], 'index': value1[tagMapping[tag]]['index'] }) #AssertionConsumerService.append(element) #SPSSODescriptor.append(element) SPSSODescriptor.insert(index + 3, element) tag1 = "md0:AttributeConsumingService" element1 = xml.etree.ElementTree.Element( tag1, attrib={'index': value1[tagMapping[tag]]['index']}) #SPSSODescriptor.append(element1) #AttributeConsumingService.append(element1) #attributeConsumingService = SPSSODescriptor.find("md0:AttributeConsumingService[@index=\""+indexValue+"\"]", ns) SPSSODescriptor.append(element1) tag2 = "md0:ServiceName" element2 = xml.etree.ElementTree.Element( tag2, attrib={ 'xml:lang': self._OneLogin_Saml2_Settings__sp['lang'] }) element2.text = value1[tagMapping[tag]][tagMapping[tag1]][ tagMapping[tag2]] element1.append(element2) tag2 = "md0:ServiceDescription" element2 = xml.etree.ElementTree.Element( tag2, attrib={ 'xml:lang': self._OneLogin_Saml2_Settings__sp['lang'] }) element2.text = value1[tagMapping[tag]][tagMapping[tag1]][ tagMapping[tag2]] element1.append(element2) tag3 = "md0:RequestedAttribute" for index2, value2 in enumerate(value1[tagMapping[tag]][ tagMapping[tag1]][tagMapping[tag3]]): if value2['isRequired']: attrRequired = "true" else: attrRequired = "false" attributi = { 'Name': value2['name'], 'FriendlyName': value2['friendlyName'], 'isRequired': attrRequired } element3 = xml.etree.ElementTree.Element(tag3, attrib=attributi) element1.append(element3) for index3, value3 in enumerate( value1[tagMapping[tag]][tagMapping[tag1]][ tagMapping[tag3]][index2]['attributeValue']): xml.etree.ElementTree.Element(tag3, attrib=attributi) tag4 = "md1:AttributeValue" element4 = xml.etree.ElementTree.Element(tag4) element4.text = value3 element3.append(element4) except: pass metadata = xml.etree.ElementTree.tostring(parsedMetadata, encoding="unicode") #### add_encryption = self._OneLogin_Saml2_Settings__security[ 'wantNameIdEncrypted'] or self._OneLogin_Saml2_Settings__security[ 'wantAssertionsEncrypted'] cert_new = self.get_sp_cert_new() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert_new, add_encryption) cert = self.get_sp_cert() metadata = OneLogin_Saml2_Metadata.add_x509_key_descriptors( metadata, cert, add_encryption) # Sign metadata if 'signMetadata' in self._OneLogin_Saml2_Settings__security and self._OneLogin_Saml2_Settings__security[ 'signMetadata'] is not False: if self._OneLogin_Saml2_Settings__security['signMetadata'] is True: # Use the SP's normal key to sign the metadata: if not cert: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP public key certificate.', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND) cert_metadata = cert key_metadata = self.get_sp_key() if not key_metadata: raise OneLogin_Saml2_Error( 'Cannot sign metadata: missing SP private key.', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND) else: # Use a custom key to sign the metadata: if ('keyFileName' not in self._OneLogin_Saml2_Settings__security['signMetadata'] or 'certFileName' not in self. _OneLogin_Saml2_Settings__security['signMetadata']): raise OneLogin_Saml2_Error( 'Invalid Setting: signMetadata value of the sp is not valid', OneLogin_Saml2_Error.SETTINGS_INVALID_SYNTAX) key_file_name = self._OneLogin_Saml2_Settings__security[ 'signMetadata']['keyFileName'] cert_file_name = self._OneLogin_Saml2_Settings__security[ 'signMetadata']['certFileName'] key_metadata_file = self._OneLogin_Saml2_Settings__paths[ 'cert'] + key_file_name cert_metadata_file = self._OneLogin_Saml2_Settings__paths[ 'cert'] + cert_file_name try: with open(key_metadata_file, 'r') as f_metadata_key: key_metadata = f_metadata_key.read() except IOError: raise OneLogin_Saml2_Error( 'Private key file not readable: %s', OneLogin_Saml2_Error.PRIVATE_KEY_FILE_NOT_FOUND, key_metadata_file) try: with open(cert_metadata_file, 'r') as f_metadata_cert: cert_metadata = f_metadata_cert.read() except IOError: raise OneLogin_Saml2_Error( 'Public cert file not readable: %s', OneLogin_Saml2_Error.PUBLIC_CERT_FILE_NOT_FOUND, cert_metadata_file) signature_algorithm = self._OneLogin_Saml2_Settings__security[ 'signatureAlgorithm'] digest_algorithm = self._OneLogin_Saml2_Settings__security[ 'digestAlgorithm'] metadata = OneLogin_Saml2_Metadata.sign_metadata( metadata, key_metadata, cert_metadata, signature_algorithm, digest_algorithm) ## fix signature element position #parsedMetadata = xml.etree.ElementTree.fromstring(metadata) #if parsedMetadata.find('{http://www.w3.org/2000/09/xmldsig#}Signature') == None: # for i, j in enumerate(parsedMetadata): # if j.find('{http://www.w3.org/2000/09/xmldsig#}Signature') != None: # signature = j.find('{http://www.w3.org/2000/09/xmldsig#}Signature') # parsedMetadata[i].remove(signature) # parsedMetadata.insert(0, signature) # break # metadata = xml.etree.ElementTree.tostring(parsedMetadata) return metadata