openfga/community

[Playground] Support AND and BUT NOT operators in the graph

andreadistefano opened this issue · 2 comments

Hi!
I'm trying to implement a model with Blocklists on different levels of my hierarchy, in order to define something like:

user:a is admin on archive:xxx of tenant:yyy (so she should have access to all documents inside all folders in the archive:xxx)
but must not have access to documents inside folder:zzz (which is part of archive:xxx)

I tried with a model like this:

type user

type tenant
  relations
    define deny as self

    define admin as self but not deny
    define editor as self but not deny
    define reader as self but not deny

type archive
  relations
    define parent as self
    define deny as self or deny from parent

    define admin as self or admin from parent but not deny
    define editor as self or admin or editor from parent but not deny
    define reader as self or editor or reader from parent but not deny

type folder
  relations
    define parent as self
    define deny as self or deny from parent

    define admin as self or admin from parent but not deny
    define editor as self or admin or editor from parent but not deny
    define reader as self or editor or reader from parent but not deny

type doc
  relations
    define parent as self
    define deny as self or deny from parent

    define admin as self or admin from parent but not deny
    define editor as self or admin or editor from parent but not deny
    define reader as self or editor or reader from parent but not deny

Unfortunately, the playground wouldn't let me save my model, and all the but not deny were marked as syntax errors.

So I tried to be smart and changed my model to this:

type user

type tenant
  relations
    define deny as self

    define admin as self but not deny
    define editor as self but not deny
    define reader as self but not deny

type archive
  relations
    define parent as self
    define deny as self or deny from parent

    define admin as admin_allow but not deny
    define admin_allow as self or admin from parent
    define editor as editor_allow but not deny
    define editor_allow as self or admin or editor from parent
    define reader as reader_allow but not deny
    define reader_allow as self or editor or reader from parent

type folder
  relations
    define parent as self
    define deny as self or deny from parent

    define admin as admin_allow but not deny
    define admin_allow as self or admin from parent
    define editor as editor_allow but not deny
    define editor_allow as self or admin or editor from parent
    define reader as reader_allow but not deny
    define reader_allow as self or editor or reader from parent

type doc
  relations
    define parent as self
    define deny as self or deny from parent

    define admin as admin_allow but not deny
    define admin_allow as self or admin from parent
    define editor as editor_allow but not deny
    define editor_allow as self or admin or editor from parent
    define reader as reader_allow but not deny
    define reader_allow as self or editor or reader from parent

Now the syntax is correct, but when I try to run some assertions I get the error AND and BUT NOT operators are currently not supported on this graph.
Am I doing something wrong? Is there any other way to do what I'm trying to do?

Thanks!

EDIT: I'll add an example that hopefully clarifies what I'm trying to do.
My data is something like:

tenant:xxx
|
|_archive:archive1
| |
| |_folder:folder1-1
| | |
| | |_doc:doc1-1-1
| | |_doc:doc1-1-2
| | 
| |_folder:folder1-2
| | |
| | |_doc:doc1-2-1
| |_|_doc:doc1-2-2
| 
|_archive:archive2
| |
| |_folder:folder2-1
| | |
| | |_doc:doc2-1-1
| | |_doc:doc2-1-2
| | 
| |_folder:folder2-2
| | |
| | |_doc:doc2-2-1
|_|_|_doc:doc2-2-2

I'd like to be able to do something like this:

user:alice is reader on tenant:xxx, so she is reader on both archive:archive1 and archive:archive2 and their subtrees.
user:alice MUST NOT read folder:folder2-2 and its documents, namely doc:doc2-2-1 and doc:doc2-2-2, so she is deny on folder:folder2-2

Hey @andreadistefano! Apologies if the UX was not clear, the model you have is correct. and and but not, are only unsupported in the Playground graph when showing the visualization. They are still respected when you try to perform checks.

So for the following model:

type user
type resource
  relations
    define writer as self
    define reader as self and writer

If you try running the following query:
is user:anne related to resource:roadmap as reader?

You might get one of two responses:

  • Yes, user:anne is related to resource:roadmap as reader, the response will be in blue to indicate that a relationship has been found, but the Playground cannot render it in a pretty graph.
    Screenshot from 2022-11-25 12-00-31

  • No, user:anne is NOT related to resource:roadmap as reader, the response will be in red to indicate that a relationship has not been found
    Screenshot from 2022-11-25 11-59-51

I updated your ticket to be a feature request for us.

If you have any suggestions or thoughts on what the graph should look like, please do share them!

(cc @matthewpereira )

Thanks, everything is much clearer now!