This repository has been archived by the owner on Jan 12, 2023. It is now read-only.
/
casl.js
30 lines (26 loc) 路 1.63 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
const { permittedFieldsOf } = require('@casl/ability/extra')
// O(M) with regards to the number of rules to match.
// Note, however, that since we know what the resource is beforehand,
// we can cut down the number of rules that need to be encoded in the acl
// by a factor of n where n is the number of resources.
// This different approach of monolithic vs. functional acl between role-acl and casl
// results in a drastically better overall time complexity for casl.
exports.getAccess = (acl, user, resource, action, body, opts) =>
acl(user, resource, action, body, opts)
exports.isAuthorized = (ability, action, resource) =>
ability.can(action, resource)
// While role-acl is able to "infer" that ['*', '!email'] + ['email'] = '*', casl cannot.
// In casl world, the same equation comes out to ['email'], so we need to provide ALL the fields
// for a given model when picking fields (remember, casl does not have any concept of "exclusions",
// e.g. '!email'). The model *itself* doesn't have all of the necessary field information;
// however, Objection has methods to fetch the fields by actually querying the database with knex
// and caching it; and here, we're just fetching the cached metadata and extracting the fields.
// Unfortunately, having to iterate thru every single field means we're incurring a fixed
// O(N) cost with regards to the number of fields.
// TODO: open an issue/PR about this on the casl repo?
exports.pickFields = (ability, action, resource) =>
permittedFieldsOf(ability, action, resource, {
fieldsFrom: rule =>
rule.fields || (resource.constructor.tableMetadata() || {}).columns
})
exports.omitFields = () => []