beem-acl
v2.0.8
Published
This README would normally document whatever steps are necessary to get your application up and running.
Downloads
74
Readme
Beem Role Based Access Control List
Installation
npm install beem-acl
usage
import and initialize beem acl
import BeemAcl from 'beem-acl';
const { aclRoutes, aclMiddleware, aclResponseFilter } = new BeemAcl(
'twoway:acl',
'http://localhost:5555/api',
'redis://127.0.0.1:6379',
{
POST: {
'/': {
roles: ['admin'],
},
},
},
response
);
Beem Acl receives the following parameters
appName: Name that will be used to cache the acl object e.g 'twoway:acl'
oauthUrl: open-auth url for all acl calls to perform CRUD operations
redisUrl: redis url for caching and redis operation performed by the packages
staticRules: optional hardcoded acl rules to be used to perform app-based Acl CRUD
By default, the hardcoded rules are set top allow every role to perform CRUD operations, if it is to be modified please make sure you cover every path to prevent the following response
{
error: 'User has no assigned role'
}
Acl object structure:
{
// start by creating the HTTP method as a property
POST: {
// create all the path that are under POST path
"/": {
// add the an array of roles that are allowed to access the route resurces
roles: ["admin", "account", "tech"]
}
}
}
responseObj: optional object listing all the responses that are to be filtered based on route and role.
By default, the acl package won`t filter any response coming out of the app it is being used in, but if it is to be used we need to provide it with an object that can either be a json file, or an object variable instructing it to filter path based on a role, or we can provide a wildcard, and it will filter the response without checking the role of the request.
Response filter object structure
{
// start by creating the HTTP method as a property
POST: {
// create all the path that are under POST path
"/": {
admin: {
// create an array of roles that are allowed to access the route resurces
exclude: ["created_at", "price", "id"]
}
},
"/number/admin/:number_id": {
// use the asterik symbol; to instruct the response filter to filter all the response for every role
"*": {
exclude: ["created"]
}
}
}
}
after initialize the acl package will expose the following API
aclRoutes
These are all the routes used to perform app-based acl CRUD operations
POST:
path: /
Request body:
{
method: string,
path: string,
roles: array<string>,
app: string
}
PATCH :
path: /:acl_id
acl_id : the id of the acl policy to be updated
Request body:
{
method: string,
path: string,
roles: array<string>,
app: string
}
GET:
path: /
DELETE:
path: /:acl_id
usage
e.g:
// you can namespace it per your request, just make sure you put it after the jwt middleware
app.use('/', jwtMiddleware(), aclRoutes);
or
app.use('/v1', jwtMiddleware(), aclRoutes);
aclMiddleware
An actual middleware that will evaluate incoming requests and compare them to the stored app ACL policies. This is a route level middleware, and it will be added to the route itself not the upper scope of the route,
NB: This middleware is only used on routes that have jwt middleware verification, we do this to obtain the role that is from the decoded token
eg:
const indexRouter = express.Router();
// route level middleware is to be placed here
indexRouter.patch('/number/admin/:number_id', aclMiddleware, (req, res) => {
return res.json({ status: 200, created: '2021' });
});
// upper level routing
app.use('/v1', jwtMiddleware(), indexRouter);
aclResponseFilter
to filter out responses coming out of the API we will need to set up the acl response filter interceptor and provide the response object during initialing of the acl package.
NB: interceptor are added before any route declarations
response filter structure:
{
"PUT": {
"/api/roles/": {
"*": {
"exclude": ["created"]
}
}
}
}
or
{
"PUT": {
"/api/roles/": {
"path": "data",
"*": {
"exclude": ["created"]
}
}
}
}
path: is added only, if the object or array to be filtered is a sub-property ofthe reponse object
{
"status": 200,
"data": [
{
"code": "works",
"created": "2021"
}
]
}
loggers
loggers are added to help the developer quickly resolve acl problems e.g
info: acl:route /v1/acl/
info: acl:role admin
one of the main distinction that a dev might some across without knowing
if a path has no params, let say if you do a GET /v1/contact
in acl or express routing format this will be considered
as GET /v1/contacts/
on the other hand, if it has param, let say you send a GET /v1/contact/:contact_id
then this will be read as is
without the /
at the end
Full Example: es-6
// initialize beem Acl
import BeemAcl from 'beem-acl';
// acl rules
{
POST: {
'/v1/acl/': {
roles: ['admin', 'tech'],
},
},
PATCH: {
'/v1/acl/:acl_id': {
roles: ['admin', 'tech'],
},
},
DELETE: {
'/v1/acl/:acl_id': {
roles: ['admin', 'tech'],
},
},
GET: {
'/v1/acl/': {
roles: ['admin', 'tech'],
},
},
};
export const { aclRoutes, aclMiddleware } = new BeemAcl(
'contacts:acl',
process.env.OauthAcl,
process.env.REDIS_URL,
aclRules
);
es-5
const { default: { BeemAcl} } = require('beem-acl');
// acl rules
{
POST: {
'/v1/acl/': {
roles: ['admin', 'tech'],
},
},
PATCH: {
'/v1/acl/:acl_id': {
roles: ['admin', 'tech'],
},
},
DELETE: {
'/v1/acl/:acl_id': {
roles: ['admin', 'tech'],
},
},
GET: {
'/v1/acl/': {
roles: ['admin', 'tech'],
},
},
};
const { aclRoutes, aclMiddleware } = new BeemAcl(
'twoway:acl',
process.env.OauthUrl,
process.env.REDIS_URL,
aclRules
);
module.exports = { aclRoutes, aclMiddleware }