Ejemplo n.º 1
0
 def test_parse_response_500_failure(self):
     self._requests_response.raise_for_status.side_effect = HTTPError()
     self._requests_response.status_code = 500
     with self.assertRaises(HTTPError):
         self._transport._parse_response(self._requests_response)
Ejemplo n.º 2
0
 def raise_for_status(self):
     if self.status != 200:
         raise HTTPError('Not 200 Client Error')
Ejemplo n.º 3
0
 def raise_http_error():
     x = Response()
     x.status_code = 404
     x.reason = err
     raise HTTPError(err, response=x)
Ejemplo n.º 4
0
    def _push_loop(self):
        while True:
            msg = self._queue.get()

            LOG.debug('{} - push_loop dequeued first indicator {!r}'.format(
                self.name, msg))

            artifacts = []
            artifacts.append(msg)

            try:
                while len(artifacts) < MAX_BATCH_SIZE:
                    m = self._queue.get_nowait()
                    artifacts.append(m)
                    LOG.debug(
                        '{} - push_loop dequeued additional indicator {!r}'.
                        format(self.name, m))
            except Empty:
                pass

            # Determine which indicators must be added and which ones must be deleted
            indicatorsToDelete = deque()
            indicatorsToCreateUpdate = deque()

            for i in artifacts:
                if 'expirationDateTime' in i and i[
                        'expirationDateTime'] == EXPIRED:
                    indicatorsToDelete.append(i)
                else:
                    indicatorsToCreateUpdate.append(i)

            LOG.info(
                '{} - _push_loop has a total of {} indicators to create/update and {} to delete'
                .format(self.name, len(indicatorsToCreateUpdate),
                        len(indicatorsToDelete)))

            # Retry loop for pushing/deleting indicators
            while True:
                retries = 0

                try:

                    # Get authentication token first
                    token = self._get_auth_token()
                    LOG.debug('{} - token: {}'.format(self.name, token))

                    # Delete expired indicators before creating new ones
                    if len(indicatorsToDelete) > 0:
                        LOG.debug('{} - Deleting {} indicators'.format(
                            self.name, len(indicatorsToDelete)))

                        try:
                            self._delete_indicators(
                                token=token, indicators=indicatorsToDelete)
                            # Indicators successfully deleted, empty the list
                            indicatorsToDelete = []

                        # HTTP Error to track 4xx during the delete phase, with no retry
                        except HTTPError as e:
                            LOG.debug(
                                '{} - error deleting indicators - {}'.format(
                                    self.name, str(e)))
                            status_code = e.response.status_code

                            # If it's a 4xx, don't retry, else throw it up and go in the retry loop
                            if status_code >= 400 and status_code < 500:
                                LOG.error(
                                    '{}: {} error in delete request - {}'.
                                    format(self.name, status_code,
                                           e.response.text))
                                self.statistics['error.invalid_request'] += 1
                                # this way it will continue to the create/update phase without retrying the delete in the next loop
                                indicatorsToDelete = []
                            else:
                                raise HTTPError(e)

                        # SecurityGraph response error shouldn't trigger a retry
                        except SecurityGraphResponseException as e:
                            LOG.exception(
                                '{} - Graph Security API error deleting indicators - {}'
                                .format(self.name, str(e)))
                            self.statistics['error.submit'] += 1
                            break

                    if len(indicatorsToCreateUpdate) > 0:
                        LOG.debug(
                            '{} - Creating/Updating {} indicators'.format(
                                self.name, len(indicatorsToCreateUpdate)))

                        try:
                            self._push_indicators(
                                token=token,
                                indicators=indicatorsToCreateUpdate)

                        # HTTP Error to track 4xx during the delete phase, with no retry
                        except HTTPError as e:
                            LOG.debug(
                                '{} - error creating/updating indicators - {}'.
                                format(self.name, str(e)))
                            status_code = e.response.status_code

                            # If it's a 4xx, don't retry, else throw it up and go in the retry loop
                            if status_code >= 400 and status_code < 500:
                                LOG.error(
                                    '{}: {} error in create/update request - {}'
                                    .format(self.name, status_code,
                                            e.response.text))
                                self.statistics['error.invalid_request'] += 1
                                # this way it will continue to the delete phase without retrying the create in the next loop
                                indicatorsToCreateUpdate = []
                            else:
                                raise HTTPError(e)

                        # SecurityGraph response error shouldn't trigger a retry
                        except SecurityGraphResponseException as e:
                            LOG.exception(
                                '{} - Graph Securty API error creating/updating indicators - {}'
                                .format(self.name, str(e)))
                            self.statistics['error.submit'] += 1
                            break

                    # Successful loop
                    break

                # Graceful Exit
                except gevent.GreenletExit:
                    return

                # Authentication error during token generation
                except AuthConfigException as e:
                    LOG.exception(
                        '{} - Error submitting indicators - {}'.format(
                            self.name, str(e)))
                    self.statistics['error.submit'] += 1
                    gevent.sleep(60.0)

                # Other error, implement a retry logic
                # Note that if this hits during the delete phase, the createUpdate is never triggered
                except Exception as e:
                    LOG.exception(
                        '{} - error submitting indicators - {}'.format(
                            self.name, str(e)))
                    self.statistics['error.submit'] += 1
                    retries += 1
                    if retries > 5:
                        break
                    gevent.sleep(120.0)

            gevent.sleep(0.1)
Ejemplo n.º 5
0
def get_text_from_url(url):
    res = requests.get(url)
    if res.status_code in (200, 304):
        return res.text
    raise HTTPError(res)
Ejemplo n.º 6
0
 def __call__(self, query, *args, **kwargs):
     raise HTTPError(response=self.response)
 def raise_for_status():
     if not 200 <= response.status_code < 400:
         raise HTTPError(response.status_code)
Ejemplo n.º 8
0
    def test_upload_large_file(self, mock_element_contains_error):
        """
        Test the upload_large_file function
        """
        mock_element_contains_error.return_value = False
        # Succeed when calling the upload_large_file function and the api call
        # gets a valid response
        with patch.object(
                UploadAPI,
                "http_post",
                return_value=test_constants.
                VALID_UPLOAD_API_UPLOADLARGEFILE_RESPONSE_XML["bytes"],
        ):
            # Policy scan
            upload_api = UploadAPI(
                app_id=test_constants.VALID_UPLOAD_API["app_id"])
            valid_artifact = test_constants.VALID_FILE["Path"]

            with patch(
                    "veracode.submit_artifacts.open",
                    new=mock_open(
                        read_data=test_constants.VALID_FILE["bytes"]),
            ):
                self.assertTrue(
                    submit_artifacts.upload_large_file(
                        upload_api=upload_api, artifact=valid_artifact))

            # Sandbox scan
            upload_api = UploadAPI(
                app_id=test_constants.VALID_UPLOAD_API["app_id"])
            upload_api.sandbox_id = "12345"
            valid_artifact = test_constants.VALID_FILE["Path"]

            with patch(
                    "veracode.submit_artifacts.open",
                    new=mock_open(
                        read_data=test_constants.VALID_FILE["bytes"]),
            ):
                self.assertTrue(
                    submit_artifacts.upload_large_file(
                        upload_api=upload_api, artifact=valid_artifact))

        # Fail when calling the upload_large_file function and the api call
        # raises a HTTPError
        with patch.object(
                UploadAPI,
                "http_post",
                return_value=test_constants.
                VALID_UPLOAD_API_UPLOADLARGEFILE_RESPONSE_XML["bytes"],
                side_effect=HTTPError(),
        ):
            # Policy scan
            upload_api = UploadAPI(
                app_id=test_constants.VALID_UPLOAD_API["app_id"])
            valid_artifact = test_constants.VALID_FILE["Path"]

            with patch(
                    "veracode.submit_artifacts.open",
                    new=mock_open(
                        read_data=test_constants.VALID_FILE["bytes"]),
            ):
                self.assertRaises(
                    HTTPError,
                    submit_artifacts.upload_large_file,
                    upload_api=upload_api,
                    artifact=valid_artifact,
                )

            # Sandbox scan
            upload_api = UploadAPI(
                app_id=test_constants.VALID_UPLOAD_API["app_id"])
            upload_api.sandbox_id = "12345"
            valid_artifact = test_constants.VALID_FILE["Path"]

            with patch(
                    "veracode.submit_artifacts.open",
                    new=mock_open(
                        read_data=test_constants.VALID_FILE["bytes"]),
            ):
                self.assertRaises(
                    HTTPError,
                    submit_artifacts.upload_large_file,
                    upload_api=upload_api,
                    artifact=valid_artifact,
                )
Ejemplo n.º 9
0
    def test_create_build(self):
        """
        Test the create_build function
        """
        # Test the create_build function when the api call gets a valid response
        with patch.object(
                UploadAPI,
                "http_post",
                return_value=test_constants.
                VALID_UPLOAD_API_CREATEBUILD_RESPONSE_XML["Element"],
        ):
            with patch("veracode.submit_artifacts.element_contains_error",
                       return_value=False):
                # Policy scan, no error in response body
                upload_api = UploadAPI(
                    app_id=test_constants.VALID_UPLOAD_API["app_id"])
                self.assertTrue(
                    submit_artifacts.create_build(upload_api=upload_api))

                # Sandbox scan, no error in response body
                upload_api = UploadAPI(
                    app_id=test_constants.VALID_UPLOAD_API["app_id"])
                upload_api.sandbox_id = "12345"
                self.assertTrue(
                    submit_artifacts.create_build(upload_api=upload_api))

            # Fail when the create_build function gets a response containing an
            # error in the response body
            with patch("veracode.submit_artifacts.element_contains_error",
                       return_value=True):
                # Policy scan, response body contains error
                upload_api = UploadAPI(
                    app_id=test_constants.VALID_UPLOAD_API["app_id"])
                self.assertFalse(
                    submit_artifacts.create_build(upload_api=upload_api))

                # Sandbox scan, response body contains error
                upload_api = UploadAPI(
                    app_id=test_constants.VALID_UPLOAD_API["app_id"])
                upload_api.sandbox_id = "12345"
                self.assertFalse(
                    submit_artifacts.create_build(upload_api=upload_api))

        # Fail when calling the create_build function and the api call gets a
        # mocked error message response and a mocked side effect of HTTPError
        with patch.object(
                UploadAPI,
                "http_post",
                return_value=test_constants.
                VERACODE_ERROR_RESPONSE_XML["Element"],
                side_effect=HTTPError(),
        ):
            with patch("veracode.submit_artifacts.element_contains_error",
                       return_value=False):
                # Policy scan, no error in response body
                upload_api = UploadAPI(
                    app_id=test_constants.VALID_UPLOAD_API["app_id"])
                self.assertFalse(
                    submit_artifacts.create_build(upload_api=upload_api))

                # Sandbox scan, no error in response body
                upload_api = UploadAPI(
                    app_id=test_constants.VALID_UPLOAD_API["app_id"])
                upload_api.sandbox_id = "12345"
                self.assertFalse(
                    submit_artifacts.create_build(upload_api=upload_api))
Ejemplo n.º 10
0
 def reset_job(self, data):
     if data[api.JOBS_RESOURCE_JOB_ID] not in self.jobs_in_databricks:
         raise HTTPError('Job Not Found')
     self.jobs_in_databricks[data[api.JOBS_RESOURCE_JOB_ID]]['job_settings'] = \
         data['new_settings']
Ejemplo n.º 11
0
    def request(self,
                method,
                url,
                params=None,
                data=None,
                headers=None,
                cookies=None,
                files=None,
                auth=None,
                timeout=None,
                allow_redirects=True,
                proxies=None,
                hooks=None,
                stream=None,
                verify=None,
                cert=None,
                json=None,
                **kwargs):
        """Constructs a :class:`Request <Request>`, prepares it and sends it.
        Returns :class:`Response <Response>` object.

        :param method: method for the new :class:`Request` object.
        :param url: URL for the new :class:`Request` object.
        :param params: (optional) Dictionary or bytes to be sent in the query
            string for the :class:`Request`.
        :param data: (optional) Dictionary or bytes to send in the body of the
            :class:`Request`.
        :param json: (optional) json to send in the body of the
            :class:`Request`.
        :param headers: (optional) Dictionary of HTTP Headers to send with the
            :class:`Request`.
        :param cookies: (optional) Dict or CookieJar object to send with the
            :class:`Request`.
        :param files: (optional) Dictionary of ``'filename': file-like-objects``
            for multipart encoding upload.
        :param auth: (optional) Auth tuple or callable to enable
            Basic/Digest/Custom HTTP Auth.
        :param timeout: (optional) How long to wait for the server to send
            data before giving up, as a float, or a (`connect timeout, read
            timeout <user/advanced.html#timeouts>`_) tuple.
        :type timeout: float or tuple
        :param allow_redirects: (optional) Set to True by default.
        :type allow_redirects: bool
        :param proxies: (optional) Dictionary mapping protocol to the URL of
            the proxy.
        :param stream: (optional) whether to immediately download the response
            content. Defaults to ``False``.
        :param verify: (optional) if ``True``, the SSL cert will be verified.
            A CA_BUNDLE path can also be provided.
        :param cert: (optional) if String, path to ssl client cert file (.pem).
            If Tuple, ('cert', 'key') pair.
        """
        #===============================================================================================================
        # add by mz
        error_type = kwargs.get("error_type")
        if error_type:
            from requests.exceptions import InvalidURL, URLRequired, ConnectTimeout, ConnectionError, SSLError, ReadTimeout
            from requests.exceptions import InvalidSchema, MissingSchema, ChunkedEncodingError, ContentDecodingError
            from requests.exceptions import RequestException, HTTPError, ProxyError, Timeout, RetryError, StreamConsumedError

            get_error = {
                "InvalidURL": InvalidURL(),
                "URLRequired": URLRequired(),
                "ConnectTimeout": ConnectTimeout(),
                "ConnectionError": ConnectionError(),
                "SSLError": SSLError(),
                "ReadTimeout": ReadTimeout(),
                "InvalidSchema": InvalidSchema(),
                "MissingSchema": MissingSchema(),
                "ChunkedEncodingError": ChunkedEncodingError(),
                "ContentDecodingError": ContentDecodingError(),
                "StreamConsumedError": StreamConsumedError(),
                "TooManyRedirects": TooManyRedirects(),
                "RequestException": RequestException(),
                "HTTPError": HTTPError(),
                "ProxyError": ProxyError(),
                "Timeout": Timeout(),
                "RetryError": RetryError
            }

            error_ = get_error[error_type]
            raise error_
        #===============================================================================================================

        method = to_native_string(method)

        # Create the Request.
        req = Request(
            method=method.upper(),
            url=url,
            headers=headers,
            files=files,
            data=data or {},
            json=json,
            params=params or {},
            auth=auth,
            cookies=cookies,
            hooks=hooks,
        )
        prep = self.prepare_request(req)

        proxies = proxies or {}

        settings = self.merge_environment_settings(prep.url, proxies, stream,
                                                   verify, cert)

        # Send the request.
        send_kwargs = {
            'timeout': timeout,
            'allow_redirects': allow_redirects,
        }
        send_kwargs.update(settings)
        resp = self.send(prep, **send_kwargs)

        return resp
Ejemplo n.º 12
0
 def get_job(self, job_id):
     if job_id not in self.jobs_in_databricks:
         # Job created is not found.
         raise HTTPError('Job not Found')
     else:
         return self.jobs_in_databricks[job_id]
Ejemplo n.º 13
0
 def handler(method, url, *args, **kwargs):
     raise HTTPError('Bam!')
Ejemplo n.º 14
0
from requests.exceptions import HTTPError
from requests.exceptions import Timeout
from requests.exceptions import TooManyRedirects
from requests.exceptions import InvalidURL

@pytest.mark.parametrize("payload_a,payload_b,expected", [
    ({ "foo": "bar"}, { "one": "two" }, { "foo": "bar", "one": "two" }),
])
def test_merge_payloads(core_client, payload_a, payload_b, expected):
    merged = core_client.merge_payloads(payload_a, payload_b)
    assert merged == expected

@pytest.mark.parametrize("resource,caught,raised", [
    ("foo", SSLError(), cpauto.SSLError),
    ("foo", ConnectionError(), cpauto.ConnectionError),
    ("foo", HTTPError(), cpauto.HTTPError),
    ("foo", Timeout(), cpauto.Timeout),
    ("foo", TooManyRedirects(), cpauto.TooManyRedirects),
    ("foo", InvalidURL(), cpauto.InvalidURL),
])
def test_http_post_exceptions(core_client, mgmt_server_base_uri, resource, caught, raised):
    endpoint = mgmt_server_base_uri + resource
    with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
        rsps.add(responses.POST, endpoint,
                 body=caught, status=200,
                 content_type='application/json')

        with pytest.raises(raised):
            r = core_client.http_post(endpoint=resource, payload={})

@pytest.mark.parametrize("params", [
Ejemplo n.º 15
0
 def raise_for_status(self):
     if self.status_code != 200:
         raise (HTTPError(response=self))
Ejemplo n.º 16
0
    def test_build_exists(self):
        """
        Test the build_exists function
        """
        upload_api = UploadAPI(
            app_id=test_constants.VALID_UPLOAD_API["app_id"])

        with patch.object(
                UploadAPI,
                "http_get",
                return_value=test_constants.
                VALID_UPLOAD_API_GETBUILDLIST_MISSING_BUILDID_IN_RESPONSE_XML[
                    "Element"],
        ):
            # Succeed when no existing build IDs are present
            with patch("veracode.submit_artifacts.element_contains_error",
                       return_value=False):
                self.assertTrue(
                    submit_artifacts.build_exists(upload_api=upload_api))

            # Raise a RuntimeError when element_contains_error returns True
            with patch("veracode.submit_artifacts.element_contains_error",
                       return_value=True):
                self.assertRaises(
                    RuntimeError,
                    submit_artifacts.build_exists,
                    upload_api=upload_api,
                )

        ## Create Sandbox Scan and have existing build ID
        upload_api.sandbox_id = "12345"
        with patch.object(
                UploadAPI,
                "http_get",
                return_value=test_constants.
                VALID_UPLOAD_API_GETBUILDLIST_BUILDID_IN_RESPONSE_XML[
                    "Element"],
        ):
            # Fail when build already exists
            with patch("veracode.submit_artifacts.element_contains_error",
                       return_value=False):
                self.assertFalse(
                    submit_artifacts.build_exists(upload_api=upload_api))

        # Raise RuntimeError when HTTPError occurs
        with patch("veracode.api.VeracodeXMLAPI.http_get") as mock_http:
            with patch("veracode.submit_artifacts.element_contains_error",
                       return_value=False):
                mock_http.side_effect = HTTPError()
                self.assertRaises(
                    RuntimeError,
                    submit_artifacts.build_exists,
                    upload_api=upload_api,
                )

        # Raise RuntimeError when HTTPError occurs
        with patch("veracode.api.VeracodeXMLAPI.http_get") as mock_http:
            with patch("veracode.submit_artifacts.element_contains_error",
                       return_value=False):
                mock_http.side_effect = HTTPError()
                self.assertRaises(
                    RuntimeError,
                    submit_artifacts.build_exists,
                    upload_api=upload_api,
                )
Ejemplo n.º 17
0
 def user_not_found():
     raise HTTPError(response=mock_response)
Ejemplo n.º 18
0
"""Tests for certbot_dns_aliyun.dns_aliyun."""

import os
import unittest

import mock
from requests.exceptions import HTTPError, RequestException

from certbot.plugins import dns_test_common
from certbot.plugins import dns_test_common_lexicon
from certbot.tests import util as test_util

DOMAIN_NOT_FOUND = Exception('No domain found')
GENERIC_ERROR = RequestException
LOGIN_ERROR = HTTPError('400 Client Error: ...')

ACCESS_KEY = '123'
ACCESS_KEY_SECRET = 'bar'


class AuthenticatorTest(test_util.TempDirTestCase,
                        dns_test_common_lexicon.BaseLexiconAuthenticatorTest):

    def setUp(self):
        super(AuthenticatorTest, self).setUp()

        from certbot_dns_aliyun.dns_aliyun import Authenticator

        path = os.path.join(self.tempdir, 'file.ini')
        dns_test_common.write({
            "aliyun_access_key": ACCESS_KEY,
Ejemplo n.º 19
0
 def raise_for_status(self):
     raise HTTPError('error', response=self)
Ejemplo n.º 20
0
 def p(self):
     raise HTTPError("foo")
Ejemplo n.º 21
0
class BaseLexiconClientTest:
    DOMAIN_NOT_FOUND = Exception('No domain found')
    GENERIC_ERROR = RequestException
    LOGIN_ERROR = HTTPError('400 Client Error: ...')
    UNKNOWN_LOGIN_ERROR = HTTPError('500 Surprise! Error: ...')

    record_prefix = "_acme-challenge"
    record_name = record_prefix + "." + DOMAIN
    record_content = "bar"

    def test_add_txt_record(self: _LexiconAwareTestCase):
        self.client.add_txt_record(DOMAIN, self.record_name,
                                   self.record_content)

        self.provider_mock.create_record.assert_called_with(
            rtype='TXT', name=self.record_name, content=self.record_content)

    def test_add_txt_record_try_twice_to_find_domain(
            self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = [
            self.DOMAIN_NOT_FOUND, ''
        ]

        self.client.add_txt_record(DOMAIN, self.record_name,
                                   self.record_content)

        self.provider_mock.create_record.assert_called_with(
            rtype='TXT', name=self.record_name, content=self.record_content)

    def test_add_txt_record_fail_to_find_domain(self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = [
            self.DOMAIN_NOT_FOUND,
            self.DOMAIN_NOT_FOUND,
            self.DOMAIN_NOT_FOUND,
        ]

        self.assertRaises(errors.PluginError, self.client.add_txt_record,
                          DOMAIN, self.record_name, self.record_content)

    def test_add_txt_record_fail_to_authenticate(self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = self.LOGIN_ERROR

        self.assertRaises(errors.PluginError, self.client.add_txt_record,
                          DOMAIN, self.record_name, self.record_content)

    def test_add_txt_record_fail_to_authenticate_with_unknown_error(
            self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = self.UNKNOWN_LOGIN_ERROR

        self.assertRaises(errors.PluginError, self.client.add_txt_record,
                          DOMAIN, self.record_name, self.record_content)

    def test_add_txt_record_error_finding_domain(self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = self.GENERIC_ERROR

        self.assertRaises(errors.PluginError, self.client.add_txt_record,
                          DOMAIN, self.record_name, self.record_content)

    def test_add_txt_record_error_adding_record(self: _LexiconAwareTestCase):
        self.provider_mock.create_record.side_effect = self.GENERIC_ERROR

        self.assertRaises(errors.PluginError, self.client.add_txt_record,
                          DOMAIN, self.record_name, self.record_content)

    def test_del_txt_record(self: _LexiconAwareTestCase):
        self.client.del_txt_record(DOMAIN, self.record_name,
                                   self.record_content)

        self.provider_mock.delete_record.assert_called_with(
            rtype='TXT', name=self.record_name, content=self.record_content)

    def test_del_txt_record_fail_to_find_domain(self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = [
            self.DOMAIN_NOT_FOUND,
            self.DOMAIN_NOT_FOUND,
            self.DOMAIN_NOT_FOUND,
        ]

        self.client.del_txt_record(DOMAIN, self.record_name,
                                   self.record_content)

    def test_del_txt_record_fail_to_authenticate(self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = self.LOGIN_ERROR

        self.client.del_txt_record(DOMAIN, self.record_name,
                                   self.record_content)

    def test_del_txt_record_fail_to_authenticate_with_unknown_error(
            self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = self.UNKNOWN_LOGIN_ERROR

        self.client.del_txt_record(DOMAIN, self.record_name,
                                   self.record_content)

    def test_del_txt_record_error_finding_domain(self: _LexiconAwareTestCase):
        self.provider_mock.authenticate.side_effect = self.GENERIC_ERROR

        self.client.del_txt_record(DOMAIN, self.record_name,
                                   self.record_content)

    def test_del_txt_record_error_deleting_record(self: _LexiconAwareTestCase):
        self.provider_mock.delete_record.side_effect = self.GENERIC_ERROR

        self.client.del_txt_record(DOMAIN, self.record_name,
                                   self.record_content)
class ConfirmPendingDisbursementTestCase(PendingDisbursementTestCase):
    def url(self, pk):
        return reverse('disbursements:pending_detail', args=[pk])

    @mock_pending_detail
    @mock.patch(
        'disbursements.views.nomis.create_transaction',
        return_value={'id': '12345-1'},
    )
    def test_confirm_disbursement(self, calls_mocker,
                                  mock_nomis_create_transaction):
        self.login(credentials={
            'username': '******',
            'password': '******'
        })

        disbursement = SAMPLE_DISBURSEMENTS[4]
        calls_mocker(disbursement)
        responses.add(responses.POST,
                      api_url('/disbursements/actions/preconfirm/'),
                      status=200)
        responses.add(responses.POST,
                      api_url('/disbursements/actions/confirm/'),
                      status=200)

        response = self.client.post(self.url(disbursement['id']),
                                    data={'confirmation': 'yes'},
                                    follow=True)
        self.assertOnPage(response, 'disbursements:confirmed')
        self.assertContains(response, '12345-1')

        mock_nomis_create_transaction.assert_called_once_with(
            prison_id='BXI',
            prisoner_number='A1448AE',
            amount=3000,
            record_id='d660',
            description='Sent to Katy Hicks',
            transaction_type='RELA',
            retries=1,
        )

    @mock_pending_detail
    @mock.patch(
        'disbursements.views.nomis.create_transaction',
        side_effect=HTTPError(response=mock.Mock(status_code=500)),
    )
    def test_confirm_disbursement_resets_on_failure(self, calls_mocker, _):
        self.login(credentials={
            'username': '******',
            'password': '******'
        })

        disbursement = SAMPLE_DISBURSEMENTS[4]
        calls_mocker(disbursement)
        responses.add(responses.POST,
                      api_url('/disbursements/actions/preconfirm/'),
                      status=200)
        responses.add(responses.POST,
                      api_url('/disbursements/actions/reset/'),
                      status=200)

        with silence_logger():
            response = self.client.post(self.url(disbursement['id']),
                                        data={'confirmation': 'yes'},
                                        follow=True)
        self.assertOnPage(response, 'disbursements:pending_detail')
        self.assertContains(response,
                            'Payment not confirmed due to technical error')
Ejemplo n.º 23
0
def notify_build():
    """
    An endpoint to trigger an update about a build event to be sent.
    This will usually be triggered by a webhook from Launchpad
    """

    # Verify contents
    signature = hmac.new(
        flask.current_app.config["SECRET_KEY"].encode("utf-8"),
        flask.request.data,
        hashlib.sha1,
    ).hexdigest()

    if "X-Hub-Signature" not in flask.request.headers:
        return "No X-Hub-Signature provided\n", 403

    if not hmac.compare_digest(
            signature, flask.request.headers["X-Hub-Signature"].split("=")[1]):
        try:
            raise HTTPError(400)
        except HTTPError:
            flask.current_app.extensions["sentry"].captureException(
                extra={
                    "request_headers":
                    str(flask.request.headers.keys()),
                    "message":
                    "x-hub-signature did not match",
                    "expected_signature":
                    signature,
                    "header_contents":
                    flask.request.headers["X-Hub-Signature"],
                    "extracted_signature":
                    flask.request.headers["X-Hub-Signature"].split("=")[1],
                })

        return "X-Hub-Signature does not match\n", 400

    event_content = flask.request.json
    status = event_content["status"]
    build_url = ("https://api.launchpad.net/devel" +
                 event_content["livefs_build"])

    launchpad = Launchpad(
        username=os.environ["LAUNCHPAD_IMAGE_BUILD_USER"],
        token=os.environ["LAUNCHPAD_IMAGE_BUILD_TOKEN"],
        secret=os.environ["LAUNCHPAD_IMAGE_BUILD_SECRET"],
        session=session,
        auth_consumer=os.environ["LAUNCHPAD_IMAGE_BUILD_AUTH_CONSUMER"],
    )

    build = launchpad.request(build_url).json()
    author_json = (gnupg.GPG().decrypt(
        build["metadata_override"]["_author_data"],
        passphrase=flask.current_app.config["SECRET_KEY"],
    ).data)

    if author_json:
        author = json.loads(author_json)
    else:
        return "_author_data could not be decoded\n", 400

    email = author["email"]
    names = author["name"].split(" ")
    board = author["board"]
    snaps = ", ".join(build["metadata_override"]["extra_snaps"])
    codename = build["distro_series_link"].split("/")[-1]
    version = Data().by_codename(codename).version
    arch = build["distro_arch_series_link"].split("/")[-1]
    build_link = build["web_link"]
    build_id = build_link.split("/")[-1]

    download_url = None

    if status == "Successfully built":
        download_url = launchpad.request(
            f"{build_url}?ws.op=getFileUrls").json()[0]

    session.post(
        "https://pages.ubuntu.com/index.php/leadCapture/save",
        data={
            "FirstName": " ".join(names[:-1]),
            "LastName": names[-1] if len(names) > 1 else "",
            "Email": email,
            "formid": "3546",
            "lpId": "2154",
            "subId": "30",
            "munchkinId": "066-EOV-335",
            "imageBuilderVersion": version,
            "imageBuilderArchitecture": arch,
            "imageBuilderBoard": board,
            "imageBuilderSnaps": snaps,
            "imageBuilderID": build_id,
            "imageBuilderBuildlink": build_link,
            "imageBuilderStatus": status,
            "imageBuilderDownloadlink": download_url,
        },
    )

    return "Submitted\n", 202
Ejemplo n.º 24
0
def raise_detailed_error(request_object):
    try:
        request_object.raise_for_status()
    except HTTPError as e:
        # raise detailed error message
        raise HTTPError(e, request_object.text)
Ejemplo n.º 25
0
def _make_github_request(url, token):
    response = requests.get(url, headers={'Authorization': f"token {token}"})
    if response.status_code != 200:
        raise HTTPError("There was an error retrieving data from GitHub: " +
                        str(response.content))
    return response.content
Ejemplo n.º 26
0
    def _internal_request(self, request_obj, url, method, **kwargs):
        """ Internal handling of requests. Handles Exceptions.

        :param request_obj: a requests session.
        :param str url: url to send request to
        :param str method: type of request (get/put/post/patch/delete)
        :param kwargs: extra params to send to the request api
        :return: Response of the request
        :rtype: requests.Response
        """

        method = method.lower()
        if method not in self._allowed_methods:
            raise ValueError('Method must be one of the allowed ones')
        if method == 'get':
            kwargs.setdefault('allow_redirects', True)
        elif method in ['post', 'put', 'patch']:
            if 'headers' not in kwargs:
                kwargs['headers'] = {}
            if kwargs.get('headers') is not None and kwargs['headers'].get(
                    'Content-type') is None:
                kwargs['headers']['Content-type'] = 'application/json'
            if 'data' in kwargs and kwargs['data'] is not None and kwargs['headers'].get(
                    'Content-type') == 'application/json':
                kwargs['data'] = json.dumps(kwargs['data'])  # convert to json

        request_done = False
        token_refreshed = False

        while not request_done:
            self._check_delay()  # sleeps if needed
            try:
                log.info('Requesting ({}) URL: {}'.format(method.upper(), url))
                log.info('Request parameters: {}'.format(kwargs))
                # auto_retry will occur inside this function call if enabled
                response = request_obj.request(method, url,
                                               **kwargs)
                response.raise_for_status()  # raise 4XX and 5XX error codes.
                log.info('Received response ({}) from URL {}'.format(
                    response.status_code, response.url))
                request_done = True
                return response
            except TokenExpiredError as e:
                # Token has expired, try to refresh the token and try again on the next loop
                if not self.token_backend.token.is_long_lived:
                    raise e
                if token_refreshed:
                    # Refresh token done but still TokenExpiredError raise
                    raise RuntimeError('Token Refresh Operation not working')
                log.info('Oauth Token is expired, fetching a new token')
                self.refresh_token()
                log.info('New oauth token fetched')
                token_refreshed = True
            except (ConnectionError, ProxyError, SSLError, Timeout) as e:
                # We couldn't connect to the target url, raise error
                log.debug('Connection Error calling: {}.{}'
                          ''.format(url, ('Using proxy: {}'.format(self.proxy)
                                          if self.proxy else '')))
                raise e  # re-raise exception
            except HTTPError as e:
                # Server response with 4XX or 5XX error status codes

                # try to extract the error message:
                try:
                    error = response.json()
                    error_message = error.get('error', {}).get('message', '')
                except ValueError:
                    error_message = ''

                status_code = int(e.response.status_code / 100)
                if status_code == 4:
                    # Client Error
                    # Logged as error. Could be a library error or Api changes
                    log.error('Client Error: {} | Error Message: {}'.format(str(e), error_message))
                else:
                    # Server Error
                    log.debug('Server Error: {}'.format(str(e)))
                if self.raise_http_errors:
                    if error_message:
                        raise HTTPError('{} | Error Message: {}'.format(e.args[0], error_message), response=response) from None
                    else:
                        raise e
                else:
                    return e.response
            except RequestException as e:
                # catch any other exception raised by requests
                log.debug('Request Exception: {}'.format(str(e)))
                raise e
Ejemplo n.º 27
0
def mock_obs_creation_error(mocker, mock_obs_creation):
    mock_obs_creation.side_effect = HTTPError(
        response=mocker.Mock(response=mocker.Mock(text="eror")))
Ejemplo n.º 28
0
 def test_function():
     resp = Response()
     resp.status_code = 401
     raise HTTPError(response=resp)
Ejemplo n.º 29
0
 def raise_for_status(self):
     if self.status_code != 200:
         raise HTTPError(None)
Ejemplo n.º 30
0
 def reset_job(self, data):
     if data['job_id'] not in self.jobs_in_databricks:
         raise HTTPError('Job Not Found')
     self.jobs_in_databricks[
         data['job_id']]['job_settings'] = data['new_settings']