def __init__(self, **kwargs): super().__init__(**kwargs) if self.auto_IdP_metadata: idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote( self.auto_IdP_metadata) self.saml_settings = OneLogin_Saml2_IdPMetadataParser.merge_settings( self.saml_settings, idp_data)
def testMergeSettings(self): """ Tests the merge_settings method of the OneLogin_Saml2_IdPMetadataParser """ with self.assertRaises(AttributeError): settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings(None, {}) with self.assertRaises(TypeError): settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings({}, None) xml_idp_metadata = self.file_contents(join(self.data_path, 'metadata', 'idp_metadata.xml')) data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata) settings = self.loadSettingsJSON() settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings(settings, data) expected_data = {u'sp': {'NameIDFormat': 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'}, u'idp': {'singleLogoutService': {'url': 'https://app.onelogin.com/trust/saml2/http-post/sso/383123'}, 'entityId': 'https://app.onelogin.com/saml/metadata/383123', 'x509cert': 'MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzET\nMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYD\nVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbTAeFw0xMzA2\nMDUxNzE2MjBaFw0xODA2MDUxNzE2MjBaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQI\nDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9u\nZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEAse8rnep4qL2GmhH10pMQyJ2Jae+AQHyfgVjaQZ7Z\n0QQog5jX91vcJRSMi0XWJnUtOr6lF0dq1+yckjZ92wyLrH+7fvngNO1aV4Mjk9sT\ngf+iqMrae6y6fRxDt9PXrEFVjvd3vv7QTJf2FuIPy4vVP06Dt8EMkQIr8rmLmU0m\nTr1k2DkrdtdlCuNFTXuAu3QqfvNCRrRwfNObn9MP6JeOUdcGLJsBjGF8exfcN1SF\nzRF0JFr3dmOlx761zK5liD0T1sYWnDquatj/JD9fZMbKecBKni1NglH/LVd+b6aJ\nUAr5LulERULUjLqYJRKW31u91/4Qazdo9tbvwqyFxaoUrwIDAQABo4HUMIHRMAwG\nA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPWcXvQSlTXnzZD2xziuoUvrrDedMIGRBgNV\nHSMEgYkwgYaAFPWcXvQSlTXnzZD2xziuoUvrrDedoWukaTBnMQswCQYDVQQGEwJV\nUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREw\nDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbYIBATAO\nBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADggEBAB/8xe3rzqXQVxzHyAHu\nAuPa73ClDoL1cko0Fp8CGcqEIyj6Te9gx5z6wyfv+Lo8RFvBLlnB1lXqbC+fTGcV\ngG/4oKLJ5UwRFxInqpZPnOAudVNnd0PYOODn9FWs6u+OTIQIaIcPUv3MhB9lwHIJ\nsTk/bs9xcru5TPyLIxLLd6ib/pRceKH2mTkzUd0DYk9CQNXXeoGx/du5B9nh3ClP\nTbVakRzl3oswgI5MQIphYxkW70SopEh4kOFSRE1ND31NNIq1YrXlgtkguQBFsZWu\nQOPR6cEwFZzP0tHTYbI839WgxX6hfhIUTUz6mLqq4+3P4BG3+1OXeVDg63y8Uh78\n1sE='}, u'strict': False, u'contactPerson': {u'technical': {u'givenName': u'technical_name', u'emailAddress': u'*****@*****.**'}, u'support': {u'givenName': u'support_name', u'emailAddress': u'*****@*****.**'}}, u'debug': False, u'organization': {u'en-US': {u'url': u'http://sp.example.com', u'displayname': u'SP test', u'name': u'sp_test'}}, u'security': {u'signMetadata': False, u'wantAssertionsSigned': False, u'authnRequestsSigned': False}, u'custom_base_path': u'../../../tests/data/customPath/'} self.assertEqual(expected_data, settings_result) expected_data2 = {'sp': {u'singleLogoutService': {u'url': u'http://stuff.com/endpoints/endpoints/sls.php'}, u'assertionConsumerService': {u'url': u'http://stuff.com/endpoints/endpoints/acs.php'}, u'entityId': u'http://stuff.com/endpoints/metadata.php', u'NameIDFormat': u'urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified'}, 'idp': {u'singleLogoutService': {u'url': u'http://idp.example.com/SingleLogoutService.php'}, u'entityId': u'http://idp.example.com/', u'x509cert': u'MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo', u'singleSignOnService': {u'url': u'http://idp.example.com/SSOService.php'}}, u'strict': False, u'contactPerson': {u'technical': {u'givenName': u'technical_name', u'emailAddress': u'*****@*****.**'}, u'support': {u'givenName': u'support_name', u'emailAddress': u'*****@*****.**'}}, u'debug': False, u'organization': {u'en-US': {u'url': u'http://sp.example.com', u'displayname': u'SP test', u'name': u'sp_test'}}, u'security': {u'signMetadata': False, u'wantAssertionsSigned': False, u'authnRequestsSigned': False}, u'custom_base_path': u'../../../tests/data/customPath/'} settings_result2 = OneLogin_Saml2_IdPMetadataParser.merge_settings(data, settings) self.assertEqual(expected_data2, settings_result2)
def _set_saml_settings(cmd, sp_x_509_cert, sp_private_key, has_sp_cert): ceph_dashboard_base_url = cmd['ceph_dashboard_base_url'] idp_metadata = cmd['idp_metadata'] idp_username_attribute = _get_optional_attr( cmd, 'idp_username_attribute', 'uid') idp_entity_id = _get_optional_attr(cmd, 'idp_entity_id', None) idp_settings = _parse_saml_settings(idp_metadata, idp_entity_id) url_prefix = prepare_url_prefix( mgr.get_module_option('url_prefix', default='')) settings = { 'sp': { 'entityId': '{}{}/auth/saml2/metadata'.format(ceph_dashboard_base_url, url_prefix), 'assertionConsumerService': { 'url': '{}{}/auth/saml2'.format(ceph_dashboard_base_url, url_prefix), 'binding': "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, 'attributeConsumingService': { 'serviceName': "Ceph Dashboard", "serviceDescription": "Ceph Dashboard Service", "requestedAttributes": [ { "name": idp_username_attribute, "isRequired": True } ] }, 'singleLogoutService': { 'url': '{}{}/auth/saml2/logout'.format(ceph_dashboard_base_url, url_prefix), 'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' }, "x509cert": sp_x_509_cert, "privateKey": sp_private_key }, 'security': { "nameIdEncrypted": has_sp_cert, "authnRequestsSigned": has_sp_cert, "logoutRequestSigned": has_sp_cert, "logoutResponseSigned": has_sp_cert, "signMetadata": has_sp_cert, "wantMessagesSigned": has_sp_cert, "wantAssertionsSigned": has_sp_cert, "wantAssertionsEncrypted": has_sp_cert, # Not all Identity Providers support this. "wantNameIdEncrypted": False, "metadataValidUntil": '', "wantAttributeStatement": False } } settings = Saml2Parser.merge_settings(settings, idp_settings) mgr.SSO_DB.saml2.onelogin_settings = settings mgr.SSO_DB.protocol = 'saml2' mgr.SSO_DB.save()
def fetch_settings(app): json_filename = app['SSO_CONFIG_FOLDER'] + '/settings.json' json_data_file = open(json_filename, 'r') settings_base = json.load(json_data_file) json_data_file.close() idp_filename = app['SSO_CONFIG_FOLDER'] + '/idp.xml' idp_data_file = open(idp_filename, 'r') idp_data = OneLogin_Saml2_IdPMetadataParser.parse(idp_data_file.read()) idp_data_file.close() settings = OneLogin_Saml2_IdPMetadataParser.merge_settings( settings_base, idp_data) app['saml_settings'] = settings
def initialize(self, *args, **kwargs): super().initialize(*args, **kwargs) self.log.info("Initializing AuthHub") self.parse_command_line(*args, **kwargs) if self.generate_config: return self.log.info("Loading config") self.load_config_file(self.config_file) if self.auto_IdP_metadata: self.log.info("Getting the IdP metadata.") idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote( self.auto_IdP_metadata) self.saml_settings = OneLogin_Saml2_IdPMetadataParser.merge_settings( self.saml_settings, idp_data) self.init_logging() self.init_db() self.init_secrets() self.init_handlers() self.init_tornado_settings() self.init_tornado()
def _get_saml_settings(): # load settings from environment settings = current_app.config.get('SAML_SETTINGS') # if settings doesn't exist and a file is provided, load the file settings_file = current_app.config.get('SAML_SETTINGS_FILE') if not settings and settings_file: with open(settings_file, 'r') as json_data_file: settings = json.load(json_data_file) # if saml metadata url is provided, load idp settings via metadata idp_metadata_url = current_app.config.get('SAML_METADATA_URL') idp_metadata_entity_id = current_app.config.get('SAML_METADATA_ENTITY_ID', None) if idp_metadata_url: idp_settings = OneLogin_Saml2_IdPMetadataParser.parse_remote( idp_metadata_url, entity_id=idp_metadata_entity_id) settings = OneLogin_Saml2_IdPMetadataParser.merge_settings( settings, idp_settings) return settings
def _get_saml_settings(): # load settings from environment settings = current_app.config.get('SAML_SETTINGS') # if settings doesn't exist and a file is provided, load the file settings_file = current_app.config.get('SAML_SETTINGS_FILE') if not settings and settings_file: with open(settings_file, 'r') as json_data_file: settings = json.load(json_data_file) # if saml metadata url is provided, load idp settings via metadata idp_metadata_url = current_app.config.get('SAML_METADATA_URL') idp_metadata_entity_id = current_app.config.get('SAML_METADATA_ENTITY_ID', None) if idp_metadata_url: idp_settings = OneLogin_Saml2_IdPMetadataParser.parse_remote( idp_metadata_url, entity_id=idp_metadata_entity_id ) settings = OneLogin_Saml2_IdPMetadataParser.merge_settings(settings, idp_settings) return settings
def test_merge_settings(self): """ Tests the merge_settings method of the OneLogin_Saml2_IdPMetadataParser """ with self.assertRaises(TypeError): settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings( None, {}) with self.assertRaises(TypeError): settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings( {}, None) xml_idp_metadata = self.file_contents( join(self.data_path, 'metadata', 'idp_metadata.xml')) # Parse XML metadata. data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata) # Read base settings. settings = self.loadSettingsJSON() # Merge settings from XML metadata into base settings, # let XML metadata have priority if there are conflicting # attributes. settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings( settings, data) # Generate readable JSON representation: # print("%s" % json.dumps(settings_result, indent=2) expected_settings_json = """ { "custom_base_path": "../../../tests/data/customPath/", "contactPerson": { "support": { "emailAddress": "*****@*****.**", "givenName": "support_name" }, "technical": { "emailAddress": "*****@*****.**", "givenName": "technical_name" } }, "idp": { "singleSignOnService": { "url": "https://app.onelogin.com/trust/saml2/http-post/sso/383123", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "entityId": "https://app.onelogin.com/saml/metadata/383123", "singleLogoutService": { "url": "http://idp.example.com/SingleLogoutService.php" }, "x509cert": "MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbTAeFw0xMzA2MDUxNzE2MjBaFw0xODA2MDUxNzE2MjBaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAse8rnep4qL2GmhH10pMQyJ2Jae+AQHyfgVjaQZ7Z0QQog5jX91vcJRSMi0XWJnUtOr6lF0dq1+yckjZ92wyLrH+7fvngNO1aV4Mjk9sTgf+iqMrae6y6fRxDt9PXrEFVjvd3vv7QTJf2FuIPy4vVP06Dt8EMkQIr8rmLmU0mTr1k2DkrdtdlCuNFTXuAu3QqfvNCRrRwfNObn9MP6JeOUdcGLJsBjGF8exfcN1SFzRF0JFr3dmOlx761zK5liD0T1sYWnDquatj/JD9fZMbKecBKni1NglH/LVd+b6aJUAr5LulERULUjLqYJRKW31u91/4Qazdo9tbvwqyFxaoUrwIDAQABo4HUMIHRMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPWcXvQSlTXnzZD2xziuoUvrrDedMIGRBgNVHSMEgYkwgYaAFPWcXvQSlTXnzZD2xziuoUvrrDedoWukaTBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbYIBATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADggEBAB/8xe3rzqXQVxzHyAHuAuPa73ClDoL1cko0Fp8CGcqEIyj6Te9gx5z6wyfv+Lo8RFvBLlnB1lXqbC+fTGcVgG/4oKLJ5UwRFxInqpZPnOAudVNnd0PYOODn9FWs6u+OTIQIaIcPUv3MhB9lwHIJsTk/bs9xcru5TPyLIxLLd6ib/pRceKH2mTkzUd0DYk9CQNXXeoGx/du5B9nh3ClPTbVakRzl3oswgI5MQIphYxkW70SopEh4kOFSRE1ND31NNIq1YrXlgtkguQBFsZWuQOPR6cEwFZzP0tHTYbI839WgxX6hfhIUTUz6mLqq4+3P4BG3+1OXeVDg63y8Uh781sE=" }, "sp": { "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "entityId": "http://stuff.com/endpoints/metadata.php", "assertionConsumerService": { "url": "http://stuff.com/endpoints/endpoints/acs.php" }, "singleLogoutService": { "url": "http://stuff.com/endpoints/endpoints/sls.php" } }, "security": { "wantAssertionsSigned": false, "authnRequestsSigned": false, "signMetadata": false }, "debug": false, "organization": { "en-US": { "displayname": "SP test", "url": "http://sp.example.com", "name": "sp_test" } }, "strict": false } """ expected_settings = json.loads(expected_settings_json) self.assertEqual(expected_settings, settings_result) # Commute merge operation. As the order determines which settings # dictionary has priority, here we expect a different result. settings_result2 = OneLogin_Saml2_IdPMetadataParser.merge_settings( data, settings) expected_settings2_json = """ { "debug": false, "idp": { "singleLogoutService": { "url": "http://idp.example.com/SingleLogoutService.php" }, "singleSignOnService": { "url": "http://idp.example.com/SSOService.php", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "entityId": "http://idp.example.com/", "x509cert": "MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo" }, "security": { "authnRequestsSigned": false, "wantAssertionsSigned": false, "signMetadata": false }, "contactPerson": { "technical": { "emailAddress": "*****@*****.**", "givenName": "technical_name" }, "support": { "emailAddress": "*****@*****.**", "givenName": "support_name" } }, "strict": false, "sp": { "singleLogoutService": { "url": "http://stuff.com/endpoints/endpoints/sls.php" }, "assertionConsumerService": { "url": "http://stuff.com/endpoints/endpoints/acs.php" }, "entityId": "http://stuff.com/endpoints/metadata.php", "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" }, "custom_base_path": "../../../tests/data/customPath/", "organization": { "en-US": { "displayname": "SP test", "url": "http://sp.example.com", "name": "sp_test" } } } """ expected_settings2 = json.loads(expected_settings2_json) self.assertEqual(expected_settings2, settings_result2) # Test merging multiple certs xml_idp_metadata = self.file_contents( join(self.data_path, 'metadata', 'idp_metadata_multi_certs.xml')) data3 = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata) settings_result3 = OneLogin_Saml2_IdPMetadataParser.merge_settings( settings, data3) expected_settings3_json = """ { "debug": false, "strict": false, "custom_base_path": "../../../tests/data/customPath/", "sp": { "singleLogoutService": { "url": "http://stuff.com/endpoints/endpoints/sls.php" }, "assertionConsumerService": { "url": "http://stuff.com/endpoints/endpoints/acs.php" }, "entityId": "http://stuff.com/endpoints/metadata.php", "NameIDFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" }, "idp": { "singleLogoutService": { "url": "https://idp.examle.com/saml/slo", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "x509certMulti": { "encryption": [ "MIIEZTCCA02gAwIBAgIUPyy/A3bZAZ4m28PzEUUoT7RJhxIwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UEBhMCVVMxKzApBgNVBAoMIk9uZUxvZ2luIFRlc3QgKHNnYXJjaWEtdXMtcHJlcHJvZCkxFTATBgNVBAsMDE9uZUxvZ2luIElkUDEfMB0GA1UEAwwWT25lTG9naW4gQWNjb3VudCA4OTE0NjAeFw0xNjA4MDQyMjI5MzdaFw0yMTA4MDUyMjI5MzdaMHIxCzAJBgNVBAYTAlVTMSswKQYDVQQKDCJPbmVMb2dpbiBUZXN0IChzZ2FyY2lhLXVzLXByZXByb2QpMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgODkxNDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDN6iqQGcLOCglNO42I2rkzE05UXSiMXT6c8ALThMMiaDw6qqzo3sd/tKK+NcNKWLIIC8TozWVyh5ykUiVZps+08xil7VsTU7E+wKu3kvmOsvw2wlRwtnoKZJwYhnr+RkBa+h1r3ZYUgXm1ZPeHMKj1g18KaWz9+MxYL6BhKqrOzfW/P2xxVRcFH7/pq+ZsDdgNzD2GD+apzY4MZyZj/N6BpBWJ0GlFsmtBegpbX3LBitJuFkk5L4/U/jjF1AJa3boBdCUVfATqO5G03H4XS1GySjBIRQXmlUF52rLjg6xCgWJ30/+t1X+IHLJeixiQ0vxyh6C4/usCEt94cgD1r8ADAgMBAAGjgfIwge8wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUPW0DcH0G3IwynWgi74co4wZ6n7gwga8GA1UdIwSBpzCBpIAUPW0DcH0G3IwynWgi74co4wZ6n7ihdqR0MHIxCzAJBgNVBAYTAlVTMSswKQYDVQQKDCJPbmVMb2dpbiBUZXN0IChzZ2FyY2lhLXVzLXByZXByb2QpMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgODkxNDaCFD8svwN22QGeJtvD8xFFKE+0SYcSMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUFAAOCAQEAQhB4q9jrycwbHrDSoYR1X4LFFzvJ9Us75wQquRHXpdyS9D6HUBXMGI6ahPicXCQrfLgN8vzMIiqZqfySXXv/8/dxe/X4UsWLYKYJHDJmxXD5EmWTa65chjkeP1oJAc8f3CKCpcP2lOBTthbnk2fEVAeLHR4xNdQO0VvGXWO9BliYPpkYqUIBvlm+Fg9mF7AM/Uagq2503XXIE1Lq//HON68P10vNMwLSKOtYLsoTiCnuIKGJqG37MsZVjQ1ZPRcO+LSLkq0i91gFxrOrVCrgztX4JQi5XkvEsYZGIXXjwHqxTVyt3adZWQO0LPxPqRiUqUzyhDhLo/xXNrHCu4VbMw==" ], "signing": [ "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" ] }, "entityId": "https://idp.examle.com/saml/metadata", "singleSignOnService": { "url": "https://idp.examle.com/saml/sso", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" } }, "security": { "authnRequestsSigned": false, "wantAssertionsSigned": false, "signMetadata": false }, "contactPerson": { "technical": { "emailAddress": "*****@*****.**", "givenName": "technical_name" }, "support": { "emailAddress": "*****@*****.**", "givenName": "support_name" } }, "organization": { "en-US": { "displayname": "SP test", "url": "http://sp.example.com", "name": "sp_test" } } } """ expected_settings3 = json.loads(expected_settings3_json) self.assertEqual(expected_settings3, settings_result3)
def testMergeSettings(self): """ Tests the merge_settings method of the OneLogin_Saml2_IdPMetadataParser """ with self.assertRaises(AttributeError): settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings( None, {}) with self.assertRaises(TypeError): settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings( {}, None) xml_idp_metadata = self.file_contents( join(self.data_path, 'metadata', 'idp_metadata.xml')) data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata) settings = self.loadSettingsJSON() settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings( settings, data) expected_data = { u'sp': { 'NameIDFormat': 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress' }, u'idp': { 'singleLogoutService': { 'url': 'https://app.onelogin.com/trust/saml2/http-post/sso/383123' }, 'entityId': 'https://app.onelogin.com/saml/metadata/383123', 'x509cert': 'MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzET\nMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYD\nVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbTAeFw0xMzA2\nMDUxNzE2MjBaFw0xODA2MDUxNzE2MjBaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQI\nDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9u\nZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEAse8rnep4qL2GmhH10pMQyJ2Jae+AQHyfgVjaQZ7Z\n0QQog5jX91vcJRSMi0XWJnUtOr6lF0dq1+yckjZ92wyLrH+7fvngNO1aV4Mjk9sT\ngf+iqMrae6y6fRxDt9PXrEFVjvd3vv7QTJf2FuIPy4vVP06Dt8EMkQIr8rmLmU0m\nTr1k2DkrdtdlCuNFTXuAu3QqfvNCRrRwfNObn9MP6JeOUdcGLJsBjGF8exfcN1SF\nzRF0JFr3dmOlx761zK5liD0T1sYWnDquatj/JD9fZMbKecBKni1NglH/LVd+b6aJ\nUAr5LulERULUjLqYJRKW31u91/4Qazdo9tbvwqyFxaoUrwIDAQABo4HUMIHRMAwG\nA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPWcXvQSlTXnzZD2xziuoUvrrDedMIGRBgNV\nHSMEgYkwgYaAFPWcXvQSlTXnzZD2xziuoUvrrDedoWukaTBnMQswCQYDVQQGEwJV\nUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREw\nDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbYIBATAO\nBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADggEBAB/8xe3rzqXQVxzHyAHu\nAuPa73ClDoL1cko0Fp8CGcqEIyj6Te9gx5z6wyfv+Lo8RFvBLlnB1lXqbC+fTGcV\ngG/4oKLJ5UwRFxInqpZPnOAudVNnd0PYOODn9FWs6u+OTIQIaIcPUv3MhB9lwHIJ\nsTk/bs9xcru5TPyLIxLLd6ib/pRceKH2mTkzUd0DYk9CQNXXeoGx/du5B9nh3ClP\nTbVakRzl3oswgI5MQIphYxkW70SopEh4kOFSRE1ND31NNIq1YrXlgtkguQBFsZWu\nQOPR6cEwFZzP0tHTYbI839WgxX6hfhIUTUz6mLqq4+3P4BG3+1OXeVDg63y8Uh78\n1sE=' }, u'strict': False, u'contactPerson': { u'technical': { u'givenName': u'technical_name', u'emailAddress': u'*****@*****.**' }, u'support': { u'givenName': u'support_name', u'emailAddress': u'*****@*****.**' } }, u'debug': False, u'organization': { u'en-US': { u'url': u'http://sp.example.com', u'displayname': u'SP test', u'name': u'sp_test' } }, u'security': { u'signMetadata': False, u'wantAssertionsSigned': False, u'authnRequestsSigned': False }, u'custom_base_path': u'../../../tests/data/customPath/' } self.assertEqual(expected_data, settings_result) expected_data2 = { 'sp': { u'singleLogoutService': { u'url': u'http://stuff.com/endpoints/endpoints/sls.php' }, u'assertionConsumerService': { u'url': u'http://stuff.com/endpoints/endpoints/acs.php' }, u'entityId': u'http://stuff.com/endpoints/metadata.php', u'NameIDFormat': u'urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified' }, 'idp': { u'singleLogoutService': { u'url': u'http://idp.example.com/SingleLogoutService.php' }, u'entityId': u'http://idp.example.com/', u'x509cert': u'MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo', u'singleSignOnService': { u'url': u'http://idp.example.com/SSOService.php' } }, u'strict': False, u'contactPerson': { u'technical': { u'givenName': u'technical_name', u'emailAddress': u'*****@*****.**' }, u'support': { u'givenName': u'support_name', u'emailAddress': u'*****@*****.**' } }, u'debug': False, u'organization': { u'en-US': { u'url': u'http://sp.example.com', u'displayname': u'SP test', u'name': u'sp_test' } }, u'security': { u'signMetadata': False, u'wantAssertionsSigned': False, u'authnRequestsSigned': False }, u'custom_base_path': u'../../../tests/data/customPath/' } settings_result2 = OneLogin_Saml2_IdPMetadataParser.merge_settings( data, settings) self.assertEqual(expected_data2, settings_result2)
def handle_sso_command(cmd): if cmd['prefix'] not in ['dashboard sso enable saml2', 'dashboard sso disable', 'dashboard sso status', 'dashboard sso show saml2', 'dashboard sso setup saml2']: return -errno.ENOSYS, '', '' if not python_saml_imported: python_saml_name = 'python3-saml' if sys.version_info >= (3, 0) else 'python-saml' return -errno.EPERM, '', 'Required library not found: `{}`'.format(python_saml_name) if cmd['prefix'] == 'dashboard sso enable saml2': try: OneLogin_Saml2_Settings(SSO_DB.saml2.onelogin_settings) except OneLogin_Saml2_Error: return -errno.EPERM, '', 'Single Sign-On is not configured: ' \ 'use `ceph dashboard sso setup saml2`' SSO_DB.protocol = 'saml2' SSO_DB.save() return 0, 'SSO is "enabled" with "SAML2" protocol.', '' if cmd['prefix'] == 'dashboard sso disable': SSO_DB.protocol = '' SSO_DB.save() return 0, 'SSO is "disabled".', '' if cmd['prefix'] == 'dashboard sso status': if SSO_DB.protocol == 'saml2': return 0, 'SSO is "enabled" with "SAML2" protocol.', '' return 0, 'SSO is "disabled".', '' if cmd['prefix'] == 'dashboard sso show saml2': return 0, json.dumps(SSO_DB.saml2.to_dict()), '' if cmd['prefix'] == 'dashboard sso setup saml2': ceph_dashboard_base_url = cmd['ceph_dashboard_base_url'] idp_metadata = cmd['idp_metadata'] idp_username_attribute = _get_optional_attr(cmd, 'idp_username_attribute', 'uid') idp_entity_id = _get_optional_attr(cmd, 'idp_entity_id', None) sp_x_509_cert = _get_optional_attr(cmd, 'sp_x_509_cert', '') sp_private_key = _get_optional_attr(cmd, 'sp_private_key', '') if sp_x_509_cert and not sp_private_key: return -errno.EINVAL, '', 'Missing parameter `sp_private_key`.' if not sp_x_509_cert and sp_private_key: return -errno.EINVAL, '', 'Missing parameter `sp_x_509_cert`.' has_sp_cert = sp_x_509_cert != "" and sp_private_key != "" try: # pylint: disable=undefined-variable FileNotFoundError except NameError: # pylint: disable=redefined-builtin FileNotFoundError = IOError try: f = open(sp_x_509_cert, 'r') sp_x_509_cert = f.read() f.close() except FileNotFoundError: pass try: f = open(sp_private_key, 'r') sp_private_key = f.read() f.close() except FileNotFoundError: pass try: idp_settings = OneLogin_Saml2_IdPMetadataParser.parse_remote(idp_metadata, validate_cert=False, entity_id=idp_entity_id) # pylint: disable=broad-except except Exception: try: f = open(idp_metadata, 'r') idp_metadata = f.read() f.close() except FileNotFoundError: pass try: idp_settings = OneLogin_Saml2_IdPMetadataParser.parse(idp_metadata, entity_id=idp_entity_id) # pylint: disable=broad-except except Exception: return -errno.EINVAL, '', 'Invalid parameter `idp_metadata`.' url_prefix = prepare_url_prefix(mgr.get_config('url_prefix', default='')) settings = { 'sp': { 'entityId': '{}{}/auth/saml2/metadata'.format(ceph_dashboard_base_url, url_prefix), 'assertionConsumerService': { 'url': '{}{}/auth/saml2'.format(ceph_dashboard_base_url, url_prefix), 'binding': "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, 'attributeConsumingService': { 'serviceName': "Ceph Dashboard", "serviceDescription": "Ceph Dashboard Service", "requestedAttributes": [ { "name": idp_username_attribute, "isRequired": True } ] }, 'singleLogoutService': { 'url': '{}{}/auth/saml2/logout'.format(ceph_dashboard_base_url, url_prefix), 'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' }, "x509cert": sp_x_509_cert, "privateKey": sp_private_key }, 'security': { "nameIdEncrypted": has_sp_cert, "authnRequestsSigned": has_sp_cert, "logoutRequestSigned": has_sp_cert, "logoutResponseSigned": has_sp_cert, "signMetadata": has_sp_cert, "wantMessagesSigned": has_sp_cert, "wantAssertionsSigned": has_sp_cert, "wantAssertionsEncrypted": has_sp_cert, "wantNameIdEncrypted": has_sp_cert, "metadataValidUntil": '', "wantAttributeStatement": False } } settings = OneLogin_Saml2_IdPMetadataParser.merge_settings(settings, idp_settings) SSO_DB.saml2.onelogin_settings = settings SSO_DB.protocol = 'saml2' SSO_DB.save() return 0, json.dumps(SSO_DB.saml2.onelogin_settings), '' return -errno.ENOSYS, '', ''
def test_merge_settings(self): """ Tests the merge_settings method of the OneLogin_Saml2_IdPMetadataParser """ with self.assertRaises(TypeError): settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings(None, {}) with self.assertRaises(TypeError): settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings({}, None) xml_idp_metadata = self.file_contents(join(self.data_path, 'metadata', 'idp_metadata.xml')) # Parse XML metadata. data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata) # Read base settings. settings = self.loadSettingsJSON() # Merge settings from XML metadata into base settings, # let XML metadata have priority if there are conflicting # attributes. settings_result = OneLogin_Saml2_IdPMetadataParser.merge_settings(settings, data) # Generate readable JSON representation: # print("%s" % json.dumps(settings_result, indent=2).replace(r'\n', r'\\n')) expected_settings_json = """ { "custom_base_path": "../../../tests/data/customPath/", "contactPerson": { "support": { "emailAddress": "*****@*****.**", "givenName": "support_name" }, "technical": { "emailAddress": "*****@*****.**", "givenName": "technical_name" } }, "idp": { "singleSignOnService": { "url": "https://app.onelogin.com/trust/saml2/http-post/sso/383123", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "entityId": "https://app.onelogin.com/saml/metadata/383123", "singleLogoutService": { "url": "http://idp.example.com/SingleLogoutService.php" }, "x509cert": "MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbTAeFw0xMzA2MDUxNzE2MjBaFw0xODA2MDUxNzE2MjBaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAse8rnep4qL2GmhH10pMQyJ2Jae+AQHyfgVjaQZ7Z0QQog5jX91vcJRSMi0XWJnUtOr6lF0dq1+yckjZ92wyLrH+7fvngNO1aV4Mjk9sTgf+iqMrae6y6fRxDt9PXrEFVjvd3vv7QTJf2FuIPy4vVP06Dt8EMkQIr8rmLmU0mTr1k2DkrdtdlCuNFTXuAu3QqfvNCRrRwfNObn9MP6JeOUdcGLJsBjGF8exfcN1SFzRF0JFr3dmOlx761zK5liD0T1sYWnDquatj/JD9fZMbKecBKni1NglH/LVd+b6aJUAr5LulERULUjLqYJRKW31u91/4Qazdo9tbvwqyFxaoUrwIDAQABo4HUMIHRMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPWcXvQSlTXnzZD2xziuoUvrrDedMIGRBgNVHSMEgYkwgYaAFPWcXvQSlTXnzZD2xziuoUvrrDedoWukaTBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbYIBATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADggEBAB/8xe3rzqXQVxzHyAHuAuPa73ClDoL1cko0Fp8CGcqEIyj6Te9gx5z6wyfv+Lo8RFvBLlnB1lXqbC+fTGcVgG/4oKLJ5UwRFxInqpZPnOAudVNnd0PYOODn9FWs6u+OTIQIaIcPUv3MhB9lwHIJsTk/bs9xcru5TPyLIxLLd6ib/pRceKH2mTkzUd0DYk9CQNXXeoGx/du5B9nh3ClPTbVakRzl3oswgI5MQIphYxkW70SopEh4kOFSRE1ND31NNIq1YrXlgtkguQBFsZWuQOPR6cEwFZzP0tHTYbI839WgxX6hfhIUTUz6mLqq4+3P4BG3+1OXeVDg63y8Uh781sE=" }, "sp": { "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "entityId": "http://stuff.com/endpoints/metadata.php", "assertionConsumerService": { "url": "http://stuff.com/endpoints/endpoints/acs.php" }, "singleLogoutService": { "url": "http://stuff.com/endpoints/endpoints/sls.php" } }, "security": { "wantAssertionsSigned": false, "authnRequestsSigned": false, "signMetadata": false }, "debug": false, "organization": { "en-US": { "displayname": "SP test", "url": "http://sp.example.com", "name": "sp_test" } }, "strict": false } """ expected_settings = json.loads(expected_settings_json) self.assertEqual(expected_settings, settings_result) # Commute merge operation. As the order determines which settings # dictionary has priority, here we expect a different result. settings_result2 = OneLogin_Saml2_IdPMetadataParser.merge_settings(data, settings) expected_settings2_json = """ { "debug": false, "idp": { "singleLogoutService": { "url": "http://idp.example.com/SingleLogoutService.php" }, "singleSignOnService": { "url": "http://idp.example.com/SSOService.php", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "entityId": "http://idp.example.com/", "x509cert": "MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo" }, "security": { "authnRequestsSigned": false, "wantAssertionsSigned": false, "signMetadata": false }, "contactPerson": { "technical": { "emailAddress": "*****@*****.**", "givenName": "technical_name" }, "support": { "emailAddress": "*****@*****.**", "givenName": "support_name" } }, "strict": false, "sp": { "singleLogoutService": { "url": "http://stuff.com/endpoints/endpoints/sls.php" }, "assertionConsumerService": { "url": "http://stuff.com/endpoints/endpoints/acs.php" }, "entityId": "http://stuff.com/endpoints/metadata.php", "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" }, "custom_base_path": "../../../tests/data/customPath/", "organization": { "en-US": { "displayname": "SP test", "url": "http://sp.example.com", "name": "sp_test" } } } """ expected_settings2 = json.loads(expected_settings2_json) self.assertEqual(expected_settings2, settings_result2) # Test merging multiple certs xml_idp_metadata = self.file_contents(join(self.data_path, 'metadata', 'idp_metadata_multi_certs.xml')) data3 = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata) settings_result3 = OneLogin_Saml2_IdPMetadataParser.merge_settings(settings, data3) expected_settings3_json = """ { "debug": false, "strict": false, "custom_base_path": "../../../tests/data/customPath/", "sp": { "singleLogoutService": { "url": "http://stuff.com/endpoints/endpoints/sls.php" }, "assertionConsumerService": { "url": "http://stuff.com/endpoints/endpoints/acs.php" }, "entityId": "http://stuff.com/endpoints/metadata.php", "NameIDFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" }, "idp": { "singleLogoutService": { "url": "https://idp.examle.com/saml/slo", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, "x509certMulti": { "encryption": [ "MIIEZTCCA02gAwIBAgIUPyy/A3bZAZ4m28PzEUUoT7RJhxIwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UEBhMCVVMxKzApBgNVBAoMIk9uZUxvZ2luIFRlc3QgKHNnYXJjaWEtdXMtcHJlcHJvZCkxFTATBgNVBAsMDE9uZUxvZ2luIElkUDEfMB0GA1UEAwwWT25lTG9naW4gQWNjb3VudCA4OTE0NjAeFw0xNjA4MDQyMjI5MzdaFw0yMTA4MDUyMjI5MzdaMHIxCzAJBgNVBAYTAlVTMSswKQYDVQQKDCJPbmVMb2dpbiBUZXN0IChzZ2FyY2lhLXVzLXByZXByb2QpMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgODkxNDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDN6iqQGcLOCglNO42I2rkzE05UXSiMXT6c8ALThMMiaDw6qqzo3sd/tKK+NcNKWLIIC8TozWVyh5ykUiVZps+08xil7VsTU7E+wKu3kvmOsvw2wlRwtnoKZJwYhnr+RkBa+h1r3ZYUgXm1ZPeHMKj1g18KaWz9+MxYL6BhKqrOzfW/P2xxVRcFH7/pq+ZsDdgNzD2GD+apzY4MZyZj/N6BpBWJ0GlFsmtBegpbX3LBitJuFkk5L4/U/jjF1AJa3boBdCUVfATqO5G03H4XS1GySjBIRQXmlUF52rLjg6xCgWJ30/+t1X+IHLJeixiQ0vxyh6C4/usCEt94cgD1r8ADAgMBAAGjgfIwge8wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUPW0DcH0G3IwynWgi74co4wZ6n7gwga8GA1UdIwSBpzCBpIAUPW0DcH0G3IwynWgi74co4wZ6n7ihdqR0MHIxCzAJBgNVBAYTAlVTMSswKQYDVQQKDCJPbmVMb2dpbiBUZXN0IChzZ2FyY2lhLXVzLXByZXByb2QpMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgODkxNDaCFD8svwN22QGeJtvD8xFFKE+0SYcSMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUFAAOCAQEAQhB4q9jrycwbHrDSoYR1X4LFFzvJ9Us75wQquRHXpdyS9D6HUBXMGI6ahPicXCQrfLgN8vzMIiqZqfySXXv/8/dxe/X4UsWLYKYJHDJmxXD5EmWTa65chjkeP1oJAc8f3CKCpcP2lOBTthbnk2fEVAeLHR4xNdQO0VvGXWO9BliYPpkYqUIBvlm+Fg9mF7AM/Uagq2503XXIE1Lq//HON68P10vNMwLSKOtYLsoTiCnuIKGJqG37MsZVjQ1ZPRcO+LSLkq0i91gFxrOrVCrgztX4JQi5XkvEsYZGIXXjwHqxTVyt3adZWQO0LPxPqRiUqUzyhDhLo/xXNrHCu4VbMw==" ], "signing": [ "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" ] }, "entityId": "https://idp.examle.com/saml/metadata", "singleSignOnService": { "url": "https://idp.examle.com/saml/sso", "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" } }, "security": { "authnRequestsSigned": false, "wantAssertionsSigned": false, "signMetadata": false }, "contactPerson": { "technical": { "emailAddress": "*****@*****.**", "givenName": "technical_name" }, "support": { "emailAddress": "*****@*****.**", "givenName": "support_name" } }, "organization": { "en-US": { "displayname": "SP test", "url": "http://sp.example.com", "name": "sp_test" } } } """ expected_settings3 = json.loads(expected_settings3_json) self.assertEqual(expected_settings3, settings_result3)
def handle_sso_command(cmd): if cmd['prefix'] not in ['dashboard sso enable saml2', 'dashboard sso disable', 'dashboard sso status', 'dashboard sso show saml2', 'dashboard sso setup saml2']: return -errno.ENOSYS, '', '' if not python_saml_imported: return -errno.EPERM, '', 'Required library not found: `python3-saml`' if cmd['prefix'] == 'dashboard sso enable saml2': try: Saml2Settings(mgr.SSO_DB.saml2.onelogin_settings) except Saml2Error: return -errno.EPERM, '', 'Single Sign-On is not configured: ' \ 'use `ceph dashboard sso setup saml2`' mgr.SSO_DB.protocol = 'saml2' mgr.SSO_DB.save() return 0, 'SSO is "enabled" with "SAML2" protocol.', '' if cmd['prefix'] == 'dashboard sso disable': mgr.SSO_DB.protocol = '' mgr.SSO_DB.save() return 0, 'SSO is "disabled".', '' if cmd['prefix'] == 'dashboard sso status': if mgr.SSO_DB.protocol == 'saml2': return 0, 'SSO is "enabled" with "SAML2" protocol.', '' return 0, 'SSO is "disabled".', '' if cmd['prefix'] == 'dashboard sso show saml2': return 0, json.dumps(mgr.SSO_DB.saml2.to_dict()), '' if cmd['prefix'] == 'dashboard sso setup saml2': ceph_dashboard_base_url = cmd['ceph_dashboard_base_url'] idp_metadata = cmd['idp_metadata'] idp_username_attribute = _get_optional_attr(cmd, 'idp_username_attribute', 'uid') idp_entity_id = _get_optional_attr(cmd, 'idp_entity_id', None) sp_x_509_cert_path = _get_optional_attr(cmd, 'sp_x_509_cert', '') sp_private_key_path = _get_optional_attr(cmd, 'sp_private_key', '') if sp_x_509_cert_path and not sp_private_key_path: return -errno.EINVAL, '', 'Missing parameter `sp_private_key`.' if not sp_x_509_cert_path and sp_private_key_path: return -errno.EINVAL, '', 'Missing parameter `sp_x_509_cert`.' has_sp_cert = sp_x_509_cert_path != "" and sp_private_key_path != "" try: with open(sp_x_509_cert_path, 'r') as f: sp_x_509_cert = f.read() except FileNotFoundError: sp_x_509_cert = '' try: with open(sp_private_key_path, 'r') as f: sp_private_key = f.read() except FileNotFoundError: sp_private_key = '' if os.path.isfile(idp_metadata): warnings.warn( "Please prepend 'file://' to indicate a local SAML2 IdP file", DeprecationWarning) with open(idp_metadata, 'r') as f: idp_settings = Saml2Parser.parse(f.read(), entity_id=idp_entity_id) elif parse.urlparse(idp_metadata)[0] in ('http', 'https', 'file'): idp_settings = Saml2Parser.parse_remote( url=idp_metadata, validate_cert=False, entity_id=idp_entity_id) else: idp_settings = Saml2Parser.parse(idp_metadata, entity_id=idp_entity_id) url_prefix = prepare_url_prefix(mgr.get_module_option('url_prefix', default='')) settings = { 'sp': { 'entityId': '{}{}/auth/saml2/metadata'.format(ceph_dashboard_base_url, url_prefix), 'assertionConsumerService': { 'url': '{}{}/auth/saml2'.format(ceph_dashboard_base_url, url_prefix), 'binding': "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, 'attributeConsumingService': { 'serviceName': "Ceph Dashboard", "serviceDescription": "Ceph Dashboard Service", "requestedAttributes": [ { "name": idp_username_attribute, "isRequired": True } ] }, 'singleLogoutService': { 'url': '{}{}/auth/saml2/logout'.format(ceph_dashboard_base_url, url_prefix), 'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' }, "x509cert": sp_x_509_cert, "privateKey": sp_private_key }, 'security': { "nameIdEncrypted": has_sp_cert, "authnRequestsSigned": has_sp_cert, "logoutRequestSigned": has_sp_cert, "logoutResponseSigned": has_sp_cert, "signMetadata": has_sp_cert, "wantMessagesSigned": has_sp_cert, "wantAssertionsSigned": has_sp_cert, "wantAssertionsEncrypted": has_sp_cert, "wantNameIdEncrypted": has_sp_cert, "metadataValidUntil": '', "wantAttributeStatement": False } } settings = Saml2Parser.merge_settings(settings, idp_settings) mgr.SSO_DB.saml2.onelogin_settings = settings mgr.SSO_DB.protocol = 'saml2' mgr.SSO_DB.save() return 0, json.dumps(mgr.SSO_DB.saml2.onelogin_settings), '' return -errno.ENOSYS, '', ''
def handle_sso_command(cmd): if cmd['prefix'] not in [ 'dashboard sso enable saml2', 'dashboard sso disable', 'dashboard sso status', 'dashboard sso show saml2', 'dashboard sso setup saml2' ]: return -errno.ENOSYS, '', '' if not python_saml_imported: python_saml_name = 'python3-saml' if sys.version_info >= ( 3, 0) else 'python-saml' return -errno.EPERM, '', 'Required library not found: `{}`'.format( python_saml_name) if cmd['prefix'] == 'dashboard sso enable saml2': try: OneLogin_Saml2_Settings(mgr.SSO_DB.saml2.onelogin_settings) except OneLogin_Saml2_Error: return -errno.EPERM, '', 'Single Sign-On is not configured: ' \ 'use `ceph dashboard sso setup saml2`' mgr.SSO_DB.protocol = 'saml2' mgr.SSO_DB.save() return 0, 'SSO is "enabled" with "SAML2" protocol.', '' if cmd['prefix'] == 'dashboard sso disable': mgr.SSO_DB.protocol = '' mgr.SSO_DB.save() return 0, 'SSO is "disabled".', '' if cmd['prefix'] == 'dashboard sso status': if mgr.SSO_DB.protocol == 'saml2': return 0, 'SSO is "enabled" with "SAML2" protocol.', '' return 0, 'SSO is "disabled".', '' if cmd['prefix'] == 'dashboard sso show saml2': return 0, json.dumps(mgr.SSO_DB.saml2.to_dict()), '' if cmd['prefix'] == 'dashboard sso setup saml2': ceph_dashboard_base_url = cmd['ceph_dashboard_base_url'] idp_metadata = cmd['idp_metadata'] idp_username_attribute = _get_optional_attr(cmd, 'idp_username_attribute', 'uid') idp_entity_id = _get_optional_attr(cmd, 'idp_entity_id', None) sp_x_509_cert = _get_optional_attr(cmd, 'sp_x_509_cert', '') sp_private_key = _get_optional_attr(cmd, 'sp_private_key', '') if sp_x_509_cert and not sp_private_key: return -errno.EINVAL, '', 'Missing parameter `sp_private_key`.' if not sp_x_509_cert and sp_private_key: return -errno.EINVAL, '', 'Missing parameter `sp_x_509_cert`.' has_sp_cert = sp_x_509_cert != "" and sp_private_key != "" try: # pylint: disable=undefined-variable FileNotFoundError except NameError: # pylint: disable=redefined-builtin FileNotFoundError = IOError try: f = open(sp_x_509_cert, 'r', encoding='utf-8') if six.PY3 else \ open(sp_x_509_cert, 'rb') sp_x_509_cert = f.read() f.close() except FileNotFoundError: pass try: f = open(sp_private_key, 'r', encoding='utf-8') if six.PY3 else \ open(sp_private_key, 'rb') sp_private_key = f.read() f.close() except FileNotFoundError: pass try: idp_settings = OneLogin_Saml2_IdPMetadataParser.parse_remote( idp_metadata, validate_cert=False, entity_id=idp_entity_id) # pylint: disable=broad-except except Exception: try: f = open(idp_metadata, 'r', encoding='utf-8') if six.PY3 else \ open(idp_metadata, 'rb') idp_metadata = f.read() f.close() except FileNotFoundError: pass try: idp_settings = OneLogin_Saml2_IdPMetadataParser.parse( idp_metadata, entity_id=idp_entity_id) # pylint: disable=broad-except except Exception: return -errno.EINVAL, '', 'Invalid parameter `idp_metadata`.' url_prefix = prepare_url_prefix( mgr.get_module_option('url_prefix', default='')) settings = { 'sp': { 'entityId': '{}{}/auth/saml2/metadata'.format(ceph_dashboard_base_url, url_prefix), 'assertionConsumerService': { 'url': '{}{}/auth/saml2'.format(ceph_dashboard_base_url, url_prefix), 'binding': "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, 'attributeConsumingService': { 'serviceName': "Ceph Dashboard", "serviceDescription": "Ceph Dashboard Service", "requestedAttributes": [{ "name": idp_username_attribute, "isRequired": True }] }, 'singleLogoutService': { 'url': '{}{}/auth/saml2/logout'.format(ceph_dashboard_base_url, url_prefix), 'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' }, "x509cert": sp_x_509_cert, "privateKey": sp_private_key }, 'security': { "nameIdEncrypted": has_sp_cert, "authnRequestsSigned": has_sp_cert, "logoutRequestSigned": has_sp_cert, "logoutResponseSigned": has_sp_cert, "signMetadata": has_sp_cert, "wantMessagesSigned": has_sp_cert, "wantAssertionsSigned": has_sp_cert, "wantAssertionsEncrypted": has_sp_cert, "wantNameIdEncrypted": False, # Not all Identity Providers support this. "metadataValidUntil": '', "wantAttributeStatement": False } } settings = OneLogin_Saml2_IdPMetadataParser.merge_settings( settings, idp_settings) mgr.SSO_DB.saml2.onelogin_settings = settings mgr.SSO_DB.protocol = 'saml2' mgr.SSO_DB.save() return 0, json.dumps(mgr.SSO_DB.saml2.onelogin_settings), '' return -errno.ENOSYS, '', ''