Skip to content

Commit

Permalink
Elided long log lines in the client. (#954)
Browse files Browse the repository at this point in the history
* [client] Update and simplify test dependencies.

* [client] Allow specifying a requests session to use.

* [client] Elided long log lines.
  • Loading branch information
tomprince authored and bhearsum committed Jul 5, 2019
1 parent 7184701 commit 6482692
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 235 deletions.
22 changes: 15 additions & 7 deletions client/balrogclient/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
_token_cache = {}


def _json_log_data(data):
log = json.dumps(data)
if len(log) > 100:
log = log[:80] + "<...{} characters elided ...>".format(len(log) - 80)
return log


def is_csrf_token_expired(token):
"""Checks whether a CSRF token is still valid
Expand All @@ -31,7 +38,7 @@ def is_csrf_token_expired(token):
return False


def _get_auth0_token(secrets):
def _get_auth0_token(secrets, session):
"""Get Auth0 token
See https://auth0.com/docs/api/authentication#regular-web-app-login-flow43 for the description
Expand All @@ -48,7 +55,7 @@ def _get_auth0_token(secrets):
url = "https://{}/oauth/token".format(secrets["domain"])
payload = dict(client_id=secrets["client_id"], client_secret=secrets["client_secret"], audience=secrets["audience"], grant_type="client_credentials")
headers = {"Content-Type": "application/json"}
request = requests.post(url, data=json.dumps(payload), headers=headers)
request = session.post(url, data=json.dumps(payload), headers=headers)
response = request.json()
# In order to know exact expiration we would need to decode the token, what
# requires more dependencies. Instead we use the returned "expires_in" in
Expand Down Expand Up @@ -98,7 +105,7 @@ class API(object):
prerequest_url_template = None
url_template_vars = None

def __init__(self, auth0_secrets, api_root="https://aus4-admin-dev.allizom.org/api", ca_certs=True, timeout=60, raise_exceptions=True):
def __init__(self, auth0_secrets, api_root="https://aus4-admin-dev.allizom.org/api", ca_certs=True, timeout=60, raise_exceptions=True, session=None):
""" Creates an API object which wraps REST API of Balrog server.
api_root: API root URL of balrog server
Expand All @@ -110,12 +117,13 @@ def __init__(self, auth0_secrets, api_root="https://aus4-admin-dev.allizom.org/a
CA bundle.
timeout : request timeout
raise_exceptions: controls exception handling of python-requests.
session: requests esssion to use for API calls
"""
self.api_root = api_root.rstrip("/")
self.verify = ca_certs
self.timeout = timeout
self.raise_exceptions = raise_exceptions
self.session = requests.session()
self.session = session or requests.session()
self.csrf_token = None
self.auth0_secrets = auth0_secrets

Expand Down Expand Up @@ -155,12 +163,12 @@ def do_request(self, url, data, method):
if data is not None and "csrf_token" in data:
sanitised_data = data.copy()
del sanitised_data["csrf_token"]
logging.debug("Data sent: %s", sanitised_data)
logging.debug("Data sent: %s", _json_log_data(sanitised_data))
else:
logging.debug("Data sent: %s", data)
logging.debug("Data sent: %s", _json_log_data(data))
headers = {"Accept-Encoding": "application/json", "Accept": "application/json", "Content-Type": "application/json", "Referer": self.api_root}
before = time.time()
access_token = _get_auth0_token(self.auth0_secrets)
access_token = _get_auth0_token(self.auth0_secrets, session=self.session)
auth = BearerAuth(access_token)
# Don't dump data to json unless it actually exists. Otherwise we end up with a string of
# 'None', which is not intended, and is not actually supported by some servers for HEAD/GET
Expand Down
42 changes: 42 additions & 0 deletions client/balrogclient/test/test_balrog_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from __future__ import absolute_import, print_function

import logging

from requests import Session
from requests_mock import Adapter

from balrogclient.api import API

AUTH0_SECRETS = {
"client_id": "some-client",
"client_secret": "super-secret",
"audience": "tests",
"domain": "auth0.test",
}


def test_log_lines_truncated(caplog):
session = Session()
adapter = Adapter()
session.mount("https://", adapter)
adapter.register_uri(
"POST",
"https://auth0.test/oauth/token",
json={"expires_in": 3600, "access_token": "the-token"},
)
adapter.register_uri("GET", "https://api/")

caplog.set_level(logging.DEBUG)

api = API(AUTH0_SECRETS, session=session)
api.do_request("https://api/", {"data": "a" * 100}, "GET")

logs = [message.split(': ', 1)[1] for message in caplog.messages if message.startswith("Data sent: ")]
assert logs == ['{"data": "' + 'a'*70 + "<...32 characters elided ...>"]
print(logs)
Loading

0 comments on commit 6482692

Please sign in to comment.