Skip to content

Instantly share code, notes, and snippets.

@doraemonxxx
Created June 30, 2022 21:03
Show Gist options
  • Save doraemonxxx/c53e92dd8d059d46ba07ffddbf9e444f to your computer and use it in GitHub Desktop.
Save doraemonxxx/c53e92dd8d059d46ba07ffddbf9e444f to your computer and use it in GitHub Desktop.
simple react or vanilla js permission checking
import { USER_INFO } from '../../redux/Authenticate/reducer';
import { useSelector } from 'react-redux';
import { cloneDeep, each, omit } from 'lodash';
const APP_USER = {
jsecalias: [],
permission: [],
allPermitted: false,
cache: {},
getLoggedInUser: function (options = {}) {
// for class component
if (options.isClazz) {
const mapStateToProps = (state) => state;
return mapStateToProps;
}
// global let variable from reducer
// dirty = should use store
if (USER_INFO !== null) {
return USER_INFO.user;
}
// for functional component
const { user } = useSelector((state) => state.authenticateReducer);
return user;
},
currentUser: function () {
let user = this.getLoggedInUser();
let userClone = omit(cloneDeep(user), [
'created_by',
'date_created',
'date_updated',
'updated_by',
'email_verified_at',
'employee_id',
]);
return userClone;
},
getUserRoles: function () {
let roles = this.currentUser().roles;
let roleNames = [];
each(roles, function (obj) {
roleNames.push(obj.name.toLowerCase());
});
return roleNames;
},
/**
*
* @param {*} array = specific if alteast one is not present then return false
* @returns
*/
hasRoles: function (array = []) {
let roles = this.getUserRoles().map((e) => e.toLowerCase());
let check = array.every((i) => roles.includes(i.toLowerCase()));
return check;
},
/**
*
* @param {*} array = if alteast one is present then return true
* @returns
*/
hasAnyRoles: function (array = []) {
let roles = this.getUserRoles().map((e) => e.toLowerCase());
let check = array.some((i) => roles.includes(i.toLowerCase()));
return check;
},
getUserRolesPermissions: function () {
let rolesObj = this.currentUser().roles;
let rolesPerms = [];
let rolesPermsName = [];
each(rolesObj, function (obj) {
each(obj.permissions, function (ob2) {
rolesPerms.push(ob2);
});
});
each(rolesPerms, function (obj) {
rolesPermsName.push(obj.name);
});
return rolesPermsName;
},
/**
*
* @param {*} value = array
* @returns
*/
hasRolesPermissions: function (value = []) {
let rolesPerms = this.getUserRolesPermissions();
// params then the role
let check = value.every((i) => rolesPerms.includes(i));
return check;
},
getUserPermissions: function () {
let perms = this.currentUser().permissions;
let permsName = [];
each(perms, function (obj) {
permsName.push(obj.name);
});
return permsName;
},
/**
*
* @param {*} value = array
* @returns
*/
hasPermissions: function (value = []) {
let perms = this.getUserPermissions();
let check = value.every((i) => perms.includes(i));
return check;
},
/**
* CA means Controller - Action
* @param {*} perm
* @returns
*/
getCA: function (perm) {
let p = perm.split(/:/);
if (p.length < 2) {
return null;
}
let ret = { controller: p[0], action: p[1] };
return ret;
},
setPermission: function () {
const me = this;
let user = me.currentUser();
_.each(user.permissions, function (i) {
me.permission.push(i.name);
});
},
/**
*
* @param {*} p = permission
* @param {*} option = debugger -> console info
* @returns
*/
hasPermission: function (p, option = {}) {
const me = this;
if (option.debugger) console.info('me.permission', me.permission);
if (me.allPermitted) {
if (option.debugger) {
console.info('me.allPermitted true');
}
return true;
}
if (p in me.cache) {
if (option.debugger) {
console.info('p in me.cache true');
}
return me.cache[p];
}
if (
me.permission.find(function (perm) {
return perm === '*:*';
})
) {
if (option.debugger) {
console.info('find *:* true');
}
me.allPermitted = true;
return true;
}
let pCA = [],
tmp;
let permitted = false;
pCA.push(p);
// jsecalias - no implementation yet
_.each(
[0, 1],
function (__i) {
if (__i) {
// do nothing
}
_.each(me.jsecalias, function (alias) {
let isAlias = alias.alias.find(function (a) {
return a == p;
});
if (isAlias && alias.name == 'user:basic') {
if (option.debugger) {
console.info('user:basic true');
}
permitted = true;
return false; //break each
}
if (isAlias) {
if (option.debugger) {
console.info('isAlias true');
}
pCA.push(alias.name);
}
});
if (permitted) {
if (option.debugger) {
console.info('permitted return true, true');
}
return true; // break each
}
},
this,
);
// if not permitted in basic user permission, check all permissions assigned to the user
if (!permitted) {
if (option.debugger) {
console.info('!permitted true');
}
// wildcard checking
if (
me.permission.find(function (perm) {
let c = p.split(/:/)[0];
let ca = me.getCA(perm);
if (c === ca?.controller && ca?.action === '*') {
return true;
}
})
) {
if (option.debugger) {
console.info('this is wilcard true');
}
permitted = true;
}
//view
tmp = _.clone(pCA);
_.each(
pCA,
function (act) {
let ca = me.getCA(act);
if (/^list|^view|^show|getjson$|listjson$|^get|^check|^trackback$/.test(ca.action)) {
if (option.debugger) {
console.info('this is view true');
}
tmp.push(`${ca.controller}:view`);
}
},
this,
);
pCA = _.clone(tmp);
// edit
tmp = _.clone(pCA);
_.each(
pCA,
function (act) {
let ca = me.getCA(act);
if (/^view$|^edit|^save|^update|^create|savejson$|updatejson$/.test(ca.action)) {
if (option.debugger) {
console.info('this is edit true');
}
tmp.push(`${ca.controller}:edit`);
}
},
this,
);
pCA = _.clone(tmp);
// admin
tmp = _.clone(pCA);
_.each(
pCA,
function (act) {
let ca = me.getCA(act);
if (/^edit$|^delete|deletejson$/.test(ca.action)) {
if (option.debugger) {
console.info('this is admin true');
}
tmp.push(`${ca.controller}:admin`);
}
},
this,
);
pCA = _.clone(tmp);
pCA = _.uniq(pCA);
_.each(
pCA,
function (ca) {
if (
me.permission.find(function (p) {
return p === ca;
})
) {
if (option.debugger) {
console.info('p === ca true');
}
permitted = true;
}
if (permitted) {
if (option.debugger) {
console.info('permitted return false, true');
}
return false; // break each
}
},
this,
);
}
me.cache[p] = permitted;
if (option.debugger) {
console.info('me.cache', me.cache);
console.info('me.cache[p]', me.cache[p]);
console.info('p--->', p);
console.info('permitted', permitted);
}
return permitted;
},
};
// init permission set
APP_USER.setPermission();
export default APP_USER;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment