Пример #1
0
    def test_get_post_data(self):
        class FakeRequest:
            """Serves as a mock flask.request object"""
            pass

        request = FakeRequest()
        request.values = "format=form"
        request.get_json = lambda **x: {'format': 'json'}

        # empty content-type -> default to json
        data = utils.get_post_data(request)
        self.assertEqual(data, request.get_json())

        # raise some exception when it tries to run get_json(force=true)
        request.get_json = lambda **x: {}.not_a_method()
        data = utils.get_post_data(request)
        self.assertEqual(data, request.values)
Пример #2
0
    def test_get_post_data(self):
        class FakeRequest:
            """Serves as a mock flask.request object"""
            pass

        request = FakeRequest()
        request.values = "format=form"
        request.get_json = lambda **x: {'format': 'json'}

        # empty content-type -> default to json
        data = utils.get_post_data(request)
        self.assertEqual(data, request.get_json())

        # raise some exception when it tries to run get_json(force=true)
        request.get_json = lambda **x: {}.not_a_method()
        data = utils.get_post_data(request)
        self.assertEqual(data, request.values)
Пример #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
Пример #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