fix: annotate auto-grant permission failures with required_scope and console_url#1045
fix: annotate auto-grant permission failures with required_scope and console_url#1045ZEden0 wants to merge 1 commit into
Conversation
…console_url When AutoGrantCurrentUserDrivePermission encounters lark code 99991672/99991679, extract permission_violations from the underlying ExitError and surface lark_code, required_scope, and console_url on the result map. Override the generic fallback hint with one pointing at the developer console — the concrete next step a user can take. Refactor extractRequiredScopes / SelectRecommendedScope wrapping / console URL construction out of cmd/root.go into internal/registry/scope_hint.go so both the top-level enrichPermissionError path and the best-effort sub-call path in shortcuts/common share one implementation. Change-Id: Ida63ed160d1167b7961b6faac5c2cf9b7f971c65
📝 WalkthroughWalkthroughThis PR adds OAuth scope extraction and URL-building infrastructure for permission error enrichment. New registry helpers parse required scopes from API errors, select recommended scopes with fallback logic, and generate brand-specific developer console URLs. These helpers are integrated into permission grant error annotation and refactored into ChangesScope helpers and permission grant enrichment
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
cmd/root.go (1)
406-440:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winGuard console-specific hints when
console_urlis unavailable.At Line 406,
BuildConsoleScopeURLcan return""(e.g., missing AppID/scope), but Lines 419/428/435/438 still tell users to “see console_url”. That produces misleading guidance.Suggested patch
// Build admin console URL with the recommended scope consoleURL := registry.BuildConsoleScopeURL(cfg.Brand, cfg.AppID, recommended) + hasConsoleURL := consoleURL != "" @@ case output.LarkErrUserScopeInsufficient, output.LarkErrUserNotAuthorized: // User has not authorized the scope → re-authorize exitErr.Detail.Message = fmt.Sprintf("User not authorized: required scope %s [%d]", recommended, larkCode) if isBot { - exitErr.Detail.Hint = "enable the scope in developer console (see console_url)" + if hasConsoleURL { + exitErr.Detail.Hint = "enable the scope in developer console (see console_url)" + } else { + exitErr.Detail.Hint = "enable the required scope in developer console, then retry" + } } else { exitErr.Detail.Hint = fmt.Sprintf("run `lark-cli auth login --scope \"%s\"` in the background. It blocks and outputs a verification URL — retrieve the URL and open it in a browser to complete login.", recommended) } - exitErr.Detail.ConsoleURL = consoleURL + if hasConsoleURL { + exitErr.Detail.ConsoleURL = consoleURL + } @@ case output.LarkErrAppScopeNotEnabled: // App has not enabled the API scope → admin console exitErr.Detail.Message = fmt.Sprintf("App scope not enabled: required scope %s [%d]", recommended, larkCode) - exitErr.Detail.Hint = "enable the scope in developer console (see console_url)" - exitErr.Detail.ConsoleURL = consoleURL + if hasConsoleURL { + exitErr.Detail.Hint = "enable the scope in developer console (see console_url)" + exitErr.Detail.ConsoleURL = consoleURL + } else { + exitErr.Detail.Hint = "enable the required scope in developer console, then retry" + } @@ default: // Other permission errors (matched by keyword) exitErr.Detail.Message = fmt.Sprintf("Permission denied: required scope %s [%d]", recommended, larkCode) if isBot { - exitErr.Detail.Hint = "enable the scope in developer console (see console_url)" + if hasConsoleURL { + exitErr.Detail.Hint = "enable the scope in developer console (see console_url)" + } else { + exitErr.Detail.Hint = "enable the required scope in developer console, then retry" + } } else { exitErr.Detail.Hint = fmt.Sprintf( "enable scope in console (see console_url), or run `lark-cli auth login --scope \"%s\"` in the background. It blocks and outputs a verification URL — retrieve the URL and open it in a browser to complete login.", recommended) } - exitErr.Detail.ConsoleURL = consoleURL + if hasConsoleURL { + exitErr.Detail.ConsoleURL = consoleURL + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cmd/root.go` around lines 406 - 440, The code assumes registry.BuildConsoleScopeURL(cfg.Brand, cfg.AppID, recommended) (consoleURL) is always present but sometimes returns "", so adjust the permission-error handling (switch block around consoleURL, exitErr.Detail.Message/Hint/ConsoleURL) to guard console-specific hints: compute consoleURL once, then before setting exitErr.Detail.Hint or exitErr.Detail.ConsoleURL check if consoleURL != "" and only then append or use phrases like "(see console_url)" and set exitErr.Detail.ConsoleURL = consoleURL; otherwise provide alternative hint text that omits the console_url reference (for both isBot and non-bot branches) and ensure exitErr.Detail.ConsoleURL is left empty/nil when consoleURL == "".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@cmd/root.go`:
- Around line 406-440: The code assumes registry.BuildConsoleScopeURL(cfg.Brand,
cfg.AppID, recommended) (consoleURL) is always present but sometimes returns "",
so adjust the permission-error handling (switch block around consoleURL,
exitErr.Detail.Message/Hint/ConsoleURL) to guard console-specific hints: compute
consoleURL once, then before setting exitErr.Detail.Hint or
exitErr.Detail.ConsoleURL check if consoleURL != "" and only then append or use
phrases like "(see console_url)" and set exitErr.Detail.ConsoleURL = consoleURL;
otherwise provide alternative hint text that omits the console_url reference
(for both isBot and non-bot branches) and ensure exitErr.Detail.ConsoleURL is
left empty/nil when consoleURL == "".
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 182ddedc-7f43-488b-b1e3-4574fb68631c
📒 Files selected for processing (5)
cmd/root.gointernal/registry/scope_hint.gointernal/registry/scope_hint_test.goshortcuts/common/permission_grant.goshortcuts/common/permission_grant_test.go
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1045 +/- ##
==========================================
+ Coverage 67.72% 67.79% +0.06%
==========================================
Files 575 591 +16
Lines 54360 55237 +877
==========================================
+ Hits 36817 37448 +631
- Misses 14496 14680 +184
- Partials 3047 3109 +62 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@bd70f7cf9542eec2940bf13f931f15e46479c861🧩 Skill updatenpx skills add ZEden0/cli#fix/auto-grant-permission-error-annotation -y -g |
Summary
Follow-up to #1015. When
AutoGrantCurrentUserDrivePermissionfails with apermission-class API error (lark code 99991672 / 99991679), the result map
now carries
lark_code,required_scope, andconsole_urlso AI agentsand CLI users can jump straight to the developer console to enable the
missing scope, instead of seeing only a generic "retry later" hint.
Changes
annotateGrantPermissionErrorhelper that inspects
*output.ExitError, extractspermission_violations,picks the recommended scope, builds a brand-aware console URL, and
overrides the generic fallback hint with an actionable one.
between the two permission-error paths:
ExtractRequiredScopes— parsepermission_violationsdefensively.SelectRecommendedScopeFromStrings— string wrapper around the existingSelectRecommendedScope, with a "first scope" fallback.BuildConsoleScopeURL— construct thescope-applyURL with brandrouting (
open.feishu.cnvsopen.larksuite.com) and proper escaping.enrichPermissionErrorto delegate to the newhelpers; deletes the local
extractRequiredScopesand inline URL buildingthat previously duplicated this logic.
covering happy path, malformed input, brand variants, empty input, and
the priority-table-vs-fallback ordering.
app-scope-not-enabled annotation, lark brand console URL, non-permission
errors no-op, missing violations, empty appID, nil-args safety, plus an
integration test through
AutoGrantCurrentUserDrivePermissionwith amocked 99991672 response.
Test Plan
go test -race -count=1 ./internal/registry/... ./shortcuts/common/... ./cmd/...passesgolangci-lint v2.1.6 run --new-from-rev=origin/main: 0 issuesgo vetclean;go mod tidyis a no-opExtractRequiredScopes100%,BuildConsoleScopeURL100%SelectRecommendedScopeFromStrings87.5%annotateGrantPermissionError91.3%lark drive +upload-fileagainst anapp missing the
drive:drivescope; confirmed JSON result now containslark_code,required_scope,console_url, and that thehinttextreferences the developer console.
Related Issues
Follow-up to #1015.
Summary by CodeRabbit