fix(vc): align meeting query scopes by identity

This commit is contained in:
houzhicong
2026-07-09 20:29:35 +08:00
parent 74d8458635
commit 6c88d6b79c
6 changed files with 68 additions and 5 deletions

View File

@@ -52,7 +52,8 @@ var VCMeetingEvents = common.Shortcut{
Command: "+meeting-events",
Description: "List meeting events by meeting ID",
Risk: "read",
Scopes: []string{"vc:meeting.meetingevent:read"},
UserScopes: []string{"vc:meeting.meetingevent:read"},
BotScopes: []string{"vc:meeting.bot.join:write"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
Flags: []common.Flag{

View File

@@ -418,6 +418,24 @@ func TestMeetingEvents_Validation_PageAllIgnoresInvalidPageSize(t *testing.T) {
}
}
func TestMeetingEvents_ScopesMatchIdentityPermissions(t *testing.T) {
userScopes := []string{"vc:meeting.meetingevent:read"}
botScopes := []string{"vc:meeting.bot.join:write"}
if got := VCMeetingEvents.ScopesForIdentity("user"); !reflect.DeepEqual(got, userScopes) {
t.Fatalf("ScopesForIdentity(user) = %v, want %v", got, userScopes)
}
if got := VCMeetingEvents.ScopesForIdentity("bot"); !reflect.DeepEqual(got, botScopes) {
t.Fatalf("ScopesForIdentity(bot) = %v, want %v", got, botScopes)
}
if got := VCMeetingEvents.DeclaredScopesForIdentity("user"); !reflect.DeepEqual(got, userScopes) {
t.Fatalf("DeclaredScopesForIdentity(user) = %v, want %v", got, userScopes)
}
if got := VCMeetingEvents.DeclaredScopesForIdentity("bot"); !reflect.DeepEqual(got, botScopes) {
t.Fatalf("DeclaredScopesForIdentity(bot) = %v, want %v", got, botScopes)
}
}
func TestMeetingEvents_Validation_InvalidPageSizeReturnsFlagError(t *testing.T) {
runtime := newMeetingEventsRuntime()
mustSetMeetingEventsFlag(t, runtime, "meeting-id", "7628568141510692381")

View File

@@ -23,7 +23,8 @@ var VCMeetingListActive = common.Shortcut{
Command: "+meeting-list-active",
Description: "List active meetings for the current identity or target user",
Risk: "read",
Scopes: []string{"vc:meeting.meetingevent:read"},
UserScopes: []string{"vc:meeting.meetingevent:read"},
BotScopes: []string{"vc:meeting.bot.join:write"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
Flags: []common.Flag{

View File

@@ -9,6 +9,7 @@ import (
"encoding/json"
"errors"
"net/http"
"reflect"
"strings"
"testing"
@@ -608,9 +609,21 @@ func TestMeetingListActive_DryRun_UserIdentity(t *testing.T) {
}
}
func TestMeetingListActive_ScopeMatchesEventReadPermission(t *testing.T) {
if len(VCMeetingListActive.Scopes) != 1 || VCMeetingListActive.Scopes[0] != "vc:meeting.meetingevent:read" {
t.Fatalf("scopes = %#v, want [vc:meeting.meetingevent:read]", VCMeetingListActive.Scopes)
func TestMeetingListActive_ScopesMatchIdentityPermissions(t *testing.T) {
userScopes := []string{"vc:meeting.meetingevent:read"}
botScopes := []string{"vc:meeting.bot.join:write"}
if got := VCMeetingListActive.ScopesForIdentity("user"); !reflect.DeepEqual(got, userScopes) {
t.Fatalf("ScopesForIdentity(user) = %v, want %v", got, userScopes)
}
if got := VCMeetingListActive.ScopesForIdentity("bot"); !reflect.DeepEqual(got, botScopes) {
t.Fatalf("ScopesForIdentity(bot) = %v, want %v", got, botScopes)
}
if got := VCMeetingListActive.DeclaredScopesForIdentity("user"); !reflect.DeepEqual(got, userScopes) {
t.Fatalf("DeclaredScopesForIdentity(user) = %v, want %v", got, userScopes)
}
if got := VCMeetingListActive.DeclaredScopesForIdentity("bot"); !reflect.DeepEqual(got, botScopes) {
t.Fatalf("DeclaredScopesForIdentity(bot) = %v, want %v", got, botScopes)
}
}

View File

@@ -11,6 +11,21 @@
- `meeting_id` 来自 `+meeting-list-active --as bot --user-id <user_open_id>``+meeting-join --as bot`:后续读取事件继续 `--as bot`
- 应用身份下,应用机器人必须在该会中或参会过;应用身份 active meeting 返回的是“目标用户在会中且应用机器人也在会中”的会议,不表示可以读取任意 `meeting_id`
## 权限建议
本命令当前按身份声明不同权限:
| 场景 | 推荐权限 |
|------|----------|
| UAT / 用户身份 `--as user` | `vc:meeting.meetingevent:read` |
| TAT / 应用身份 `--as bot` | `vc:meeting.bot.join:write` |
注意:
- 这里的 TAT 建议只说明 CLI 当前为应用身份声明了 `vc:meeting.bot.join:write` 这条窄版权限路径,不代表服务端已经把会中事件读取降成“无数据范围风险”的纯读点位。
- 应用身份是否能真正读到事件,仍取决于应用机器人是否在会中或曾在会中、租户安装、权限可访问的数据范围,以及后端对该会议的可见性判断。
- 如果你的目标是最小化读权限,优先使用用户身份并开通 `vc:meeting.meetingevent:read`
## 命令
```bash

View File

@@ -4,6 +4,21 @@
本 skill 对应 shortcut`lark-cli vc +meeting-list-active`(调用 `GET /open-apis/vc/v1/bots/user_active_meeting`)。
## 权限建议
本命令当前按身份声明不同权限:
| 场景 | 推荐权限 |
|------|----------|
| UAT / 用户身份 `--as user` | `vc:meeting.meetingevent:read` |
| TAT / 应用身份 `--as bot` | `vc:meeting.bot.join:write` |
注意:
- TAT 这里的 `vc:meeting.bot.join:write` 是窄版 CLI 权限点位支持,不表示服务端已经把 active meeting 可见性变成纯读无数据范围风险模型。
- 应用身份依然只返回“目标用户在会中且应用机器人也在会中”的会议;如果机器人没进会、数据范围没放开、应用没安装,结果仍可能为空。
- 如果只是查询当前登录用户自己正在参加的会议,优先用用户身份和 `vc:meeting.meetingevent:read`
## 命令
```bash