Skip to content

feat: auto-grant current user access for bot-created docs, sheets, imports, and uploads#360

Merged
fangshuyu-768 merged 1 commit intomainfrom
feat/bot-auto-grant-current-user-access
Apr 9, 2026
Merged

feat: auto-grant current user access for bot-created docs, sheets, imports, and uploads#360
fangshuyu-768 merged 1 commit intomainfrom
feat/bot-auto-grant-current-user-access

Conversation

@wittam-01
Copy link
Copy Markdown
Collaborator

@wittam-01 wittam-01 commented Apr 9, 2026

Change-Id: Idf5b35dbf77d72788895e0a3c34563281d658c88

Summary

This PR improves the bot-identity resource creation flow by automatically granting the current CLI user full_access on newly created docs, sheets, uploaded files, and imported resources when possible. It also makes the grant
result explicit in command output and aligns the related skill/docs wording with the full_access (可管理权限) terminology.

Changes

  • Add shared auto-grant logic for bot-created Drive resources and surface the result via permission_grant
  • Apply the auto-grant flow to docs +create, sheets +create, drive +upload, drive +import, and drive +task_result --scenario import
  • Add and update tests covering successful grant, skipped grant, failed grant, and import-ready follow-up grant behavior
  • Update shortcut/skill documentation and user-facing copy to consistently describe full_access as 可管理权限

Test Plan

  • Unit tests pass
  • Manual local verification confirms the lark xxx command works as expected

Manual verification included:

  • ./lark-cli docs +create --as bot
  • ./lark-cli sheets +create --as bot
  • ./lark-cli drive +import --as bot --file ./2.csv --type sheet
  • ./lark-cli drive +import --as bot --file ./big.xlsx --type bitable

Related Issues

  • None

Summary by CodeRabbit

  • New Features

    • Automatic permission granting for bot-created resources (documents, uploads, imports, sheets). CLI will attempt to grant the current CLI user "full_access" and include a new permission_grant field with status: granted / skipped / failed.
    • permission_grant is only emitted when the final online target is returned (omitted for ready=false / timed_out follow-ups). Dry-run now notes this bot-only behavior.
  • Documentation

    • Updated guides to describe auto-grant behavior and permission_grant semantics.
  • Tests

    • Added end-to-end tests covering bot/user and success/failure/skip outcomes.

@github-actions github-actions bot added domain/ccm PR touches the ccm domain size/L Large or sensitive change across domains or core paths labels Apr 9, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

This PR adds a bot-only automatic Drive permission-granting flow and integrates it across shortcuts (docs create, drive upload/import, sheets create). It introduces shortcuts/common/permission_grant.go, augments shortcut execution/dry-run outputs to call the auto-grant helper when running as a bot, adds tests, and updates docs to surface a new permission_grant response field and semantics.

Changes

Cohort / File(s) Summary
Permission Granting Core
shortcuts/common/permission_grant.go
New exported constants and AutoGrantCurrentUserDrivePermission(runtime *RuntimeContext, token, resourceType string) map[string]interface{}. Validates bot runtime and inputs, fetches current user open_id, builds permission member payload (perm=full_access, member_type=openid, type=user), sets perm_type for some resource kinds, POSTs to /open-apis/drive/v1/permissions/{token}/members, and returns structured permission_grant maps: granted/skipped/failed.
Docs Shortcut Integration
shortcuts/doc/docs_create.go
Refactored create-args building; selects permission target from doc_url or doc_id and calls auto-grant post-success, storing returned grant under result["permission_grant"] when present; extends bot dry-run messaging.
Docs Tests
shortcuts/doc/docs_create_test.go
New end-to-end CLI tests covering bot-mode success/failure/missing open_id and user-mode no-augmentation; stubs MCP and permissions API and asserts permission_grant structure and captured request payloads.
Drive Upload / Import
shortcuts/drive/drive_upload.go, shortcuts/drive/drive_import.go
Added bot-only dry-run messaging; after successful upload/import readiness, invoke auto-grant and include permission_grant in output when non-nil.
Drive Task Result
shortcuts/drive/drive_task_result.go
Replaced queryImportTask with queryImportTaskAndAutoGrantPermission in import scenario; when import is ready, call auto-grant and append permission_grant if returned.
Drive Permission Grant Tests
shortcuts/drive/drive_permission_grant_test.go, shortcuts/drive/drive_task_result_test.go, shortcuts/drive/drive_import_common_test.go
Added tests for auto-grant in upload/import flows (bot vs user), asserting permission_grant presence/absence, status values, messages, and validating HTTP request payloads; updated timeout test to assert absence of permission_grant on timed-out ready=false responses.
Sheets Shortcut Integration & Tests
shortcuts/sheets/sheet_create.go, shortcuts/sheets/sheet_create_test.go
Bot dry-run messaging updated; Execute conditionally augments output with permission_grant via auto-grant helper. Tests added for bot success and user-mode non-augmentation, validating captured grant request.
Documentation
skills/lark-doc/..., skills/lark-drive/..., skills/lark-sheets/...
Updated reference docs to document new permission_grant response field, status semantics (granted/skipped/failed), perm = full_access meaning, trigger points, and conditional output behavior (omitted when result not final).

Sequence Diagram(s)

sequenceDiagram
  actor CLI
  participant Runtime as RuntimeContext
  participant Shortcut as Shortcut (upload/import/create)
  participant DriveAPI as Drive Permissions API

  CLI->>Runtime: run shortcut (--as bot)
  Shortcut->>Runtime: perform operation (upload/import/create)
  Shortcut-->>Runtime: receive result with token/type
  alt runtime.IsBot() && token != ""
    Shortcut->>Runtime: Runtime.UserOpenId()
    alt userOpenId present
      Shortcut->>DriveAPI: POST /open-apis/drive/v1/permissions/{token}/members {member_type: "openid", member_id: userOpenId, perm: "full_access", type: "user", perm_type: ...}
      DriveAPI-->>Shortcut: 200 OK / error
      Shortcut-->>CLI: include permission_grant {status: "granted"/"failed", user_open_id, message, perm}
    else missing open_id
      Shortcut-->>CLI: include permission_grant {status: "skipped", perm: "full_access", message}
    end
  else
    Shortcut-->>CLI: no permission_grant included
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • fangshuyu-768

Poem

🐰 I hopped through code with nimble feet,
Bots now lend users access sweet,
No extra clicks, no manual race,
A gentle grant—a rabbit's grace. 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: automatic access granting for the current user on bot-created resources across multiple features (docs, sheets, imports, uploads).
Description check ✅ Passed The description follows the template structure with Summary, Changes, Test Plan, and Related Issues sections. It clearly explains the motivation, lists main changes, documents manual verification steps, and confirms tests pass.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bot-auto-grant-current-user-access

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 9, 2026

Greptile Summary

This PR adds auto-grant of full_access to the current CLI user on bot-created docs, sheets, uploaded files, and imported resources by introducing a shared AutoGrantCurrentUserDrivePermission helper. Permission failures are soft (the command succeeds, permission_grant.status is set to "failed" or "skipped"), and tests cover granted, skipped, and failed scenarios across the affected commands.

Confidence Score: 5/5

Safe to merge — all remaining findings are P2 style/clarity suggestions with no correctness impact.

The shared helper correctly gates on IsBot(), handles all three outcome states, and never lets a grant failure bubble up to the caller. Tests cover granted, skipped, and failed paths across all affected commands. Both P2 findings (misleading skip message wording and missing DocType fallback comment in +task_result) are polish items that don't affect functional correctness.

shortcuts/common/permission_grant.go (skip message wording) and shortcuts/drive/drive_task_result.go (missing DocType fallback note)

Vulnerabilities

No security concerns identified. User open IDs are path-segment encoded via validate.EncodePathSegment, validate.SafeInputPath is applied before file operations, and the permission grant is strictly gated on runtime.IsBot() so it never runs for user-auth sessions.

Important Files Changed

Filename Overview
shortcuts/common/permission_grant.go New shared helper for auto-granting Drive permissions; handles all skipped/failed/granted outcomes, but the "missing token/type" skip message fires even when only resourceType is empty (token is present), which can be misleading in the +task_result scenario.
shortcuts/doc/docs_create.go Adds augmentDocsCreateResult that selects the permission target from doc_url (with wiki/docx type detection) or falls back to doc_id with type "docx"; grant failure does not fail the create operation.
shortcuts/drive/drive_import.go Auto-grant wired correctly after the polling loop resolves ready=true; uses spec.DocType fallback when status.DocType is empty, unlike the standalone +task_result path.
shortcuts/drive/drive_task_result.go Renames queryImportTask to queryImportTaskAndAutoGrantPermission and appends grant result when status.Ready(); has no fallback for empty status.DocType unlike drive_import.go, causing a silent skip with a misleading message if the API omits the type.
shortcuts/drive/drive_upload.go Auto-grant appended after successful upload with resourceType="file"; clean and consistent with other commands.
shortcuts/sheets/sheet_create.go Auto-grant appended with resourceType="sheet" after successful spreadsheet creation; grant failure does not fail the create; missing a test for the grant-fails-but-create-succeeds scenario.
shortcuts/drive/drive_permission_grant_test.go Covers granted, skipped (user mode), and import auto-grant success; missing a test for the sheet/upload grant-fails-but-command-succeeds scenario.
shortcuts/drive/drive_task_result_test.go New test TestDriveTaskResultImportBotAutoGrantSuccess covers the ready-state grant path; no-grant assertions added to the existing processing-state test.
shortcuts/doc/docs_create_test.go Comprehensive: covers granted (docx URL), skipped (no user open_id), user-mode skip, and failed-grant-does-not-fail-create (wiki with perm_type=container check).
shortcuts/sheets/sheet_create_test.go Covers granted and user-mode skip; missing a failure scenario test analogous to TestDocsCreateBotAutoGrantFailureDoesNotFailCreate.
shortcuts/drive/drive_import_common_test.go Adds permission_grant absence assertion to the existing TestDriveImportTimeoutReturnsFollowUpCommand test; no new failures introduced.

Sequence Diagram

sequenceDiagram
    participant CLI
    participant Lark API
    participant Drive Permissions API

    Note over CLI: --as bot mode only
    CLI->>Lark API: Create resource (doc/sheet/upload/import)
    Lark API-->>CLI: resource token + type
    
    alt token && type present
        CLI->>CLI: AutoGrantCurrentUserDrivePermission(token, type)
        CLI->>CLI: Fetch UserOpenId from config
        alt UserOpenId empty
            CLI-->>CLI: permission_grant = {status: skipped}
        else UserOpenId present
            CLI->>Drive Permissions API: POST /drive/v1/permissions/{token}/members
            alt API success
                Drive Permissions API-->>CLI: 200 OK
                CLI-->>CLI: permission_grant = {status: granted}
            else API error
                Drive Permissions API-->>CLI: error
                CLI-->>CLI: permission_grant = {status: failed}
            end
        end
    else token or type missing
        CLI-->>CLI: permission_grant = {status: skipped}
    end
    CLI-->>CLI: runtime.Out(result with permission_grant)
Loading

Reviews (2): Last reviewed commit: "feat: auto-grant current user access for..." | Re-trigger Greptile

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 9, 2026

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@3961e37d8c9f2849a7e444322cffecff5af14121

🧩 Skill update

npx skills add larksuite/cli#feat/bot-auto-grant-current-user-access -y -g

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
shortcuts/drive/drive_permission_grant_test.go (2)

232-234: Dead code: registerDriveBotTokenStub is a no-op.

This function accepts a registry but doesn't register any stubs. It's called in all three tests but has no effect. Either implement the intended stub registration or remove the function and its call sites.

🔧 Remove unused placeholder
-func registerDriveBotTokenStub(reg *httpmock.Registry) {
-	_ = reg
-}

And remove the calls from the test functions:

 func TestDriveUploadBotAutoGrantSuccess(t *testing.T) {
 	f, stdout, _, reg := cmdutil.TestFactory(t, drivePermissionGrantTestConfig(t, "ou_current_user"))
-	registerDriveBotTokenStub(reg)
 
 	reg.Register(&httpmock.Stub{
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/drive/drive_permission_grant_test.go` around lines 232 - 234, The
helper registerDriveBotTokenStub(reg *httpmock.Registry) is a no-op and should
be removed or implemented; pick one: either implement the intended HTTP stub
registration inside registerDriveBotTokenStub (use the reg to add the expected
token endpoints used by the tests) or delete the function and remove all calls
to registerDriveBotTokenStub from the three test functions so there are no
unused placeholders; update any imports or test setup accordingly and ensure
tests still register any needed stubs directly if you remove the helper.

19-76: Consider adding t.Parallel() for test isolation.

The other test files in this PR (docs_create_test.go, sheet_create_test.go) use t.Parallel(). This test uses withDriveWorkingDir to change the working directory, which may prevent parallelization. If these tests cannot run in parallel due to working directory changes, consider documenting why, or refactor to avoid global state mutation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/drive/drive_permission_grant_test.go` around lines 19 - 76, Test
TestDriveUploadBotAutoGrantSuccess mutates global working directory via
withDriveWorkingDir which prevents safe parallel execution; either mark the test
parallel by adding t.Parallel() at the top of TestDriveUploadBotAutoGrantSuccess
and ensure withDriveWorkingDir properly isolates/restores cwd, or refactor to
avoid global state (e.g., change withDriveWorkingDir to return a scoped working
directory helper that chdirs only for the test and restores on cleanup, or use a
per-test mutex around os.Chdir). Update the TestDriveUploadBotAutoGrantSuccess
function and the withDriveWorkingDir helper (or introduce a scoped helper) to
guarantee cwd is restored so t.Parallel() can be safely added.
shortcuts/sheets/sheet_create_test.go (1)

79-111: Consider adding tests for skipped and failed grant scenarios.

The docs_create_test.go includes tests for:

  • TestDocsCreateBotAutoGrantSkippedWithoutCurrentUser
  • TestDocsCreateBotAutoGrantFailureDoesNotFailCreate

Adding similar tests for sheets would ensure consistent coverage across all resource types.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/sheets/sheet_create_test.go` around lines 79 - 111, Add two tests
mirroring the docs tests: one to verify auto-grant is skipped when there is no
current user and one to verify a permission-grant failure does not cause sheet
creation to fail. Create tests named similarly to
TestSheetCreateBotAutoGrantSkippedWithoutCurrentUser and
TestSheetCreateBotAutoGrantFailureDoesNotFailCreate that reuse
runSheetCreateShortcut, decodeSheetCreateEnvelope and the HTTP stubbing approach
(reg.Register) used in TestSheetCreateUserSkipsPermissionGrantAugmentation; for
the skipped case stub the grant endpoint to not be called or return an expected
"skipped" response and assert permission_grant is absent, and for the failure
case stub the grant endpoint to return an error payload but assert the create
succeeds (no returned error) and the output still contains the new spreadsheet
info.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@shortcuts/drive/drive_permission_grant_test.go`:
- Around line 232-234: The helper registerDriveBotTokenStub(reg
*httpmock.Registry) is a no-op and should be removed or implemented; pick one:
either implement the intended HTTP stub registration inside
registerDriveBotTokenStub (use the reg to add the expected token endpoints used
by the tests) or delete the function and remove all calls to
registerDriveBotTokenStub from the three test functions so there are no unused
placeholders; update any imports or test setup accordingly and ensure tests
still register any needed stubs directly if you remove the helper.
- Around line 19-76: Test TestDriveUploadBotAutoGrantSuccess mutates global
working directory via withDriveWorkingDir which prevents safe parallel
execution; either mark the test parallel by adding t.Parallel() at the top of
TestDriveUploadBotAutoGrantSuccess and ensure withDriveWorkingDir properly
isolates/restores cwd, or refactor to avoid global state (e.g., change
withDriveWorkingDir to return a scoped working directory helper that chdirs only
for the test and restores on cleanup, or use a per-test mutex around os.Chdir).
Update the TestDriveUploadBotAutoGrantSuccess function and the
withDriveWorkingDir helper (or introduce a scoped helper) to guarantee cwd is
restored so t.Parallel() can be safely added.

In `@shortcuts/sheets/sheet_create_test.go`:
- Around line 79-111: Add two tests mirroring the docs tests: one to verify
auto-grant is skipped when there is no current user and one to verify a
permission-grant failure does not cause sheet creation to fail. Create tests
named similarly to TestSheetCreateBotAutoGrantSkippedWithoutCurrentUser and
TestSheetCreateBotAutoGrantFailureDoesNotFailCreate that reuse
runSheetCreateShortcut, decodeSheetCreateEnvelope and the HTTP stubbing approach
(reg.Register) used in TestSheetCreateUserSkipsPermissionGrantAugmentation; for
the skipped case stub the grant endpoint to not be called or return an expected
"skipped" response and assert permission_grant is absent, and for the failure
case stub the grant endpoint to return an error payload but assert the create
succeeds (no returned error) and the output still contains the new spreadsheet
info.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0b8d76c4-d989-4041-b309-3bba8d810457

📥 Commits

Reviewing files that changed from the base of the PR and between 284e5b6 and 3d86395.

📒 Files selected for processing (16)
  • shortcuts/common/permission_grant.go
  • shortcuts/doc/docs_create.go
  • shortcuts/doc/docs_create_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_permission_grant_test.go
  • shortcuts/drive/drive_task_result.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_upload.go
  • shortcuts/sheets/sheet_create.go
  • shortcuts/sheets/sheet_create_test.go
  • skills/lark-doc/references/lark-doc-create.md
  • skills/lark-drive/references/lark-drive-import.md
  • skills/lark-drive/references/lark-drive-task-result.md
  • skills/lark-drive/references/lark-drive-upload.md
  • skills/lark-sheets/references/lark-sheets-create.md

…ports, and uploads

Change-Id: Idf5b35dbf77d72788895e0a3c34563281d658c88
@wittam-01 wittam-01 force-pushed the feat/bot-auto-grant-current-user-access branch from 3d86395 to 3961e37 Compare April 9, 2026 09:25
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
shortcuts/doc/docs_create_test.go (1)

65-67: Prefer semantic assertion over exact full message match.

This assertion is brittle to non-functional copy changes. Consider validating stable substrings (like you already do in the failure case).

♻️ Suggested assertion tweak
-	if grant["message"] != "Granted the current CLI user full_access (可管理权限) on the new document." {
-		t.Fatalf("permission_grant.message = %#v", grant["message"])
-	}
+	msg, _ := grant["message"].(string)
+	if !strings.Contains(msg, "Granted the current CLI user") ||
+		!strings.Contains(msg, "full_access (可管理权限)") {
+		t.Fatalf("permission_grant.message = %q", msg)
+	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/doc/docs_create_test.go` around lines 65 - 67, The test currently
asserts exact equality on grant["message"], which is brittle; instead check for
stable substrings (e.g., that grant["message"] contains "Granted the current CLI
user" and/or "full_access" or "可管理权限") using a contains/assert approach and
adjust the t.Fatalf branch accordingly; update the test around grant["message"]
(and add strings import if needed) so the assertion verifies semantic content
rather than an exact full-message match.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@shortcuts/doc/docs_create_test.go`:
- Around line 65-67: The test currently asserts exact equality on
grant["message"], which is brittle; instead check for stable substrings (e.g.,
that grant["message"] contains "Granted the current CLI user" and/or
"full_access" or "可管理权限") using a contains/assert approach and adjust the
t.Fatalf branch accordingly; update the test around grant["message"] (and add
strings import if needed) so the assertion verifies semantic content rather than
an exact full-message match.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dfc87bfd-7dd9-4ed0-9112-4acba5c5530a

📥 Commits

Reviewing files that changed from the base of the PR and between 3d86395 and 3961e37.

📒 Files selected for processing (16)
  • shortcuts/common/permission_grant.go
  • shortcuts/doc/docs_create.go
  • shortcuts/doc/docs_create_test.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_import_common_test.go
  • shortcuts/drive/drive_permission_grant_test.go
  • shortcuts/drive/drive_task_result.go
  • shortcuts/drive/drive_task_result_test.go
  • shortcuts/drive/drive_upload.go
  • shortcuts/sheets/sheet_create.go
  • shortcuts/sheets/sheet_create_test.go
  • skills/lark-doc/references/lark-doc-create.md
  • skills/lark-drive/references/lark-drive-import.md
  • skills/lark-drive/references/lark-drive-task-result.md
  • skills/lark-drive/references/lark-drive-upload.md
  • skills/lark-sheets/references/lark-sheets-create.md
✅ Files skipped from review due to trivial changes (1)
  • shortcuts/sheets/sheet_create_test.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • shortcuts/drive/drive_import.go
  • skills/lark-drive/references/lark-drive-task-result.md
  • shortcuts/drive/drive_upload.go
  • shortcuts/sheets/sheet_create.go
  • shortcuts/drive/drive_permission_grant_test.go

@fangshuyu-768 fangshuyu-768 merged commit 3774717 into main Apr 9, 2026
17 checks passed
@fangshuyu-768 fangshuyu-768 deleted the feat/bot-auto-grant-current-user-access branch April 9, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/ccm PR touches the ccm domain size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants