Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OPL permissions have inconsistencies when using this.permits(ctx) vs calling a transitive permits directly #1626

Open
5 tasks done
AustinCase opened this issue Nov 13, 2024 · 0 comments
Labels
bug Something is not working.

Comments

@AustinCase
Copy link

AustinCase commented Nov 13, 2024

Preflight checklist

Ory Network Project

No response

Describe the bug

When using the OPL file, the this.permits(ctx) not translating into the proper permissions structure when calling self that calls a transitive relation.

Reproducing the bug

The following example returns different results when calling the check permission api for read relation then the update, delete, create_media_stack, and list_media_stacks. The read relation returns true while all others return false. We have other Namespaces that do NOT exhibit this behavior. They work as expected.

class Bin implements Namespace {
  related: {
    projects: Project[];
  };
  permits = {
    read: (ctx: Context): boolean => this.related.projects.transitive((project) => project.permits.list_bins(ctx)),
    update: (ctx: Context): boolean => this.permits.read(ctx),
    delete: (ctx: Context): boolean => this.permits.read(ctx),
    create_media_stack: (ctx: Context): boolean => this.permits.read(ctx),
    list_media_stacks: (ctx: Context): boolean => this.permits.read(ctx),
  };
}

When changing the above to the following, everything works as expected:

class Bin implements Namespace {
  related: {
    projects: Project[];
  };
  permits = {
    read: (ctx: Context): boolean => this.related.projects.transitive((project) => project.permits.list_bins(ctx)),
    update: (ctx: Context): boolean => this.related.projects.transitive((project) => project.permits.list_bins(ctx)),
    delete: (ctx: Context): boolean => this.related.projects.transitive((project) => project.permits.list_bins(ctx)),
    create_media_stack: (ctx: Context): boolean => this.related.projects.transitive((project) => project.permits.list_bins(ctx))),
    list_media_stacks: (ctx: Context): boolean => this.related.projects.transitive((project) => project.permits.list_bins(ctx)),
  };
}

Relevant log output

No response

Relevant configuration

The entirety of the OPL file ( that is relevant to this issue ) is copied below

import { Namespace, Context } from "@ory/keto-namespace-types";

class User implements Namespace {}

class Workspace implements Namespace {
  related: {
    owners: User[];
    admins: User[];
    members: User[];
  };
  permits = {
    read: (ctx: Context): boolean =>
      this.related.owners.includes(ctx.subject) ||
      this.related.admins.includes(ctx.subject) ||
      this.related.members.includes(ctx.subject),
    update: (ctx: Context): boolean =>
      this.related.owners.includes(ctx.subject) || this.related.admins.includes(ctx.subject),
    deactivate: (ctx: Context): boolean => this.related.owners.includes(ctx.subject),
    transfer_ownership: (ctx: Context): boolean => this.related.owners.includes(ctx.subject),
    manage_members: (ctx: Context): boolean => this.permits.update(ctx),
    create_project: (ctx: Context): boolean => this.permits.read(ctx),
    list_projects: (ctx: Context): boolean => this.permits.read(ctx),
  };
}

class Project implements Namespace {
  related: {
    workspaces: Workspace[];
    admins: User[];
    members: User[];
  };
  permits = {
    read: (ctx: Context): boolean =>
      this.related.workspaces.traverse((workspace) => workspace.permits.list_projects(ctx)) ||
      this.related.admins.includes(ctx.subject) ||
      this.related.members.includes(ctx.subject),
    update: (ctx: Context): boolean =>
      this.related.workspaces.traverse((workspace) => workspace.permits.list_projects(ctx)) ||
      this.related.admins.includes(ctx.subject),
    delete: (ctx: Context): boolean =>
      this.related.workspaces.traverse((workspace) => workspace.permits.list_projects(ctx)) ||
      this.related.admins.includes(ctx.subject),
    invite: (ctx: Context): boolean =>
      this.related.workspaces.traverse((workspace) => workspace.permits.manage_members(ctx)) ||
      this.related.admins.includes(ctx.subject),
    create_bin: (ctx: Context): boolean => this.permits.read(ctx),
    list_bins: (ctx: Context): boolean => this.permits.read(ctx),
    analyze_assets: (ctx: Context): boolean => this.permits.read(ctx),
    transcribe_assets: (ctx: Context): boolean => this.permits.read(ctx),
  };
}

class Bin implements Namespace {
  related: {
    projects: Project[];
  };
  permits = {
    read: (ctx: Context): boolean => this.related.projects.transitive((project) => project.permits.list_bins(ctx)),
    update: (ctx: Context): boolean => this.permits.read(ctx),
    delete: (ctx: Context): boolean => this.permits.read(ctx),
    create_media_stack: (ctx: Context): boolean => this.permits.read(ctx),
    list_media_stacks: (ctx: Context): boolean => this.permits.read(ctx),
  };
}

Version

0.13.0-alpha.0

On which operating system are you observing this issue?

macOS

In which environment are you deploying?

Other

Additional Context

This is in our devenv nix environment, same behavior with docker. Postgres backend.

@AustinCase AustinCase added the bug Something is not working. label Nov 13, 2024
@AustinCase AustinCase changed the title OPL parsing bug OPL permissions have inconsistencies when using this.permits(ctx) vs calling a transitive permits directly Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working.
Projects
None yet
Development

No branches or pull requests

1 participant