[auth] cache LUCI_CONTEXT local_auth parameters.

R=vadimsh@chromium.org

Bug: 834536
Change-Id: I84d27c2d962e94cfe7befebfb374b17949bba7e5
Reviewed-on: https://chromium-review.googlesource.com/1020296
Reviewed-by: Vadim Shtayura <vadimsh@chromium.org>
Commit-Queue: Andrii Shyshkalov <tandrii@chromium.org>
changes/96/1020296/3
Andrii Shyshkalov 7 years ago committed by Commit Bot
parent 733d4ec8e3
commit b3c4441c81

@ -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):
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(
]) ])
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
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):
- 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')

Loading…
Cancel
Save