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())
    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())
    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())
        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('The LogoutRequest was received at',
                      logout_request2.get_error())

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

        dom.documentElement.removeAttribute('Destination')
        logout_request4 = OneLogin_Saml2_Logout_Request(
            settings, b64encode(dom.toxml()))
        self.assertTrue(logout_request4.is_valid(request_data))
    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)
        try:
            logout_request2 = OneLogin_Saml2_Logout_Request(
                settings, b64encode(request))
            valid = logout_request2.is_valid(request_data)
            self.assertFalse(valid)
        except Exception as e:
            self.assertIn('Timing issues (please check your clock settings)',
                          e.message)
Beispiel #5
0
    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())

        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)
        logout_request5 = OneLogin_Saml2_Logout_Request(settings, b64encode(request))
        self.assertTrue(logout_request5.is_valid(request_data))
Beispiel #6
0
    def logout(self, return_to=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

        :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
            )

        logout_request = OneLogin_Saml2_Logout_Request(self.__settings)

        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'] = OneLogin_Saml2_Constants.RSA_SHA1
            parameters['Signature'] = self.build_request_signature(saml_request, parameters['RelayState'])
        return self.redirect_to(slo_url, parameters)
Beispiel #7
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 = []

        get_data = 'get_data' in self.__request_data and self.__request_data['get_data']
        if get_data and 'SAMLResponse' in get_data:
            logout_response = OneLogin_Saml2_Logout_Response(self.__settings, get_data['SAMLResponse'])
            if not self.validate_response_signature(get_data):
                self.__errors.append('invalid_logout_response_signature')
                self.__errors.append('Signature validation failed. Logout Response rejected')
            elif 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 and 'SAMLRequest' in get_data:
            logout_request = OneLogin_Saml2_Logout_Request(self.__settings, get_data['SAMLRequest'])
            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
                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 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 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.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')
        self.assertRegex(inflated, '<saml:EncryptedID>')
Beispiel #9
0
    def logout(self,
               return_to=None,
               name_id=None,
               session_index=None,
               nq=None,
               name_id_format=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

        :param name_id_format: The NameID Format that will be set in the LogoutRequest.
        :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

        if name_id_format is None and self.__nameid_format is not None:
            name_id_format = self.__nameid_format

        logout_request = OneLogin_Saml2_Logout_Request(
            self.__settings,
            name_id=name_id,
            session_index=session_index,
            nq=nq,
            name_id_format=name_id_format)
        self.__last_request = logout_request.get_xml()
        self.__last_request_id = logout_request.id

        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):
            self.add_request_signature(parameters,
                                       security['signatureAlgorithm'])
        return self.redirect_to(slo_url, parameters)
    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))
Beispiel #11
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())
Beispiel #12
0
    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.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_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(Exception, 'NameID not found in the Logout Request'):
            OneLogin_Saml2_Logout_Request.get_nameid(dom_2.toxml(), key)

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

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

        logout_request = OneLogin_Saml2_Logout_Request(settings, None, expected_name_id_data['Value'], None, idp_data['entityId'], expected_name_id_data['Format'])
        name_id_data_3 = OneLogin_Saml2_Logout_Request.get_nameid_data(logout_request.get_xml())
        self.assertEqual(expected_name_id_data, name_id_data_3)
    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)
    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)
Beispiel #15
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')
Beispiel #16
0
 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)
Beispiel #17
0
    def SAML_process_logout_request(self):
        '''
            HANDLE BACK CHANNEL LOGOUT POST FROM ASTRA
            We recieve this message when the user has logged out
            of another control panel, and must end their SAML session.
            AN HTTP POST is not supported by the SAML Library, so
            we have to manually process it.
        '''

        current_app.logger.debug(
            'SAML_process_logout_request - POST DATA:{0}'.format(
                self.saml_req))
        saml_data = self.saml_req.get("post_data").get('SAMLRequest', None)

        if saml_data is None:
            current_app.logger.debug('>>>>>>>> SAML REQUEST NOT FOUND')
            return abort(400)

        # this is not a url, it uses the pre-loaded saml json settings
        settings = OneLogin_Saml2_Settings(current_app.config["saml_settings"])

        logout_request = OneLogin_Saml2_Logout_Request(settings, saml_data)

        if not logout_request.is_valid({}):
            current_app.logger.debug('>>>>>>>> SAML REQUEST IS NOT VALID')
            return abort(400)

        data = self.SAML_decode_logout_request(saml_data)

        for session_index in \
                OneLogin_Saml2_Logout_Request.get_session_indexes(data):

            current_app.logger.debug(
                "*** LOGOUT SESSION: {0}".format(session_index))
            self.clear_session(session_index)

        saml_response = OneLogin_Saml2_Logout_Response(settings)
        saml_response.build(OneLogin_Saml2_Logout_Request.get_id(data))

        response = make_response(
            urllib.urlencode(
                {'SAMLResponse': saml_response.get_response(False)}))
        response.headers['Content-Type'] = 'application/x-www-form-urlencoded'

        return response
 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 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 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())