@inventi/acl
v1.1.0
Published
[![@inventi/acl](https://img.shields.io/npm/v/@inventi/acl.svg)]()
Downloads
68
Readme
@inventi/acl 🇩🇪
Example
See tests in source code for more examples!
Permission definition and plain usage:
import Permission, { Permission, PermissionUser, ResourceNameArgument } from '@inventi/acl'
const acl = new Permission()
acl.addRole('guest')
acl.addRole('registered', 'guest') // 'registered' dědí od 'guest'
acl.addRole('admin', 'registered') // a od něj dědí 'admin'
acl.addResource('article')
acl.addResource('comment')
acl.addResource('poll')
// guest může prohlížet články, komentáře i ankety
acl.allow('guest', ['article', 'comment', 'poll'], 'view')
// administrátor nemůže editovat ankety, to by bylo nedemokratické
acl.deny('admin', 'poll', 'edit')
// volitelný callback = dynamická aserce
acl.allow('guest', 'article', 'poll', (role: string, resource: ResourceNameArgument, operation: string, extraData?: any) => {
if (typeof resource !== 'string' && resource?.resourceName === 'article' && extraData?.userInfo?.id === 1) return true
return false
})
expect(acl.isAllowed('guest', 'article', 'view')).toBe(true)
expect(acl.isAllowed('guest', { resourceName: 'article', type: 'baz' }, 'poll', { userInfo: { id: 1 } })).toBe(true)
expect(acl.isAllowed('registered', 'article', 'view')).toBe(true)
expect(acl.isAllowed('admin', 'article', 'edit')).toBe(true)
let user = new PermissionUser(acl)
user.setRole('guest')
expect(user.isAllowed('article', 'view')).toBe(true)
expect(user.isAllowed('article', 'edit')).toBe(false)
expect(user.isAllowed('poll', 'vote')).toBe(true)
expect(user.isAllowed('comment', 'add')).toBe(false)
expect(user.isAllowed({ resourceName: 'article', type: 'baz' }, 'poll', { userInfo: { id: 1 } })).toBe(true)
expect(user.isAllowed({ resourceName: 'bar', type: 'foo' }, 'add', { userInfo: { id: 2 } })).toBe(false)
user = new PermissionUser(acl)
user.setRole('registered')
expect(user.isAllowed('article', 'view')).toBe(true)
Usage in React:
- Define permissions
import { Permission } from '@packages/acl'
const acl = new Permission()
acl.addRole('guest')
acl.addRole('admin')
acl.addResource('article')
acl.allow('guest', ['article', 'comment'], 'view')
acl.allow('admin', acl.ALL, ['view', 'edit', 'add'])
export default acl
- Add a provider to the root of your app
import { Provider as AclProvider } from '@packages/acl'
<AclProvider permission={acl} role="guest">
...
</AclProvider>
- Query (hooks or Can component) :)
import { Can, usePermission } from '@packages/acl'
const MyComponent = () => {
// the hooks way
const permision = usePermission()
console.log('Are you allowed to view a comment?', permision.isAllowed('comment', 'view'))
return (
{/* the component way */}
<Can I="launch" a="atomMissile">
<h1>You can launch a atom missile!</h1>
</Can>
<Can not I="launch" a="atomMissile">
<h1>You can NOT launch a atom missile!</h1>
</Can>
)
}
Disclaimer
This package is not intended for dynamic permissions changes (but it can be done with little effort ;)).
If you make changes like permission.permission.allow()
, permission.permission.deny()
, and so on, after Context Provider is created,
context wont catch this changes!