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