diff --git a/.changeset/remove-dwd.md b/.changeset/remove-dwd.md new file mode 100644 index 0000000..694464d --- /dev/null +++ b/.changeset/remove-dwd.md @@ -0,0 +1,5 @@ +--- +"@googleworkspace/cli": minor +--- + +Remove domain wide delegation support diff --git a/AGENTS.md b/AGENTS.md index 4ea9873..f8b7612 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -175,7 +175,6 @@ Use these labels to categorize pull requests and issues: | `GOOGLE_WORKSPACE_CLI_TOKEN` | Pre-obtained OAuth2 access token (highest priority; bypasses all credential file loading) | | `GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE` | Path to OAuth credentials JSON (no default; if unset, falls back to credentials secured by the OS Keyring and encrypted in `~/.config/gws/`) | | `GOOGLE_WORKSPACE_CLI_ACCOUNT` | Default account email for multi-account usage (overridden by `--account` flag) | -| `GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER` | Email of user to impersonate with Domain-Wide Delegation (service accounts only) | | `GOOGLE_APPLICATION_CREDENTIALS` | Standard Google ADC path; used as fallback when no gws-specific credentials are configured | ### Configuration diff --git a/README.md b/README.md index 151a9ee..6c9042c 100644 --- a/README.md +++ b/README.md @@ -209,12 +209,6 @@ export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/service-account.json gws drive files list ``` -For Domain-Wide Delegation, add: - -```bash -export GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER=admin@example.com -``` - ### Pre-obtained Access Token Useful when another tool (e.g. `gcloud`) already mints tokens for your environment. @@ -366,7 +360,6 @@ All variables are optional. See [`.env.example`](.env.example) for a copy-paste | `GOOGLE_WORKSPACE_CLI_TOKEN` | Pre-obtained OAuth2 access token (highest priority) | | `GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE` | Path to OAuth credentials JSON (user or service account) | | `GOOGLE_WORKSPACE_CLI_ACCOUNT` | Default account email (overridden by `--account` flag) | -| `GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER` | Email for Domain-Wide Delegation (service accounts) | | `GOOGLE_WORKSPACE_CLI_CLIENT_ID` | OAuth client ID (alternative to `client_secret.json`) | | `GOOGLE_WORKSPACE_CLI_CLIENT_SECRET` | OAuth client secret (paired with `CLIENT_ID`) | | `GOOGLE_WORKSPACE_CLI_CONFIG_DIR` | Override config directory (default: `~/.config/gws`) | diff --git a/src/auth.rs b/src/auth.rs index 48d28f6..3c3ff98 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -81,7 +81,6 @@ pub async fn get_token(scopes: &[&str], account: Option<&str>) -> anyhow::Result } let creds_file = std::env::var("GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE").ok(); - let impersonated_user = std::env::var("GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER").ok(); let config_dir = crate::auth_commands::config_dir(); // If env var credentials are specified, skip account resolution entirely @@ -90,7 +89,7 @@ pub async fn get_token(scopes: &[&str], account: Option<&str>) -> anyhow::Result let default_path = config_dir.join("credentials.json"); let token_cache = config_dir.join("token_cache.json"); let creds = load_credentials_inner(creds_file.as_deref(), &enc_path, &default_path).await?; - return get_token_inner(scopes, creds, &token_cache, impersonated_user.as_deref()).await; + return get_token_inner(scopes, creds, &token_cache).await; } // Resolve account from registry @@ -113,13 +112,7 @@ pub async fn get_token(scopes: &[&str], account: Option<&str>) -> anyhow::Result let default_path = config_dir.join("credentials.json"); let creds = load_credentials_inner(None, &enc_path, &default_path).await?; - get_token_inner( - scopes, - creds, - &token_cache_path, - impersonated_user.as_deref(), - ) - .await + get_token_inner(scopes, creds, &token_cache_path).await } /// Resolve which account to use: @@ -174,7 +167,6 @@ async fn get_token_inner( scopes: &[&str], creds: Credential, token_cache_path: &std::path::Path, - impersonated_user: Option<&str>, ) -> anyhow::Result { match creds { Credential::AuthorizedUser(secret) => { @@ -198,17 +190,10 @@ async fn get_token_inner( .map(|f| f.to_string_lossy().to_string()) .unwrap_or_else(|| "token_cache.json".to_string()); let sa_cache = token_cache_path.with_file_name(format!("sa_{tc_filename}")); - let mut builder = yup_oauth2::ServiceAccountAuthenticator::builder(key).with_storage( + let builder = yup_oauth2::ServiceAccountAuthenticator::builder(key).with_storage( Box::new(crate::token_storage::EncryptedTokenStorage::new(sa_cache)), ); - // Check for impersonation - if let Some(user) = impersonated_user { - if !user.trim().is_empty() { - builder = builder.subject(user.to_string()); - } - } - let auth = builder .build() .await diff --git a/src/auth_commands.rs b/src/auth_commands.rs index c9b12e1..37de109 100644 --- a/src/auth_commands.rs +++ b/src/auth_commands.rs @@ -1507,7 +1507,7 @@ const SCOPE_ENTRIES: &[ScopeEntry] = &[ // (parse_scopes removed — replaced by resolve_scopes above) /// Helper: check if a scope can't be used with user OAuth consent flow -/// (requires a Chat app, service account, or domain-wide delegation). +/// (requires a Chat app or service account). fn is_app_only_scope(url: &str) -> bool { url.contains("/auth/chat.app.") || url.contains("/auth/chat.bot") diff --git a/src/main.rs b/src/main.rs index 6940238..98c392b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -459,9 +459,6 @@ fn print_usage() { println!( " GOOGLE_WORKSPACE_CLI_ACCOUNT Default account email for multi-account" ); - println!( - " GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER Email for Domain-Wide Delegation (service accounts)" - ); println!( " GOOGLE_WORKSPACE_CLI_CONFIG_DIR Override config directory (default: ~/.config/gws)" ); diff --git a/src/setup.rs b/src/setup.rs index 5df88cc..a2730ec 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -286,7 +286,7 @@ pub async fn fetch_scopes_for_apis(enabled_api_ids: &[String]) -> Vec