fix(auth): split bot and user identity diagnostics#957
Conversation
📝 WalkthroughWalkthroughIntroduces a new identity diagnostics package that independently evaluates bot and user identity readiness, replacing prior opaque token checks. Integrates diagnostics into ChangesUnified Identity Diagnostics
Sequence Diagram(s)sequenceDiagram
participant CLI as CLI Command
participant Diagnose as identitydiag.Diagnose
participant BotDiag as diagnoseBot
participant UserDiag as diagnoseUser
participant Factory as cmdutil.Factory
participant Keychain as Token Keychain
participant BotAPI as Bot Info Endpoint
participant SDK as Lark SDK
CLI->>Diagnose: Diagnose(ctx, factory, cfg, verify)
Diagnose->>BotDiag: validate config, resolve token
alt verify enabled
BotDiag->>BotAPI: GET /open-apis/bot/v3/info
BotAPI-->>BotDiag: openId, appName
BotDiag->>BotDiag: set Verified=true
end
BotDiag-->>Diagnose: Bot Identity result
Diagnose->>UserDiag: validate config, read keychain
UserDiag->>Keychain: read stored UAToken
UserDiag->>UserDiag: derive status from token state
alt verify enabled
UserDiag->>Factory: create HTTP client
UserDiag->>SDK: initialize Lark SDK
UserDiag->>SDK: VerifyUserToken(accessToken)
SDK-->>UserDiag: verification result
UserDiag->>UserDiag: set Verified based on result
end
UserDiag-->>Diagnose: User Identity result
Diagnose-->>CLI: Result{Bot, User}
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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/auth/status.go (1)
46-49:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReturn errors via
output.Errorfper coding guidelines.The
RunEfunction in commands must returnoutput.Errorforoutput.ErrWithHintinstead of bare errors, because AI agents parse stderr as JSON. As per coding guidelines: "RunE functions in commands must return output.Errorf / output.ErrWithHint — never bare fmt.Errorf".Proposed fix
config, err := f.Config() if err != nil { - return err + return output.Errorf("failed to load config: %w", err) }🤖 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/auth/status.go` around lines 46 - 49, The RunE handler in cmd/auth/status.go currently returns a bare error from f.Config() (config, err := f.Config(); if err != nil { return err }) which violates the guideline — change the error return to use output.Errorf (or output.ErrWithHint when appropriate) so the command returns machine-parsable JSON; locate the RunE function (status command) and replace returns of raw err from f.Config() with something like output.Errorf("failed to load config: %v", err) or output.ErrWithHint(...) to preserve the original error message and context.
🤖 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/auth/status.go`:
- Around line 46-49: The RunE handler in cmd/auth/status.go currently returns a
bare error from f.Config() (config, err := f.Config(); if err != nil { return
err }) which violates the guideline — change the error return to use
output.Errorf (or output.ErrWithHint when appropriate) so the command returns
machine-parsable JSON; locate the RunE function (status command) and replace
returns of raw err from f.Config() with something like output.Errorf("failed to
load config: %v", err) or output.ErrWithHint(...) to preserve the original error
message and context.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7ac92161-d54c-4659-bbd0-1f2aad7e3245
📒 Files selected for processing (6)
cmd/auth/status.gocmd/auth/status_test.gocmd/doctor/doctor.gocmd/doctor/doctor_test.gointernal/identitydiag/diagnostics.gointernal/identitydiag/diagnostics_test.go
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@ee5310fa80e5165adca471e4ec311e9e0bf9680a🧩 Skill updatenpx skills add mtsui-cmyk/cli#fix/auth-identity-diagnostics -y -g |
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (45.56%) is below the target coverage (60.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #957 +/- ##
==========================================
+ Coverage 66.78% 66.84% +0.05%
==========================================
Files 564 565 +1
Lines 52441 52611 +170
==========================================
+ Hits 35024 35167 +143
+ Misses 14516 14513 -3
- Partials 2901 2931 +30 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
`/open-apis/bot/v3/info` returns `{code, msg, bot: {...}}` — the bot
payload is under `bot`, not `data` as the newer Lark API convention
would suggest. The decoder was reading from a non-existent `data`
field, so `envelope.Data.OpenID` was always empty and every successful
verify was reported as `Bot identity: verify failed: open_id is empty`.
The pre-existing test mocks used `{"data": {...}}` matching the buggy
decoder, so unit tests passed while production reads of every Lark
account failed verification.
Fix:
- change the JSON tag on the envelope from `json:"data"` to `json:"bot"`
- update mocks in identitydiag and cmd/auth/status tests to emit `bot`
Verified locally: `lark-cli doctor` now reports `bot_identity: pass`
for both a normal account and a bot-only profile, restoring the
behavior that #957 set out to deliver.
Change-Id: Ib26dfdd5a0cc37d2d62537ae2bf5e854e67cb83c
) * fix(identitydiag): harden verify path and tighten status semantics Follow-ups to #957: - bound bot/user verify calls with a 10s timeout (mirrors the doctor endpoint probe) so a hanging server cannot wedge `auth status --verify` or `doctor` - return StatusNotConfigured (not StatusMissing) when the user-identity path is blocked by missing app config, matching the bot side - surface the `{code, msg}` envelope on bot-info HTTP 4xx responses so callers see why bot auth was rejected, not just the bare HTTP code - introduce identity{User,Bot,None} constants in cmd/auth/status.go and use the exported StatusMessage() in the human-readable note instead of raw status codes like "not_configured" - collapse the duplicated verify-failed identity construction in the user path into a local helper - cover the new failure paths with unit tests (HTTP 4xx with envelope, business error code, user server-rejected, expired user token, strict-mode user-only, missing app config for user) Change-Id: I581348a65f15b1452a6f48a3e3245d09257314ac * fix(identitydiag): decode bot/v3/info from "bot" field, not "data" `/open-apis/bot/v3/info` returns `{code, msg, bot: {...}}` — the bot payload is under `bot`, not `data` as the newer Lark API convention would suggest. The decoder was reading from a non-existent `data` field, so `envelope.Data.OpenID` was always empty and every successful verify was reported as `Bot identity: verify failed: open_id is empty`. The pre-existing test mocks used `{"data": {...}}` matching the buggy decoder, so unit tests passed while production reads of every Lark account failed verification. Fix: - change the JSON tag on the envelope from `json:"data"` to `json:"bot"` - update mocks in identitydiag and cmd/auth/status tests to emit `bot` Verified locally: `lark-cli doctor` now reports `bot_identity: pass` for both a normal account and a bot-only profile, restoring the behavior that #957 set out to deliver. Change-Id: Ib26dfdd5a0cc37d2d62537ae2bf5e854e67cb83c * fix(shortcuts/common): decode bot/v3/info from "bot" field, not "data" Same schema bug as the one fixed in identitydiag — `RuntimeContext. fetchBotInfo` reads from a non-existent "data" key, so every successful call would report "open_id is empty" once a caller starts depending on it. There are no production callers of `RuntimeContext.BotInfo()` yet (only tests + the `TestNewRuntimeContextWithBotInfo` helper), so this bug is dormant — but the pre-existing tests pass with the same wrong schema in their mocks, so the first real consumer would silently break. Fix: tag `json:"data"` → `json:"bot"` plus aligning the four mock fixtures in runner_botinfo_test.go. The Go field name `Data` is kept to minimize the diff; only the JSON contract is corrected. Change-Id: I11e1e871603e5349f8df29b1d58e35d07b628dfd
…arksuite#961) * fix(identitydiag): harden verify path and tighten status semantics Follow-ups to larksuite#957: - bound bot/user verify calls with a 10s timeout (mirrors the doctor endpoint probe) so a hanging server cannot wedge `auth status --verify` or `doctor` - return StatusNotConfigured (not StatusMissing) when the user-identity path is blocked by missing app config, matching the bot side - surface the `{code, msg}` envelope on bot-info HTTP 4xx responses so callers see why bot auth was rejected, not just the bare HTTP code - introduce identity{User,Bot,None} constants in cmd/auth/status.go and use the exported StatusMessage() in the human-readable note instead of raw status codes like "not_configured" - collapse the duplicated verify-failed identity construction in the user path into a local helper - cover the new failure paths with unit tests (HTTP 4xx with envelope, business error code, user server-rejected, expired user token, strict-mode user-only, missing app config for user) Change-Id: I581348a65f15b1452a6f48a3e3245d09257314ac * fix(identitydiag): decode bot/v3/info from "bot" field, not "data" `/open-apis/bot/v3/info` returns `{code, msg, bot: {...}}` — the bot payload is under `bot`, not `data` as the newer Lark API convention would suggest. The decoder was reading from a non-existent `data` field, so `envelope.Data.OpenID` was always empty and every successful verify was reported as `Bot identity: verify failed: open_id is empty`. The pre-existing test mocks used `{"data": {...}}` matching the buggy decoder, so unit tests passed while production reads of every Lark account failed verification. Fix: - change the JSON tag on the envelope from `json:"data"` to `json:"bot"` - update mocks in identitydiag and cmd/auth/status tests to emit `bot` Verified locally: `lark-cli doctor` now reports `bot_identity: pass` for both a normal account and a bot-only profile, restoring the behavior that larksuite#957 set out to deliver. Change-Id: Ib26dfdd5a0cc37d2d62537ae2bf5e854e67cb83c * fix(shortcuts/common): decode bot/v3/info from "bot" field, not "data" Same schema bug as the one fixed in identitydiag — `RuntimeContext. fetchBotInfo` reads from a non-existent "data" key, so every successful call would report "open_id is empty" once a caller starts depending on it. There are no production callers of `RuntimeContext.BotInfo()` yet (only tests + the `TestNewRuntimeContextWithBotInfo` helper), so this bug is dormant — but the pre-existing tests pass with the same wrong schema in their mocks, so the first real consumer would silently break. Fix: tag `json:"data"` → `json:"bot"` plus aligning the four mock fixtures in runner_botinfo_test.go. The Go field name `Data` is kept to minimize the diff; only the JSON contract is corrected. Change-Id: I11e1e871603e5349f8df29b1d58e35d07b628dfd
Fixes #914
Summary
auth status --verifyreportidentities.botandidentities.userseparately, while preserving legacy top-level fieldsdoctorshowbot_identityanduser_identitychecks and fail only when neither identity is usableTests
go test ./internal/identitydiag ./cmd/auth ./cmd/doctorgo test ./cmd/... ./internal/...Summary by CodeRabbit
Release Notes
New Features
auth statusanddoctorcommands.Tests