From f342cc7db5c29a0a18c118dee3db0aa2847bde3d Mon Sep 17 00:00:00 2001 From: Wyatt <34258355+GreenHatHG@users.noreply.github.com> Date: Fri, 5 Dec 2025 13:22:22 +0800 Subject: [PATCH] feat(webdav): add bearer_token_command for dynamic token acquisition (#10917) Co-authored-by: GreenHatHG Co-authored-by: skshetry <18718008+skshetry@users.noreply.github.com> --- dvc/config_schema.py | 1 + pyproject.toml | 2 +- tests/unit/remote/test_webdav.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/dvc/config_schema.py b/dvc/config_schema.py index a4e00ff8a..07f79fc06 100644 --- a/dvc/config_schema.py +++ b/dvc/config_schema.py @@ -151,6 +151,7 @@ WEBDAV_COMMON = { "password": str, "ask_password": Bool, "token": str, + "bearer_token_command": str, "custom_auth_header": str, "cert_path": str, "key_path": str, diff --git a/pyproject.toml b/pyproject.toml index 0c0561eba..81f47957f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -124,7 +124,7 @@ tests = [ "sqlalchemy>=1,<3", # optional dependency for `import-db` "pandas>=1", # optional dependency for `import-db` ] -webdav = ["dvc-webdav>=3,<4"] +webdav = ["dvc-webdav>=3.0.1,<4"] webhdfs = ["dvc-webhdfs>=3.1,<4"] webhdfs_kerberos = ["dvc-webhdfs[kerberos]>=3.1,<4"] diff --git a/tests/unit/remote/test_webdav.py b/tests/unit/remote/test_webdav.py index c6f3faba1..1b7915932 100644 --- a/tests/unit/remote/test_webdav.py +++ b/tests/unit/remote/test_webdav.py @@ -153,3 +153,31 @@ def test_remote_with_jobs(dvc, base_url, fs_cls): assert config["user"] == "admin" assert f"{scheme}://{user}@example.com" in config["host"] assert cls is fs_cls + + +def test_bearer_token_command(mocker): + mock_auth_obj = mocker.Mock() + mock_get_auth = mocker.patch( + "dvc_webdav.get_bearer_auth", return_value=mock_auth_obj + ) + + command = "my-token-cmd.sh" + timeout = 10 + + # Configuration with potential conflicts + config = { + "url": url, + "token": "static-token-value", + "user": "conflict-user", + "password": "conflict-password", + "bearer_token_command": command, + "timeout": timeout, + } + + fs = WebDAVFileSystem(**config) + + # the factory function was invoked with the correct arguments from the config. + mock_get_auth.assert_called_once_with(command, timeout) + + # the generated auth object is correctly injected into `fs_args`. + assert fs.fs_args["auth"] == mock_auth_obj