Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/auth-pr175-nits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@googleworkspace/cli": patch
---

Clean up nits from PR #175 auth fix

- Update stale docstring on `resolve_account` to match new fallthrough behavior
- Add breadcrumb comment on string-based error matching in `main.rs`
- Move identity scope injection before authenticator build for readability
3 changes: 1 addition & 2 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ pub async fn get_token(scopes: &[&str], account: Option<&str>) -> anyhow::Result
/// Resolve which account to use:
/// 1. Explicit `account` parameter takes priority.
/// 2. Fall back to `accounts.json` default.
/// 3. If no registry exists but legacy `credentials.enc` exists, fail with upgrade message.
/// 4. If nothing exists, return None (will fall through to standard error).
/// 3. If no registry exists, return None to allow legacy `credentials.enc` fallthrough.
fn resolve_account(account: Option<&str>) -> anyhow::Result<Option<String>> {
let registry = crate::accounts::load_accounts()?;

Expand Down
18 changes: 9 additions & 9 deletions src/auth_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,15 @@ async fn handle_login(args: &[String]) -> Result<(), GwsError> {
..Default::default()
};

// Ensure openid + email scopes are always present so we can identify the user
// via the userinfo endpoint after login.
let identity_scopes = ["openid", "https://www.googleapis.com/auth/userinfo.email"];
for s in &identity_scopes {
if !scopes.iter().any(|existing| existing == s) {
scopes.push(s.to_string());
}
}

// Use a temp file for yup-oauth2's token persistence, then encrypt it
let temp_path = config_dir().join("credentials.tmp");

Expand Down Expand Up @@ -311,15 +320,6 @@ async fn handle_login(args: &[String]) -> Result<(), GwsError> {
.await
.map_err(|e| GwsError::Auth(format!("Failed to build authenticator: {e}")))?;

// Ensure openid + email scopes are always present so we can identify the user
// via the userinfo endpoint after login.
let identity_scopes = ["openid", "https://www.googleapis.com/auth/userinfo.email"];
for s in &identity_scopes {
if !scopes.iter().any(|existing| existing == s) {
scopes.push(s.to_string());
}
}

// Request a token — this triggers the browser OAuth flow
let scope_refs: Vec<&str> = scopes.iter().map(|s| s.as_str()).collect();
let token = auth
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ async fn run() -> Result<(), GwsError> {
// propagate the error instead of silently falling back to unauthenticated.
// Only fall back to None if no credentials exist at all.
let err_msg = format!("{e:#}");
// NB: matches the bail!() message in auth::load_credentials_inner
if err_msg.starts_with("No credentials found") {
(None, executor::AuthMethod::None)
} else {
Expand Down
Loading