Hi mates, have a question about caveats
# spicedb
r
Hi mates, have a question about caveats and optional blacklisting, I have the following domain 1. we have set of clinics where we can book appointment of different types 2. user is able to book an appointment if he has role that allows him to do this 3. also user can be marked as a blacklisted, in this case he is allowed to book only allowed types I'm build schema that comply with such requirements but I'm thing that it can be optimized somehow
Copy code
definition smile2impress/employee {
}

definition smile2impress/organization {
    // appoitments management
    relation appointment_creator: smile2impress/role#member
    relation blacklisted_on_appointment_creation: smile2impress/employee
    relation allowed_appointment_types_to_create_appointment: smile2impress/employee with allowed_appointment_type

    permission create_appointment = (appointment_creator - blacklisted_on_appointment_creation) + allowed_appointment_types_to_create_appointment
}

caveat allowed_appointment_type(appointment_type string, allowed_appointment_types list<string>) {
    appointment_type in allowed_appointment_types
}
as you see, I'm adding relation with the same employee twice, once to blacklist and block his access by role, second to allow access for a specific kind of appointments from my point of view, the ideal situation should be schema where I can do ignore caveat during removal employee from allowed by role and grant access by caveat rule in such case I need to keep only one extra relation
Copy code
permission create_appointment = (appointment_creator - blacklisted_on_appointment_creation#employee) + blacklisted_on_appointment_creation
v
based on what you are describing, couldn't you just live with one single relation? a "denied" user is allowed to only create certain types. So the difference with an appointment creator is the types they are a lowed to create so you could just use appointment_creator: - set a boolean flag in the context that is "all" for those. You can store it in the context instead of passing it. - for filtered/denied users, set the list of allowed types. - if the type provided in the request context is allowed, the user will be allowed - otherwise they will be denied
r
maybe I did not understand something, but I would like to grant access to create appointments by role and block access only for some users
appointment_creator is a role, not an employee
v
well, you are the one describing the requirements to us 😅
so you block access to folks that have the creator role already right?
or can any user create an appointment?
if so, what's the difference with an appointment_creator?
r
1. I would like to grant access to create appointment by role 2. but for some particular users, I would like to give access to create appointments only on specific appointment types ignoring their role 3. user without role can not create appointment
maybe I should use other approach to achieve expected behaviour
v
well then I don't see a way around it other than having an extra relationship that has the caveat.
Copy code
definition smile2impress/employee {
}

definition smile2impress/organization {
    // appoitments management
    relation appointment_creator: smile2impress/role#member
    relation allowed_only_on_specific_types: smile2impress/employee with allowed_appointment_type

    permission create_appointment = appointment_creator + allowed_only_on_specific_types
}

caveat allowed_appointment_type(appointment_type string, allowed_appointment_types list<string>) {
    appointment_type in allowed_appointment_types
}
I may be missing something but I'm not sure to see where the challenge is
r
I'm not sure, but I think it won't be working in case user has role that grants him access to make an appointment but maybe I'm wrong, let me check
yes, seems it won't be working, here an example of data and tests
Copy code
smile2impress/role:admin#member@smile2impress/employee:rinat
smile2impress/role:doctor#member@smile2impress/employee:georgy
smile2impress/application:kdk#user@smile2impress/role:admin#member
smile2impress/application:kdk#user@smile2impress/role:doctor#member
smile2impress/organization:impress#appointment_creator@smile2impress/role:admin#member
smile2impress/organization:impress#appointment_creator@smile2impress/role:doctor#member
smile2impress/organization:impress#allowed_only_on_specific_types@smile2impress/employee:rinat[allowed_appointment_type:{"allowed_appointment_types":["first_visit"]}]
Copy code
assertTrue:
  - smile2impress/application:kdk#use@smile2impress/employee:rinat
  - smile2impress/application:kdk#use@smile2impress/employee:georgy
  - 'smile2impress/organization:impress#create_appointment@smile2impress/employee:rinat with {"appointment_type": "first_visit"}'
assertFalse:
  - smile2impress/application:patienthub#use@smile2impress/employee:rinat
  - 'smile2impress/organization:impress#create_appointment@smile2impress/employee:rinat with {"appointment_type": "second_visit"}'
this condition should fail, but it don't
Copy code
- 'smile2impress/organization:impress#create_appointment@smile2impress/employee:rinat with {"appointment_type": "second_visit"}'
v
then I think something is incorrectly defined with the caveat or something else is going on, because that should work
r
I would be very grateful if you can help me to understand, what's wrong, because I looked through the docs and understand that in case caveat does not match, relation does not exist and it mean that when I subtracting it equals to subscruct 0
v
It works, you just made a mistake: rinat is already an admin, so of course it will not be denied when added to the "deny list", because they are an admin, and that takes precedence. Here is a working playground example: https://play.authzed.com/s/O4Rz2r-vTq_7/schema Next time, if you don't understand why a result is what is, you can use the
zed terminal
tab, and run a check with explain: https://cdn.discordapp.com/attachments/1250800471342317588/1251104594470371398/image.png?ex=666d5d73&is=666c0bf3&hm=8494ec72df62f27775b5311ac2002520eb6e39e24275948c1f1c591c515cf64f&
30 Views