import { Namespace, Subject, Context, SubjectSet } from "@ory/keto-definitions" class User implements Namespace {} class Tenant implements Namespace { related: { owners: User[] admins: User[] members: User[] parents: Tenant[] } permits = { view: (ctx: Context): boolean => this.related.members.includes(ctx.subject) || this.related.admins.includes(ctx.subject) || this.related.owners.includes(ctx.subject) || this.related.parents.traverse((p) => p.permits.view(ctx)), manage: (ctx: Context): boolean => this.related.admins.includes(ctx.subject) || this.related.owners.includes(ctx.subject) || this.related.parents.traverse((p) => p.permits.manage(ctx)), manage_admins: (ctx: Context): boolean => this.related.owners.includes(ctx.subject) || this.related.parents.traverse((p) => p.permits.manage_admins(ctx)), create_subtenant: (ctx: Context): boolean => this.permits.manage(ctx) } } class RelyingParty implements Namespace { related: { admins: User[] parents: Tenant[] access: (User | SubjectSet | SubjectSet)[] } permits = { view: (ctx: Context): boolean => this.related.admins.includes(ctx.subject) || this.related.parents.traverse((t) => t.permits.view(ctx)), manage: (ctx: Context): boolean => this.related.admins.includes(ctx.subject) || this.related.parents.traverse((t) => t.permits.manage(ctx)), access: (ctx: Context): boolean => this.related.access.includes(ctx.subject) || this.permits.manage(ctx) } } class System implements Namespace { related: { super_admins: User[] authenticated_users: User[] } permits = { manage_all: (ctx: Context): boolean => this.related.super_admins.includes(ctx.subject) } }