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