Check Feishu directory scope and highlight app availability

This commit is contained in:
Codex committed 2026-10-23 14:35:09 +08:00
1 parent bf9e1c3c2c
commit e2597719c8
7 files changed
+147 -4

No files matched your search

@@ -32,6 +32,70 @@ type directorySnapshot struct {
visibleUsers int
}
// DirectorySyncCheck probes only the app-visible scope and the first page of
// directory endpoints. It cannot attest to app publication or all-employee scope.
func (p *Provider) DirectorySyncCheck(c *gin.Context) {
noStore(c)
if !secureAdmin(c) {
c.JSON(403, gin.H{"error": "请通过可信 HTTPS 管理入口检测飞书权限"})
return
}
cfg, _, err := enabled()
if err != nil {
c.JSON(409, gin.H{"error": "请先启用飞书身份服务"})
return
}
ctx, cancel := context.WithTimeout(c.Request.Context(), 22*time.Second)
defer cancel()
secret, err := store.DecryptSecret(cfg.AppSecret)
if err != nil {
c.JSON(503, gin.H{"error": "读取飞书应用凭据失败"})
return
}
result, err := checkDirectoryAccess(ctx, cfg.AppID, secret)
if err != nil {
c.JSON(502, gin.H{"error": err.Error()})
return
}
c.JSON(200, result)
}
func checkDirectoryAccess(ctx context.Context, appID, secret string) (gin.H, error) {
token, err := directoryTenantToken(ctx, appID, secret)
if err != nil {
return nil, err
}
var scope struct {
DepartmentIDs []string `json:"department_ids"`
UserIDs []string `json:"user_ids"`
}
if err := directoryGet(ctx, token, "/scopes", url.Values{"department_id_type": {"open_department_id"}, "user_id_type": {"open_id"}}, &scope); err != nil {
return nil, err
}
result := gin.H{"visible_departments": len(scope.DepartmentIDs), "visible_users": len(scope.UserIDs), "department_access": "unverified", "user_list_access": "unverified"}
if len(scope.DepartmentIDs) == 0 {
return result, nil
}
id := scope.DepartmentIDs[0]
if id == "" || len(id) > 128 {
return nil, errors.New("飞书部门标识无效")
}
var ignored struct{}
if err := directoryGet(ctx, token, "/departments/"+url.PathEscape(id)+"/children", url.Values{"department_id_type": {"open_department_id"}, "page_size": {"1"}}, &ignored); err != nil {
result["department_access"] = "denied"
result["department_error"] = err.Error()
} else {
result["department_access"] = "ok"
}
if err := directoryGet(ctx, token, "/users", url.Values{"department_id": {id}, "department_id_type": {"open_department_id"}, "user_id_type": {"open_id"}, "page_size": {"1"}}, &ignored); err != nil {
result["user_list_access"] = "denied"
result["user_list_error"] = err.Error()
} else {
result["user_list_access"] = "ok"
}
return result, nil
}
func (p *Provider) DirectorySyncStatus(c *gin.Context) {
noStore(c)
if !secureAdmin(c) {