def testParseRemote(self):
        """
        Tests the parse_remote method of the OneLogin_Saml2_IdPMetadataParser
        """
        with self.assertRaises(Exception):
            data = OneLogin_Saml2_IdPMetadataParser.parse_remote('http://google.es')

        try:
            data = OneLogin_Saml2_IdPMetadataParser.parse_remote('https://idp.testshib.org/idp/shibboleth')
        except URLError:
            xml = self.file_contents(join(self.data_path, 'metadata', 'testshib-providers.xml'))
            data = OneLogin_Saml2_IdPMetadataParser.parse(xml)

        self.assertTrue(data is not None and data is not {})
        expected_settings_json = """
        {
            "sp": {
                "NameIDFormat": "urn:mace:shibboleth:1.0:nameIdentifier"
            },
            "idp": {
                "x509cert": "MIIDAzCCAeugAwIBAgIVAPX0G6LuoXnKS0Muei006mVSBXbvMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNVBAMMEGlkcC50ZXN0c2hpYi5vcmcwHhcNMTYwODIzMjEyMDU0WhcNMzYwODIzMjEyMDU0WjAbMRkwFwYDVQQDDBBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg9C4J2DiRTEhJAWzPt1S3ryhm3M2P3hPpwJwvt2q948vdTUxhhvNMuc3M3S4WNh6JYBs53R+YmjqJAII4ShMGNEmlGnSVfHorex7IxikpuDPKV3SNf28mCAZbQrX+hWA+ann/uifVzqXktOjs6DdzdBnxoVhniXgC8WCJwKcx6JO/hHsH1rG/0DSDeZFpTTcZHj4S9MlLNUtt5JxRzV/MmmB3ObaX0CMqsSWUOQeE4nylSlp5RWHCnx70cs9kwz5WrflnbnzCeHU2sdbNotBEeTHot6a2cj/pXlRJIgPsrL/4VSicPZcGYMJMPoLTJ8mdy6mpR6nbCmP7dVbCIm/DQIDAQABoz4wPDAdBgNVHQ4EFgQUUfaDa2mPi24x09yWp1OFXmZ2GPswGwYDVR0RBBQwEoIQaWRwLnRlc3RzaGliLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEASKKgqTxhqBzROZ1eVy++si+eTTUQZU4+8UywSKLia2RattaAPMAcXUjO+3cYOQXLVASdlJtt+8QPdRkfp8SiJemHPXC8BES83pogJPYEGJsKo19l4XFJHPnPy+Dsn3mlJyOfAa8RyWBS80u5lrvAcr2TJXt9fXgkYs7BOCigxtZoR8flceGRlAZ4p5FPPxQR6NDYb645jtOTMVr3zgfjP6Wh2dt+2p04LG7ENJn8/gEwtXVuXCsPoSCDx9Y0QmyXTJNdV1aB0AhORkWPlFYwp+zOyOIR+3m1+pqWFpn0eT/HrxpdKa74FA3R2kq4R7dXe4G0kUgXTdqXMLRKhDgdmA==",
                "entityId": "https://idp.testshib.org/idp/shibboleth",
                "singleSignOnService": {
                    "url": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO",
                    "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                }
            }
        }
        """
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, data)
    def testParseRemote(self):
        """
        Tests the parse_remote method of the OneLogin_Saml2_IdPMetadataParser
        """
        with self.assertRaises(Exception):
            data = OneLogin_Saml2_IdPMetadataParser.parse_remote('http://google.es')

        try:
            data = OneLogin_Saml2_IdPMetadataParser.parse_remote('https://www.testshib.org/metadata/testshib-providers.xml')
        except URLError:
            xml = self.file_contents(join(self.data_path, 'metadata', 'testshib-providers.xml'))
            data = OneLogin_Saml2_IdPMetadataParser.parse(xml)

        self.assertTrue(data is not None and data is not {})
        expected_settings_json = """
        {
          "sp": {
            "NameIDFormat": "urn:mace:shibboleth:1.0:nameIdentifier"
          },
          "idp": {
            "entityId": "https://idp.testshib.org/idp/shibboleth",
            "singleSignOnService": {
              "url": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            }
          }
        }
        """
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, data)
    def test_parse_testshib_required_binding_sso_post(self):
        """
        Test with testshib metadata.
        Especially test extracting SSO with POST binding.
        """
        expected_settings_json = """
        {
          "sp": {
            "NameIDFormat": "urn:mace:shibboleth:1.0:nameIdentifier"
          },
          "idp": {
            "entityId": "https://idp.testshib.org/idp/shibboleth",
            "singleSignOnService": {
              "url": "https://idp.testshib.org/idp/profile/SAML2/POST/SSO",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
            }
          }
        }
        """
        try:
            xmldoc = OneLogin_Saml2_IdPMetadataParser.get_metadata(
                'https://www.testshib.org/metadata/testshib-providers.xml')
        except URLError:
            xmldoc = self.file_contents(join(self.data_path, 'metadata', 'testshib-providers.xml'))

        # Parse, require POST binding.
        settings = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST
        )
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, settings)
    def testParse(self):
        """
        Tests the parse method of the OneLogin_Saml2_IdPMetadataParser
        """
        with self.assertRaises(XMLSyntaxError):
            data = OneLogin_Saml2_IdPMetadataParser.parse('')

        xml_sp_metadata = self.file_contents(join(self.data_path, 'metadata', 'metadata_settings1.xml'))
        data = OneLogin_Saml2_IdPMetadataParser.parse(xml_sp_metadata)
        self.assertEqual({}, data)

        xml_idp_metadata = self.file_contents(join(self.data_path, 'metadata', 'idp_metadata.xml'))
        data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata)

        # W/o further specification, expect to get the redirect binding SSO
        # URL extracted.
        expected_settings_json = """
        {
          "idp": {
            "singleSignOnService": {
              "url": "https://app.onelogin.com/trust/saml2/http-post/sso/383123",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            },
            "x509certs": ["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="],
            "entityId": "https://app.onelogin.com/saml/metadata/383123"
          },
          "sp": {
            "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
          }
        }
        """
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, data)
    def testGetMetadata(self):
        """
        Tests the get_metadata method of the OneLogin_Saml2_IdPMetadataParser
        """
        with self.assertRaises(Exception):
            data = OneLogin_Saml2_IdPMetadataParser.get_metadata('http://google.es')

        data = OneLogin_Saml2_IdPMetadataParser.get_metadata('https://www.testshib.org/metadata/testshib-providers.xml')
        self.assertTrue(data is not None and data is not {})
    def testParseRemote(self):
        """
        Tests the parse_remote method of the OneLogin_Saml2_IdPMetadataParser
        """
        with self.assertRaises(Exception):
            data = OneLogin_Saml2_IdPMetadataParser.parse_remote('http://google.es')

        data = OneLogin_Saml2_IdPMetadataParser.parse_remote('https://www.testshib.org/metadata/testshib-providers.xml')
        self.assertTrue(data is not None and data is not {})
        expected_data = {'sp': {'NameIDFormat': 'urn:mace:shibboleth:1.0:nameIdentifier'}, 'idp': {'singleLogoutService': {'url': 'https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO'}, 'entityId': 'https://idp.testshib.org/idp/shibboleth'}}
        self.assertEqual(expected_data, data)
    def test_parse_multi_same_signing_and_encrypt_cert(self):
        """
        Tests the parse method of the OneLogin_Saml2_IdPMetadataParser
        Case: IdP metadata contains multiple signature cert and encrypt cert
              that is the same
        """
        xml_idp_metadata = self.file_contents(join(self.data_path, 'metadata', 'idp_metadata_same_sign_and_encrypt_cert.xml'))
        data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata)

        expected_settings_json = """
        {
            "sp": {
                "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
            },
            "idp": {
                "x509cert": "MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbTAeFw0xMzA2MDUxNzE2MjBaFw0xODA2MDUxNzE2MjBaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAse8rnep4qL2GmhH10pMQyJ2Jae+AQHyfgVjaQZ7Z0QQog5jX91vcJRSMi0XWJnUtOr6lF0dq1+yckjZ92wyLrH+7fvngNO1aV4Mjk9sTgf+iqMrae6y6fRxDt9PXrEFVjvd3vv7QTJf2FuIPy4vVP06Dt8EMkQIr8rmLmU0mTr1k2DkrdtdlCuNFTXuAu3QqfvNCRrRwfNObn9MP6JeOUdcGLJsBjGF8exfcN1SFzRF0JFr3dmOlx761zK5liD0T1sYWnDquatj/JD9fZMbKecBKni1NglH/LVd+b6aJUAr5LulERULUjLqYJRKW31u91/4Qazdo9tbvwqyFxaoUrwIDAQABo4HUMIHRMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPWcXvQSlTXnzZD2xziuoUvrrDedMIGRBgNVHSMEgYkwgYaAFPWcXvQSlTXnzZD2xziuoUvrrDedoWukaTBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbYIBATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADggEBAB/8xe3rzqXQVxzHyAHuAuPa73ClDoL1cko0Fp8CGcqEIyj6Te9gx5z6wyfv+Lo8RFvBLlnB1lXqbC+fTGcVgG/4oKLJ5UwRFxInqpZPnOAudVNnd0PYOODn9FWs6u+OTIQIaIcPUv3MhB9lwHIJsTk/bs9xcru5TPyLIxLLd6ib/pRceKH2mTkzUd0DYk9CQNXXeoGx/du5B9nh3ClPTbVakRzl3oswgI5MQIphYxkW70SopEh4kOFSRE1ND31NNIq1YrXlgtkguQBFsZWuQOPR6cEwFZzP0tHTYbI839WgxX6hfhIUTUz6mLqq4+3P4BG3+1OXeVDg63y8Uh781sE=",
                "entityId": "https://app.onelogin.com/saml/metadata/383123",
                "singleSignOnService": {
                    "url": "https://app.onelogin.com/trust/saml2/http-post/sso/383123",
                    "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                }
            }
        }
        """
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, data)

        xml_idp_metadata_2 = self.file_contents(join(self.data_path, 'metadata', 'idp_metadata_different_sign_and_encrypt_cert.xml'))
        data_2 = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata_2)
        expected_settings_json_2 = """
        {
            "sp": {
                "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
            },
            "idp": {
                "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": [
                        "MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbTAeFw0xMzA2MDUxNzE2MjBaFw0xODA2MDUxNzE2MjBaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAse8rnep4qL2GmhH10pMQyJ2Jae+AQHyfgVjaQZ7Z0QQog5jX91vcJRSMi0XWJnUtOr6lF0dq1+yckjZ92wyLrH+7fvngNO1aV4Mjk9sTgf+iqMrae6y6fRxDt9PXrEFVjvd3vv7QTJf2FuIPy4vVP06Dt8EMkQIr8rmLmU0mTr1k2DkrdtdlCuNFTXuAu3QqfvNCRrRwfNObn9MP6JeOUdcGLJsBjGF8exfcN1SFzRF0JFr3dmOlx761zK5liD0T1sYWnDquatj/JD9fZMbKecBKni1NglH/LVd+b6aJUAr5LulERULUjLqYJRKW31u91/4Qazdo9tbvwqyFxaoUrwIDAQABo4HUMIHRMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPWcXvQSlTXnzZD2xziuoUvrrDedMIGRBgNVHSMEgYkwgYaAFPWcXvQSlTXnzZD2xziuoUvrrDedoWukaTBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbYIBATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADggEBAB/8xe3rzqXQVxzHyAHuAuPa73ClDoL1cko0Fp8CGcqEIyj6Te9gx5z6wyfv+Lo8RFvBLlnB1lXqbC+fTGcVgG/4oKLJ5UwRFxInqpZPnOAudVNnd0PYOODn9FWs6u+OTIQIaIcPUv3MhB9lwHIJsTk/bs9xcru5TPyLIxLLd6ib/pRceKH2mTkzUd0DYk9CQNXXeoGx/du5B9nh3ClPTbVakRzl3oswgI5MQIphYxkW70SopEh4kOFSRE1ND31NNIq1YrXlgtkguQBFsZWuQOPR6cEwFZzP0tHTYbI839WgxX6hfhIUTUz6mLqq4+3P4BG3+1OXeVDg63y8Uh781sE="
                    ]
                },
                "entityId": "https://app.onelogin.com/saml/metadata/383123",
                "singleSignOnService": {
                    "url": "https://app.onelogin.com/trust/saml2/http-post/sso/383123",
                    "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                }
            }
        }
        """
        expected_settings_2 = json.loads(expected_settings_json_2)
        self.assertEqual(expected_settings_2, data_2)
    def testGetMetadata(self):
        """
        Tests the get_metadata method of the OneLogin_Saml2_IdPMetadataParser
        """
        with self.assertRaises(Exception):
            data = OneLogin_Saml2_IdPMetadataParser.get_metadata('http://google.es')

        try:
            data = OneLogin_Saml2_IdPMetadataParser.get_metadata('https://www.testshib.org/metadata/testshib-providers.xml')
        except URLError:
            data = self.file_contents(join(self.data_path, 'metadata', 'testshib-providers.xml'))
        self.assertTrue(data is not None and data is not {})
    def test_parse_multi_singing_certs(self):
        """
        Tests the parse method of the OneLogin_Saml2_IdPMetadataParser
        Case: IdP metadata contains multiple signing certs and no encryption certs
        """
        xml_idp_metadata = self.file_contents(join(self.data_path, 'metadata', 'idp_metadata_multi_signing_certs.xml'))
        data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata)

        expected_settings_json = """
        {
            "sp": {
                "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": {
                    "signing": [
                        "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==",
                        "MIICZDCCAc2gAwIBAgIBADANBgkqhkiG9w0BAQ0FADBPMQswCQYDVQQGEwJ1czEUMBIGA1UECAwLZXhhbXBsZS5jb20xFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xNzA0MTUxNjMzMThaFw0xODA0MTUxNjMzMThaME8xCzAJBgNVBAYTAnVzMRQwEgYDVQQIDAtleGFtcGxlLmNvbTEUMBIGA1UECgwLZXhhbXBsZS5jb20xFDASBgNVBAMMC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6GLkl5lDUZdHNDAojp5i24OoPlqrt5TGXJIPqAZYT1hQvJW5nv17MFDHrjmtEnmW4ACKEy0fAX80QWIcHunZSkbEGHb+NG/6oTi5RipXMvmHnfFnPJJ0AdtiLiPE478CV856gXekV4Xx5u3KrylcOgkpYsp0GMIQBDzleMUXlYQIDAQABo1AwTjAdBgNVHQ4EFgQUnP8vlYPGPL2n6ZzDYij2kMDC8wMwHwYDVR0jBBgwFoAUnP8vlYPGPL2n6ZzDYij2kMDC8wMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQAlQGAl+b8Cpot1g+65lLLjVoY7APJPWLW0klKQNlMU0s4MU+71Y3ExUEOXDAZgKcFoavb1fEOGMwEf38NaJAy1e/l6VNuixXShffq20ymqHQxOG0q8ujeNkgZF9k6XDfn/QZ3AD0o/IrCT7UMc/0QsfgIjWYxwCvp2syApc5CYfQ==",
                        "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=="
                    ]
                },
                "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"
                }
            }
        }
        """
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, 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 test_parse_testshib_required_binding_sso_redirect(self):
        """
        Test with testshib metadata.

        Especially test extracting SSO with REDIRECT binding.

        Note that the testshib metadata does not contain an SLO specification
        in the first <IDPSSODescriptor> tag.
        """
        expected_settings_json = """
        {
          "sp": {
            "NameIDFormat": "urn:mace:shibboleth:1.0:nameIdentifier"
          },
          "idp": {
            "entityId": "https://idp.testshib.org/idp/shibboleth",
            "x509cert": "MIIDAzCCAeugAwIBAgIVAPX0G6LuoXnKS0Muei006mVSBXbvMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNVBAMMEGlkcC50ZXN0c2hpYi5vcmcwHhcNMTYwODIzMjEyMDU0WhcNMzYwODIzMjEyMDU0WjAbMRkwFwYDVQQDDBBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg9C4J2DiRTEhJAWzPt1S3ryhm3M2P3hPpwJwvt2q948vdTUxhhvNMuc3M3S4WNh6JYBs53R+YmjqJAII4ShMGNEmlGnSVfHorex7IxikpuDPKV3SNf28mCAZbQrX+hWA+ann/uifVzqXktOjs6DdzdBnxoVhniXgC8WCJwKcx6JO/hHsH1rG/0DSDeZFpTTcZHj4S9MlLNUtt5JxRzV/MmmB3ObaX0CMqsSWUOQeE4nylSlp5RWHCnx70cs9kwz5WrflnbnzCeHU2sdbNotBEeTHot6a2cj/pXlRJIgPsrL/4VSicPZcGYMJMPoLTJ8mdy6mpR6nbCmP7dVbCIm/DQIDAQABoz4wPDAdBgNVHQ4EFgQUUfaDa2mPi24x09yWp1OFXmZ2GPswGwYDVR0RBBQwEoIQaWRwLnRlc3RzaGliLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEASKKgqTxhqBzROZ1eVy++si+eTTUQZU4+8UywSKLia2RattaAPMAcXUjO+3cYOQXLVASdlJtt+8QPdRkfp8SiJemHPXC8BES83pogJPYEGJsKo19l4XFJHPnPy+Dsn3mlJyOfAa8RyWBS80u5lrvAcr2TJXt9fXgkYs7BOCigxtZoR8flceGRlAZ4p5FPPxQR6NDYb645jtOTMVr3zgfjP6Wh2dt+2p04LG7ENJn8/gEwtXVuXCsPoSCDx9Y0QmyXTJNdV1aB0AhORkWPlFYwp+zOyOIR+3m1+pqWFpn0eT/HrxpdKa74FA3R2kq4R7dXe4G0kUgXTdqXMLRKhDgdmA==",
            "singleSignOnService": {
              "url": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            }
          }
        }
        """
        try:
            xmldoc = OneLogin_Saml2_IdPMetadataParser.get_metadata(
                'https://www.testshib.org/metadata/testshib-providers.xml')
        except URLError:
            xmldoc = self.file_contents(
                join(self.data_path, 'metadata', 'testshib-providers.xml'))

        # Parse, require SSO REDIRECT binding, implicitly.
        settings1 = OneLogin_Saml2_IdPMetadataParser.parse(xmldoc)
        # Parse, require SSO REDIRECT binding, explicitly.
        settings2 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
        )
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, settings1)
        self.assertEqual(expected_settings, settings2)
Exemplo n.º 12
0
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 test_parse_testshib_required_binding_sso_redirect(self):
        """
        Test with testshib metadata.

        Especially test extracting SSO with REDIRECT binding.

        Note that the testshib metadata does not contain an SLO specification
        in the first <IDPSSODescriptor> tag.
        """
        expected_settings_json = """
        {
          "sp": {
            "NameIDFormat": "urn:mace:shibboleth:1.0:nameIdentifier"
          },
          "idp": {
            "entityId": "https://idp.testshib.org/idp/shibboleth",
            "singleSignOnService": {
              "url": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            }
          }
        }
        """
        try:
            xmldoc = OneLogin_Saml2_IdPMetadataParser.get_metadata(
                'https://www.testshib.org/metadata/testshib-providers.xml')
        except URLError:
            xmldoc = self.file_contents(
                join(self.data_path, 'metadata', 'testshib-providers.xml'))

        # Parse, require SSO REDIRECT binding, implicitly.
        settings1 = OneLogin_Saml2_IdPMetadataParser.parse(xmldoc)
        # Parse, require SSO REDIRECT binding, explicitly.
        settings2 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
        )
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, settings1)
        self.assertEqual(expected_settings, settings2)
Exemplo n.º 14
0
    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()
Exemplo n.º 15
0
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_parse_testshib_required_binding_sso_redirect(self):
        """
        Test with testshib metadata.

        Especially test extracting SSO with REDIRECT binding.

        Note that the testshib metadata does not contain an SLO specification
        in the first <IDPSSODescriptor> tag.
        """
        expected_settings_json = """
        {
          "sp": {
            "NameIDFormat": "urn:mace:shibboleth:1.0:nameIdentifier"
          },
          "idp": {
            "entityId": "https://idp.testshib.org/idp/shibboleth",
            "singleSignOnService": {
              "url": "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            }
          }
        }
        """
        try:
            xmldoc = OneLogin_Saml2_IdPMetadataParser.get_metadata(
                'https://www.testshib.org/metadata/testshib-providers.xml')
        except URLError:
            xmldoc = self.file_contents(join(self.data_path, 'metadata', 'testshib-providers.xml'))

        # Parse, require SSO REDIRECT binding, implicitly.
        settings1 = OneLogin_Saml2_IdPMetadataParser.parse(xmldoc)
        # Parse, require SSO REDIRECT binding, explicitly.
        settings2 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
        )
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, settings1)
        self.assertEqual(expected_settings, settings2)
Exemplo n.º 17
0
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
Exemplo n.º 18
0
async def init_saml_auth(request):
    saml_config = copy.deepcopy(
        config.get("get_user_by_saml_settings.saml_settings", {}))
    idp_metadata_url = config.get("get_user_by_saml_settings.idp_metadata_url")
    if idp_metadata_url:
        idp_metadata = OneLogin_Saml2_IdPMetadataParser.parse_remote(
            idp_metadata_url)
        saml_config = dict_merge(saml_config, idp_metadata)
    auth = await sync_to_async(OneLogin_Saml2_Auth)(
        request,
        saml_config,
        custom_base_path=config.get("get_user_by_saml_settings.saml_path"),
    )
    return auth
Exemplo n.º 19
0
    def test_parse_with_entity_id(self):
        """
        Tests the parse method of the OneLogin_Saml2_IdPMetadataParser
        Case: Provide entity_id to identify the desired IdPDescriptor from
              EntitiesDescriptor
        """
        xml_idp_metadata = self.file_contents(join(self.data_path, 'metadata', 'idp_multiple_descriptors.xml'))

        # should find first descriptor
        data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata)
        self.assertEqual("https://foo.example.com/access/saml/idp.xml", data["idp"]["entityId"])

        # should find desired descriptor
        data2 = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata, entity_id="https://bar.example.com/access/saml/idp.xml")
        self.assertEqual("https://bar.example.com/access/saml/idp.xml", data2["idp"]["entityId"])

        expected_settings_json = """
        {
            "sp": {
                "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
            },
            "idp": {
                "singleLogoutService": {
                    "url": "https://hello.example.com/access/saml/logout",
                    "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                },
                "entityId": "https://bar.example.com/access/saml/idp.xml",
                "x509cert": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxekNDQXhTZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCaGpFTE1Ba0dBMVVFQmhNQ1FWVXgKRERBS0JnTlZCQWdUQTA1VFZ6RVBNQTBHQTFVRUJ4TUdVM2xrYm1WNU1Rd3dDZ1lEVlFRS0RBTlFTVlF4Q1RBSApCZ05WQkFzTUFERVlNQllHQTFVRUF3d1BiR0YzY21WdVkyVndhWFF1WTI5dE1TVXdJd1lKS29aSWh2Y05BUWtCCkRCWnNZWGR5Wlc1alpTNXdhWFJBWjIxaGFXd3VZMjl0TUI0WERURXlNRFF4T1RJeU5UUXhPRm9YRFRNeU1EUXgKTkRJeU5UUXhPRm93Z1lZeEN6QUpCZ05WQkFZVEFrRlZNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVApCbE41Wkc1bGVURU1NQW9HQTFVRUNnd0RVRWxVTVFrd0J3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psCmJtTmxjR2wwTG1OdmJURWxNQ01HQ1NxR1NJYjNEUUVKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnYKYlRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQXFqaWUzUjJvaStwRGFldndJeXMvbWJVVApubkdsa3h0ZGlrcnExMXZleHd4SmlQTmhtaHFSVzNtVXVKRXpsbElkVkw2RW14R1lUcXBxZjkzSGxoa3NhZUowCjhVZ2pQOVVtTVlyaFZKdTFqY0ZXVjdmei9yKzIxL2F3VG5EVjlzTVlRcXVJUllZeTdiRzByMU9iaXdkb3ZudGsKN2dGSTA2WjB2WmFjREU1Ym9xVUNBd0VBQWFPQ0FTVXdnZ0VoTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRRApBZ1VnTUIwR0ExVWREZ1FXQkJTUk9OOEdKOG8rOGpnRnRqa3R3WmRxeDZCUnlUQVRCZ05WSFNVRUREQUtCZ2dyCkJnRUZCUWNEQVRBZEJnbGdoa2dCaHZoQ0FRMEVFQllPVkdWemRDQllOVEE1SUdObGNuUXdnYk1HQTFVZEl3U0IKcXpDQnFJQVVrVGpmQmlmS1B2STRCYlk1TGNHWGFzZWdVY21oZ1l5a2dZa3dnWVl4Q3pBSkJnTlZCQVlUQWtGVgpNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVEJsTjVaRzVsZVRFTU1Bb0dBMVVFQ2d3RFVFbFVNUWt3CkJ3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psYm1ObGNHbDBMbU52YlRFbE1DTUdDU3FHU0liM0RRRUoKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnZiWUlCQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9CZ1FDRQpUQWVKVERTQVc2ejFVRlRWN1FyZWg0VUxGT1JhajkrZUN1RjNLV0RIYyswSVFDajlyZG5ERzRRL3dmNy9yYVEwCkpuUFFDU0NkclBMSmV5b1BIN1FhVHdvYUY3ZHpWdzRMQ3N5TkpURld4NGNNNTBWdzZSNWZET2dpQzhic2ZmUzgKQkptb3VscnJaRE5OVmpHOG1XNmNMeHJZdlZRT3JSVmVjQ0ZJZ3NzQ2JBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
                "singleSignOnService": {
                    "url": "https://hello.example.com/access/saml/login",
                    "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                }
            }
        }
        """
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, data2)
    def test_parse_with_entity_id(self):
        """
        Tests the parse method of the OneLogin_Saml2_IdPMetadataParser
        Case: Provide entity_id to identify the desired IdPDescriptor from
              EntitiesDescriptor
        """
        xml_idp_metadata = self.file_contents(join(self.data_path, 'metadata', 'idp_multiple_descriptors.xml'))

        # should find first descriptor
        data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata)
        self.assertEqual("https://foo.example.com/access/saml/idp.xml", data["idp"]["entityId"])

        # should find desired descriptor
        data2 = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata, entity_id="https://bar.example.com/access/saml/idp.xml")
        self.assertEqual("https://bar.example.com/access/saml/idp.xml", data2["idp"]["entityId"])

        expected_settings_json = """
        {
            "sp": {
                "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
            },
            "idp": {
                "singleLogoutService": {
                    "url": "https://hello.example.com/access/saml/logout",
                    "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                },
                "entityId": "https://bar.example.com/access/saml/idp.xml",
                "x509cert": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxekNDQXhTZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCaGpFTE1Ba0dBMVVFQmhNQ1FWVXgKRERBS0JnTlZCQWdUQTA1VFZ6RVBNQTBHQTFVRUJ4TUdVM2xrYm1WNU1Rd3dDZ1lEVlFRS0RBTlFTVlF4Q1RBSApCZ05WQkFzTUFERVlNQllHQTFVRUF3d1BiR0YzY21WdVkyVndhWFF1WTI5dE1TVXdJd1lKS29aSWh2Y05BUWtCCkRCWnNZWGR5Wlc1alpTNXdhWFJBWjIxaGFXd3VZMjl0TUI0WERURXlNRFF4T1RJeU5UUXhPRm9YRFRNeU1EUXgKTkRJeU5UUXhPRm93Z1lZeEN6QUpCZ05WQkFZVEFrRlZNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVApCbE41Wkc1bGVURU1NQW9HQTFVRUNnd0RVRWxVTVFrd0J3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psCmJtTmxjR2wwTG1OdmJURWxNQ01HQ1NxR1NJYjNEUUVKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnYKYlRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQXFqaWUzUjJvaStwRGFldndJeXMvbWJVVApubkdsa3h0ZGlrcnExMXZleHd4SmlQTmhtaHFSVzNtVXVKRXpsbElkVkw2RW14R1lUcXBxZjkzSGxoa3NhZUowCjhVZ2pQOVVtTVlyaFZKdTFqY0ZXVjdmei9yKzIxL2F3VG5EVjlzTVlRcXVJUllZeTdiRzByMU9iaXdkb3ZudGsKN2dGSTA2WjB2WmFjREU1Ym9xVUNBd0VBQWFPQ0FTVXdnZ0VoTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRRApBZ1VnTUIwR0ExVWREZ1FXQkJTUk9OOEdKOG8rOGpnRnRqa3R3WmRxeDZCUnlUQVRCZ05WSFNVRUREQUtCZ2dyCkJnRUZCUWNEQVRBZEJnbGdoa2dCaHZoQ0FRMEVFQllPVkdWemRDQllOVEE1SUdObGNuUXdnYk1HQTFVZEl3U0IKcXpDQnFJQVVrVGpmQmlmS1B2STRCYlk1TGNHWGFzZWdVY21oZ1l5a2dZa3dnWVl4Q3pBSkJnTlZCQVlUQWtGVgpNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVEJsTjVaRzVsZVRFTU1Bb0dBMVVFQ2d3RFVFbFVNUWt3CkJ3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psYm1ObGNHbDBMbU52YlRFbE1DTUdDU3FHU0liM0RRRUoKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnZiWUlCQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9CZ1FDRQpUQWVKVERTQVc2ejFVRlRWN1FyZWg0VUxGT1JhajkrZUN1RjNLV0RIYyswSVFDajlyZG5ERzRRL3dmNy9yYVEwCkpuUFFDU0NkclBMSmV5b1BIN1FhVHdvYUY3ZHpWdzRMQ3N5TkpURld4NGNNNTBWdzZSNWZET2dpQzhic2ZmUzgKQkptb3VscnJaRE5OVmpHOG1XNmNMeHJZdlZRT3JSVmVjQ0ZJZ3NzQ2JBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
                "singleSignOnService": {
                    "url": "https://hello.example.com/access/saml/login",
                    "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                }
            }
        }
        """
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, data2)
    def testParseRemote(self):
        """
        Tests the parse_remote method of the OneLogin_Saml2_IdPMetadataParser
        """
        with self.assertRaises(Exception):
            data = OneLogin_Saml2_IdPMetadataParser.parse_remote(
                'http://google.es')

        data = OneLogin_Saml2_IdPMetadataParser.parse_remote(
            'https://www.testshib.org/metadata/testshib-providers.xml')
        self.assertTrue(data is not None and data is not {})
        expected_data = {
            'sp': {
                'NameIDFormat': 'urn:mace:shibboleth:1.0:nameIdentifier'
            },
            'idp': {
                'singleLogoutService': {
                    'url':
                    'https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO'
                },
                'entityId': 'https://idp.testshib.org/idp/shibboleth'
            }
        }
        self.assertEqual(expected_data, data)
Exemplo n.º 22
0
    def remote_metadata(self):
        """Load the IdP metadata from the remote server and cache it for future accesses"""
        cache_key = '%s-idp-metadata' % self.name
        cached_metadata = cache.get(cache_key)
        if cached_metadata:
            idp_config = json.loads(cached_metadata)
        else:
            idp_config = OneLogin_Saml2_IdPMetadataParser.parse_remote(
                self.metadata_url)

        idp = idp_config['idp']
        cert = self.find_valid_certificate(idp)
        out = {
            'entity_id': idp['entityId'],
            'url': idp['singleSignOnService']['url'],
            'x509cert': cert,
        }
        cache.set(cache_key, json.dumps(idp_config), timeout=24 * 3600)

        return out
Exemplo n.º 23
0
 def _settings_from_url(self, metadata_url):
     idp_settings = OneLogin_Saml2_IdPMetadataParser.parse_remote(
         metadata_url)["idp"]
     sp_settings = {
         "NameIDFormat":
         "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
         "assertionConsumerService": {
             "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTPS-POST",
             "url": "%s/saml/acs" % self.domain
         },
         "x509cert": self.x509cert,
         "privateKey": self.private_key,
         "entityId": "%s/saml/metadata" % self.domain,
         "singleLogoutService": {
             "binding":
             "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
             "url": "%s/saml/sls" % self.domain
         }
     }
     return {"strict": True, "sp": sp_settings, "idp": idp_settings}
Exemplo n.º 24
0
    def test_parse_multi_certs(self):
        """
        Tests the parse method of the OneLogin_Saml2_IdPMetadataParser
        Case: IdP metadata contains multiple certs
        """
        xml_idp_metadata = self.file_contents(
            join(self.data_path, 'metadata', 'idp_metadata_multi_certs.xml'))
        data = OneLogin_Saml2_IdPMetadataParser.parse(xml_idp_metadata)

        expected_settings_json = """
        {
            "sp": {
                "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": [
                        "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==",
                        "MIICZDCCAc2gAwIBAgIBADANBgkqhkiG9w0BAQ0FADBPMQswCQYDVQQGEwJ1czEUMBIGA1UECAwLZXhhbXBsZS5jb20xFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xNzA0MTUxNjMzMThaFw0xODA0MTUxNjMzMThaME8xCzAJBgNVBAYTAnVzMRQwEgYDVQQIDAtleGFtcGxlLmNvbTEUMBIGA1UECgwLZXhhbXBsZS5jb20xFDASBgNVBAMMC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6GLkl5lDUZdHNDAojp5i24OoPlqrt5TGXJIPqAZYT1hQvJW5nv17MFDHrjmtEnmW4ACKEy0fAX80QWIcHunZSkbEGHb+NG/6oTi5RipXMvmHnfFnPJJ0AdtiLiPE478CV856gXekV4Xx5u3KrylcOgkpYsp0GMIQBDzleMUXlYQIDAQABo1AwTjAdBgNVHQ4EFgQUnP8vlYPGPL2n6ZzDYij2kMDC8wMwHwYDVR0jBBgwFoAUnP8vlYPGPL2n6ZzDYij2kMDC8wMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQAlQGAl+b8Cpot1g+65lLLjVoY7APJPWLW0klKQNlMU0s4MU+71Y3ExUEOXDAZgKcFoavb1fEOGMwEf38NaJAy1e/l6VNuixXShffq20ymqHQxOG0q8ujeNkgZF9k6XDfn/QZ3AD0o/IrCT7UMc/0QsfgIjWYxwCvp2syApc5CYfQ=="
                    ]
                },
                "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"
                }
            }
        }
        """
        expected_settings = json.loads(expected_settings_json)
        self.assertEqual(expected_settings, data)
Exemplo n.º 25
0
    def load_idp_metadata(self, url=None):
        """Load IdP metadata in an XML format from the specified url.

        :param url: URL of a metadata service
        :type url: Optional[string]

        :return: XML string containing InCommon Metadata
        :rtype: string

        :raise: MetadataLoadError
        """
        self._logger.info(
            "Started loading IdP XML metadata from {0}".format(url))

        try:
            xml_metadata = OneLogin_Saml2_IdPMetadataParser.get_metadata(url)
        except Exception as exception:
            raise SAMLMetadataLoadingError(inner_exception=exception)

        self._logger.info(
            "Finished loading IdP XML metadata from {0}".format(url))

        return xml_metadata
Exemplo n.º 26
0
    def handle(self, request, helper):
        missing_values = error_value = error_url = False
        id_or_metadata_url = url = ''
        if 'action_save' in request.POST:
            id_or_metadata_url = request.POST['id_or_metadata_url']

            # Get metadata url if an app_id was provided
            if id_or_metadata_url and id_or_metadata_url.isdigit():
                id_or_metadata_url = ONELOGIN_METADATA_URL_PREFIX + id_or_metadata_url

            validate_url = URLValidator()
            try:
                validate_url(id_or_metadata_url)
                url = id_or_metadata_url
                try:
                    data = OneLogin_Saml2_IdPMetadataParser.parse_remote(url)

                    if data and 'idp' in data:
                        idp_data = SAML2Provider.extract_idp_data_from_parsed_data(data)
                        form2 = OneLoginSAMLForm(idp_data)
                        if form2.is_valid():
                            helper.bind_state('idp', idp_data)
                            helper.bind_state('contact', request.user.email)
                            return helper.next_step()
                        else:
                            missing_values = form2.errors.keys
                except Exception:
                    error_url = True
            except ValidationError:
                error_value = True

        return self.respond('sentry_auth_onelogin/select-idp.html', {
            'error_value': error_value,
            'error_url': error_url,
            'missing_values': missing_values,
            'id_or_metadata_url': id_or_metadata_url
        })
    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)
Exemplo n.º 28
0
    def _build_configuration(self, idp):
        """Update default config with the ones read from configuration."""
        def update(d, u):
            for k, v in u.items():
                if isinstance(v, collections.Mapping):
                    d[k] = update(d.get(k, {}), v)
                else:
                    d[k] = v
            return d

        def make_handler(handler, default=None):
            handler = handler if handler else default
            return (import_string(handler) if handler
                    and isinstance(handler, string_types) else handler)

        config = _default_config(idp)
        update(config, self.app.config["SSO_SAML_IDPS"][idp])

        # Read IdP config from file or URL if any
        if config["settings_url"]:
            external_conf = OneLogin_Saml2_IdPMetadataParser.parse_remote(
                config["settings_url"])
            config["settings"]["idp"].update(external_conf.get("idp"))

        if config["settings_file_path"]:
            with open(config["settings_file_path"], "r") as idp:
                file = config["settings_file_path"]
                # xml format
                if file.endswith(".xml"):
                    external_conf = OneLogin_Saml2_IdPMetadataParser.parse(
                        idp.read())
                # json format
                elif file.endswith(".json"):
                    external_conf = json.loads(idp.read())
            config["settings"]["idp"].update(external_conf.get("idp"))

        # Load certificate and key
        if config["sp_cert_file"]:
            with open(config["sp_cert_file"], "r") as cf:
                cert = cf.read()
            config["settings"]["sp"]["x509cert"] = cert

        if config["sp_key_file"]:
            with open(config["sp_key_file"], "r") as cf:
                cert = cf.read()
            config["settings"]["sp"]["privateKey"] = cert

        # Import handlers is present
        config["settings_handler"] = make_handler(
            config["settings_handler"],
            self.app.config.get("SSO_SAML_DEFAUTL_SETTINGS_HANDLER"),
        )
        config["login_handler"] = make_handler(
            config["login_handler"],
            self.app.config.get("SSO_SAML_DEFAUTL_LOGIN_HANDLER"),
        )
        config["logout_handler"] = make_handler(
            config["logout_handler"],
            self.app.config.get("SSO_SAML_DEFAUTL_LOGOUT_HANDLER"),
        )
        config["acs_handler"] = make_handler(
            config["acs_handler"],
            self.app.config.get("SSO_SAML_DEFAUTL_ACS_HANDLER"))
        config["sls_handler"] = make_handler(
            config["sls_handler"],
            self.app.config.get("SSO_SAML_DEFAUTL_SLS_HANDLER"))

        return config
Exemplo n.º 29
0
def spSettings(cod_sp,
               cod_idp=None,
               binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT,
               close=True):
    result = {'error': 0, 'result': None}

    # acquisisci una connessione dal pool
    #if conn is None:
    #    conn = easyspid.lib.database.Database(globalsObj.DbConnections['samlDbPollSlave']['pool'])
    #sp_settings = conn.get_sp_settings(cod_sp, close)

    dbobj = globalsObj.DbConnections['samlDb']
    sp_settings = dbobj.makeQuery("EXECUTE get_sp_settings(%s)", [cod_sp],
                                  type=dbobj.stmts['get_providers']['pool'],
                                  close=close)

    if sp_settings['error'] == 0 and sp_settings['result'] != None:
        # genera risposta tutto ok
        sp_settings['result']['settings']['idp'] = globalsObj.easyspidSettings[
            'idp']
        sp_settings['result']['settings']['sp']['x509cert'] = sp_settings[
            'result']['public_key']
        sp_settings['result']['settings']['sp']['privateKey'] = sp_settings[
            'result']['private_key']
        sp_settings['result']['settings']['sp'][
            'x509cert_fingerprint'] = sp_settings['result']['fingerprint']
        sp_settings['result']['settings']['sp'][
            'x509cert_fingerprintalg'] = sp_settings['result'][
                'fingerprintalg']
        sp_settings['result']['settings']['security'] = sp_settings['result'][
            'advanced_settings']['security']
        sp_settings['result']['settings']['contactPerson'] = sp_settings[
            'result']['advanced_settings']['contactPerson']
        sp_settings['result']['settings']['organization'] = sp_settings[
            'result']['advanced_settings']['organization']

        if cod_idp != None:
            #idp_metadata = globalsObj.DbConnections['samlSlave'].get_prvd_metadta(cod_idp)
            #idp_metadata = conn.get_prvd_metadta(cod_idp, close)

            idp_metadata = dbobj.makeQuery(
                "EXECUTE get_prvd_metadta(%s)", [cod_idp],
                type=dbobj.stmts['get_providers']['pool'],
                close=close)

            if idp_metadata['error'] == 0 and idp_metadata['result'] != None:

                metadata = idp_metadata['result']['xml']
                idp_data = OneLogin_Saml2_IdPMetadataParser.parse(
                    metadata,
                    required_sso_binding=binding,
                    required_slo_binding=binding)
                idp_settings = idp_data['idp']

                if 'entityId' in idp_settings:
                    sp_settings['result']['settings']['idp'][
                        'entityId'] = idp_settings['entityId']
                if 'singleLogoutService' in idp_settings:
                    sp_settings['result']['settings']['idp'][
                        'singleLogoutService'] = idp_settings[
                            'singleLogoutService']
                if 'singleSignOnService' in idp_settings:
                    sp_settings['result']['settings']['idp'][
                        'singleSignOnService'] = idp_settings[
                            'singleSignOnService']
                if 'x509cert' in idp_settings:
                    sp_settings['result']['settings']['idp'][
                        'x509cert'] = idp_settings['x509cert']

                sp_settings['result']['settings']['idp'][
                    'x509cert_fingerprint'] = idp_metadata['result'][
                        'fingerprint']
                sp_settings['result']['settings']['idp'][
                    'x509cert_fingerprintalg'] = idp_metadata['result'][
                        'fingerprintalg']
                sp_settings['result']['settings']['idp']['metadata'] = metadata

                result['result'] = sp_settings['result']['settings']
                return result

            elif idp_metadata['error'] > 0:
                result['error'] = 1
                response_obj = ResponseObj(
                    debugMessage=idp_metadata['result'].pgerror,
                    httpcode=500,
                    devMessage=("PostgreSQL error code: %s" %
                                idp_metadata['result'].pgcode))
                response_obj.setError('easyspid105')
                result['result'] = response_obj

            else:
                result['error'] = idp_metadata['error']
                result['result'] = idp_metadata['result']
        else:
            result['result'] = sp_settings['result']['settings']
            return result

    elif sp_settings['error'] > 0:
        result['error'] = 1
        response_obj = ResponseObj(debugMessage=sp_settings['result'].pgerror,
                                   httpcode=500,
                                   devMessage=("PostgreSQL error code: %s" %
                                               sp_settings['result'].pgcode))
        response_obj.setError('easyspid105')
        result['result'] = response_obj

    else:
        result['error'] = sp_settings['error']
        result['result'] = sp_settings['result']

    return result
Exemplo n.º 30
0
    def loginAuthnReq(self, sp_settings, idp_metadata, attributeIndex, binding,
                      srelay_cod):
        try:

            if binding == 'redirect':
                authn_request = authnreqBuildhandler.buildAthnReq(
                    self, sp_settings, attributeIndex, signed=False)
            elif binding == 'post':
                authn_request = authnreqBuildhandler.buildAthnReq(
                    self, sp_settings, attributeIndex, signed=True)

            bindingMap = {
                'redirect': OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT,
                'post': OneLogin_Saml2_Constants.BINDING_HTTP_POST
            }

            if (sp_settings['error'] == 0 and sp_settings['result'] is not None
                    and idp_metadata.error.code == '200'
                    and authn_request.error.code == '200'):

                sp = sp_settings['result']['sp']['cod_sp']
                idp = sp_settings['result']['idp']['cod_idp']

                # get relay state
                task = asyncio.run_coroutine_threadsafe(
                    self.dbobjSaml.execute_statment(
                        "get_service(%s, '%s', '%s')" %
                        ('True', str(srelay_cod), sp)), globalsObj.ioloop)
                #assert not task.done()
                #srelay = task.result()
                srelay = waitFuture(task)

                if srelay['error'] == 0 and srelay['result'] is None:
                    response_obj = ResponseObj(httpcode=404)
                    response_obj.setError('easyspid113')
                    return response_obj

                elif srelay['error'] > 0:
                    response_obj = ResponseObj(
                        httpcode=500, debugMessage=sp_settings['result'])
                    response_obj.setError("easyspid105")
                    return response_obj

            #if (sp_settings['error'] == 0 and sp_settings['result'] is not None
            #and idp_metadata.error.code == '200' and authn_request.error.code == '200'):

                idp_data = OneLogin_Saml2_IdPMetadataParser.parse(
                    idp_metadata.result.metadata,
                    required_sso_binding=bindingMap[binding],
                    required_slo_binding=bindingMap[binding])
                idp_settings = idp_data['idp']

                # fake authn_request
                req = {
                    "http_host": "",
                    "script_name": "",
                    "server_port": "",
                    "get_data": "",
                    "post_data": ""
                }

                settings = sp_settings['result']
                if 'entityId' in idp_settings:
                    settings['idp']['entityId'] = idp_settings['entityId']
                if 'singleLogoutService' in idp_settings:
                    settings['idp']['singleLogoutService'] = idp_settings[
                        'singleLogoutService']
                if 'singleSignOnService' in idp_settings:
                    settings['idp']['singleSignOnService'] = idp_settings[
                        'singleSignOnService']
                if 'x509cert' in idp_settings:
                    settings['idp']['x509cert'] = idp_settings['x509cert']

                auth = OneLogin_Saml2_Auth(req, sp_settings['result'])
                spSettings = Saml2_Settings(sp_settings['result'])

                sign_alg = (
                    spSettings.get_security_data())['signatureAlgorithm']

                # build login message
                # redirect binding
                if binding == 'redirect':
                    saml_request = OneLogin_Saml2_Utils.deflate_and_base64_encode(
                        authn_request.result.authnrequest)
                    parameters = {'SAMLRequest': saml_request}
                    parameters['RelayState'] = srelay['result'][0][
                        'relay_state']
                    auth.add_request_signature(parameters, sign_alg)
                    redirectLocation = auth.redirect_to(
                        auth.get_sso_url(), parameters)

                    response_obj = ResponseObj(httpcode=200)
                    response_obj.setError('200')
                    response_obj.setResult(redirectTo=redirectLocation,
                                           jwt=authn_request.result.jwt)

                # POST binding
                elif binding == 'post':
                    saml_request_signed = OneLogin_Saml2_Utils.b64encode(
                        authn_request.result.authnrequest)
                    relay_state = OneLogin_Saml2_Utils.b64encode(
                        srelay['result'][0]['relay_state'])
                    idpsso = idp_settings['singleSignOnService']['url']

                    try:
                        with open(
                                os.path.join(globalsObj.modules_basedir,
                                             globalsObj.easyspid_postFormPath),
                                'rb') as myfile:
                            post_form = myfile.read().decode("utf-8").replace(
                                '\n', '')
                    except:
                        with open(globalsObj.easyspid_postFormPath,
                                  'rb') as myfile:
                            post_form = myfile.read().decode("utf-8").replace(
                                '\n', '')

                    post_form = post_form.replace("%IDPSSO%", idpsso)
                    post_form = post_form.replace("%AUTHNREQUEST%",
                                                  saml_request_signed)
                    post_form = post_form.replace("%RELAYSTATE%", relay_state)

                    response_obj = ResponseObj(httpcode=200)
                    response_obj.setError('200')
                    response_obj.setResult(postTo=post_form,
                                           jwt=authn_request.result.jwt)

            elif sp_settings['error'] == 0 and sp_settings['result'] is None:
                response_obj = ResponseObj(httpcode=404)
                response_obj.setError('easyspid101')

            elif sp_settings['error'] > 0:
                response_obj = ResponseObj(httpcode=500,
                                           debugMessage=sp_settings['result'])
                response_obj.setError("easyspid105")

        except tornado.web.MissingArgumentError as error:
            response_obj = ResponseObj(debugMessage=error.log_message,
                                       httpcode=error.status_code,
                                       devMessage=error.log_message)
            response_obj.setError(str(error.status_code))
            logging.getLogger(
                type(self).__module__ + "." + type(self).__qualname__).error(
                    '%s' % error, exc_info=True)

        except Exception as inst:
            response_obj = ResponseObj(httpcode=500)
            response_obj.setError('500')
            logging.getLogger(
                type(self).__module__ + "." + type(self).__qualname__).error(
                    'Exception', exc_info=True)

        return response_obj
Exemplo n.º 31
0
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, '', ''
Exemplo n.º 32
0
def process_xml(form):
    # cast unicode xml to byte string so lxml won't complain when trying to
    # parse a xml document with a type declaration.
    xml = form.cleaned_data["metadata_xml"].encode("utf8")
    data = OneLogin_Saml2_IdPMetadataParser.parse(xml)
    return extract_idp_data_from_parsed_data(data)
Exemplo n.º 33
0
import hashlib

from app import app
from certutil import *
from distutils.version import StrictVersion
from datetime import datetime, timedelta
from threading import Thread

if app.config['SAML_ENABLED']:
    from onelogin.saml2.auth import OneLogin_Saml2_Auth
    from onelogin.saml2.utils import OneLogin_Saml2_Utils
    from onelogin.saml2.settings import OneLogin_Saml2_Settings
    from onelogin.saml2.idp_metadata_parser import OneLogin_Saml2_IdPMetadataParser
    idp_timestamp = datetime(1970, 1, 1)
    idp_data = None
    idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote(
        app.config['SAML_METADATA_URL'])
    if idp_data is None:
        print('SAML: IDP Metadata initial load failed')
        exit(-1)
    idp_timestamp = datetime.now()


def get_idp_data():
    global idp_data, idp_timestamp
    lifetime = timedelta(minutes=app.config['SAML_METADATA_CACHE_LIFETIME'])
    if idp_timestamp + lifetime < datetime.now():
        background_thread = Thread(target=retreive_idp_data)
        background_thread.start()
    return idp_data

    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": [
                "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==",
                "MIICZDCCAc2gAwIBAgIBADANBgkqhkiG9w0BAQ0FADBPMQswCQYDVQQGEwJ1czEUMBIGA1UECAwLZXhhbXBsZS5jb20xFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xNzA0MTUxNjMzMThaFw0xODA0MTUxNjMzMThaME8xCzAJBgNVBAYTAnVzMRQwEgYDVQQIDAtleGFtcGxlLmNvbTEUMBIGA1UECgwLZXhhbXBsZS5jb20xFDASBgNVBAMMC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6GLkl5lDUZdHNDAojp5i24OoPlqrt5TGXJIPqAZYT1hQvJW5nv17MFDHrjmtEnmW4ACKEy0fAX80QWIcHunZSkbEGHb+NG/6oTi5RipXMvmHnfFnPJJ0AdtiLiPE478CV856gXekV4Xx5u3KrylcOgkpYsp0GMIQBDzleMUXlYQIDAQABo1AwTjAdBgNVHQ4EFgQUnP8vlYPGPL2n6ZzDYij2kMDC8wMwHwYDVR0jBBgwFoAUnP8vlYPGPL2n6ZzDYij2kMDC8wMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQAlQGAl+b8Cpot1g+65lLLjVoY7APJPWLW0klKQNlMU0s4MU+71Y3ExUEOXDAZgKcFoavb1fEOGMwEf38NaJAy1e/l6VNuixXShffq20ymqHQxOG0q8ujeNkgZF9k6XDfn/QZ3AD0o/IrCT7UMc/0QsfgIjWYxwCvp2syApc5CYfQ=="
              ]
            },
            "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)
Exemplo n.º 35
0
    def test_parse_required_binding_all(self):
        """
        Test all combinations of the `require_slo_binding` and
        `require_sso_binding` parameters.

        Note: IdP metadata contains a single logout (SLO)
        service and does not specify any endpoint for the POST binding.
        """
        expected_settings_json = """
        {
          "sp": {
            "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
          },
          "idp": {
            "entityId": "urn:example:idp",
            "x509cert": "MIIDPDCCAiQCCQDydJgOlszqbzANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEQMA4GA1UEChMHSmFua3lDbzESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTE0MDMxMjE5NDYzM1oXDTI3MTExOTE5NDYzM1owYDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEDAOBgNVBAoTB0phbmt5Q28xEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMGvJpRTTasRUSPqcbqCG+ZnTAurnu0vVpIG9lzExnh11o/BGmzu7lB+yLHcEdwrKBBmpepDBPCYxpVajvuEhZdKFx/Fdy6j5mH3rrW0Bh/zd36CoUNjbbhHyTjeM7FN2yF3u9lcyubuvOzr3B3gX66IwJlU46+wzcQVhSOlMk2tXR+fIKQExFrOuK9tbX3JIBUqItpI+HnAow509CnM134svw8PTFLkR6/CcMqnDfDK1m993PyoC1Y+N4X9XkhSmEQoAlAHPI5LHrvuujM13nvtoVYvKYoj7ScgumkpWNEvX652LfXOnKYlkB8ZybuxmFfIkzedQrbJsyOhfL03cMECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAeHwzqwnzGEkxjzSD47imXaTqtYyETZow7XwBc0ZaFS50qRFJUgKTAmKS1xQBP/qHpStsROT35DUxJAE6NY1Kbq3ZbCuhGoSlY0L7VzVT5tpu4EY8+Dq/u2EjRmmhoL7UkskvIZ2n1DdERtd+YUMTeqYl9co43csZwDno/IKomeN5qaPc39IZjikJ+nUC6kPFKeu/3j9rgHNlRtocI6S1FdtFz9OZMQlpr0JbUt2T3xS/YoQJn6coDmJL5GTiiKM6cOe+Ur1VwzS1JEDbSS2TWWhzq8ojLdrotYLGd9JOsoQhElmz+tMfCFQUFLExinPAyy7YHlSiVX13QH2XTu/iQQ==",
            "singleSignOnService": {
              "url": "http://idp.example.com",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            },
            "singleLogoutService": {
              "url": "http://idp.example.com/logout",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            }
          }
        }
        """
        xmldoc = self.file_contents(
            join(self.data_path, 'metadata', 'idp_metadata2.xml'))

        expected_settings = json.loads(expected_settings_json)

        # Parse, require SLO and SSO REDIRECT binding, implicitly.
        settings1 = OneLogin_Saml2_IdPMetadataParser.parse(xmldoc)

        # Parse, require SLO and SSO REDIRECT binding, explicitly.
        settings2 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.
            BINDING_HTTP_REDIRECT,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
        )
        expected_settings1_2 = deepcopy(expected_settings)
        self.assertEqual(expected_settings1_2, settings1)
        self.assertEqual(expected_settings1_2, settings2)

        settings3 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST)

        expected_settings3 = deepcopy(expected_settings)
        del expected_settings3['idp']['singleLogoutService']
        del expected_settings3['idp']['singleSignOnService']
        self.assertEqual(expected_settings3, settings3)

        settings4 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
        )
        settings5 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST)
        expected_settings4_5 = deepcopy(expected_settings)
        del expected_settings4_5['idp']['singleSignOnService']
        self.assertEqual(expected_settings4_5, settings4)
        self.assertEqual(expected_settings4_5, settings5)

        settings6 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.
            BINDING_HTTP_REDIRECT,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST)
        settings7 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST)
        expected_settings6_7 = deepcopy(expected_settings)
        del expected_settings6_7['idp']['singleLogoutService']
        self.assertEqual(expected_settings6_7, settings6)
        self.assertEqual(expected_settings6_7, settings7)
Exemplo n.º 36
0
Arquivo: sso.py Projeto: markhpc/ceph
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, '', ''
Exemplo n.º 37
0
    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": [
                "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==",
                "MIICZDCCAc2gAwIBAgIBADANBgkqhkiG9w0BAQ0FADBPMQswCQYDVQQGEwJ1czEUMBIGA1UECAwLZXhhbXBsZS5jb20xFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xNzA0MTUxNjMzMThaFw0xODA0MTUxNjMzMThaME8xCzAJBgNVBAYTAnVzMRQwEgYDVQQIDAtleGFtcGxlLmNvbTEUMBIGA1UECgwLZXhhbXBsZS5jb20xFDASBgNVBAMMC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6GLkl5lDUZdHNDAojp5i24OoPlqrt5TGXJIPqAZYT1hQvJW5nv17MFDHrjmtEnmW4ACKEy0fAX80QWIcHunZSkbEGHb+NG/6oTi5RipXMvmHnfFnPJJ0AdtiLiPE478CV856gXekV4Xx5u3KrylcOgkpYsp0GMIQBDzleMUXlYQIDAQABo1AwTjAdBgNVHQ4EFgQUnP8vlYPGPL2n6ZzDYij2kMDC8wMwHwYDVR0jBBgwFoAUnP8vlYPGPL2n6ZzDYij2kMDC8wMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQAlQGAl+b8Cpot1g+65lLLjVoY7APJPWLW0klKQNlMU0s4MU+71Y3ExUEOXDAZgKcFoavb1fEOGMwEf38NaJAy1e/l6VNuixXShffq20ymqHQxOG0q8ujeNkgZF9k6XDfn/QZ3AD0o/IrCT7UMc/0QsfgIjWYxwCvp2syApc5CYfQ=="
              ]
            },
            "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)
Exemplo n.º 38
0
    def test_parse_required_binding_all(self):
        """
        Test all combinations of the `require_slo_binding` and
        `require_sso_binding` parameters.
        Note: IdP metadata contains a single logout (SLO)
        service and does not specify any endpoint for the POST binding.
        """
        expected_settings_json = """
        {
          "sp": {
            "NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
          },
          "idp": {
            "entityId": "urn:example:idp",
            "x509certs": ["MIIDPDCCAiQCCQDydJgOlszqbzANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEQMA4GA1UEChMHSmFua3lDbzESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTE0MDMxMjE5NDYzM1oXDTI3MTExOTE5NDYzM1owYDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEDAOBgNVBAoTB0phbmt5Q28xEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMGvJpRTTasRUSPqcbqCG+ZnTAurnu0vVpIG9lzExnh11o/BGmzu7lB+yLHcEdwrKBBmpepDBPCYxpVajvuEhZdKFx/Fdy6j5mH3rrW0Bh/zd36CoUNjbbhHyTjeM7FN2yF3u9lcyubuvOzr3B3gX66IwJlU46+wzcQVhSOlMk2tXR+fIKQExFrOuK9tbX3JIBUqItpI+HnAow509CnM134svw8PTFLkR6/CcMqnDfDK1m993PyoC1Y+N4X9XkhSmEQoAlAHPI5LHrvuujM13nvtoVYvKYoj7ScgumkpWNEvX652LfXOnKYlkB8ZybuxmFfIkzedQrbJsyOhfL03cMECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAeHwzqwnzGEkxjzSD47imXaTqtYyETZow7XwBc0ZaFS50qRFJUgKTAmKS1xQBP/qHpStsROT35DUxJAE6NY1Kbq3ZbCuhGoSlY0L7VzVT5tpu4EY8+Dq/u2EjRmmhoL7UkskvIZ2n1DdERtd+YUMTeqYl9co43csZwDno/IKomeN5qaPc39IZjikJ+nUC6kPFKeu/3j9rgHNlRtocI6S1FdtFz9OZMQlpr0JbUt2T3xS/YoQJn6coDmJL5GTiiKM6cOe+Ur1VwzS1JEDbSS2TWWhzq8ojLdrotYLGd9JOsoQhElmz+tMfCFQUFLExinPAyy7YHlSiVX13QH2XTu/iQQ=="],
            "singleSignOnService": {
              "url": "http://idp.example.com",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            },
            "singleLogoutService": {
              "url": "http://idp.example.com/logout",
              "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            }
          }
        }
        """
        xmldoc = self.file_contents(join(self.data_path, 'metadata', 'idp_metadata2.xml'))

        expected_settings = json.loads(expected_settings_json)

        # Parse, require SLO and SSO REDIRECT binding, implicitly.
        settings1 = OneLogin_Saml2_IdPMetadataParser.parse(xmldoc)

        # Parse, require SLO and SSO REDIRECT binding, explicitly.
        settings2 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
        )
        expected_settings1_2 = deepcopy(expected_settings)
        self.assertEqual(expected_settings1_2, settings1)
        self.assertEqual(expected_settings1_2, settings2)

        settings3 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST
        )

        expected_settings3 = deepcopy(expected_settings)
        del expected_settings3['idp']['singleLogoutService']
        del expected_settings3['idp']['singleSignOnService']
        self.assertEqual(expected_settings3, settings3)

        settings4 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
        )
        settings5 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST
        )
        expected_settings4_5 = deepcopy(expected_settings)
        del expected_settings4_5['idp']['singleSignOnService']
        self.assertEqual(expected_settings4_5, settings4)
        self.assertEqual(expected_settings4_5, settings5)

        settings6 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST
        )
        settings7 = OneLogin_Saml2_IdPMetadataParser.parse(
            xmldoc,
            required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_POST
        )
        expected_settings6_7 = deepcopy(expected_settings)
        del expected_settings6_7['idp']['singleLogoutService']
        self.assertEqual(expected_settings6_7, settings6)
        self.assertEqual(expected_settings6_7, settings7)
Exemplo n.º 39
0
def process_url(form):
    url = form.cleaned_data["metadata_url"]
    response = safe_urlopen(url)
    data = OneLogin_Saml2_IdPMetadataParser.parse(response.content)
    return extract_idp_data_from_parsed_data(data)
Exemplo n.º 40
0
async def spSettings(cod_sp,
                     cod_idp=None,
                     binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT,
                     close=True):
    result = {'error': 0, 'result': None}

    dbobj = globalsObj.DbConnections['samlDb']

    task1 = asyncio.ensure_future(dbobj.execute_statment(
        "get_sp_settings('%s')" % cod_sp),
                                  loop=globalsObj.ioloop)

    if cod_idp is not None:
        task2 = asyncio.ensure_future(dbobj.execute_statment(
            "get_prvd_metadta('%s')" % cod_idp),
                                      loop=globalsObj.ioloop)
        await task2
        idp_metadata = task2.result()

    await task1
    sp_settings = task1.result()

    if sp_settings['error'] == 0 and sp_settings['result'] is not None:
        # genera risposta tutto o
        sp_settings['result'] = sp_settings['result'][0]
        sp_settings['result']['settings']['idp'] = globalsObj.easyspidSettings[
            'idp']
        sp_settings['result']['settings']['sp']['cod_sp'] = cod_sp
        sp_settings['result']['settings']['sp']['x509cert'] = sp_settings[
            'result']['public_key']
        sp_settings['result']['settings']['sp']['privateKey'] = sp_settings[
            'result']['private_key']
        sp_settings['result']['settings']['sp'][
            'x509cert_fingerprint'] = sp_settings['result']['fingerprint']
        sp_settings['result']['settings']['sp'][
            'x509cert_fingerprintalg'] = sp_settings['result'][
                'fingerprintalg']
        sp_settings['result']['settings']['security'] = sp_settings['result'][
            'advanced_settings']['security']
        sp_settings['result']['settings']['contactPerson'] = sp_settings[
            'result']['advanced_settings']['contactPerson']
        sp_settings['result']['settings']['organization'] = sp_settings[
            'result']['advanced_settings']['organization']

        if cod_idp is not None:

            #idp_metadata = dbobj.makeQuery("EXECUTE get_prvd_metadta(%s)",
            #            [cod_idp],type = dbobj.stmts['get_providers']['pool'], close=close)
            #idp_metadata = await dbobj.execute_statment("get_prvd_metadta('%s')" % cod_idp)

            if idp_metadata['error'] == 0 and idp_metadata[
                    'result'] is not None:

                metadata = idp_metadata['result'][0]['xml']
                idp_data = OneLogin_Saml2_IdPMetadataParser.parse(
                    metadata,
                    required_sso_binding=binding,
                    required_slo_binding=binding)
                idp_settings = idp_data['idp']

                if 'entityId' in idp_settings:
                    sp_settings['result']['settings']['idp'][
                        'entityId'] = idp_settings['entityId']
                if 'singleLogoutService' in idp_settings:
                    sp_settings['result']['settings']['idp'][
                        'singleLogoutService'] = idp_settings[
                            'singleLogoutService']
                if 'singleSignOnService' in idp_settings:
                    sp_settings['result']['settings']['idp'][
                        'singleSignOnService'] = idp_settings[
                            'singleSignOnService']
                if 'x509cert' in idp_settings:
                    sp_settings['result']['settings']['idp'][
                        'x509cert'] = idp_settings['x509cert']

                sp_settings['result']['settings']['idp'][
                    'x509cert_fingerprint'] = idp_metadata['result'][0][
                        'fingerprint']
                sp_settings['result']['settings']['idp'][
                    'x509cert_fingerprintalg'] = idp_metadata['result'][0][
                        'fingerprintalg']
                sp_settings['result']['settings']['idp']['metadata'] = metadata
                sp_settings['result']['settings']['idp']['cod_idp'] = cod_idp

                result['result'] = sp_settings['result']['settings']
                return result

            elif idp_metadata['error'] > 0:
                result['error'] = 1

                sqlstate = "?"
                if hasattr(idp_metadata['result'], 'sqlstate'):
                    sqlstate = idp_metadata['result'].sqlstate

                response_obj = ResponseObj(
                    debugMessage="PostgreSQL error code: %s" % sqlstate,
                    httpcode=500,
                    devMessage=("PostgreSQL error message: %s" %
                                idp_metadata['result'].message))
                response_obj.setError('easyspid105')
                result['result'] = response_obj

            else:
                result['error'] = idp_metadata['error']
                result['result'] = idp_metadata['result']
        else:
            result['result'] = sp_settings['result']['settings']
            return result

    elif sp_settings['error'] > 0:
        result['error'] = 1

        sqlstate = "?"
        if hasattr(sp_settings['result'], 'sqlstate'):
            sqlstate = sp_settings['result'].sqlstate

        response_obj = ResponseObj(debugMessage="PostgreSQL error code: %s" %
                                   sqlstate,
                                   httpcode=500,
                                   devMessage=("PostgreSQL error message: %s" %
                                               sp_settings['result'].message))
        response_obj.setError('easyspid105')
        result['result'] = response_obj

    else:
        result['error'] = sp_settings['error']
        result['result'] = sp_settings['result']

    return result
from app import app
from distutils.version import StrictVersion
from urllib.parse import urlparse
from datetime import datetime, timedelta
from threading import Thread

from .certutil import KEY_FILE, CERT_FILE

if app.config['SAML_ENABLED']:
    from onelogin.saml2.auth import OneLogin_Saml2_Auth
    from onelogin.saml2.idp_metadata_parser import OneLogin_Saml2_IdPMetadataParser
    idp_timestamp = datetime(1970, 1, 1)
    idp_data = None
    if 'SAML_IDP_ENTITY_ID' in app.config:
        idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote(app.config['SAML_METADATA_URL'], entity_id=app.config.get('SAML_IDP_ENTITY_ID', None), required_sso_binding=app.config['SAML_IDP_SSO_BINDING'])
    else:
        idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote(app.config['SAML_METADATA_URL'], entity_id=app.config.get('SAML_IDP_ENTITY_ID', None))
    if idp_data is None:
        print('SAML: IDP Metadata initial load failed')
        exit(-1)
    idp_timestamp = datetime.now()


def get_idp_data():
    global idp_data, idp_timestamp
    lifetime = timedelta(minutes=app.config['SAML_METADATA_CACHE_LIFETIME'])
    if idp_timestamp+lifetime < datetime.now():
        background_thread = Thread(target=retrieve_idp_data)
        background_thread.start()
    return idp_data
Exemplo n.º 42
0
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, '', ''