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

Create pages from question issues and gitter questions #204

Open
1 of 10 tasks
stalniy opened this issue Jun 26, 2019 · 3 comments
Open
1 of 10 tasks

Create pages from question issues and gitter questions #204

stalniy opened this issue Jun 26, 2019 · 3 comments

Comments

@stalniy
Copy link
Owner

stalniy commented Jun 26, 2019

Tasks:


Basics:

Advanced:

Security:

Persisted permissions (i.e., roles)

Use cases:

  • 1 iphoneX, only particular users can manage it. others cannot

Hi, I'm trying to use your example (with mongoose) for my use case:

Domain definition:
A "User" could has more "Vehicles"
A "Document" must have a "Vehicle"

Schema definition:

vehicle { users: [ {type: objectId, ref: 'user'} ] }
document { vehicle: {type: objectId, ref: 'vehicle' }}

Rule definition
I successfully defined an ability for user to read/update only his vehicles
can(['read', 'update'], 'vehicle', { users: { $in: [user._id] } } )

How can I define a rule to check "user can read/update only documents of his vehicles" ?
I tried with:

can(['read', 'update'], 'document', { "vehicle.users": { $in: [user._id] } } )

Obviously with no success.

casl don't manage references on related documents. You need to do it yourself.

So, I see few ways:

  1. Retrieve ids of all vehicles when you define rules. This works good in case if amount of vehicles not big (<= 1000)
const vehicleIds = await getVehicleIds(user)

can(['read', 'update'], 'document', { vehicle: { $in: vehicleIds } })
  1. Denormalize your scheme. For example, add additional user_id field to vehicle document
  2. Think whether you can embed document as subdocument to vechicle, something like this:
vehicle {
  documents: [Document],
  users: [ {type: objectId, ref: 'user'} ]
}
  1. Just don't define rule per documents and enforce them in routes (REST or GraphQL doesn't matter).
// app - express app

app.get('/vehicle/:id/documents', async (req, res) => {
   const vehicle = await Vehicle.findById(req.params.id)

   req.ability.throwUnlessCan('read', vehicle)
   const documents = Document.find({ vehicle: vehicle.id })

   res.send({ documents })
})

frontend

Mongoose:

Tests

backend

  • filter out fields from resource returned by API, permitted/accessible fields
  • So the question is how to express something like:
    can('manage', 'Comment', { ??? <how to walk the object graph here> ???})
  • If I define conidtions for an ability, is it possible to check if a id is in a array of the object to be checked? Something like: can('edit' , 'Post', { moderators: "contain user.id" })
  • example with auth0
  • is it possible to add additional rules after the ability object was instantiated?
  • casl + feathers
  • casl + sql
@stalniy
Copy link
Owner Author

stalniy commented Oct 20, 2019

Need to check what is in this course
https://codecourse.com/watch/vue-roles-and-permissions?part=using-casl-with-vue

@stalniy
Copy link
Owner Author

stalniy commented Mar 31, 2020

FAQ will be represented as a cookbook in the new docs

@stalniy stalniy modified the milestones: 4.x, 4.next Apr 4, 2020
@stalniy stalniy changed the title Go through gitter chat and question issues to create a FAQ Create cookbook pages from question issues and gitter questions Apr 4, 2020
@stalniy stalniy changed the title Create cookbook pages from question issues and gitter questions Create pages from question issues and gitter questions Apr 20, 2020
@stalniy stalniy removed this from the v5 milestone Jul 16, 2020
@stalniy
Copy link
Owner Author

stalniy commented May 18, 2021

empty conditions object behavior:

{
    "subject": "Financial",
    "action": "read",
    "fields": [
        "salary",
        "taxcode"
    ], 
   conditions: {}
},
{
    "subject": "Financial",
    "action": "read",
    "inverted": true,
    "fields": [
        “salary"
    ],
   conditions: {}
}

Conditions are sometimes populated but in this case they are not.
After retrieving from the array of Abilities from the database I pass them in to Ability. When empty conditions objects are there the can/cannot don’t work as expected. If I remove empty conditions objects before pushing them into Ability they work exactly as expected.
This is using the latest version of CASL.
Cleaning up my data solves the problem so I’m happy but I thought you might like to know in case that is unexpected behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant