Ability Manager
This package is shipped with a management system for permissions, which scales between a claim based and subject/attribute based authorization.
The data (Ability(s)) to initialize the AbilityManager
can be serialized as json for example and shared between frontend and backend services, to provide the same features on both sides.
The Abilities can be extracted from the Payload of the /token
endpoint response (AUTHORIZATION
header required)
ResponsePayload
{
...,
"target": {
"permissions": [
{
"condition": null,
"id": "data_add",
"negation": false,
"power": 999,
"target": null
}
]
},
...
}
{
...,
"target": {
"permissions": [
{
"condition": null,
"id": "data_add",
"negation": false,
"power": 999,
"target": null
}
]
},
...
}
Define Abilities
The class constructor accepts a collection or a single ability descriptor as argument. An ability descriptor describes the permission owned and requires at least the id
property.
- Condition(s): One or many conditions can be specified using the MongoDB query language
- Fields: A string array can be provided to limit the permission on specific fields of the subject.
import { Ability, AbilityManager } from '@authup/core';
const items : Ability[] = [
{ id: 'data_add', condition: { size: { $lte: 5 } } },
{ id: 'data_edit', fields: ['value'] }
]
const abilityManager = new AbilityManager(items);
import { Ability, AbilityManager } from '@authup/core';
const items : Ability[] = [
{ id: 'data_add', condition: { size: { $lte: 5 } } },
{ id: 'data_edit', fields: ['value'] }
]
const abilityManager = new AbilityManager(items);
The list of supported operators:
- $eq and $ne
Check if the object value is equal to the specified value.$ne
meansnot $eq
. - $lt and $lte
Check if the object value is less than the specified value. Can be used forDate
s, numbers and strings.$lte
is a combination of$lt
and$eq
, so it's an inclusive check. - $gt and $gte
Check if the object value is greater than the specified value. Can be used forDate
s, numbers and strings.$gte
is a combination of$gt
and$eq
, so it's an inclusive check. - $in and $nin
Checks if the object's property is of the specified array values. Can be used for single value and for arrays as well. If object's property is an array it checks for intersection.$nin
meansnot $in
- $all
Checks if the object's property contain all elements from the specified array. Can be used for arrays only. - $size
Checks if the array length is equal to the specified value. Can be used for arrays only. - $regex
Allows to test object's property value using regular expression. Can be used for strings only. - $exists
Checks if the property exists in the object. - $elemMatch
Checks nested elements shape. Use$elemMatch
operator to specify multiple criteria on the elements of an array such that at least one array element satisfies all the specified criteria. If you specify only a single condition in the$elemMatch
expression,$elemMatch
is not necessary. See Specify Multiple Conditions for Array Elements for details.
Check
To check if a permission is owned in general without any restrictions (conditions or fields), use the has()
method of the class instance.
import { Ability, AbilityManager } from '@authup/core';
const items : Ability[] = [
{ id: 'data_add', condition: { size: { $lte: 5 } } },
{ id: 'data_edit', fields: ['value'] }
]
const abilityManager = new AbilityManager(items);
console.log(abilityManager.has('data_add'));
// true
console.log(abilityManager.has('data_drop'));
// false
import { Ability, AbilityManager } from '@authup/core';
const items : Ability[] = [
{ id: 'data_add', condition: { size: { $lte: 5 } } },
{ id: 'data_edit', fields: ['value'] }
]
const abilityManager = new AbilityManager(items);
console.log(abilityManager.has('data_add'));
// true
console.log(abilityManager.has('data_drop'));
// false
Verify
To verify a permission with condition and field restriction, use the verify()
method of the class instance.
Verify Conditions
Conditions will be evaluated, if an object (subject) is provided as second argument to the verify()
method.
import { Ability, AbilityManager } from '@authup/core';
type Data = {
value: string,
size: number
}
const items : Ability[] = [
{ id: 'data_add', condition: { size: { $lte: 5 } } }
]
const abilityManager = new AbilityManager(items);
let exampleData : Data = {
value: '0123456789',
size: 10
}
console.log(abilityManager.verify('data_add', exampleData));
// false
exampleData = {
value: '01234',
size: 5
}
console.log(abilityManager.verify('data_add', exampleData));
// true
import { Ability, AbilityManager } from '@authup/core';
type Data = {
value: string,
size: number
}
const items : Ability[] = [
{ id: 'data_add', condition: { size: { $lte: 5 } } }
]
const abilityManager = new AbilityManager(items);
let exampleData : Data = {
value: '0123456789',
size: 10
}
console.log(abilityManager.verify('data_add', exampleData));
// false
exampleData = {
value: '01234',
size: 5
}
console.log(abilityManager.verify('data_add', exampleData));
// true
Verify Fields
To verify if the permission applies on a specific field of an object (subject), provide the field name as third argument to the verify()
method.
import { Ability, AbilityManager } from '@authup/core';
type Data = {
value: string,
size: number
}
const items : Ability[] = [
{ id: 'data_edit', fields: ['value'] }
]
const abilityManager = new AbilityManager(items);
let exampleData : Data = {
value: '01234',
size: 5
}
console.log(abilityManager.can('data_edit', exampleData, 'value'));
// true
console.log(abilityManager.can('data_edit', exampleData, 'size'));
// false
import { Ability, AbilityManager } from '@authup/core';
type Data = {
value: string,
size: number
}
const items : Ability[] = [
{ id: 'data_edit', fields: ['value'] }
]
const abilityManager = new AbilityManager(items);
let exampleData : Data = {
value: '01234',
size: 5
}
console.log(abilityManager.can('data_edit', exampleData, 'value'));
// true
console.log(abilityManager.can('data_edit', exampleData, 'size'));
// false