i'm not entirely sure it solves your
# spicedb
y
i'm not entirely sure it solves your problem, but one way to model "boolean" stuff is to have a relation from the object to itself
Copy code
definition resource {
  relation is_public: resource
  relation viewer: user
  permission view = viewer + is_public
}
and then you write
resource:1#is_public@resource_1
to enable that "flag"
m
this would be useful, but I don't quite understand how is it supposed to work. If
resource:1#is_public@resource_1
is set, how exactly does
viewer + is_public
evaluate to all users since viewer and is_public are relationships with two different types?
y
it doesn't matter - the union of the set of relations is nonempty, even though the types are different
j
to evaluate to all users, you'd need to write a wildcard
relation viewer: user | user:*
m
Copy code
definition user {}

definition resource {
  relation is_public: resource
  relation viewer: user
  permission view = viewer + is_public
}

---

resource:resource1#is_public@resource:resource1

resource:resource1#viewer@user:user1
resource:resource2#viewer@user:user1
Here I have two resources and two users. user1 is viewer of both resources and user2 is viewer of non. resource1 has is_public flag set. But in case of both resources, only user1 (the viewer) can view it, so I don't quite understand what is is_public flag changing exactly? https://cdn.discordapp.com/attachments/1350103155039277067/1351321424224059422/image.png?ex=67d9f3a5&is=67d8a225&hm=f050ff3370ff8a54d730ea7184dbc0f1f42a9085dc87f0a3ed5872566bf66b51&
j
it doesn't
if you want to mark it as public, use a wildcard as I showed above ^
and then only write the wildcard if it is public
y
ah, then i was wrong there :/
i may have been thinking of the use of it in intersection logic
m
ah ok, but is there a way to do boolean flags or not? Ultimately I am working on a drive system where I have the following:
Copy code
definition archive {
    relation owner: team // archive has one owner that is a team
    relation administrators: user // archive has multiple adminstrators who are users

    /* Who can view the archive? */
    // setting this relationship for certain archive would enable any user to view it
    relation viewers: user:* 
    // administrators and owner team members can always view the archive
    permission view = administrators + owner->members + viewers

    /* Who can edit the archive? */
    // setting this relationship for certain archive would enable either any user to view it or members of a specific team to view it
    // Application logic should ensure this is only ever set for the owner team
    relation editors : user:* | team#members
    // administrators can always edit the archive
    permission edit = administrators + editors

    // Only administrators can delete the archive
    permission delete = administrators
}
I am a bit stuck at the
Copy code
// Application logic should ensure this is only ever set for the owner team
relation editors : user:* | team#members
and am wondering if there's a way to not have to enforce this in application logic but create a relation that would work something like this:
relation editors: user:* | owner#members
so that there is no possibility of some non-owner team to get the edit permission
j
yes
you can write a relationship from the same resource to itself, pointing to another relation or permission
it works as a boolean
but you also need that relation to point to subject(s)
m
could you give me an example, cause I don't quite follow what you mean with
pointing to another relation or permission
?
j
Copy code
definition resource {
  relation some_flag: resource#someotherrelation
  relation viewer: user
  relation someotherrelation: user
  permission view = viewer + some_flag
}
write some_flag pointing to the resource's own
someotherrelation
IF it is enabled
m
Amazing, thanks a lot! Just out of curiosity, when I do this everything works as expected:
Copy code
definition team {
    relation member: user // team has multiple members who are users
}

definition user {}

definition archive {
    relation owner: team // archive's owner is a team
    permission owner_member = owner->member
    
    relation archive_administrator: user // archive's administrator is an user
    
    /* Who can edit the archive? */
    // Setting this relationship for certain archive would enable the members of owner team to edit it
    relation owner_members_can_edit: archive#owner_member
    // administrators can always edit the archive
    permission edit = archive_administrator + owner_members_can_edit
}

--- 
archive:archive1#owner@team:team1
archive:archive1#owner_members_can_edit@archive:archive1#owner_member -> now members of team1 can edit archive1
However, when I tried to do this, so that I don't have to create synthetic owner_member permission, it does not work:
Copy code
definition team {
    relation member: user // team has multiple members who are users
}

definition user {}

definition archive {
    relation owner: team // archive's owner is a team
    
    relation archive_administrator: user // archive's administrator is an user
    
    /* Who can edit the archive? */
    relation owner_members_can_edit: archive#owner
    // administrators can always edit the archive
    permission edit = archive_administrator + owner_members_can_edit->member
}

---

// user2 is member of team1
team:team1#member@user:user2

// team1 owns archive 1
archive:archive1#owner@team:team1

// use1 is administrator of archive1
archive:archive1#archive_administrator@user:user1


// archive 1 can be edited by owner team members
archive:archive1#owner_members_can_edit@archive:archive1#owner
j
arrows operate over the subject, not the subject relation
owner_members_can_edit->member
is pointing to
member
on the archive
not on the owner under archive
there should be a warning about it in the Playground
m
I am running playground in docker, so I didn't have the warning, but in the authzed playground I do indeed get it. Anyhow, thanks for the help!
5 Views