def wrapper(*args, **kwargs):
        # Disable authentication for local setup
        if getenv('DISABLE_AUTHENTICATION') in ('1', 'True', 'true'):
            return view(*args, **kwargs)

        lgr = current_app.logger

        try:
            decoded = decode_token(get_token_from_auth_header())
            if not decoded:
                lgr.exception(
                    'Provide an Authorization token with the API request')
                raise HTTPError(401, 'Authentication failed - token missing')

            lgr.info('Successfuly authenticated user {e} using JWT'.format(
                e=decoded.get('email')))
        except jwt.ExpiredSignatureError as exc:
            lgr.exception('Expired JWT token')
            raise HTTPError(
                401, 'Authentication failed - token has expired') from exc
        except Exception as exc:
            lgr.exception('Failed decoding JWT token')
            raise HTTPError(
                401,
                'Authentication failed - could not decode JWT token') from exc

        return view(*args, **kwargs)
Exemple #2
0
    def request(self, domain, path, params={}, headers={}, timeout=10):
        headers.update(self.headers)
        log("(URL) Headers: %s" % str(headers), LOGLEVEL.NONE)

        self.scheme, self.netloc, self.uri, self.url = self.urlParse(
            domain, path, params)
        log("(URL) Trying to obtaining data from %s" % self.url, LOGLEVEL.NONE)
        try:
            if self.scheme == 'https':
                self.conn = httplib.HTTPSConnection(self.netloc,
                                                    timeout=timeout)
            else:
                self.conn = httplib.HTTPConnection(self.netloc,
                                                   timeout=timeout)
            if _settings.debug:
                self.conn.set_debuglevel(1)
            self.conn.request("GET", self.uri, headers=headers)
            response = self.conn.getresponse()
            if response.status == httplib.OK:
                return self._read(response)
            raise HTTPError(
                "Received wrong status code (%s %s) from %s" %
                (response.status, httplib.responses.get(response.status,
                                                        ''), self.url), 30329)
        except socket.error as e:
            if e.errno in [errno.ESHUTDOWN, errno.ECONNABORTED]:
                log(
                    "(URL) socket.error: %s. (Connection has most likely been canceled by user choices)"
                    % str(e), LOGLEVEL.NOTICE)
                sys.exc_clear()
                return None
            raise
Exemple #3
0
    def request(self, url, rpc_request):
        request = Request(url, data=rpc_request, headers=self.headers)

        try:
            response = self._opener.open(request, timeout=self.timeout)

            content = response.read()
        except _HTTPError as e:
            raise HTTPError(e)
        except URLError as e:
            if isinstance(e.reason, socket.timeout):
                raise TimeoutError(e)
            else:
                raise TransportError(e)
        except socket.timeout as e:
            raise TimeoutError(e)

        encoding = response.info().get('Content-Encoding', '').lower()
        if encoding in ('gzip', 'x-gzip'):
            if not gzip:
                raise ValueError('gzip is not available')

            b = BytesIO(content)
            try:
                content = gzip.GzipFile(mode='rb', fileobj=b).read()
            except IOError as e:
                raise ContentDecodingError(e)

        return content
Exemple #4
0
def https_post(url, payload, params={}, ignore_status=False):
    '''Posts a data payload to Bill.com. It can optionally check for failed status.

    Args:
        payload (dict): A JSON compatible dict with data to send to bill.com's api.
        ignore_status (bool): If True, don't check for failed status codes.

    Returns:
        Dict of the JSON response.

    Raises:
        ServerReponseError
        HTTPError
    '''
    LOG = get_logger()

    api_url = API_URL + '/' + url

    headers = {'content-type': 'application/x-www-form-urlencoded'}

    try:
        response = requests.post(api_url,
                                 params=params,
                                 data=payload,
                                 headers=headers)
    except Exception as e:
        raise ServerResponseError('Could not post to {0}: {1}'.format(
            api_url, e))

    if response.status_code not in OK_CODES:
        message = "received HTTP {0}: {1} when sending to {2}: {3}".format(
            response.status_code, response.text, API_URL, payload)
        LOG.error(message)
        raise HTTPError(message)

    try:
        data = json.loads(response.text)
        status, message = get_status_and_message(data)
    except:
        message = 'sent {0} got badly formatted reponse: {1}'.format(
            payload, response.text)
        LOG.error(message)
        LOG.error("SENT TO {}: {}".format(response.url, payload))
        LOG.error("RECEIVED {}".format(data))
        raise

    if not ignore_status and status and status != 'OK':
        LOG.error(message)
        LOG.error("SENT TO {}: {}".format(response.url, payload))
        LOG.error("RECEIVED {}".format(data))
        raise ServerResponseError(message)

    return data['response_data']
Exemple #5
0
    def request(self, url, rpc_request):
        try:
            response = self.session.post(url,
                                         data=rpc_request,
                                         timeout=self.timeout)

            response.raise_for_status()

            content = response.content
        except requests.Timeout as e:
            raise TimeoutError(e)
        except requests.exceptions.ContentDecodingError as e:
            raise ContentDecodingError(e)
        except requests.HTTPError as e:
            raise HTTPError(e)
        except requests.RequestException as e:
            raise TransportError(e)

        return content
Exemple #6
0
    def call(self, method, path, data=None, need_auth=True):
        """
        Lowest level call helper. If ``consumer_key`` is not ``None``, inject
        authentication headers and sign the request.

        Request signature is a sha1 hash on following fields, joined by '+'
         - application_secret
         - consumer_key
         - METHOD
         - full request url
         - body
         - server current time (takes time delta into account)

        :param str method: HTTP verb. Usualy one of GET, POST, PUT, DELETE
        :param str path: api entrypoint to call, relative to endpoint base path
        :param data: any json serializable data to send as request's body
        :param boolean need_auth: if False, bypass signature
        :raises HTTPError: when underlying request failed for network reason
        :raises InvalidResponse: when API response could not be decoded
        """
        body = ''
        target = self._endpoint + path
        headers = {'X-Ovh-Application': self._application_key}

        # include payload
        if data is not None:
            headers['Content-type'] = 'application/json'
            body = json.dumps(data)
            _logger.info('body before %s' % (body))

        # sign request. Never sign 'time' or will recuse infinitely
        if need_auth:
            if not self._application_secret:
                raise InvalidKey("Invalid ApplicationSecret '%s'" %
                                 self._application_secret)

            if not self._consumer_key:
                raise InvalidKey("Invalid ConsumerKey '%s'" %
                                 self._consumer_key)

            now = str(int(time.time()) + self.time_delta)
            signature = hashlib.sha1()
            signature.update("+".join([
                self._application_secret, self._consumer_key,
                method.upper(), target, body, now
            ]).encode('utf-8'))

            headers['X-Ovh-Consumer'] = self._consumer_key
            headers['X-Ovh-Timestamp'] = now
            headers['X-Ovh-Signature'] = "$1$" + signature.hexdigest()

        # attempt request
        try:
            result = self._session.request(method,
                                           target,
                                           headers=headers,
                                           data=body)
            _logger.info('status ovh result pure client %s' % (result))
        except RequestException as error:
            raise HTTPError("Low HTTP request failed error", error)

        status = result.status_code
        _logger.info('status ovh 1ere client %s' % (status))
        # attempt to decode and return the response
        try:
            json_result = result.json()
            _logger.info('status ovh ss json result client %s' % (result))
        except ValueError as error:
            raise InvalidResponse("Failed to decode API response", error)

        # error check
        if status >= 100 and status < 300:
            return json_result
        elif status == 404:
            raise ResourceNotFoundError(json_result.get('message'))
        elif status == 400:
            raise BadParametersError(json_result.get('message'))
        elif status == 409:
            raise ResourceConflictError(json_result.get('message'))
        elif status == 0:
            raise NetworkError()
        else:
            raise APIError(json_result.get('message'))
Exemple #7
0
 def __init__(self, message):
     HTTPError.__init__(self, 500, message)
Exemple #8
0
def abort(code=500, text='Unknown Error: Appliction stopped.'):
    """ Aborts execution and causes a HTTP error. """
    raise HTTPError(code, text)