mirror of
https://chromium.googlesource.com/chromium/tools/depot_tools.git
synced 2026-01-11 10:41:31 +00:00
git_auth: Delete unused ConfigChanger
All usages have been removed a while ago. Bug: 446999231 Change-Id: I40de9de7dc027c22652dd45ad75bbba3377bd923 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/7082062 Reviewed-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Allen Li <ayatane@chromium.org>
This commit is contained in:
250
git_auth.py
250
git_auth.py
@@ -11,261 +11,13 @@ import contextlib
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
from typing import TYPE_CHECKING, Callable, NamedTuple, TextIO
|
||||
from typing import Callable, NamedTuple, TextIO
|
||||
import urllib.parse
|
||||
|
||||
import gerrit_util
|
||||
import newauth
|
||||
import scm
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# Causes import cycle if imported normally
|
||||
import git_cl
|
||||
|
||||
|
||||
class ConfigMode(enum.Enum):
|
||||
"""Modes to pass to ConfigChanger"""
|
||||
NO_AUTH = 1
|
||||
NEW_AUTH = 2
|
||||
NEW_AUTH_SSO = 3
|
||||
|
||||
|
||||
class ConfigChanger(object):
|
||||
"""Changes Git auth config as needed for Gerrit."""
|
||||
|
||||
# Can be used to determine whether this version of the config has
|
||||
# been applied to a Git repo.
|
||||
#
|
||||
# Increment this when making changes to the config, so that reliant
|
||||
# code can determine whether the config needs to be re-applied.
|
||||
VERSION: int = 6
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
mode: ConfigMode,
|
||||
remote_url: str,
|
||||
set_config_func: Callable[..., None] = scm.GIT.SetConfig,
|
||||
):
|
||||
"""Create a new ConfigChanger.
|
||||
|
||||
Args:
|
||||
mode: How to configure auth
|
||||
remote_url: Git repository's remote URL, e.g.,
|
||||
https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
set_config_func: Function used to set configuration. Used
|
||||
for testing.
|
||||
"""
|
||||
self.mode: ConfigMode = mode
|
||||
|
||||
self._remote_url: str = remote_url
|
||||
self._set_config_func: Callable[..., None] = set_config_func
|
||||
|
||||
@functools.cached_property
|
||||
def _shortname(self) -> str:
|
||||
# Example: chromium
|
||||
parts: urllib.parse.SplitResult = urllib.parse.urlsplit(
|
||||
self._remote_url)
|
||||
return _url_shortname(parts)
|
||||
|
||||
@functools.cached_property
|
||||
def _host_url(self) -> str:
|
||||
# Example: https://chromium.googlesource.com
|
||||
# Example: https://chromium-review.googlesource.com
|
||||
parts: urllib.parse.SplitResult = urllib.parse.urlsplit(
|
||||
self._remote_url)
|
||||
return _url_host_url(parts)
|
||||
|
||||
@functools.cached_property
|
||||
def _root_url(self) -> str:
|
||||
# Example: https://chromium.googlesource.com/
|
||||
# Example: https://chromium-review.googlesource.com/
|
||||
parts: urllib.parse.SplitResult = urllib.parse.urlsplit(
|
||||
self._remote_url)
|
||||
return _url_root_url(parts)
|
||||
|
||||
@classmethod
|
||||
def new_from_env(cls, cwd: str, cl: git_cl.Changelist) -> ConfigChanger:
|
||||
"""Create a ConfigChanger by inferring from env.
|
||||
|
||||
The Gerrit host is inferred from the current repo/branch.
|
||||
The user, which is used to determine the mode, is inferred using
|
||||
git-config(1) in the given `cwd`.
|
||||
"""
|
||||
# This is determined either from the branch or repo config.
|
||||
#
|
||||
# Example: chromium-review.googlesource.com
|
||||
gerrit_host = cl.GetGerritHost()
|
||||
# This depends on what the user set for their remote.
|
||||
# There are a couple potential variations for the same host+repo.
|
||||
#
|
||||
# Example:
|
||||
# https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
remote_url = cl.GetRemoteUrl()
|
||||
|
||||
if gerrit_host is None or remote_url is None:
|
||||
raise Exception(
|
||||
'Error Git auth settings inferring from environment:'
|
||||
f' {gerrit_host=} {remote_url=}')
|
||||
assert gerrit_host is not None
|
||||
assert remote_url is not None
|
||||
|
||||
return cls(
|
||||
mode=cls._infer_mode(cwd, gerrit_host),
|
||||
remote_url=remote_url,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def new_for_remote(cls, cwd: str, remote_url: str) -> ConfigChanger:
|
||||
"""Create a ConfigChanger for the given Gerrit host.
|
||||
|
||||
The user, which is used to determine the mode, is inferred using
|
||||
git-config(1) in the given `cwd`.
|
||||
"""
|
||||
c = cls(
|
||||
mode=ConfigMode.NEW_AUTH,
|
||||
remote_url=remote_url,
|
||||
)
|
||||
assert c._shortname, "Short name is empty"
|
||||
c.mode = cls._infer_mode(cwd, c._shortname + '-review.googlesource.com')
|
||||
return c
|
||||
|
||||
@staticmethod
|
||||
def _infer_mode(cwd: str, gerrit_host: str) -> ConfigMode:
|
||||
"""Infer default mode to use."""
|
||||
if not newauth.Enabled():
|
||||
return ConfigMode.NO_AUTH
|
||||
email: str = scm.GIT.GetConfig(cwd, 'user.email') or ''
|
||||
if gerrit_util.ShouldUseSSO(gerrit_host, email):
|
||||
return ConfigMode.NEW_AUTH_SSO
|
||||
if not gerrit_util.GitCredsAuthenticator.gerrit_account_exists(
|
||||
gerrit_host):
|
||||
return ConfigMode.NO_AUTH
|
||||
return ConfigMode.NEW_AUTH
|
||||
|
||||
def apply(self, cwd: str) -> None:
|
||||
"""Apply config changes to the Git repo directory."""
|
||||
self._apply_cred_helper(cwd)
|
||||
self._apply_sso(cwd)
|
||||
self._apply_gitcookies(cwd)
|
||||
|
||||
def apply_global(self, cwd: str) -> None:
|
||||
"""Apply config changes to the global (user) Git config.
|
||||
|
||||
This will make the instance's mode (e.g., SSO or not) the global
|
||||
default for the Gerrit host, if not overridden by a specific Git repo.
|
||||
"""
|
||||
self._apply_global_cred_helper(cwd)
|
||||
self._apply_global_sso(cwd)
|
||||
|
||||
def _apply_cred_helper(self, cwd: str) -> None:
|
||||
"""Apply config changes relating to credential helper."""
|
||||
cred_key: str = f'credential.{self._host_url}.helper'
|
||||
if self.mode == ConfigMode.NEW_AUTH:
|
||||
self._set_config(cwd, cred_key, '', modify_all=True)
|
||||
self._set_config(cwd, cred_key, 'luci', append=True)
|
||||
elif self.mode == ConfigMode.NEW_AUTH_SSO:
|
||||
self._set_config(cwd, cred_key, None, modify_all=True)
|
||||
elif self.mode == ConfigMode.NO_AUTH:
|
||||
self._set_config(cwd, cred_key, None, modify_all=True)
|
||||
else:
|
||||
raise TypeError(f'Invalid mode {self.mode!r}')
|
||||
|
||||
# Cleanup old from version 4
|
||||
old_key: str = f'credential.{self._root_url}.helper'
|
||||
self._set_config(cwd, old_key, None, modify_all=True)
|
||||
|
||||
def _apply_sso(self, cwd: str) -> None:
|
||||
"""Apply config changes relating to SSO."""
|
||||
sso_key: str = f'url.sso://{self._shortname}/.insteadOf'
|
||||
http_key: str = f'url.{self._remote_url}.insteadOf'
|
||||
if self.mode == ConfigMode.NEW_AUTH:
|
||||
self._set_config(cwd, 'protocol.sso.allow', None)
|
||||
self._set_config(cwd, sso_key, None, modify_all=True)
|
||||
# Shadow a potential global SSO rewrite rule.
|
||||
self._set_config(cwd, http_key, self._remote_url, modify_all=True)
|
||||
elif self.mode == ConfigMode.NEW_AUTH_SSO:
|
||||
self._set_config(cwd, 'protocol.sso.allow', 'always')
|
||||
self._set_config(cwd, sso_key, self._root_url, modify_all=True)
|
||||
self._set_config(cwd, http_key, None, modify_all=True)
|
||||
elif self.mode == ConfigMode.NO_AUTH:
|
||||
self._set_config(cwd, 'protocol.sso.allow', None)
|
||||
self._set_config(cwd, sso_key, None, modify_all=True)
|
||||
self._set_config(cwd, http_key, None, modify_all=True)
|
||||
else:
|
||||
raise TypeError(f'Invalid mode {self.mode!r}')
|
||||
|
||||
def _apply_gitcookies(self, cwd: str) -> None:
|
||||
"""Apply config changes relating to gitcookies."""
|
||||
if self.mode == ConfigMode.NEW_AUTH:
|
||||
# Override potential global setting
|
||||
self._set_config(cwd, 'http.cookieFile', '', modify_all=True)
|
||||
elif self.mode == ConfigMode.NEW_AUTH_SSO:
|
||||
# Override potential global setting
|
||||
self._set_config(cwd, 'http.cookieFile', '', modify_all=True)
|
||||
elif self.mode == ConfigMode.NO_AUTH:
|
||||
self._set_config(cwd, 'http.cookieFile', None, modify_all=True)
|
||||
else:
|
||||
raise TypeError(f'Invalid mode {self.mode!r}')
|
||||
|
||||
def _apply_global_cred_helper(self, cwd: str) -> None:
|
||||
"""Apply config changes relating to credential helper."""
|
||||
cred_key: str = f'credential.{self._host_url}.helper'
|
||||
if self.mode == ConfigMode.NEW_AUTH:
|
||||
self._set_config(cwd, cred_key, '', scope='global', modify_all=True)
|
||||
self._set_config(cwd, cred_key, 'luci', scope='global', append=True)
|
||||
elif self.mode == ConfigMode.NEW_AUTH_SSO:
|
||||
# Avoid editing the user's config in case they manually
|
||||
# configured something.
|
||||
pass
|
||||
elif self.mode == ConfigMode.NO_AUTH:
|
||||
# Avoid editing the user's config in case they manually
|
||||
# configured something.
|
||||
pass
|
||||
else:
|
||||
raise TypeError(f'Invalid mode {self.mode!r}')
|
||||
|
||||
# Cleanup old from version 4
|
||||
old_key: str = f'credential.{self._root_url}.helper'
|
||||
self._set_config(cwd, old_key, None, modify_all=True, scope='global')
|
||||
|
||||
def _apply_global_sso(self, cwd: str) -> None:
|
||||
"""Apply config changes relating to SSO."""
|
||||
sso_key: str = f'url.sso://{self._shortname}/.insteadOf'
|
||||
if self.mode == ConfigMode.NEW_AUTH:
|
||||
# Do not unset protocol.sso.allow because it may be used by
|
||||
# other hosts.
|
||||
self._set_config(cwd,
|
||||
sso_key,
|
||||
None,
|
||||
scope='global',
|
||||
modify_all=True)
|
||||
elif self.mode == ConfigMode.NEW_AUTH_SSO:
|
||||
self._set_config(cwd,
|
||||
'protocol.sso.allow',
|
||||
'always',
|
||||
scope='global')
|
||||
self._set_config(cwd,
|
||||
sso_key,
|
||||
self._root_url,
|
||||
scope='global',
|
||||
modify_all=True)
|
||||
elif self.mode == ConfigMode.NO_AUTH:
|
||||
# Avoid editing the user's config in case they manually
|
||||
# configured something.
|
||||
pass
|
||||
else:
|
||||
raise TypeError(f'Invalid mode {self.mode!r}')
|
||||
|
||||
def _set_config(self, *args, **kwargs) -> None:
|
||||
self._set_config_func(*args, **kwargs)
|
||||
|
||||
|
||||
def ClearRepoConfig(cwd: str, cl: git_cl.Changelist) -> None:
|
||||
"""Clear the current Git repo authentication."""
|
||||
# TODO(ayatane): Disable prior to removal
|
||||
return
|
||||
|
||||
|
||||
class _ConfigError(Exception):
|
||||
"""Subclass for errors raised by ConfigWizard.
|
||||
|
||||
@@ -24,183 +24,6 @@ import scm
|
||||
import scm_mock
|
||||
|
||||
|
||||
class TestConfigChanger(unittest.TestCase):
|
||||
|
||||
maxDiff = None
|
||||
|
||||
def setUp(self):
|
||||
self._global_state_view: Iterable[tuple[str,
|
||||
list[str]]] = scm_mock.GIT(self)
|
||||
|
||||
@property
|
||||
def global_state(self):
|
||||
return dict(self._global_state_view)
|
||||
|
||||
def test_apply_new_auth(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
want = {
|
||||
'/some/fake/dir': {
|
||||
'credential.https://chromium.googlesource.com.helper':
|
||||
['', 'luci'],
|
||||
'http.cookiefile': [''],
|
||||
'url.https://chromium.googlesource.com/chromium/tools/depot_tools.git.insteadof':
|
||||
[
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git'
|
||||
],
|
||||
},
|
||||
}
|
||||
self.assertEqual(scm.GIT._dump_config_state(), want)
|
||||
|
||||
def test_apply_new_auth_sso(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH_SSO,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
want = {
|
||||
'/some/fake/dir': {
|
||||
'protocol.sso.allow': ['always'],
|
||||
'url.sso://chromium/.insteadof':
|
||||
['https://chromium.googlesource.com/'],
|
||||
'http.cookiefile': [''],
|
||||
},
|
||||
}
|
||||
self.assertEqual(scm.GIT._dump_config_state(), want)
|
||||
|
||||
def test_apply_no_auth(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NO_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
want = {
|
||||
'/some/fake/dir': {},
|
||||
}
|
||||
self.assertEqual(scm.GIT._dump_config_state(), want)
|
||||
|
||||
def test_apply_chain_sso_new(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH_SSO,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
want = {
|
||||
'/some/fake/dir': {
|
||||
'credential.https://chromium.googlesource.com.helper':
|
||||
['', 'luci'],
|
||||
'http.cookiefile': [''],
|
||||
'url.https://chromium.googlesource.com/chromium/tools/depot_tools.git.insteadof':
|
||||
[
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git'
|
||||
],
|
||||
},
|
||||
}
|
||||
self.assertEqual(scm.GIT._dump_config_state(), want)
|
||||
|
||||
def test_apply_chain_new_sso(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH_SSO,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
want = {
|
||||
'/some/fake/dir': {
|
||||
'protocol.sso.allow': ['always'],
|
||||
'url.sso://chromium/.insteadof':
|
||||
['https://chromium.googlesource.com/'],
|
||||
'http.cookiefile': [''],
|
||||
},
|
||||
}
|
||||
self.assertEqual(scm.GIT._dump_config_state(), want)
|
||||
|
||||
def test_apply_chain_new_no(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NO_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
want = {
|
||||
'/some/fake/dir': {},
|
||||
}
|
||||
self.assertEqual(scm.GIT._dump_config_state(), want)
|
||||
|
||||
def test_apply_chain_sso_no(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH_SSO,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NO_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply('/some/fake/dir')
|
||||
want = {
|
||||
'/some/fake/dir': {},
|
||||
}
|
||||
self.assertEqual(scm.GIT._dump_config_state(), want)
|
||||
|
||||
def test_apply_global_new_auth(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply_global('/some/fake/dir')
|
||||
want = {
|
||||
'credential.https://chromium.googlesource.com.helper': ['', 'luci'],
|
||||
}
|
||||
self.assertEqual(self.global_state, want)
|
||||
|
||||
def test_apply_global_new_auth_sso(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH_SSO,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply_global('/some/fake/dir')
|
||||
want = {
|
||||
'protocol.sso.allow': ['always'],
|
||||
'url.sso://chromium/.insteadof':
|
||||
['https://chromium.googlesource.com/'],
|
||||
}
|
||||
self.assertEqual(self.global_state, want)
|
||||
|
||||
def test_apply_global_chain_sso_new(self):
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH_SSO,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply_global('/some/fake/dir')
|
||||
git_auth.ConfigChanger(
|
||||
mode=git_auth.ConfigMode.NEW_AUTH,
|
||||
remote_url=
|
||||
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
|
||||
).apply_global('/some/fake/dir')
|
||||
want = {
|
||||
'protocol.sso.allow': ['always'],
|
||||
'credential.https://chromium.googlesource.com.helper': ['', 'luci'],
|
||||
}
|
||||
self.assertEqual(self.global_state, want)
|
||||
|
||||
|
||||
class TestParseCookiefile(unittest.TestCase):
|
||||
|
||||
def test_ignore_comments(self):
|
||||
|
||||
Reference in New Issue
Block a user