Files
xinmi/internal/accesspolicy/context.go
T
yawan f7fc992f57
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
2026-09-22 16:19:06 +08:00

109 lines
2.7 KiB
Go

package accesspolicy
import (
"context"
"github.com/Tencent/WeKnora/internal/types"
)
// Snapshot is loaded from the active workspace on each authenticated request.
// An absent snapshot preserves native service behavior for background jobs.
type Snapshot struct {
Restricted bool
Permissions map[string]bool
Publications map[string]bool
Grants map[string]bool
Hidden map[string]bool
NoExport map[string]bool
}
func WithSnapshot(ctx context.Context, snapshot *Snapshot) context.Context {
return context.WithValue(ctx, types.AccessPolicySnapshotContextKey, snapshot)
}
func FromContext(ctx context.Context) *Snapshot {
value, _ := ctx.Value(types.AccessPolicySnapshotContextKey).(*Snapshot)
return value
}
func Allowed(ctx context.Context, permission string) bool {
s := FromContext(ctx)
return s == nil || !s.Restricted || s.Permissions[permission]
}
// WorkbenchActionPermission is shared by request and queued-job authorization.
func WorkbenchActionPermission(kind, action string) string {
if kind == "flows" {
return "flows.write"
}
if kind == "training-maps" {
return "content.maps"
}
if kind == "content-tasks" && (action == "accept" || action == "skip" || action == "review" || action == "review-settings" || action == "compose") {
return "content.review"
}
return "content.generate"
}
func Readable(ctx context.Context, kind, id string, owned, nativePublic bool) bool {
if Hidden(ctx, kind, id) {
return false
}
if owned {
return true
}
s := FromContext(ctx)
if s == nil {
return nativePublic
}
resource := kind + ":" + id
if global, managed := s.Publications[resource]; managed {
return global || s.Grants[resource]
}
return nativePublic || s.Grants[resource]
}
func SharedIDs(ctx context.Context, kind string) []string {
s := FromContext(ctx)
if s == nil {
return nil
}
ids := map[string]bool{}
prefix := kind + ":"
for key, enabled := range s.Publications {
if enabled && len(key) > len(prefix) && key[:len(prefix)] == prefix {
ids[key[len(prefix):]] = true
}
}
for key, enabled := range s.Grants {
if enabled && len(key) > len(prefix) && key[:len(prefix)] == prefix {
ids[key[len(prefix):]] = true
}
}
out := make([]string, 0, len(ids))
for id := range ids {
if !s.Hidden[prefix+id] {
out = append(out, id)
}
}
return out
}
func Hidden(ctx context.Context, kind, id string) bool {
s := FromContext(ctx)
return s != nil && s.Hidden[kind+":"+id]
}
func HiddenIDs(ctx context.Context, kind string) []string {
s := FromContext(ctx)
if s == nil {
return nil
}
result := []string{}
prefix := kind + ":"
for key, hidden := range s.Hidden {
if hidden && len(key) > len(prefix) && key[:len(prefix)] == prefix {
result = append(result, key[len(prefix):])
}
}
return result
}