WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
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

This commit is contained in:
yawan
2026-09-22 16:19:06 +08:00
commit f7fc992f57
3929 changed files with 1006607 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
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
}
+40
View File
@@ -0,0 +1,40 @@
package accesspolicy
import (
"context"
"testing"
)
func TestManagedResourceRequiresOwnerPublicationOrGrant(t *testing.T) {
s := &Snapshot{Restricted: true, Permissions: map[string]bool{"knowledge.read": true}, Publications: map[string]bool{"knowledge:k": false}, Grants: map[string]bool{}}
ctx := WithSnapshot(context.Background(), s)
if Readable(ctx, "knowledge", "k", false, true) {
t.Fatal("managed private resource retained native public access")
}
if !Readable(ctx, "knowledge", "k", true, false) {
t.Fatal("owner lost resource access")
}
s.Grants["knowledge:k"] = true
if !Readable(ctx, "knowledge", "k", false, false) {
t.Fatal("grant did not provide read access")
}
delete(s.Grants, "knowledge:k")
if Readable(ctx, "knowledge", "k", false, true) {
t.Fatal("revoked grant still readable")
}
s.Publications["knowledge:k"] = true
if !Readable(ctx, "knowledge", "k", false, false) {
t.Fatal("published resource inaccessible")
}
if Allowed(ctx, "knowledge.write") || Allowed(ctx, "content.read") {
t.Fatal("unassigned feature allowed")
}
}
func TestSharedIDsSeparateKinds(t *testing.T) {
ctx := WithSnapshot(context.Background(), &Snapshot{Publications: map[string]bool{"agents:a": true, "agents:b": false, "knowledge:c": true}, Grants: map[string]bool{"agents:a": true}})
ids := SharedIDs(ctx, "agents")
if len(ids) != 1 || ids[0] != "a" {
t.Fatalf("unexpected shared IDs: %v", ids)
}
}
+45
View File
@@ -0,0 +1,45 @@
package accesspolicy
import (
"context"
"github.com/Tencent/WeKnora/internal/types"
)
type executionDependencyKey struct{}
type executionDependency struct {
tenant uint64
owner string
}
// WithExecutionDependency is only for server-verified bindings of an authorized
// resource. It never changes publication, list visibility, or write ownership.
func WithExecutionDependency(ctx context.Context, tenant uint64, kind, id, owner string) context.Context {
bindings := map[string]executionDependency{}
if previous, ok := ctx.Value(executionDependencyKey{}).(map[string]executionDependency); ok {
for key, binding := range previous {
bindings[key] = binding
}
}
if tenant != 0 && id != "" && owner != "" {
bindings[kind+":"+id] = executionDependency{tenant, owner}
}
return context.WithValue(ctx, executionDependencyKey{}, bindings)
}
func CanExecuteDependency(ctx context.Context, tenant uint64, kind, id, owner string) bool {
current, ok := types.TenantIDFromContext(ctx)
if !ok || tenant == 0 || tenant != current || owner == "" || Hidden(ctx, kind, id) {
return false
}
module := kind
if module == "skills" {
module = "agents"
}
if !Allowed(ctx, module+".read") {
return false
}
bindings, _ := ctx.Value(executionDependencyKey{}).(map[string]executionDependency)
return bindings[kind+":"+id] == (executionDependency{tenant, owner})
}
+42
View File
@@ -0,0 +1,42 @@
package accesspolicy
import (
"context"
"testing"
"github.com/Tencent/WeKnora/internal/types"
)
func TestExecutionDependenciesDoNotGrantOrdinaryResourceAccess(t *testing.T) {
ctx := context.WithValue(context.Background(), types.TenantIDContextKey, uint64(1))
ctx = WithSnapshot(ctx, &Snapshot{Restricted: true, Permissions: map[string]bool{"agents.read": true, "knowledge.read": true}})
bound := WithExecutionDependency(ctx, 1, "agents", "bound", "owner")
if !CanExecuteDependency(bound, 1, "agents", "bound", "owner") {
t.Fatal("bound dependency denied")
}
if Readable(bound, "agents", "bound", false, false) || len(SharedIDs(bound, "agents")) != 0 || Allowed(bound, "agents.write") {
t.Fatal("execution dependency changed normal visibility or write permission")
}
for _, check := range []struct {
tenant uint64
kind, id, owner string
}{
{2, "agents", "bound", "owner"}, {1, "agents", "other", "owner"},
{1, "agents", "bound", "other"}, {1, "knowledge", "bound", "owner"},
} {
if CanExecuteDependency(bound, check.tenant, check.kind, check.id, check.owner) {
t.Fatalf("unbound dependency allowed: %+v", check)
}
}
if CanExecuteDependency(ctx, 1, "agents", "bound", "owner") {
t.Fatal("execution scope leaked into original request")
}
denied := WithSnapshot(bound, &Snapshot{Restricted: true, Permissions: map[string]bool{}})
if CanExecuteDependency(denied, 1, "agents", "bound", "owner") {
t.Fatal("dependency bypassed module permission")
}
hidden := WithSnapshot(bound, &Snapshot{Hidden: map[string]bool{"agents:bound": true}})
if CanExecuteDependency(hidden, 1, "agents", "bound", "owner") {
t.Fatal("hidden dependency allowed")
}
}