142 lines
5.5 KiB
JavaScript
142 lines
5.5 KiB
JavaScript
export class AccesRights {
|
|
|
|
constructor(config, debug){
|
|
this.debug = debug
|
|
this.config = config
|
|
this.rights = config.accessRights
|
|
}
|
|
|
|
refreshAccessRights(config){
|
|
this.rights = config.accessRights
|
|
}
|
|
|
|
expandPattern(pattern, uid, cnxId=null) {
|
|
if(/\[CUID\]/.test(pattern) && !cnxId) return(null)
|
|
let item = pattern.replace(/\[UID\]/g, uid)
|
|
if(cnxId) item = item.replace(/\[CUID\]/g, cnxId)
|
|
return(item)
|
|
}
|
|
|
|
expandPatterns(patterns, uid, cnxId=null) {
|
|
return(patterns.map(item => this.expandPattern(item, uid, cnxId)).filter(item => item != null))
|
|
}
|
|
|
|
mustSubscribe(uid, roles, cnxId=null) {
|
|
if(roles.indexOf('*')<0) roles.push('*')
|
|
let chans = []
|
|
for(let myRole of roles){
|
|
for(let rightBlock of this.rights) {
|
|
if(!rightBlock.mustSubscribe) continue
|
|
if((rightBlock.roles=='*') || (rightBlock.roles.indexOf(myRole)>-1)) {
|
|
chans = this.merge(chans, this.expandPatterns(rightBlock.mustSubscribe, uid, cnxId))
|
|
}
|
|
}
|
|
}
|
|
return(chans)
|
|
}
|
|
|
|
isMandatory(uid, roles, chan, cnxId=null){
|
|
return(this.mustSubscribe(uid, roles, cnxId).filter(this.chanMatch.bind(this, chan)).length>0)
|
|
}
|
|
|
|
canSubscribe(uid, roles, myChan, cnxId=null) {
|
|
if(roles.indexOf('*')<0) roles.push('*')
|
|
for(let myRole of roles){
|
|
for(let rightBlock of this.rights) {
|
|
if(!rightBlock.canSubscribe) continue
|
|
if((rightBlock.roles=='*') || (rightBlock.roles.indexOf(myRole)>-1)) {
|
|
let canSubList = this.expandPatterns(rightBlock.canSubscribe, uid, cnxId)
|
|
if(canSubList.find(this.chanMatch.bind(this, myChan))) return(true)
|
|
}
|
|
}
|
|
}
|
|
//if(this.debug) console.log(`Roles : ${roles} cannot subscribe on ${myChan}`)
|
|
return(false)
|
|
}
|
|
|
|
canPublish(uid, roles, myChan, cnxId=null) {
|
|
if(roles.indexOf('*')<0) roles.push('*')
|
|
for(let myRole of roles){
|
|
for(let rightBlock of this.rights) {
|
|
if(!rightBlock.canPublish) continue
|
|
if((rightBlock.roles=='*') || (rightBlock.roles.indexOf(myRole)>-1)) {
|
|
let canPubList = this.expandPatterns(rightBlock.canPublish, uid, cnxId)
|
|
if(canPubList.find(this.chanMatch.bind(this, myChan))) return(true)
|
|
}
|
|
}
|
|
}
|
|
//if(this.debug) console.log(`Roles : ${roles} cannot publish on ${myChan}`)
|
|
return(false)
|
|
}
|
|
|
|
canSet(uid, roles, myKey, cnxId=null){
|
|
if(roles.indexOf('*')<0) roles.push('*')
|
|
for(let myRole of roles){
|
|
for(let rightBlock of this.rights) {
|
|
if(!rightBlock.canSet) continue
|
|
if((rightBlock.roles=='*') || (rightBlock.roles.indexOf(myRole)>-1)) {
|
|
let canSetList = this.expandPatterns(rightBlock.canSet, uid, cnxId)
|
|
if(canSetList.find(this.chanMatch.bind(this, myKey))) return(true)
|
|
}
|
|
}
|
|
}
|
|
//if(this.debug) console.log(`Roles : ${roles} cannot set ${myKey}`)
|
|
return(false)
|
|
}
|
|
|
|
canGet(uid, roles, myKey, cnxId=null){
|
|
if(roles.indexOf('*')<0) roles.push('*')
|
|
for(let myRole of roles){
|
|
for(let rightBlock of this.rights) {
|
|
if(!rightBlock.canGet) continue
|
|
if((rightBlock.roles=='*') || (rightBlock.roles.indexOf(myRole)>-1)) {
|
|
let canGetList = this.expandPatterns(rightBlock.canGet, uid, cnxId)
|
|
if(canGetList.find(this.chanMatch.bind(this, myKey))) return(true)
|
|
}
|
|
}
|
|
}
|
|
//if(this.debug) console.log(`Roles : ${roles} cannot get ${myKey}`)
|
|
return(false)
|
|
}
|
|
|
|
canDo(roles, action, uid=null){
|
|
if(roles.indexOf('*')<0) roles.push('*')
|
|
for(let myRole of roles){
|
|
for(let rightBlock of this.rights) {
|
|
if(!rightBlock.canDo) continue
|
|
if((rightBlock.roles=='*') || (rightBlock.roles.indexOf(myRole)>-1)) {
|
|
if(rightBlock.canDo.indexOf(action)>-1) {
|
|
if((rightBlock.uuids) && Array.isArray((rightBlock.uuids))) {
|
|
// !!! Separate condition so if rightBlock.uuids but not uid in it, we don't give access !
|
|
if(rightBlock.uuids.includes(uid)) return(true) // null should never be in config uuids => old style calls are safe
|
|
} else { // no uuid block => role is sufficient to give access
|
|
return(true)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Anti-shoot-your-foot
|
|
if((action=='reloadAccessRights') && (roles.includes('EIC_Dev'))) {
|
|
console.error('Prevented you from shooting your foot ! \nPlease keep least EIC_Dev in reload access rights !')
|
|
return(true)
|
|
}
|
|
|
|
//if(this.debug) console.log(`Roles : ${roles} cannot do ${action}`)
|
|
return(false)
|
|
}
|
|
|
|
chanMatch(myChan, configChan) {
|
|
if((!myChan) || (typeof(myChan)!='string')) return(false)
|
|
let re = new RegExp('^'+configChan.replace(/\*/g,'(.+)')+'$','g')
|
|
return(myChan.match(re)!=null)
|
|
}
|
|
|
|
merge(x, y) {
|
|
let tmp = x
|
|
for(let yitem of y) if(tmp.indexOf(yitem)<0) tmp.push(yitem)
|
|
return(tmp)
|
|
}
|
|
|
|
} |