UNPKG

1.73 kBJavaScriptView Raw
1const ACLInterface = require('./base')
2const objectDeepKeys = require('../utils/object-deep-keys')
3const { permittedFieldsOf } = require('@casl/ability/extra')
4
5class CASL extends ACLInterface {
6 _checkIndividualAccess(item, inputItem) {
7 // Check whether the user can perform a particular action
8 // NOTE: body is only used for BUILDING the rules, not CHECKING it!
9 const ability = this.acl(
10 this.user,
11 item,
12 this.action,
13 inputItem,
14 this.opts,
15 this.relation
16 )
17
18 // Now that we don't need to "filter out" wrong inputs,
19 // we can simply check all of the attributes it's trying to change.
20 // Note that we're passing ALL the fields, including the embedded ones,
21 // as dot notation for the ability checker;
22 // normally this would be overkill but this covers cases where you're somehow
23 // checking ACL on deep, nested fields.
24 const fields = objectDeepKeys(inputItem)
25 if (fields.length) {
26 for (let i = 0; i < fields.length; i++)
27 if (ability.cannot(this.action, item, fields[i])) return false
28 return true
29 } else return ability.can(this.action, item)
30 }
31
32 get allowedFields() {
33 const modelInstance = this.items[0]
34 const fields = objectDeepKeys(modelInstance)
35 const ability = this.acl(
36 this.user,
37 modelInstance,
38 this.action,
39 this.inputItems[0],
40 this.opts
41 )
42
43 // casl on its own does not have any idea what all of the fields available are.
44 // Therefore, we must inject them directly by reading them from the actual model instance
45 return permittedFieldsOf(ability, this.action, modelInstance, {
46 fieldsFrom: rule => rule.fields || fields
47 })
48 }
49}
50
51module.exports = CASL