Commit b3c4441c authored by Andrii Shyshkalov's avatar Andrii Shyshkalov Committed by Commit Bot

[auth] cache LUCI_CONTEXT local_auth parameters.

R=vadimsh@chromium.org

Bug: 834536
Change-Id: I84d27c2d962e94cfe7befebfb374b17949bba7e5
Reviewed-on: https://chromium-review.googlesource.com/1020296Reviewed-by: 's avatarVadim Shtayura <vadimsh@chromium.org>
Commit-Queue: Andrii Shyshkalov <tandrii@chromium.org>
parent 733d4ec8
...@@ -132,7 +132,7 @@ def has_luci_context_local_auth(): ...@@ -132,7 +132,7 @@ def has_luci_context_local_auth():
"""Returns whether LUCI_CONTEXT should be used for ambient authentication. """Returns whether LUCI_CONTEXT should be used for ambient authentication.
""" """
try: try:
params = _get_luci_context_local_auth_params(os.environ) params = _get_luci_context_local_auth_params()
except LuciContextAuthError: except LuciContextAuthError:
return False return False
if params is None: if params is None:
...@@ -155,7 +155,7 @@ def get_luci_context_access_token(scopes=OAUTH_SCOPE_EMAIL): ...@@ -155,7 +155,7 @@ def get_luci_context_access_token(scopes=OAUTH_SCOPE_EMAIL):
LuciContextAuthError if LUCI_CONTEXT is present, but there was a failure LuciContextAuthError if LUCI_CONTEXT is present, but there was a failure
obtaining its access token. obtaining its access token.
""" """
params = _get_luci_context_local_auth_params(os.environ) params = _get_luci_context_local_auth_params()
if params is None: if params is None:
return None return None
return _get_luci_context_access_token( return _get_luci_context_access_token(
...@@ -170,12 +170,31 @@ _LuciContextLocalAuthParams = collections.namedtuple( ...@@ -170,12 +170,31 @@ _LuciContextLocalAuthParams = collections.namedtuple(
]) ])
def _get_luci_context_local_auth_params(env): def _cache_thread_safe(f):
"""Decorator caching result of nullary function in thread-safe way."""
lock = threading.Lock()
cache = []
@functools.wraps(f)
def caching_wrapper():
if not cache:
with lock:
if not cache:
cache.append(f())
return cache[0]
# Allow easy way to clear cache, particularly useful in tests.
caching_wrapper.clear_cache = lambda: cache.pop() if cache else None
return caching_wrapper
@_cache_thread_safe
def _get_luci_context_local_auth_params():
"""Returns local auth parameters if local auth is configured else None. """Returns local auth parameters if local auth is configured else None.
Raises LuciContextAuthError on unexpected failures. Raises LuciContextAuthError on unexpected failures.
""" """
ctx_path = env.get('LUCI_CONTEXT') ctx_path = os.environ.get('LUCI_CONTEXT')
if not ctx_path: if not ctx_path:
return None return None
ctx_path = ctx_path.decode(sys.getfilesystemencoding()) ctx_path = ctx_path.decode(sys.getfilesystemencoding())
......
...@@ -25,6 +25,9 @@ import auth ...@@ -25,6 +25,9 @@ import auth
class TestLuciContext(auto_stub.TestCase): class TestLuciContext(auto_stub.TestCase):
def setUp(self):
auth._get_luci_context_local_auth_params.clear_cache()
def _mock_local_auth(self, account_id, secret, rpc_port): def _mock_local_auth(self, account_id, secret, rpc_port):
self.mock(os, 'environ', {'LUCI_CONTEXT': 'default/test/path'}) self.mock(os, 'environ', {'LUCI_CONTEXT': 'default/test/path'})
self.mock(auth, '_load_luci_context', mock.Mock()) self.mock(auth, '_load_luci_context', mock.Mock())
...@@ -55,7 +58,7 @@ class TestLuciContext(auto_stub.TestCase): ...@@ -55,7 +58,7 @@ class TestLuciContext(auto_stub.TestCase):
- datetime.datetime.utcfromtimestamp(0)).total_seconds(), - datetime.datetime.utcfromtimestamp(0)).total_seconds(),
} }
self._mock_loc_server_resp(200, json.dumps(resp_content)) self._mock_loc_server_resp(200, json.dumps(resp_content))
params = auth._get_luci_context_local_auth_params(os.environ) params = auth._get_luci_context_local_auth_params()
token = auth._get_luci_context_access_token(params, datetime.datetime.min) token = auth._get_luci_context_access_token(params, datetime.datetime.min)
self.assertEquals(token.token, 'token') self.assertEquals(token.token, 'token')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment