Authouriztion
We use casl to check user ability with some changes.
All the services in the app are private by default.
with rules you can manage how can access the services.
Rule structure
Each rule is an object
You can define rules in 3 places:
1.Service options Add serviceRules to options
skipAbilitiesCheck Inside service.options you can set the skipAbilitiesCheck = true. and handle the Authorization by your self
2.Config file Add rules to defaultRules at the config.feathers-mongoose-casl
3. DB rules collection
Service default rules
By default any service have get 5 rules
create-<serviceName>
read-<serviceName>
update-<serviceName>
delete-<serviceName>
manage-<serviceName>
If you want to allow a specific user to delete posts then add delete-posts to user.roles
Each rule define by this fields:
name - string the name of the rule.
description - string optional, add info about the rule
actions - array required, define the methods to allow
manage - allow all actions
create
read
update
remove
example ['posts' ,'users']
subject - array required, define the services to allow
example ['posts' ,'users']
conditions - object when hardcoded \ stringify on DB, Allow specific user by user context
examples:
"conditions": { "_id": "{{ user._id }}" } let the user to [actions] only if doc id equal to user id
"conditions": { "author": "{{ user._id }}" } let user to [actions] only if author equal to is _id
"conditions": { "active": true } let the user [actions] only when active is true
we use nunjucks to handle the templates, to convert {{ user._id}} to a user id (we get the user id from jwt)
you can build conditions like a mongoose query with MongoDB operators: $in, $nin, $exists....
see this feathers-mongoose docs, some of operators need to expose with whitelist[] inside the options
userContext - object when hardcoded \ stringify on DB Define the users that the rule are relevant for them by the user document context
examples:
{"email":{"$eq":"doron+1@committed.co.il"}}
{"writer":{"$eq": true}}
anonymousUser - boolean Set true if the rules relevant to anonymous user
roles - array Define the users that the rule are relevant for them by the user roles
example - ["writer"]
fields - array Define specific fields the the rule allow or not allow.
Simple
Allow specific fields before find/get we add this fields to feathers select example - ['title', 'body']
Block specific fields example - ['-price'] before create/update/patch we add this fields to feathers select
Complex
Allow/block field with condition examples: 1. expose the author object only when the user is the author, all the else user can see the email field in the author object ["*", { "path": "author", "when": {"author._id" : "{{ user._id}}"} , "then" : ["*"] , "otherwise": ["email"] } ] 2. expose only email from author object ["*", {"path": "author", "select": ["email", "-updatedAt"] }] 3. expose only email from each item inside authors array ["*", {"path": "authors", "select": ["email", "-updatedAt"], type: 'array' }]
we support deep field ['user.name']
we also support a deep field in array values
we use nunjucks to handle the templates and convert {{ user._id}} to user id (we get the user id from jwt)
populateWhitelist - array Define the collections that you allow to populates. when a user requests to populate something that not in the list, we remove it before we call to DB, to use populate you need to enabled this in the service options read more https://feathersjs-mongoose.gitbook.io/feathers-mongoose-casl/guides/populate
active - boolean - relevant only to DB rule Set true to enabled the rule.
from - date optional - enabled the rule from specific date
to - date optional - enabled the rule until specific date
schema
rules JOI schema
Example of rules:
When user make request to one service and from this service you make another request to other service, you need to persist user and provider to get response from the other service base is user abilities, read this:
Persist user requestLast updated