Example #1
0
    def request_raw(self, method, url, params=None):
        """
        Mechanism for issuing an API call
        """
        from shippo import api_version

        if self.api_key:
            my_api_key = self.api_key
        else:
            from shippo import api_key
            my_api_key = api_key

        if my_api_key is None:
            raise error.AuthenticationError(
                'No API key provided. (HINT: set your API key using '
                '"shippo.api_key = <API-KEY>"). You can generate API keys '
                'from the Shippo web interface.  See https://goshippo.com/api '
                'for details, or email [email protected] if you have any '
                'questions.')

        token_type = 'ShippoToken'
        if my_api_key.startswith('oauth.'):
            token_type = 'Bearer'

        abs_url = '%s%s' % (shippo.api_base, url)

        if method == 'get' or method == 'delete':
            if params:
                encoded_params = urllib.urlencode(
                    list(_api_encode(params or {})))
                abs_url = _build_api_url(abs_url, encoded_params)
            post_data = None
        elif method == 'post' or method == 'put':
            post_data = util.json.dumps(params)
        else:
            raise error.APIConnectionError(
                'Unrecognized HTTP method %r.  This may indicate a bug in the '
                'Shippo bindings.  Please contact [email protected] for '
                'assistance.' % (method, ))

        ua = {
            'bindings_version': VERSION,
            'lang': 'python',
            'publisher': 'shippo',
            'httplib': self._client.name,
        }
        for attr, func in [['lang_version', platform.python_version],
                           ['platform', platform.platform],
                           ['uname', lambda: ' '.join(platform.uname())]]:
            try:
                val = func()
            except Exception, e:
                val = "!! %s" % (e, )
            ua[attr] = val
Example #2
0
    def _handle_request_error(self, e, url):
        if isinstance(e, urlfetch.InvalidURLError):
            msg = ("The Shippo library attempted to fetch an "
                   "invalid URL (%r). This is likely due to a bug "
                   "in the Shippo Python bindings. Please let us know "
                   "at [email protected]." % (url, ))
        elif isinstance(e, urlfetch.DownloadError):
            msg = "There was a problem retrieving data from Shippo."
        elif isinstance(e, urlfetch.ResponseTooLargeError):
            msg = ("There was a problem receiving all of your data from "
                   "Shippo.  This is likely due to a bug in Shippo. "
                   "Please let us know at [email protected].")
        else:
            msg = ("Unexpected error communicating with Shippo. If this "
                   "problem persists, let us know at [email protected].")

        msg = textwrap.fill(msg) + "\n\n(Network error: " + str(e) + ")"
        raise error.APIConnectionError(msg)
Example #3
0
 def _handle_request_error(self, e):
     if isinstance(e, requests.exceptions.RequestException):
         msg = ("Unexpected error communicating with Shippo.  "
                "If this problem persists, let us know at "
                "[email protected].")
         err = "%s: %s" % (type(e).__name__, str(e))
     else:
         msg = ("Unexpected error communicating with Shippo. "
                "It looks like there's probably a configuration "
                "issue locally.  If this problem persists, let us "
                "know at [email protected].")
         err = "A %s was raised" % (type(e).__name__, )
         if str(e):
             err += " with error message %s" % (str(e), )
         else:
             err += " with no error message"
     msg = textwrap.fill(msg) + "\n\n(Network error: %s)" % (err, )
     raise error.APIConnectionError(msg)
Example #4
0
    def _check_ssl_cert(self):
        """Preflight the SSL certificate presented by the backend.

        This isn't 100% bulletproof, in that we're not actually validating the
        transport used to communicate with Shippo, merely that the first
        attempt to does not use a revoked certificate.

        Unfortunately the interface to OpenSSL doesn't make it easy to check
        the certificate before sending potentially sensitive data on the wire.
        This approach raises the bar for an attacker significantly."""

        from shippo.config import verify_ssl_certs

        if verify_ssl_certs and not self._CERTIFICATE_VERIFIED:
            uri = urllib.parse.urlparse(shippo.config.api_base)
            try:
                certificate = ssl.get_server_certificate(
                    (uri.hostname, uri.port or 443))
                der_cert = ssl.PEM_cert_to_DER_cert(certificate)
            except socket.error as e:
                raise error.APIConnectionError(e)
            except TypeError:
                # The Google App Engine development server blocks the C socket
                # module which causes a type error when using the SSL library
                if ('APPENGINE_RUNTIME' in os.environ
                        and 'Dev' in os.environ.get('SERVER_SOFTWARE', '')):
                    self._CERTIFICATE_VERIFIED = True
                    warnings.warn(
                        'We were unable to verify Shippo\'s SSL certificate '
                        'due to a bug in the Google App Engine development '
                        'server. Please alert us immediately at '
                        'suppgoshippo.compo.com if this message appears in your '
                        'production logs.')
                    return
                else:
                    raise

            self._CERTIFICATE_VERIFIED = certificate_blacklist.verify(
                uri.hostname, der_cert)
Example #5
0
    def request_raw(self, method, url, params=None):
        """
        Mechanism for issuing an API call
        """

        if self.api_key:
            my_api_key = self.api_key
        else:
            my_api_key = config.api_key

        if my_api_key is None:
            raise error.AuthenticationError(
                'No API key provided. (HINT: set your API key using '
                '"shippo.config.api_key = shippo_test_d90f00698a0a8def0495fddb4212bb08051469d3"). You can generate API keys '
                'from the Shippo web interface.  See https://goshippo.com/api '
                'for details, or email [email protected] if you have any '
                'questions.')

        token_type = 'ShippoToken'
        if my_api_key.startswith('oauth.'):
            token_type = 'Bearer'

        abs_url = '%s%s' % (config.api_base, url)

        if method == 'get' or method == 'delete':
            if params:
                encoded_params = urllib.parse.urlencode(
                    list(_api_encode(params or {})))
                abs_url = _build_api_url(abs_url, encoded_params)
            post_data = None
        elif method == 'post' or method == 'put':
            post_data = util.json.dumps(params)
        else:
            raise error.APIConnectionError(
                'Unrecognized HTTP method %r.  This may indicate a bug in the '
                'Shippo bindings.  Please contact [email protected] for '
                'assistance.' % (method, ))

        shippo_user_agent = APIRequestor.get_shippo_user_agent_header(config)

        headers = {
            'Content-Type':
            'application/json',
            'X-Shippo-Client-User-Agent':
            shippo_user_agent,
            'User-Agent':
            '%s/%s ShippoPythonSDK/%s' % (
                config.app_name,
                config.app_version,
                config.sdk_version,
            ),
            'Authorization':
            '%s %s' % (
                token_type,
                my_api_key,
            ),
            'Shippo-API-Version':
            config.api_version
        }

        rbody, rcode = self._client.request(method, abs_url, headers,
                                            post_data)
        util.logger.info(
            'API request to %s returned (response code, response body) of '
            '(%d, %r)', abs_url, rcode, rbody)
        return rbody, rcode, my_api_key
Example #6
0
    def request_raw(self, method, url, params=None):
        """
        Mechanism for issuing an API call
        """
        from shippo.config import api_version

        if self.api_key:
            my_api_key = self.api_key
        else:
            from shippo.config import api_key
            my_api_key = api_key

        if my_api_key is None:
            raise error.AuthenticationError(
                'No API key provided. (HINT: set your API key using '
                '"shippo.config.api_key = shippo_test_d90f00698a0a8def0495fddb4212bb08051469d3"). You can generate API keys '
                'from the Shippo web interface.  See https://goshippo.com/api '
                'for details, or email [email protected] if you have any '
                'questions.')

        token_type = 'ShippoToken'
        if my_api_key.startswith('oauth.'):
            token_type = 'Bearer'

        abs_url = '%s%s' % (shippo.config.api_base, url)

        if method == 'get' or method == 'delete':
            if params:
                encoded_params = urllib.parse.urlencode(
                    list(_api_encode(params or {})))
                abs_url = _build_api_url(abs_url, encoded_params)
            post_data = None
        elif method == 'post' or method == 'put':
            post_data = util.json.dumps(params)
        else:
            raise error.APIConnectionError(
                'Unrecognized HTTP method %r.  This may indicate a bug in the '
                'Shippo bindings.  Please contact [email protected] for '
                'assistance.' % (method, ))

        ua = {
            'bindings_version': VERSION,
            'lang': 'python',
            'publisher': 'shippo',
            'httplib': self._client.name,
        }
        for attr, func in [['lang_version', platform.python_version],
                           ['platform', platform.platform],
                           ['uname', lambda: ' '.join(platform.uname())]]:
            try:
                val = func()
            except Exception as e:
                val = "!! %s" % (e, )
            ua[attr] = val

        headers = {
            'Content-Type': 'application/json',
            'X-Shippo-Client-User-Agent': util.json.dumps(ua),
            'User-Agent': 'Shippo/v1 PythonBindings/%s' % (VERSION, ),
            'Authorization': '%s %s' % (
                token_type,
                my_api_key,
            )
        }

        if api_version is not None:
            headers['Shippo-API-Version'] = api_version

        rbody, rcode = self._client.request(method, abs_url, headers,
                                            post_data)
        util.logger.info(
            'API request to %s returned (response code, response body) of '
            '(%d, %r)', abs_url, rcode, rbody)
        return rbody, rcode, my_api_key