[gerrit_util] Add dogfoodable luci-auth Authenticator.

Inspired by https://chromium-review.googlesource.com/c/5577744.

This implementation allows toggling the entire new-auth-stack with
the git configuration:

    [depot-tools]
        useNewAuthStack = 1

Additionally, you can set:

    [depot-tools]
        newAuthSkipSSO = 1

To intentionally skip SSOAuthenticator for now while doing local
evaluation of these auth methods.

This CL was uploaded without gitcookies using the new luci-auth
Authenticator.

Subsequent CLs will adjust creds-check and EnsureAuthenticated to
work correctly with the new auth stack.

R=ayatane@google.com

Bug: 336351842, 336652327
Change-Id: I0eb6d82ca106ddd114b74f63d8cda4c5a7b70c86
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/5590324
Reviewed-by: Yiwei Zhang <yiwzhang@google.com>
Reviewed-by: Scott Lee <ddoman@chromium.org>
Commit-Queue: Allen Li <ayatane@chromium.org>
changes/24/5590324/15
Robert Iannucci 11 months ago committed by LUCI CQ
parent 165fdee7e6
commit f871d80a7e

@ -107,7 +107,7 @@ class Authenticator(object):
return self._access_token
# Nope, still expired. Needs user interaction.
logging.error('Failed to create access token')
logging.debug('Failed to create access token')
raise LoginRequiredError(self._scopes)
def get_id_token(self):
@ -127,7 +127,7 @@ class Authenticator(object):
return self._id_token
# Nope, still expired. Needs user interaction.
logging.error('Failed to create id token')
logging.debug('Failed to create id token')
raise LoginRequiredError()
def authorize(self, http, use_id_token=False):

@ -177,24 +177,42 @@ class Authenticator(object):
Probes the local system and its environment and identifies the
Authenticator instance to use.
"""
authenticators: List[Type[Authenticator]] = [
SSOAuthenticator,
# LUCI Context takes priority since it's normally present only on bots,
# which then must use it.
LuciContextAuthenticator,
# TODO(crbug.com/1059384): Automatically detect when running on
# cloudtop, and use CookiesAuthenticator instead.
GceAuthenticator,
CookiesAuthenticator,
]
use_new_auth = scm.GIT.GetConfig(os.getcwd(),
'depot-tools.usenewauthstack') == '1'
# Allow skipping SSOAuthenticator for local testing purposes.
skip_sso = scm.GIT.GetConfig(os.getcwd(),
'depot-tools.newauthskipsso') == '1'
authenticators: List[Type[Authenticator]]
if use_new_auth:
LOGGER.debug('Authenticator.get: using new auth stack.')
authenticators = [
SSOAuthenticator,
LuciContextAuthenticator,
GceAuthenticator,
LuciAuthAuthenticator,
]
if skip_sso:
LOGGER.debug('Authenticator.get: skipping SSOAuthenticator.')
authenticators = authenticators[1:]
else:
authenticators = [
LuciContextAuthenticator,
GceAuthenticator,
CookiesAuthenticator,
]
for candidate in authenticators:
if candidate.is_applicable():
LOGGER.debug('Authenticator.get: Selected %s.',
candidate.__name__)
return candidate()
auth_names = ', '.join(a.__name__ for a in authenticators)
raise ValueError(
f"Could not find suitable authenticator, tried: {authenticators}")
f"Could not find suitable authenticator, tried: [{auth_names}].")
class SSOAuthenticator(Authenticator):
@ -234,14 +252,7 @@ class SSOAuthenticator(Authenticator):
def is_applicable(cls) -> bool:
"""If the git-remote-sso binary is in $PATH, we consider this
authenticator to be applicable."""
if scm.GIT.GetConfig(os.getcwd(), 'depot-tools.usenewauthstack') != '1':
LOGGER.debug('SSOAuthenticator: skipping due to missing opt-in.')
return False
pth = cls._resolve_sso_binary_path()
if pth:
LOGGER.debug('SSOAuthenticator: enabled %r.', pth)
return bool(pth)
return bool(cls._resolve_sso_binary_path())
@classmethod
def _parse_config(cls, config: str) -> SSOInfo:
@ -636,6 +647,18 @@ class LuciContextAuthenticator(Authenticator):
return ''
class LuciAuthAuthenticator(LuciContextAuthenticator):
"""Authenticator implementation that uses `luci-auth` credentials.
This is the same as LuciContextAuthenticator, except that it is for local
non-google.com developer credentials.
"""
@staticmethod
def is_applicable():
return True
class ReqParams(TypedDict):
uri: str
method: str

Loading…
Cancel
Save