Created
June 30, 2022 21:03
-
-
Save doraemonxxx/c53e92dd8d059d46ba07ffddbf9e444f to your computer and use it in GitHub Desktop.
simple react or vanilla js permission checking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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