Skip to content

Instantly share code, notes, and snippets.

@nickschot
Last active March 21, 2017 14:32
Show Gist options
  • Save nickschot/3275d5621ca51471cebcb35cee70aa44 to your computer and use it in GitHub Desktop.
Save nickschot/3275d5621ca51471cebcb35cee70aa44 to your computer and use it in GitHub Desktop.
Lux action level permission middleware test + example
// app/middleware/restrict-access.js
import User from 'app/models/user';
import Employee from 'app/models/employee';
import {UserTypes} from 'app/utils/constants';
/**
* Options contains action's as key names and callback functions as values
* Callback receives request, response and a user object as arguments
* @param options
* @returns {function(*, *)}
*/
export default function(options) {
let actions = new Map([
['create', []],
['update', []],
['destroy', []],
['index', []],
['show', []]
]);
options.forEach((item) => {
actions.forEach((functions, action) => {
if(item.actions.includes(action)){
functions.push(item.callback);
actions.set(action, functions);
}
});
});
return async (request, response) => {
const {
action
} = request;
if(action !== 'preflight'){
const {
user: {
user,
type
}
} = request;
let userObj;
if(type === UserTypes.ADMIN){
userObj = await User.find(user);
} else if(type === UserTypes.EMPLOYEE){
userObj = await Actor.find(user);
}
if(!userObj){
return 401;
}
let result;
// run functions for this action until one returns some result
actions.get(action).some((fn) => {
result = fn(request, response, userObj);
return result !== undefined;
});
// return if the callback had a defined result (e.g. a status code)
if(result !== undefined){
return result;
}
}
}
}
// app/controllers/some-controller.js
class SomeController extends Controller {
beforeAction = [
restrictAccess([
{
actions: ['create', 'update'],
callback: async (request, response, user) => {
const {
params: {
data: {
relationships: {
assignment
}
}
}
} = request;
const assignmentObj = await Assignment.where({id: assignment.data.id});
if (user.customerId !== assignmentObj.customerId) {
return 401;
}
}
},
{
actions: ['destroy'],
callback: async (request, response, user) => {
const {
params: {
id
}
} = request;
const some = await SomeModel.where({id: id});
const assignment = await Assignment.where({id: some.assignmentId});
if(assignment.customerId !== user.customerId){
return 401;
}
}
},
{
actions: ['index'],
callback: async (request, response, user) => {
const filterIdsArr = await this.getAllowedIds(request, user);
request.params.filter = filterIds(request, filterIdsArr);
}
},
{
actions: ['show'],
callback: async (request, response, user) => {
const {
params: {
id
}
} = request;
const some = await SomeModel.where({id: id});
const assignment = await Assignment.where({id: some.assignmentId});
if(assignment.customerId !== user.customerId){
return 401;
}
}
}
])
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment