package workbench import ( "context" "errors" "testing" "github.com/Tencent/WeKnora/internal/types" "gorm.io/gorm" ) func TestAdministratorCanManageTenantResourcesWithoutChangingOwner(t *testing.T) { s := sqliteWorkbench(t) r := seedResource(t, s, 1, "contributor", "training-maps") ctx := workbenchContext(1, "admin", types.TenantRoleAdmin) if _, err := s.get(ctx, r.Kind, r.ID); err != nil { t.Fatal(err) } if _, err := lockResource(ctx, s.db, r.Kind, r.ID); err != nil { t.Fatalf("administrator cannot lock tenant resource for writing: %v", err) } if _, err := s.submit(ctx, r.Kind, r.ID, "generate", ActionRequest{Version: 1}); !errors.Is(err, ErrForbidden) { t.Fatalf("administrator queued another user's task: %v", err) } r.Name = "Administrator edit" if err := s.save(ctx, r, 1); err != nil { t.Fatalf("administrator cannot persist tenant resource: %v", err) } var stored Resource if err := s.db.First(&stored, "id = ?", r.ID).Error; err != nil || stored.OwnerID != "contributor" || stored.Name != r.Name || stored.Version != 2 { t.Fatalf("administrator edit changed ownership or was not saved: %+v %v", stored, err) } var revision Revision if err := s.db.Where("resource_id = ? AND version = ?", r.ID, 2).First(&revision).Error; err != nil || revision.ActorID != "admin" { t.Fatalf("administrator edit audit missing: %+v %v", revision, err) } var count int64 s.db.Model(&Job{}).Count(&count) if count != 0 { t.Fatal("unauthorized job was queued") } } func TestOnlyAdministratorCanBindAnotherUsersPrivateMap(t *testing.T) { s := sqliteWorkbench(t) mapResource := seedResource(t, s, 1, "contributor", "training-maps") s.db.Model(mapResource).Update("status", "confirmed") flow := seedResource(t, s, 1, "admin", "flows") ctx := workbenchContext(1, "admin", types.TenantRoleAdmin) task := &Resource{TenantID: 1, OwnerID: "admin", Kind: "content-tasks", Data: asJSON(TaskData{MapID: mapResource.ID, FlowID: flow.ID})} err := s.db.WithContext(context.Background()).Transaction(func(tx *gorm.DB) error { return lockReferences(ctx, tx, task) }) if err != nil { t.Fatalf("administrator cannot use tenant map: %v", err) } ctx = workbenchContext(1, "admin", types.TenantRoleContributor) err = s.db.Transaction(func(tx *gorm.DB) error { return lockReferences(ctx, tx, task) }) if !errors.Is(err, gorm.ErrRecordNotFound) { t.Fatalf("non-administrator bound another user's private map: %v", err) } } func TestWorkbenchAdministratorNeverEscapesActiveTenant(t *testing.T) { s := sqliteWorkbench(t) r := seedResource(t, s, 2, "contributor", "flows") ctx := context.WithValue(workbenchContext(1, "admin", types.TenantRoleViewer), types.SystemAdminContextKey, true) if _, err := lockResource(ctx, s.db, r.Kind, r.ID); !errors.Is(err, gorm.ErrRecordNotFound) { t.Fatalf("cross-tenant write lock allowed: %v", err) } if err := persistResource(ctx, s.db, r, r.Version); !errors.Is(err, ErrForbidden) { t.Fatalf("cross-tenant save allowed: %v", err) } }