Skip to content
This repository has been archived by the owner on Jan 12, 2023. It is now read-only.

Commit

Permalink
[skip ci] 3.0 in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
JaneJeon committed Jan 2, 2020
1 parent 45df2a3 commit 10f0a00
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 32 deletions.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,9 @@ const opts = {
defaultRole: 'anonymous',
unauthenticatedErrorCode: 401,
unauthorizedErrorCode: 403,
resourceName: model => model.name,
resourceAugments: { true: true, false: false, undefined: undefined },
userFromResult: false,
contextKey: 'req',
library: 'role-acl',
wrapClass: false
contextKey: 'req'
}
```

Expand Down
13 changes: 3 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const assert = require('http-assert')
const isEmpty = obj => !Object.keys(obj || {}).length
const debug = require('debug')('objection-authorize')
const pick = require('lodash.pick')
const omit = require('lodash.omit')

module.exports = (acl, library = 'role-acl', opts) => {
if (!acl) throw new Error('acl is a required parameter!')
Expand Down Expand Up @@ -41,17 +43,11 @@ module.exports = (acl, library = 'role-acl', opts) => {
} = this.context()
body = body || resource
action = _action || action
const ctx = Object.assign(
{},
{ [opts.contextKey]: { user, body } },
opts.resourceAugments,
resource
)
resource = this.modelClass().fromJson(resource, {
skipValidation: true
})

const access = lib.getAccess(acl, user, resource, action, ctx)
const access = lib.getAccess(acl, user, resource, action, ctx, opts)

// authorize request
assert(
Expand Down Expand Up @@ -246,9 +242,6 @@ module.exports = (acl, library = 'role-acl', opts) => {
}

return class extends Model {
// used to filter model's attributes according to a user's read access.
// First pick the fields, and then filter them, as per:
// https://github.com/oscaroox/objection-visibility
_filter (access) {
const pickFields = lib.pickFields(access)
const omitFields = lib.omitFields(access)
Expand Down
24 changes: 9 additions & 15 deletions lib/casl.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
exports.getAccess = (acl, user, resource, action, ctx) =>
acl
.can(user.role)
.execute(action)
.context(ctx)
.on(resource.constructor.name)
const { permittedFieldsOf } = require('@casl/ability/extra')

exports.isAuthorized = access => access.granted
exports.getAccess = (acl, user, resource, action, opts) =>
acl(user, resource, action)

exports.filter = (access, body) => access.filter(body)
exports.isAuthorized = (ability, action, subject) =>
ability.can(action, subject)

exports.pickFields = access =>
access.attributes.filter(field => field !== '*' && !field.startsWith('!')) ||
[]
exports.filter = (ability, body) => access.filter(body)

exports.omitFields = access =>
access.attributes
.filter(field => field.startsWith('!'))
.map(field => field.substr(1)) || []
exports.pickFields = (ability, action, subject) => permittedFieldsOf(ability)

exports.omitFields = ability => []
11 changes: 9 additions & 2 deletions lib/role-acl.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
exports.getAccess = (acl, user, resource, action, ctx) =>
exports.getAccess = (acl, user, resource, action, body, opts) =>
acl
.can(user.role)
.execute(action)
.context(ctx)
.context(
Object.assign(
{},
{ [opts.contextKey]: { user, body } },
opts.resourceAugments,
resource
)
)
.on(resource.constructor.name)

exports.isAuthorized = access => access.granted
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
},
"dependencies": {
"debug": "^4.1.1",
"http-assert": "^1.4.1"
"http-assert": "^1.4.1",
"lodash.omit": "^4.5.0",
"lodash.pick": "^4.4.0"
},
"peerDependencies": {
"objection": "1.X"
Expand Down
21 changes: 21 additions & 0 deletions test/casl.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const pluginTest = require('./utils/plugin-test')
const { AbilityBuilder, Ability } = require('@casl/ability')

// TODO: do I need to put the deny before or after the allow?
function acl (user, resource, action, ctx) {
return AbilityBuilder.define((allow, forbid) => {
allow('read', 'User')
forbid('read', 'User', ['email', 'secrethiddenfield'])

if (user.role === 'anonymous') {
allow('create', 'User')
} else if (user.role === 'user') {
allow('read', 'User', ['email'], { id: user.id })
allow('update', 'User', { id: user.id })
forbid('update', 'User', ['id'])
allow('delete', 'User', { id: user.id })
}
})
}

pluginTest(acl, 'casl')
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3452,6 +3452,16 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"

lodash.omit@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=

lodash.pick@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=

lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
Expand Down

0 comments on commit 10f0a00

Please sign in to comment.