Beispiel #1
0
    def test_verify_google_recaptcha(self):
        """
        Test the function responsible for contacting the google recaptcha API
        and verifying the captcha response, using a mocked API
        """
        self.setup_google_recaptcha_response()

        # Set up a fake request object that will be passed directly to
        # the function being tested
        class FakeRequest:  pass
        fakerequest = FakeRequest()
        fakerequest.remote_addr = 'placeholder'

        # Test a "success" response
        fakerequest.get_json = lambda **x: \
            {'g-recaptcha-response': 'correct_response'}
        res = utils.verify_recaptcha(fakerequest)
        self.assertTrue(res)

        # Test a "fail" response
        fakerequest.get_json = lambda **x: \
            {'g-recaptcha-response': 'incorrect_response'}
        res = utils.verify_recaptcha(fakerequest)
        self.assertFalse(res)

        # Test a 503 response
        fakerequest.get_json = lambda **x: \
            {'g-recaptcha-response': 'dont_return_200'}
        self.assertRaises(
            requests.HTTPError,
            utils.verify_recaptcha,
            fakerequest
        )

        # Test a malformed request
        fakerequest = FakeRequest()
        self.assertRaises(
            (KeyError, AttributeError),
            utils.verify_recaptcha,
            fakerequest
        )
Beispiel #2
0
    def test_verify_google_recaptcha(self):
        """
        Test the function responsible for contacting the google recaptcha API
        and verifying the captcha response, using a mocked API
        """
        self.setup_google_recaptcha_response()

        # Set up a fake request object that will be passed directly to
        # the function being tested
        class FakeRequest:
            pass

        fakerequest = FakeRequest()
        fakerequest.remote_addr = 'placeholder'

        # Test a "success" response
        fakerequest.get_json = lambda **x: \
            {'g-recaptcha-response': 'correct_response'}
        res = utils.verify_recaptcha(fakerequest)
        self.assertTrue(res)

        # Test a "fail" response
        fakerequest.get_json = lambda **x: \
            {'g-recaptcha-response': 'incorrect_response'}
        res = utils.verify_recaptcha(fakerequest)
        self.assertFalse(res)

        # Test a 503 response
        fakerequest.get_json = lambda **x: \
            {'g-recaptcha-response': 'dont_return_200'}
        self.assertRaises(requests.HTTPError, utils.verify_recaptcha,
                          fakerequest)

        # Test a malformed request
        fakerequest = FakeRequest()
        self.assertRaises((KeyError, AttributeError), utils.verify_recaptcha,
                          fakerequest)
Beispiel #3
0
    def post(self):
        """
        HTTP POST request
        :return: status code from the slack end point
        """

        post_data = get_post_data(request)
        current_app.logger.info('Received feedback: {0}'.format(post_data))

        if not post_data.get('g-recaptcha-response', False) or \
                not verify_recaptcha(request):
            current_app.logger.info('The captcha was not verified!')
            return err(ERROR_UNVERIFIED_CAPTCHA)
        else:
            current_app.logger.info('Skipped captcha!')

        try:
            current_app.logger.info('Prettifiying post data: {0}'
                                    .format(post_data))
            formatted_post_data = json.dumps(self.prettify_post(post_data))
            current_app.logger.info('Data prettified: {0}'
                                    .format(formatted_post_data))
        except BadRequestKeyError as error:
            current_app.logger.error('Missing keywords: {0}, {1}'
                                     .format(error, post_data))
            return err(ERROR_MISSING_KEYWORDS)

        try:
            slack_response = requests.post(
                url=current_app.config['FEEDBACK_SLACK_END_POINT'],
                data=formatted_post_data,
                timeout=60
            )
        except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
            return b'504 Gateway Timeout', 504
        current_app.logger.info('slack response: {0}'
                                .format(slack_response.status_code))

        # Slack annoyingly redirects if you have the wrong end point
        current_app.logger.info('Slack API' in slack_response.text)

        if 'Slack API' in slack_response.text:
            return err(ERROR_WRONG_ENDPOINT)
        elif slack_response.status_code == 200:
            return {}, 200
        else:
            return {'msg': 'Unknown error'}, slack_response.status_code
Beispiel #4
0
    def post(self):
        """
        HTTP POST request
        :return: status code from the slack end point and for sending user feedback emails
        """

        post_data = get_post_data(request)

        current_app.logger.info('Received feedback of type {0}: {1}'.format(post_data.get('_subject'), post_data))

        if not post_data.get('g-recaptcha-response', False) or \
                not verify_recaptcha(request):
            current_app.logger.info('The captcha was not verified!')
            return err(ERROR_UNVERIFIED_CAPTCHA)
        else:
            current_app.logger.info('Skipped captcha!')
        # We only allow POST data from certain origins
        allowed_origins = [v for k,v in current_app.config.items() if k.endswith('_ORIGIN')]
        origin = post_data.get('origin', 'NA')
        if origin == 'NA' or origin not in allowed_origins:
            return err(ERROR_UNKNOWN_ORIGIN)
        # Some variable definitions
        email_body = ''
        slack_data = ''
        attachments=[]
        # Generate the email body based on the data in the POST payload
        try:
            email_body = self.create_email_body(post_data)
        except BadRequestKeyError as error:
            current_app.logger.error('Missing keywords: {0}, {1}'
                                     .format(error, post_data))
            return err(ERROR_MISSING_KEYWORDS)
        except Exception as error:
            current_app.logger.error('Fatal error creating email body: {0}'.format(error))
            return err(ERROR_EMAILBODY_PROBLEM)
        # Retrieve the name of the person submitting the feedback
        name = post_data.get('name', 'TownCrier')
        # There are some origin-specific actions
        if origin == current_app.config['FEEDBACK_FORMS_ORIGIN']:
            # The reply_to for feedback form data
            reply_to = post_data.get('email')
            # In the case of new or corrected records, attachments are sent along
            if post_data.get('_subject') == 'New Record':
                attachments.append(('new_record.json', post_data['new']))
            if post_data.get('_subject') == 'Updated Record':
                attachments.append(('updated_record.json', post_data['new']))
                attachments.append(('original_record.json', post_data['original']))
            # Prepare a minimal Slack message
            channel = post_data.get('channel', '#feedback')
            username = post_data.get('username', 'TownCrier')
            icon_emoji = current_app.config['FORM_SLACK_EMOJI']
            text = 'Received data from feedback form "{0}" from {1}'.format(post_data.get('_subject'), post_data.get('email'))
            slack_data = {
                'text': text,
                'username': username,
                'channel': channel,
                'icon_emoji': icon_emoji
            }
        elif origin == current_app.config['BBB_FEEDBACK_ORIGIN']:
            # The reply_to for the general feedback data
            reply_to = post_data.get('_replyto', '*****@*****.**')
            # Prepare the Slack message with submitted data
            text = '```Incoming Feedback```\n' + email_body
            channel = post_data.get('channel', '#feedback')
            username = post_data.get('username', 'TownCrier')
            icon_emoji = current_app.config['FEEDBACK_SLACK_EMOJI']
            slack_data = {
                'text': text,
                'username': username,
                'channel': channel,
                'icon_emoji': icon_emoji
            }
        # If we have an email body (should always be the case), send out the email
        if email_body:
            email_sent = False
            try:
                res = send_feedback_email(name, reply_to, post_data['_subject'], email_body, attachments=attachments)
                email_sent = True
            except Exception as e:
                current_app.logger.error('Fatal error while processing feedback form data: {0}'.format(e))
                email_sent = False
            if not email_sent:
                # If the email could not be sent, we can still log the data submitted
                current_app.logger.error('Sending of email failed. Feedback data submitted by {0}: {1}'.format(post_data.get('email'), post_data))
                return err(ERROR_EMAIL_NOT_SENT)
        # If we have Slack data, post the message to Slack
        if slack_data:
            slack_data['text'] += '\n*sent to adshelp*: {0}'.format(email_sent)
            try:
                slack_response = requests.post(
                    url=current_app.config['FEEDBACK_SLACK_END_POINT'],
                    data=json.dumps(slack_data),
                    timeout=60
                )
            except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
                return b'504 Gateway Timeout', 504
            current_app.logger.info('slack response: {0}'
                                    .format(slack_response.status_code))

            # Slack annoyingly redirects if you have the wrong end point
            current_app.logger.info('Slack API' in slack_response.text)

            if 'Slack API' in slack_response.text:
                return err(ERROR_WRONG_ENDPOINT)
            elif slack_response.status_code == 200:
                return {}, 200
            else:
                return {'msg': 'Unknown error'}, slack_response.status_code

        return {}, 200