def testIsValid(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        """
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html'
        }
        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())

        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))

        settings.set_strict(True)
        self.assertFalse(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))

        settings.set_strict(False)
        dom = parseString(request)
        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, dom, request_data))

        settings.set_strict(True)
        self.assertFalse(OneLogin_Saml2_Logout_Request.is_valid(settings, dom, request_data))

        current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)
        request_2 = request.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url)
        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data))
    def testIsInvalidDestination(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        Case Invalid Destination
        """
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html'
        }
        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))

        settings.set_strict(True)
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('The LogoutRequest was received at', e.message)

        dom = parseString(request)
        dom.documentElement.setAttribute('Destination', None)
        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, dom.toxml(), request_data))

        dom.documentElement.removeAttribute('Destination')
        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, dom.toxml(), request_data))
    def testGetIDFromSAMLLogoutRequest(self):
        """
        Tests the get_id method of the OneLogin_Saml2_LogoutRequest
        """
        logout_request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        id = OneLogin_Saml2_Logout_Request.get_id(logout_request)
        self.assertEqual('ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e', id)

        dom = parseString(logout_request)
        id2 = OneLogin_Saml2_Logout_Request.get_id(dom)
        self.assertEqual('ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e', id2)
Example #4
0
    def process_slo(self, keep_local_session=False, request_id=None, delete_session_cb=None):
        """
        Process the SAML Logout Response / Logout Request sent by the IdP.

        :param keep_local_session: When false will destroy the local session, otherwise will destroy it
        :type keep_local_session: bool

        :param request_id: The ID of the LogoutRequest sent by this SP to the IdP
        :type request_id: string

        :returns: Redirection url
        """
        self.__errors = []

        if 'get_data' in self.__request_data and 'SAMLResponse' in self.__request_data['get_data']:
            logout_response = OneLogin_Saml2_Logout_Response(self.__settings, self.__request_data['get_data']['SAMLResponse'])
            if not logout_response.is_valid(self.__request_data, request_id):
                self.__errors.append('invalid_logout_response')
            elif logout_response.get_status() != OneLogin_Saml2_Constants.STATUS_SUCCESS:
                self.__errors.append('logout_not_success')
            elif not keep_local_session:
                OneLogin_Saml2_Utils.delete_local_session(delete_session_cb)

        elif 'get_data' in self.__request_data and 'SAMLRequest' in self.__request_data['get_data']:
            request = OneLogin_Saml2_Utils.decode_base64_and_inflate(self.__request_data['get_data']['SAMLRequest'])
            if not OneLogin_Saml2_Logout_Request.is_valid(self.__settings, request, self.__request_data):
                self.__errors.append('invalid_logout_request')
            else:
                if not keep_local_session:
                    OneLogin_Saml2_Utils.delete_local_session(delete_session_cb)

                in_response_to = OneLogin_Saml2_Logout_Request.get_id(request)
                response_builder = OneLogin_Saml2_Logout_Response(self.__settings)
                response_builder.build(in_response_to)
                logout_response = response_builder.get_response()

                parameters = {'SAMLResponse': logout_response}
                if 'RelayState' in self.__request_data['get_data']:
                    parameters['RelayState'] = self.__request_data['get_data']['RelayState']

                security = self.__settings.get_security_data()
                if 'logoutResponseSigned' in security and security['logoutResponseSigned']:
                    parameters['SigAlg'] = OneLogin_Saml2_Constants.RSA_SHA1
                    parameters['Signature'] = self.build_response_signature(logout_response, parameters.get('RelayState', None))

                return self.redirect_to(self.get_slo_url(), parameters)
        else:
            self.__errors.append('invalid_binding')
            raise OneLogin_Saml2_Error(
                'SAML LogoutRequest/LogoutResponse not found. Only supported HTTP_REDIRECT Binding',
                OneLogin_Saml2_Error.SAML_LOGOUTMESSAGE_NOT_FOUND
            )
    def testIsInvalidXML(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        Case Invalid XML
        """
        request = '<xml>invalid</xml>'
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html'
        }
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())

        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))
        settings.set_strict(True)
        self.assertFalse(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))
    def testGetSessionIndexes(self):
        """
        Tests the get_session_indexes of the OneLogin_Saml2_LogoutRequest
        """
        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))

        session_indexes = OneLogin_Saml2_Logout_Request.get_session_indexes(request)
        self.assertEqual(len(session_indexes), 0)

        dom = parseString(request)
        session_indexes_2 = OneLogin_Saml2_Logout_Request.get_session_indexes(dom)
        self.assertEqual(len(session_indexes_2), 0)

        request_2 = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_with_sessionindex.xml'))
        session_indexes_3 = OneLogin_Saml2_Logout_Request.get_session_indexes(request_2)
        self.assertEqual(['_ac72a76526cb6ca19f8438e73879a0e6c8ae5131'], session_indexes_3)
    def testGetNameId(self):
        """
        Tests the get_nameid of the OneLogin_Saml2_LogoutRequest
        """
        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        name_id = OneLogin_Saml2_Logout_Request.get_nameid(request)
        self.assertEqual(name_id, 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c')

        request_2 = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_encrypted_nameid.xml'))
        self.assertRaisesRegexp(Exception, 'Key is required in order to decrypt the NameID',
                                OneLogin_Saml2_Logout_Request.get_nameid, request_2)

        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        key = settings.get_sp_key()
        name_id_3 = OneLogin_Saml2_Logout_Request.get_nameid(request_2, key)
        self.assertEqual('ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69', name_id_3)
    def testGetIssuer(self):
        """
        Tests the get_issuer of the OneLogin_Saml2_LogoutRequest
        """
        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))

        issuer = OneLogin_Saml2_Logout_Request.get_issuer(request)
        self.assertEqual('http://idp.example.com/', issuer)

        dom = parseString(request)
        issuer_2 = OneLogin_Saml2_Logout_Request.get_issuer(dom)
        self.assertEqual('http://idp.example.com/', issuer_2)

        issuer_node = dom.getElementsByTagName('saml:Issuer')[0]
        issuer_node.parentNode.removeChild(issuer_node)
        issuer_3 = OneLogin_Saml2_Logout_Request.get_issuer(dom)
        self.assertIsNone(issuer_3)
 def testGetIDFromDeflatedSAMLLogoutRequest(self):
     """
     Tests the get_id method of the OneLogin_Saml2_LogoutRequest
     """
     deflated_logout_request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_deflated.xml.base64'))
     logout_request = OneLogin_Saml2_Utils.decode_base64_and_inflate(deflated_logout_request)
     id = OneLogin_Saml2_Logout_Request.get_id(logout_request)
     self.assertEqual('ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e', id)
    def testGetNameIdData(self):
        """
        Tests the get_nameid_data method of the OneLogin_Saml2_LogoutRequest
        """
        expected_name_id_data = {
            'Value': 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c',
            'Format': 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
            'SPNameQualifier': 'http://idp.example.com/'
        }

        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(request)
        self.assertEqual(expected_name_id_data, name_id_data)

        dom = parseString(request)
        name_id_data_2 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom)
        self.assertEqual(expected_name_id_data, name_id_data_2)

        request_2 = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_encrypted_nameid.xml'))
        try:
            OneLogin_Saml2_Logout_Request.get_nameid_data(request_2)
            self.assertTrue(False)
        except Exception as e:
            self.assertIn('Key is required in order to decrypt the NameID', e.message)

        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        key = settings.get_sp_key()
        name_id_data_4 = OneLogin_Saml2_Logout_Request.get_nameid_data(request_2, key)
        expected_name_id_data = {
            'Value': 'ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69',
            'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress',
            'SPNameQualifier': 'https://pitbulk.no-ip.org/newonelogin/demo1/metadata.php'
        }
        self.assertEqual(expected_name_id_data, name_id_data_4)

        dom_2 = parseString(request_2)
        encrypted_id_nodes = dom_2.getElementsByTagName('saml:EncryptedID')
        encrypted_data = encrypted_id_nodes[0].firstChild.nextSibling
        encrypted_id_nodes[0].removeChild(encrypted_data)
        try:
            OneLogin_Saml2_Logout_Request.get_nameid_data(dom_2.toxml(), key)
            self.assertTre(False)
        except Exception as e:
            self.assertIn('Not NameID found in the Logout Request', e.message)

        inv_request = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'no_nameId.xml'))
        try:
            OneLogin_Saml2_Logout_Request.get_nameid_data(inv_request)
            self.assertTre(False)
        except Exception as e:
            self.assertIn('Not NameID found in the Logout Request', e.message)
    def testGetIssuer(self):
        """
        Tests the get_issuer of the OneLogin_Saml2_LogoutRequest
        """
        request = self.file_contents(
            join(self.data_path, 'logout_requests', 'logout_request.xml'))

        issuer = OneLogin_Saml2_Logout_Request.get_issuer(request)
        self.assertEqual('http://idp.example.com/', issuer)

        dom = parseString(request)
        issuer_2 = OneLogin_Saml2_Logout_Request.get_issuer(dom)
        self.assertEqual('http://idp.example.com/', issuer_2)

        issuer_node = dom.getElementsByTagName('saml:Issuer')[0]
        issuer_node.parentNode.removeChild(issuer_node)
        issuer_3 = OneLogin_Saml2_Logout_Request.get_issuer(dom)
        self.assertIsNone(issuer_3)
 def testConstructorWithNameIdFormatOnSettings(self):
     """
     Tests the OneLogin_Saml2_LogoutRequest Constructor.
     Case: Defines NameIDFormat from settings
     """
     settings_info = self.loadSettingsJSON()
     name_id = 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c'
     name_id_format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
     settings_info['sp']['NameIDFormat'] = name_id_format
     settings = OneLogin_Saml2_Settings(settings_info)
     logout_request = OneLogin_Saml2_Logout_Request(settings,
                                                    name_id=name_id)
     logout_request_xml = OneLogin_Saml2_Utils.decode_base64_and_inflate(
         logout_request.get_request())
     name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(
         logout_request_xml)
     expected_name_id_data = {'Value': name_id, 'Format': name_id_format}
     self.assertEqual(expected_name_id_data, name_id_data)
 def testConstructorWithoutNameIdFormat(self):
     """
     Tests the OneLogin_Saml2_LogoutRequest Constructor.
     Case: Checks that NameIDFormat is not added
     """
     settings_info = self.loadSettingsJSON()
     name_id = 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c'
     name_id_format = 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
     settings_info['sp']['NameIDFormat'] = name_id_format
     settings = OneLogin_Saml2_Settings(settings_info)
     logout_request = OneLogin_Saml2_Logout_Request(settings,
                                                    name_id=name_id)
     logout_request_xml = OneLogin_Saml2_Utils.decode_base64_and_inflate(
         logout_request.get_request())
     name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(
         logout_request_xml)
     expected_name_id_data = {'Value': name_id}
     self.assertEqual(expected_name_id_data, name_id_data)
Example #14
0
    def logout(self,
               return_to=None,
               name_id=None,
               session_index=None,
               nq=None):
        """
        Initiates the SLO process.

        :param return_to: Optional argument. The target URL the user should be redirected to after logout.
        :type return_to: string

        :param name_id: The NameID that will be set in the LogoutRequest.
        :type name_id: string

        :param session_index: SessionIndex that identifies the session of the user.
        :type session_index: string

        :param nq: IDP Name Qualifier
        :type: string

        :returns: Redirection url
        """
        slo_url = self.get_slo_url()
        if slo_url is None:
            raise OneLogin_Saml2_Error(
                'The IdP does not support Single Log Out',
                OneLogin_Saml2_Error.SAML_SINGLE_LOGOUT_NOT_SUPPORTED)

        if name_id is None and self.__nameid is not None:
            name_id = self.__nameid

        logout_request = OneLogin_Saml2_Logout_Request(
            self.__settings,
            name_id=name_id,
            session_index=session_index,
            nq=nq)

        self.__last_request_id = logout_request.id

        saml_request = logout_request.get_request()

        parameters = {'SAMLRequest': logout_request.get_request()}
        if return_to is not None:
            parameters['RelayState'] = return_to
        else:
            parameters[
                'RelayState'] = OneLogin_Saml2_Utils.get_self_url_no_query(
                    self.__request_data)

        security = self.__settings.get_security_data()
        if security.get('logoutRequestSigned', False):
            parameters['SigAlg'] = security['signatureAlgorithm']
            parameters['Signature'] = self.build_request_signature(
                saml_request, parameters['RelayState'],
                security['signatureAlgorithm'])
        return self.redirect_to(slo_url, parameters)
Example #15
0
    def testGetXML(self):
        """
        Tests that we can get the logout request XML directly without
        going through intermediate steps
        """
        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())

        logout_request_generated = OneLogin_Saml2_Logout_Request(settings)
        expectedFragment = (
            'Destination="http://idp.example.com/SingleLogoutService.php">\n'
            '    <saml:Issuer>http://stuff.com/endpoints/metadata.php</saml:Issuer>\n'
            '    <saml:NameID SPNameQualifier="http://stuff.com/endpoints/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://idp.example.com/</saml:NameID>\n'
            '    \n</samlp:LogoutRequest>'
        )
        self.assertIn(expectedFragment, logout_request_generated.get_xml())

        logout_request_processed = OneLogin_Saml2_Logout_Request(settings, OneLogin_Saml2_Utils.b64encode(request))
        self.assertEqual(request, logout_request_processed.get_xml())
    def testGetNameIdData(self):
        """
        Tests the get_nameid_data method of the OneLogin_Saml2_LogoutRequest
        """
        expected_name_id_data = {
            'Value': 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c',
            'Format': 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
            'SPNameQualifier': 'http://idp.example.com/'
        }

        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(request)
        self.assertEqual(expected_name_id_data, name_id_data)

        dom = parseString(request)
        name_id_data_2 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom.toxml())
        self.assertEqual(expected_name_id_data, name_id_data_2)

        request_2 = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_encrypted_nameid.xml'))
        with self.assertRaises(Exception) as context:
            OneLogin_Saml2_Logout_Request.get_nameid(request_2)
            exception = context.exception
            self.assertIn("Key is required in order to decrypt the NameID", str(exception))

        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        key = settings.get_sp_key()
        name_id_data_4 = OneLogin_Saml2_Logout_Request.get_nameid_data(request_2, key)
        expected_name_id_data = {
            'Value': 'ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69',
            'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress',
            'SPNameQualifier': 'https://pitbulk.no-ip.org/newonelogin/demo1/metadata.php'
        }
        self.assertEqual(expected_name_id_data, name_id_data_4)

        dom_2 = parseString(request_2)
        encrypted_id_nodes = dom_2.getElementsByTagName('saml:EncryptedID')
        encrypted_data = encrypted_id_nodes[0].firstChild.nextSibling
        encrypted_id_nodes[0].removeChild(encrypted_data)
        with self.assertRaises(Exception) as context:
            OneLogin_Saml2_Logout_Request.get_nameid(dom_2.toxml(), key)
            exception = context.exception
            self.assertIn("Not NameID found in the Logout Request", str(exception))

        inv_request = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'no_nameId.xml'))
        with self.assertRaises(Exception) as context:
            OneLogin_Saml2_Logout_Request.get_nameid(inv_request)
            exception = context.exception
            self.assertIn("Not NameID found in the Logout Request", str(exception))
Example #17
0
    def testGetNameId(self):
        """
        Tests the get_nameid of the OneLogin_Saml2_LogoutRequest
        """
        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        name_id = OneLogin_Saml2_Logout_Request.get_nameid(request)
        self.assertEqual(name_id, 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c')

        request_2 = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_encrypted_nameid.xml'))
        try:
            OneLogin_Saml2_Logout_Request.get_nameid(request_2)
            self.assertTrue(False)
        except Exception as e:
            self.assertIn('Key is required in order to decrypt the NameID', e.message)

        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        key = settings.get_sp_key()
        name_id_3 = OneLogin_Saml2_Logout_Request.get_nameid(request_2, key)
        self.assertEqual('ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69', name_id_3)
    def testIsInvalidXML(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        Case Invalid XML
        """
        request = b64encode('<xml>invalid</xml>')
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html',
        }
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())

        logout_request = OneLogin_Saml2_Logout_Request(settings, request)

        self.assertTrue(logout_request.is_valid(request_data))

        settings.set_strict(True)
        logout_request2 = OneLogin_Saml2_Logout_Request(settings, request)
        self.assertFalse(logout_request2.is_valid(request_data))
    def testIsInvalidIssuer(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        Case Invalid Issuer
        """
        request = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'invalid_issuer.xml'))
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html'
        }
        current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)
        request = request.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url)
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        logout_request = OneLogin_Saml2_Logout_Request(settings, b64encode(request))
        self.assertTrue(logout_request.is_valid(request_data))

        settings.set_strict(True)
        logout_request2 = OneLogin_Saml2_Logout_Request(settings, b64encode(request))
        self.assertFalse(logout_request2.is_valid(request_data))
        self.assertIn('Invalid issuer in the Logout Request', logout_request2.get_error())
Example #20
0
    def process_slo(self, keep_local_session=False, request_id=None, delete_session_cb=None):
        """
        Process the SAML Logout Response / Logout Request sent by the IdP.

        :param keep_local_session: When false will destroy the local session, otherwise will destroy it
        :type keep_local_session: bool

        :param request_id: The ID of the LogoutRequest sent by this SP to the IdP
        :type request_id: string

        :returns: Redirection url
        """
        self.__errors = []

        if 'get_data' in self.__request_data and 'SAMLResponse' in self.__request_data['get_data']:
            logout_response = OneLogin_Saml2_Logout_Response(self.__settings, self.__request_data['get_data']['SAMLResponse'])
            if not logout_response.is_valid(self.__request_data, request_id):
                self.__errors.append('invalid_logout_response')
                self.__error_reason = logout_response.get_error()
            elif logout_response.get_status() != OneLogin_Saml2_Constants.STATUS_SUCCESS:
                self.__errors.append('logout_not_success')
            elif not keep_local_session:
                OneLogin_Saml2_Utils.delete_local_session(delete_session_cb)

        elif 'get_data' in self.__request_data and 'SAMLRequest' in self.__request_data['get_data']:
            logout_request = OneLogin_Saml2_Logout_Request(self.__settings, self.__request_data['get_data']['SAMLRequest'])
            if not logout_request.is_valid(self.__request_data):
                self.__errors.append('invalid_logout_request')
                self.__error_reason = logout_request.get_error()
            else:
                if not keep_local_session:
                    OneLogin_Saml2_Utils.delete_local_session(delete_session_cb)

                in_response_to = logout_request.id
                response_builder = OneLogin_Saml2_Logout_Response(self.__settings)
                response_builder.build(in_response_to)
                logout_response = response_builder.get_response()

                parameters = {'SAMLResponse': logout_response}
                if 'RelayState' in self.__request_data['get_data']:
                    parameters['RelayState'] = self.__request_data['get_data']['RelayState']

                security = self.__settings.get_security_data()
                if 'logoutResponseSigned' in security and security['logoutResponseSigned']:
                    parameters['SigAlg'] = security['signatureAlgorithm']
                    parameters['Signature'] = self.build_response_signature(logout_response, parameters.get('RelayState', None), security['signatureAlgorithm'])

                return self.redirect_to(self.get_slo_url(), parameters)
        else:
            self.__errors.append('invalid_binding')
            raise OneLogin_Saml2_Error(
                'SAML LogoutRequest/LogoutResponse not found. Only supported HTTP_REDIRECT Binding',
                OneLogin_Saml2_Error.SAML_LOGOUTMESSAGE_NOT_FOUND
            )
    def testIsInvalidNotOnOrAfter(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        Case Invalid NotOnOrAfter
        """
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html'
        }
        request = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'not_after_failed.xml'))
        current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)
        request = request.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url)
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))

        settings.set_strict(True)
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('Timing issues (please check your clock settings)', e.message)
 def testGetIDFromDeflatedSAMLLogoutRequest(self):
     """
     Tests the get_id method of the OneLogin_Saml2_LogoutRequest
     """
     deflated_logout_request = self.file_contents(
         join(self.data_path, 'logout_requests',
              'logout_request_deflated.xml.base64'))
     logout_request = OneLogin_Saml2_Utils.decode_base64_and_inflate(
         deflated_logout_request)
     id = OneLogin_Saml2_Logout_Request.get_id(logout_request)
     self.assertEqual('ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e',
                      id)
    def testIsInvalidNotOnOrAfter(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        Case Invalid NotOnOrAfter
        """
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html'
        }
        request = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'not_after_failed.xml'))
        current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)
        request = request.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url)
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())

        logout_request = OneLogin_Saml2_Logout_Request(settings, b64encode(request))
        self.assertTrue(logout_request.is_valid(request_data))

        settings.set_strict(True)
        logout_request2 = OneLogin_Saml2_Logout_Request(settings, b64encode(request))
        self.assertFalse(logout_request2.is_valid(request_data))
        self.assertIn('Could not validate timestamp: expired. Check system clock.', logout_request2.get_error())
Example #24
0
    def testIsInValidWithCapitalization(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        """
        request_data = {
            'http_host': 'example.com',
            'script_name': 'INdex.html'
        }
        request = self.file_contents(
            join(self.data_path, 'logout_requests', 'logout_request.xml'))
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())

        logout_request = OneLogin_Saml2_Logout_Request(settings,
                                                       b64encode(request))
        self.assertTrue(logout_request.is_valid(request_data))

        settings.set_strict(True)
        logout_request2 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(request))
        self.assertFalse(logout_request2.is_valid(request_data))

        settings.set_strict(False)
        dom = parseString(request)
        logout_request3 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(dom.toxml()))
        self.assertTrue(logout_request3.is_valid(request_data))

        settings.set_strict(True)
        logout_request4 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(dom.toxml()))
        self.assertFalse(logout_request4.is_valid(request_data))

        current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)
        request = request.replace(
            'http://stuff.com/endpoints/endpoints/sls.php',
            current_url.lower())
        logout_request5 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(request))
        self.assertFalse(logout_request5.is_valid(request_data))
Example #25
0
    def testLogoutNameIDandSessionIndex(self):
        """
        Tests the logout method of the OneLogin_Saml2_Auth class
        Case nameID and sessionIndex as parameters.
        """
        settings_info = self.loadSettingsJSON()
        request_data = self.get_request()
        auth = OneLogin_Saml2_Auth(request_data, old_settings=settings_info)

        name_id = 'name_id_example'
        session_index = 'session_index_example'
        target_url = auth.logout(name_id=name_id, session_index=session_index)
        parsed_query = parse_qs(urlparse(target_url)[4])
        slo_url = settings_info['idp']['singleLogoutService']['url']
        self.assertIn(slo_url, target_url)
        self.assertIn('SAMLRequest', parsed_query)

        logout_request = OneLogin_Saml2_Utils.decode_base64_and_inflate(parsed_query['SAMLRequest'][0])
        name_id_from_request = OneLogin_Saml2_Logout_Request.get_nameid(logout_request)
        sessions_index_in_request = OneLogin_Saml2_Logout_Request.get_session_indexes(logout_request)
        self.assertIn(session_index, sessions_index_in_request)
        self.assertEqual(name_id, name_id_from_request)
    def testGetSessionIndexes(self):
        """
        Tests the get_session_indexes of the OneLogin_Saml2_LogoutRequest
        """
        request = self.file_contents(
            join(self.data_path, 'logout_requests', 'logout_request.xml'))

        session_indexes = OneLogin_Saml2_Logout_Request.get_session_indexes(
            request)
        self.assertEqual(len(session_indexes), 0)

        dom = parseString(request)
        session_indexes_2 = OneLogin_Saml2_Logout_Request.get_session_indexes(
            dom)
        self.assertEqual(len(session_indexes_2), 0)

        request_2 = self.file_contents(
            join(self.data_path, 'logout_requests',
                 'logout_request_with_sessionindex.xml'))
        session_indexes_3 = OneLogin_Saml2_Logout_Request.get_session_indexes(
            request_2)
        self.assertEqual(['_ac72a76526cb6ca19f8438e73879a0e6c8ae5131'],
                         session_indexes_3)
    def testIsValidRaisesExceptionWhenRaisesArgumentIsTrue(self):
        request = OneLogin_Saml2_Utils.deflate_and_base64_encode('<xml>invalid</xml>')
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html'
        }
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        settings.set_strict(True)

        logout_request = OneLogin_Saml2_Logout_Request(settings, request)

        self.assertFalse(logout_request.is_valid(request_data))

        with self.assertRaisesRegexp(OneLogin_Saml2_ValidationError, "Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd"):
            logout_request.is_valid(request_data, raise_exceptions=True)
    def testIsValidRaisesExceptionWhenRaisesArgumentIsTrue(self):
        request = OneLogin_Saml2_Utils.b64encode('<xml>invalid</xml>')
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html',
        }
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        settings.set_strict(True)

        logout_request = OneLogin_Saml2_Logout_Request(settings, request)

        self.assertFalse(logout_request.is_valid(request_data))

        with self.assertRaises(Exception):
            logout_request.is_valid(request_data, raise_exceptions=True)
Example #29
0
    def testCreateDeflatedSAMLLogoutRequestURLParameter(self):
        """
        Tests the OneLogin_Saml2_LogoutRequest Constructor.
        The creation of a deflated SAML Logout Request
        """
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        logout_request = OneLogin_Saml2_Logout_Request(settings)

        parameters = {'SAMLRequest': logout_request.get_request()}
        logout_url = OneLogin_Saml2_Utils.redirect('http://idp.example.com/SingleLogoutService.php', parameters, True)
        self.assertRegexpMatches(logout_url, '^http://idp\.example\.com\/SingleLogoutService\.php\?SAMLRequest=')
        url_parts = urlparse(logout_url)
        exploded = parse_qs(url_parts.query)
        payload = exploded['SAMLRequest'][0]
        inflated = OneLogin_Saml2_Utils.decode_base64_and_inflate(payload)
        self.assertRegexpMatches(inflated, '^<samlp:LogoutRequest')
 def testConstructorWithoutNameIdFormat(self):
     """
     Tests the OneLogin_Saml2_LogoutRequest Constructor.
     Case: Checks that NameIDFormat is not added
     """
     settings_info = self.loadSettingsJSON()
     name_id = 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c'
     name_id_format = 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
     settings_info['sp']['NameIDFormat'] = name_id_format
     settings = OneLogin_Saml2_Settings(settings_info)
     logout_request = OneLogin_Saml2_Logout_Request(settings, name_id=name_id)
     logout_request_xml = OneLogin_Saml2_Utils.decode_base64_and_inflate(logout_request.get_request())
     name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(logout_request_xml)
     expected_name_id_data = {
         'Value': name_id
     }
     self.assertEqual(expected_name_id_data, name_id_data)
 def testConstructorWithNameIdFormatOnSettings(self):
     """
     Tests the OneLogin_Saml2_LogoutRequest Constructor.
     Case: Defines NameIDFormat from settings
     """
     settings_info = self.loadSettingsJSON()
     name_id = 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c'
     name_id_format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
     settings_info['sp']['NameIDFormat'] = name_id_format
     settings = OneLogin_Saml2_Settings(settings_info)
     logout_request = OneLogin_Saml2_Logout_Request(settings, name_id=name_id)
     logout_request_xml = OneLogin_Saml2_Utils.decode_base64_and_inflate(logout_request.get_request())
     name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(logout_request_xml)
     expected_name_id_data = {
         'Value': name_id,
         'Format': name_id_format
     }
     self.assertEqual(expected_name_id_data, name_id_data)
Example #32
0
    def testConstructor(self):
        """
        Tests the OneLogin_Saml2_LogoutRequest Constructor.
        """
        settings_info = self.loadSettingsJSON()
        settings_info['security']['nameIdEncrypted'] = True
        settings = OneLogin_Saml2_Settings(settings_info)

        logout_request = OneLogin_Saml2_Logout_Request(settings)

        parameters = {'SAMLRequest': logout_request.get_request()}
        logout_url = OneLogin_Saml2_Utils.redirect('http://idp.example.com/SingleLogoutService.php', parameters, True)
        self.assertRegex(logout_url, '^http://idp\.example\.com\/SingleLogoutService\.php\?SAMLRequest=')
        url_parts = urlparse(logout_url)
        exploded = parse_qs(url_parts.query)
        payload = exploded['SAMLRequest'][0]
        inflated = compat.to_string(OneLogin_Saml2_Utils.decode_base64_and_inflate(payload))
        self.assertRegex(inflated, '^<samlp:LogoutRequest')
 def testIsValidSignUsingX509certMulti(self):
     """
     Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
     """
     request_data = {
         'http_host': 'example.com',
         'script_name': 'index.html',
         'get_data': {
             'SAMLRequest': 'fZJNa+MwEIb/itHdiTz6sC0SQyEsBPoB27KHXoIsj7cGW3IlGfLzV7G7kN1DL2KYmeedmRcdgp7GWT26326JP/FzwRCz6zTaoNbKkSzeKqfDEJTVEwYVjXp9eHpUsKNq9i4640Zyh3xP6BDQx8FZkp1PR3KpqexAl72QmpUCS8SW01IiZz2TVVGD4X1VQYlAsl/oQyKPJAklPIQFzzZEbWNK0YLnlOVA3wqpQCoB7yQ7pWsGq+NKfcQ4q/0+xKXvd8ZNe7Td7AYbw10UxrCbP2aSPbv4Yl/8Qx/R3+SB5bTOoXiDQvFNvjnc7lXrIr75kh+6eYdXPc0jrkMO+/umjXhOtpxP2Q/nJx2/9+uWGbq8X1tV9NqGAW0kzaVvoe1AAJeCSWqYaUVRM2SilKKuqDTpFSlszdcK29RthVm9YriZebYdXpsLdhVAB7VJzif3haYMqqTVcl0JMBR4y+s2zak3sf/4v8l/vlHzBw==',
             'RelayState': '_1037fbc88ec82ce8e770b2bed1119747bb812a07e6',
             'SigAlg': 'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
             'Signature': 'Ouxo9BV6zmq4yrgamT9EbSKy/UmvSxGS8z26lIMgKOEP4LFR/N23RftdANmo4HafrzSfA0YTXwhKDqbOByS0j+Ql8OdQOes7vGioSjo5qq/Bi+5i6jXwQfphnfcHAQiJL4gYVIifkhhHRWpvYeiysF1Y9J02me0izwazFmoRXr4='
         }
     }
     settings_info = self.loadSettingsJSON('settings8.json')
     settings_info['strict'] = False
     settings = OneLogin_Saml2_Settings(settings_info)
     logout_request = OneLogin_Saml2_Logout_Request(settings, request_data['get_data']['SAMLRequest'])
     self.assertTrue(logout_request.is_valid(request_data))
    def testConstructorEncryptIdUsingX509certMulti(self):
        """
        Tests the OneLogin_Saml2_LogoutRequest Constructor.
        Case: Able to generate encryptedID with MultiCert
        """
        settings_info = self.loadSettingsJSON('settings8.json')
        settings_info['security']['nameIdEncrypted'] = True
        settings = OneLogin_Saml2_Settings(settings_info)

        logout_request = OneLogin_Saml2_Logout_Request(settings)

        parameters = {'SAMLRequest': logout_request.get_request()}
        logout_url = OneLogin_Saml2_Utils.redirect('http://idp.example.com/SingleLogoutService.php', parameters, True)
        self.assertRegexpMatches(logout_url, r'^http://idp\.example\.com\/SingleLogoutService\.php\?SAMLRequest=')
        url_parts = urlparse(logout_url)
        exploded = parse_qs(url_parts.query)
        payload = exploded['SAMLRequest'][0]
        inflated = OneLogin_Saml2_Utils.decode_base64_and_inflate(payload)
        self.assertRegexpMatches(inflated, '^<samlp:LogoutRequest')
        self.assertRegexpMatches(inflated, '<saml:EncryptedID>')
Example #35
0
    def testLogoutNameID(self):
        """
        Tests the logout method of the OneLogin_Saml2_Auth class
        Case nameID loaded after process SAML Response
        """
        request_data = self.get_request()
        message = self.file_contents(join(self.data_path, "responses", "valid_response.xml.base64"))
        del request_data["get_data"]
        request_data["post_data"] = {"SAMLResponse": message}
        auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON())
        auth.process_response()

        name_id_from_response = auth.get_nameid()

        target_url = auth.logout()
        parsed_query = parse_qs(urlparse(target_url)[4])
        self.assertIn("SAMLRequest", parsed_query)
        logout_request = OneLogin_Saml2_Utils.decode_base64_and_inflate(parsed_query["SAMLRequest"][0])

        name_id_from_request = OneLogin_Saml2_Logout_Request.get_nameid(logout_request)
        self.assertEqual(name_id_from_response, name_id_from_request)
Example #36
0
    def process_slo(self,
                    keep_local_session=False,
                    request_id=None,
                    delete_session_cb=None):
        """
        Process the SAML Logout Response / Logout Request sent by the IdP.

        :param keep_local_session: When false will destroy the local session, otherwise will destroy it
        :type keep_local_session: bool

        :param request_id: The ID of the LogoutRequest sent by this SP to the IdP
        :type request_id: string

        :returns: Redirection url
        """
        self.__errors = []
        self.__error_reason = None

        post_data = 'post_data' in self._SpidSaml2Auth__request_data and self._SpidSaml2Auth__request_data[
            'post_data']
        get_data = 'get_data' in self._SpidSaml2Auth__request_data and self._SpidSaml2Auth__request_data[
            'get_data']
        method = 'redirect'
        if post_data:
            get_data = post_data
            method = 'post'
        elif get_data and 'SAMLResponse' in get_data:
            logout_response = SpidSaml2LogoutResponse(self.__settings,
                                                      get_data['SAMLResponse'],
                                                      method)
            self._OneLogin_Saml2_Auth__last_response = logout_response.get_xml(
            )
            if not self.validate_response_signature(get_data):
                self.__errors.append('invalid_logout_response_signature')
                self.__errors.append(
                    'Signature validation failed. Logout Response rejected')
            if not logout_response.is_valid(self.__request_data, request_id):
                self.__errors.append('invalid_logout_response')
                self.__error_reason = logout_response.get_error()
            elif logout_response.get_status(
            ) != OneLogin_Saml2_Constants.STATUS_SUCCESS:
                self.__errors.append('logout_not_success')
            else:
                self._OneLogin_Saml2_Auth__last_message_id = logout_response.id
                if not keep_local_session:
                    OneLogin_Saml2_Utils.delete_local_session(
                        delete_session_cb)

        elif get_data and 'SAMLRequest' in get_data:
            logout_request = OneLogin_Saml2_Logout_Request(
                self.__settings, get_data['SAMLRequest'])
            self._OneLogin_Saml2_Auth__last_request = logout_request.get_xml()
            if not self.validate_request_signature(get_data):
                self.__errors.append("invalid_logout_request_signature")
                self.__errors.append(
                    'Signature validation failed. Logout Request rejected')
            elif not logout_request.is_valid(self.__request_data):
                self.__errors.append('invalid_logout_request')
                self.__error_reason = logout_request.get_error()
            else:
                if not keep_local_session:
                    OneLogin_Saml2_Utils.delete_local_session(
                        delete_session_cb)

                in_response_to = logout_request.id
                self._OneLogin_Saml2_Auth__last_message_id = logout_request.id
                response_builder = OneLogin_Saml2_Logout_Response(
                    self.__settings, method)
                response_builder.build(in_response_to)
                self._OneLogin_Saml2_Auth__last_response = response_builder.get_xml(
                )
                logout_response = response_builder.get_response()

                parameters = {'SAMLResponse': logout_response}
                if 'RelayState' in self._OneLogin_Saml2_Auth__request_data[
                        'get_data']:
                    parameters['RelayState'] = self.__request_data['get_data'][
                        'RelayState']

                security = self._OneLogin_Saml2_Auth__settings.get_security_data(
                )
                if security['logoutResponseSigned']:
                    self.add_response_signature(parameters,
                                                security['signatureAlgorithm'])

                return self.redirect_to(self.get_slo_url(), parameters)
        else:
            self.__errors.append('invalid_binding')
            raise OneLogin_Saml2_Error(
                'SAML LogoutRequest/LogoutResponse not found. Only supported HTTP_REDIRECT Binding',
                OneLogin_Saml2_Error.SAML_LOGOUTMESSAGE_NOT_FOUND)
    def testGetNameIdData(self):
        """
        Tests the get_nameid_data method of the OneLogin_Saml2_LogoutRequest
        """
        expected_name_id_data = {
            'Value': 'ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c',
            'Format': 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
            'SPNameQualifier': 'http://idp.example.com/'
        }

        request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml'))
        name_id_data = OneLogin_Saml2_Logout_Request.get_nameid_data(request)
        self.assertEqual(expected_name_id_data, name_id_data)

        dom = parseString(request)
        name_id_data_2 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom)
        self.assertEqual(expected_name_id_data, name_id_data_2)

        request_2 = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_encrypted_nameid.xml'))
        with self.assertRaisesRegexp(OneLogin_Saml2_Error, 'Key is required in order to decrypt the NameID'):
            OneLogin_Saml2_Logout_Request.get_nameid_data(request_2)

        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        key = settings.get_sp_key()
        name_id_data_4 = OneLogin_Saml2_Logout_Request.get_nameid_data(request_2, key)
        expected_name_id_data = {
            'Value': 'ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69',
            'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress',
            'SPNameQualifier': 'https://pitbulk.no-ip.org/newonelogin/demo1/metadata.php'
        }
        self.assertEqual(expected_name_id_data, name_id_data_4)

        dom_2 = parseString(request_2)
        encrypted_id_nodes = dom_2.getElementsByTagName('saml:EncryptedID')
        encrypted_data = encrypted_id_nodes[0].firstChild.nextSibling
        encrypted_id_nodes[0].removeChild(encrypted_data)
        with self.assertRaisesRegexp(OneLogin_Saml2_ValidationError, 'NameID not found in the Logout Request'):
            OneLogin_Saml2_Logout_Request.get_nameid_data(dom_2.toxml(), key)

        idp_data = settings.get_idp_data()
        sp_data = settings.get_sp_data()
        expected_name_id_data = {
            'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress',
            'NameQualifier': idp_data['entityId'],
            'SPNameQualifier': sp_data['entityId'],
            'Value': 'ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69'
        }

        inv_request = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'no_nameId.xml'))
        with self.assertRaisesRegexp(OneLogin_Saml2_ValidationError, 'NameID not found in the Logout Request'):
            OneLogin_Saml2_Logout_Request.get_nameid_data(inv_request)

        logout_request = OneLogin_Saml2_Logout_Request(settings, None, expected_name_id_data['Value'], None, idp_data['entityId'], expected_name_id_data['Format'])
        dom = parseString(logout_request.get_xml())
        name_id_data_3 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom)
        self.assertEqual(expected_name_id_data, name_id_data_3)

        expected_name_id_data = {
            'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress',
            'Value': 'ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69'
        }
        logout_request = OneLogin_Saml2_Logout_Request(settings, None, expected_name_id_data['Value'], None, None, expected_name_id_data['Format'])
        dom = parseString(logout_request.get_xml())
        name_id_data_4 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom)
        self.assertEqual(expected_name_id_data, name_id_data_4)

        expected_name_id_data = {
            'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity',
            'Value': 'http://idp.example.com/'
        }
        logout_request = OneLogin_Saml2_Logout_Request(settings)
        dom = parseString(logout_request.get_xml())
        name_id_data_5 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom)
        self.assertEqual(expected_name_id_data, name_id_data_5)
    def testIsValidSign(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        """
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html',
            'get_data': {
                'SAMLRequest':
                'lVLBitswEP0Vo7tjeWzJtki8LIRCYLvbNksPewmyPc6K2pJqyXQ/v1LSQlroQi/DMJr33rwZbZ2cJysezNms/gt+X9H55G2etBOXlx1ZFy2MdMoJLWd0wvfieP/xQcCGCrsYb3ozkRvI+wjpHC5eGU2Sw35HTg3lA8hqZFwWFcMKsStpxbEsxoLXeQN9OdY1VAgk+YqLC8gdCUQB7tyKB+281D6UaF6mtEiBPudcABcMXkiyD26Ulv6CevXeOpFlVvlunb5ttEmV3ZjlnGn8YTRO5qx0NuBs8kzpAd829tXeucmR5NH4J/203I8el6gFRUqbFPJnyEV51Wq30by4TLW0/9ZyarYTxt4sBsjUYLMZvRykl1Fxm90SXVkfwx4P++T4KSafVzmpUcVJ/sfSrQZJPphllv79W8WKGtLx0ir8IrVTqD1pT2MH3QAMSs4KTvui71jeFFiwirOmprwPkYW063+5uRq4urHiiC4e8hCX3J5wqAEGaPpw9XB5JmkBdeDqSlkz6CmUXdl0Qae5kv2F/1384wu3PwE=',
                'RelayState':
                '_1037fbc88ec82ce8e770b2bed1119747bb812a07e6',
                'SigAlg':
                'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
                'Signature':
                'XCwCyI5cs7WhiJlB5ktSlWxSBxv+6q2xT3c8L7dLV6NQG9LHWhN7gf8qNsahSXfCzA0Ey9dp5BQ0EdRvAk2DIzKmJY6e3hvAIEp1zglHNjzkgcQmZCcrkK9Czi2Y1WkjOwR/WgUTUWsGJAVqVvlRZuS3zk3nxMrLH6f7toyvuJc='
            }
        }
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)

        request = OneLogin_Saml2_Utils.decode_base64_and_inflate(
            request_data['get_data']['SAMLRequest'])

        settings.set_strict(False)
        logout_request = OneLogin_Saml2_Logout_Request(settings,
                                                       b64encode(request))
        self.assertTrue(logout_request.is_valid(request_data))

        relayState = request_data['get_data']['RelayState']
        del request_data['get_data']['RelayState']
        self.assertFalse(logout_request.is_valid(request_data))
        request_data['get_data']['RelayState'] = relayState

        settings.set_strict(True)
        logout_request2 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(request))
        self.assertFalse(logout_request2.is_valid(request_data))
        self.assertIn('The LogoutRequest was received at',
                      logout_request2.get_error())

        settings.set_strict(False)
        old_signature = request_data['get_data']['Signature']
        request_data['get_data'][
            'Signature'] = 'vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVf3333='
        logout_request3 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(request))
        self.assertFalse(logout_request3.is_valid(request_data))
        self.assertIn('Signature validation failed. Logout Request rejected',
                      logout_request3.get_error())

        request_data['get_data']['Signature'] = old_signature
        old_signature_algorithm = request_data['get_data']['SigAlg']
        del request_data['get_data']['SigAlg']
        self.assertTrue(logout_request3.is_valid(request_data))

        request_data['get_data'][
            'RelayState'] = 'http://example.com/relaystate'
        self.assertFalse(logout_request3.is_valid(request_data))
        self.assertIn('Signature validation failed. Logout Request rejected',
                      logout_request3.get_error())

        settings.set_strict(True)
        request_2 = request.replace(
            'https://pitbulk.no-ip.org/newonelogin/demo1/index.php?sls',
            current_url)
        request_2 = request_2.replace(
            'https://pitbulk.no-ip.org/simplesaml/saml2/idp/metadata.php',
            'http://idp.example.com/')
        request_data['get_data'][
            'SAMLRequest'] = OneLogin_Saml2_Utils.deflate_and_base64_encode(
                request_2)
        logout_request4 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(request_2))
        self.assertFalse(logout_request4.is_valid(request_data))
        self.assertIn('Signature validation failed. Logout Request rejected',
                      logout_request4.get_error())

        settings.set_strict(False)
        logout_request5 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(request_2))
        self.assertFalse(logout_request5.is_valid(request_data))
        self.assertIn('Signature validation failed. Logout Request rejected',
                      logout_request5.get_error())

        request_data['get_data'][
            'SigAlg'] = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1'
        self.assertFalse(logout_request5.is_valid(request_data))
        self.assertIn('Signature validation failed. Logout Request rejected',
                      logout_request5.get_error())

        settings_info = self.loadSettingsJSON()
        settings_info['strict'] = True
        settings_info['security']['wantMessagesSigned'] = True
        settings = OneLogin_Saml2_Settings(settings_info)
        request_data['get_data']['SigAlg'] = old_signature_algorithm
        old_signature = request_data['get_data']['Signature']
        del request_data['get_data']['Signature']
        logout_request6 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(request_2))
        self.assertFalse(logout_request6.is_valid(request_data))
        self.assertIn(
            'The Message of the Logout Request is not signed and the SP require it',
            logout_request6.get_error())

        request_data['get_data']['Signature'] = old_signature
        settings_info['idp'][
            'certFingerprint'] = 'afe71c28ef740bc87425be13a2263d37971da1f9'
        del settings_info['idp']['x509cert']
        settings_2 = OneLogin_Saml2_Settings(settings_info)
        logout_request7 = OneLogin_Saml2_Logout_Request(
            settings_2, b64encode(request_2))
        self.assertFalse(logout_request7.is_valid(request_data))
        self.assertEqual(
            'In order to validate the sign on the Logout Request, the x509cert of the IdP is required',
            logout_request7.get_error())
    def testIsValidSign(self):
        """
        Tests the is_valid method of the OneLogin_Saml2_LogoutRequest
        """
        request_data = {
            'http_host': 'example.com',
            'script_name': 'index.html',
            'SAMLRequest': 'lVLBitswEP0Vo7tjeWzJtki8LIRCYLvbNksPewmyPc6K2pJqyXQ/v1LSQlroQi/DMJr33rwZbZ2cJysezNms/gt+X9H55G2etBOXlx1ZFy2MdMoJLWd0wvfieP/xQcCGCrsYb3ozkRvI+wjpHC5eGU2Sw35HTg3lA8hqZFwWFcMKsStpxbEsxoLXeQN9OdY1VAgk+YqLC8gdCUQB7tyKB+281D6UaF6mtEiBPudcABcMXkiyD26Ulv6CevXeOpFlVvlunb5ttEmV3ZjlnGn8YTRO5qx0NuBs8kzpAd829tXeucmR5NH4J/203I8el6gFRUqbFPJnyEV51Wq30by4TLW0/9ZyarYTxt4sBsjUYLMZvRykl1Fxm90SXVkfwx4P++T4KSafVzmpUcVJ/sfSrQZJPphllv79W8WKGtLx0ir8IrVTqD1pT2MH3QAMSs4KTvui71jeFFiwirOmprwPkYW063+5uRq4urHiiC4e8hCX3J5wqAEGaPpw9XB5JmkBdeDqSlkz6CmUXdl0Qae5kv2F/1384wu3PwE=',
            'RelayState': '_1037fbc88ec82ce8e770b2bed1119747bb812a07e6',
            'SigAlg': 'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
            'Signature': 'XCwCyI5cs7WhiJlB5ktSlWxSBxv+6q2xT3c8L7dLV6NQG9LHWhN7gf8qNsahSXfCzA0Ey9dp5BQ0EdRvAk2DIzKmJY6e3hvAIEp1zglHNjzkgcQmZCcrkK9Czi2Y1WkjOwR/WgUTUWsGJAVqVvlRZuS3zk3nxMrLH6f7toyvuJc='
        }
        settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
        current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)

        request = OneLogin_Saml2_Utils.decode_base64_and_inflate(request_data['SAMLRequest'])

        settings.set_strict(False)
        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))

        relayState = request_data['RelayState']
        del request_data['RelayState']
        self.assertFalse(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))
        request_data['RelayState'] = relayState

        settings.set_strict(True)
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('The LogoutRequest was received at', e.message)

        settings.set_strict(False)
        old_signature = request_data['Signature']
        request_data['Signature'] = 'vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVf3333='
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('Signature validation failed. Logout Request rejected', e.message)

        request_data['Signature'] = old_signature
        old_signature_algorithm = request_data['SigAlg']
        del request_data['SigAlg']
        self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))

        request_data['RelayState'] = 'http://example.com/relaystate'
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('Signature validation failed. Logout Request rejected', e.message)

        settings.set_strict(True)
        request_2 = request.replace('https://pitbulk.no-ip.org/newonelogin/demo1/index.php?sls', current_url)
        request_2 = request_2.replace('https://pitbulk.no-ip.org/simplesaml/saml2/idp/metadata.php', 'http://idp.example.com/')
        request_data['SAMLRequest'] = OneLogin_Saml2_Utils.deflate_and_base64_encode(request_2)
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('Signature validation failed. Logout Request rejected', e.message)

        settings.set_strict(False)
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('Signature validation failed. Logout Request rejected', e.message)

        request_data['SigAlg'] = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1'
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('Invalid signAlg in the recieved Logout Request', e.message)

        settings_info = self.loadSettingsJSON()
        settings_info['strict'] = True
        settings_info['security']['wantMessagesSigned'] = True
        settings = OneLogin_Saml2_Settings(settings_info)
        request_data['SigAlg'] = old_signature_algorithm
        old_signature = request_data['Signature']
        del request_data['Signature']
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('The Message of the Logout Request is not signed and the SP require it', e.message)

        request_data['Signature'] = old_signature
        settings_info['idp']['certFingerprint'] = 'afe71c28ef740bc87425be13a2263d37971da1f9'
        del settings_info['idp']['x509cert']
        settings_2 = OneLogin_Saml2_Settings(settings_info)
        try:
            valid = OneLogin_Saml2_Logout_Request.is_valid(settings_2, request_2, request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('In order to validate the sign on the Logout Request, the x509cert of the IdP is required', e.message)