File: //var/dev/farhangmoaser/web/models/userAccess.js
"use strict";
var md5 = require('md5');
var path = require('path');
var db = require(path.join(BASEDIR, 'connectors/mysql'));
var redis = require(path.join(BASEDIR, 'connectors/redis.js'));
var redclient;
redis.connect(function(client) {
redclient = client;
});
var actions = [];
class UserAccessModel {
/**
* Constructor
* @param {object} conn db connection from db pool.
* @param {Object} data values for table fields.
* At least on of `title` or `id` must be set.
*/
constructor(data) {
this.data = data;
}
field(key, value) {
if(arguments.length==0) return;
if(arguments.length==1)
return this.data[key];
if(value===undefined)
delete this.data[key];
else
this.data[key] = value;
}
fields(){
return this.data;
}
static fail(conn, reject, err){
if(conn) conn.release();
reject(err);
};
save() {
var self = this;
return new Promise(function(resolve, reject){
if(!self.data.hasOwnProperty('action'))
return reject('action is required.');
if(!self.data.hasOwnProperty('role'))
return reject('role is required.');
db.getConnection(function(err, conn){
conn.release();
if(err) return reject(err.message);
conn.query(`INSERT INTO user_role_access SET ?`, {role: self.data.role, action: self.data.action}, function(err, result){
if(err) return reject(err.message);
self.data.id = result.insertId;
redclient.set('permit|'+self.data.role+'|'+self.data.action, true, function(){
resolve(self);
});
});
});
});
}
remove() {
var self = this;
return new Promise(function(resolve, reject){
if(!self.data.hasOwnProperty('action'))
return reject('action is required.');
if(!self.data.hasOwnProperty('role'))
return reject('role is required.');
db.getConnection(function(err, conn){
conn.release();
if(err) return reject(err.message);
conn.query(`DELETE FROM user_role_access WHERE !!`, {role: self.data.role, action: self.data.action}, function(err, result){
if(err) return reject(err.message);
self.data.id = result.insertId;
redclient.del('permit|'+self.data.role+'|'+self.data.action, function(){
resolve(self);
});
});
});
});
}
static list(action, role) {
return new Promise(function(resolve, reject){
db.getConnection(function(err, conn){
if(err) return UserAccessModel.fail(conn, reject, err.message);
var query = {};
if(action) query.action = action;
if(role) query.role = role;
var where = '';
if(action || role) where = 'WHERE !!';
conn.query(`SELECT action,role FROM user_role_access ${where} GROUP BY action,role`, query, function(err, rows, fields){
if (err) return UserAccessModel.fail(conn, reject, err.message);
resolve(rows);
});
});
});
}
static register(action, desc) {
let newaction = true;
actions.map(function(elem, index){
if (elem.id == action)
newaction = false;
});
if(newaction)
actions.push({id: action, desc: desc});
}
static listActions() {
return actions;
}
static check(action, role){
return new Promise(function(resolve, reject){
redclient.get('permit|'+role+'|'+action, function(err, value){
if(err) UserAccessModel.fail(conn, reject, err.message);
resolve(value=='true');
});
});
}
static rebuild(){
return new Promise(function(resolve, reject){
db.getConnection(function(err, conn){
if(err) return UserAccessModel.fail(conn, reject, err.message);
var listRoles = function(callback){
conn.query(`SELECT id FROM user_role`, function(err, rows, fields){
if(err) return UserAccessModel.fail(conn, reject, err.message);
callback(rows);
});
};
var listAccessRules = function(callback) {
conn.query(`SELECT action,role FROM user_role_access GROUP BY action,role`, function(err, rows, fields){
if(err) return UserAccessModel.fail(conn, reject, err.message);
callback(rows);
});
};
var setKeys = function(keyList, callback){
var setNext = function() {
if(keyList.length) {
let key = keyList.pop();
redclient.set(key, true, setNext);
}
else callback();
};
setNext();
};
var deleteKeys = function(keyList, callback){
var deleteNext = function() {
if(keyList.length) {
let key = keyList.pop();
redclient.del(key, deleteNext);
}
else callback();
};
deleteNext();
};
listRoles(function(roles){
var keyList = [];
for(let ax in actions)
for(let rx in roles)
keyList.push('permit|'+roles[rx].id+'|'+actions[ax].id);
deleteKeys(keyList, function(){
listAccessRules(function(rules){
keyList = [];
for(let i in rules)
keyList.push('permit|'+rules[i].role+'|'+rules[i].action);
setKeys(keyList, function(){
resolve();
});
});
});
});
});
});
}
}
module.exports = UserAccessModel;