mirror of
https://github.com/thinkjs/thinkjs.git
synced 2026-01-25 14:42:47 +00:00
193 lines
5.6 KiB
JavaScript
193 lines
5.6 KiB
JavaScript
/**
|
||
* 权限认证
|
||
* 需要创建如下的数据表
|
||
|
||
DROP TABLE IF EXISTS `think_auth_role`;
|
||
CREATE TABLE `think_auth_role` (
|
||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||
`desc` varchar(255) NOT NULL DEFAULT '',
|
||
`status` tinyint(11) NOT NULL DEFAULT '1',
|
||
`rule_ids` varchar(255) DEFAULT '' COMMENT '含有的权限列表',
|
||
PRIMARY KEY (`id`)
|
||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||
|
||
DROP TABLE IF EXISTS `think_auth_rule`;
|
||
CREATE TABLE `think_auth_rule` (
|
||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '名称',
|
||
`desc` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
|
||
`pid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '父级id',
|
||
`status` tinyint(11) NOT NULL DEFAULT '1',
|
||
`condition` varchar(255) DEFAULT '' COMMENT '附加条件',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `name` (`name`),
|
||
KEY `status` (`status`)
|
||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||
|
||
DROP TABLE IF EXISTS `think_auth_user_role`;
|
||
CREATE TABLE `think_auth_user_role` (
|
||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||
`user_id` int(11) NOT NULL,
|
||
`role_id` int(11) NOT NULL,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `user_role` (`user_id`,`role_id`)
|
||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||
|
||
* @type {[type]}
|
||
*/
|
||
module.exports = Class({
|
||
/**
|
||
* 初始化
|
||
* @param int userId 当前登录用户的id
|
||
* @param obj config 配置项
|
||
* @return this
|
||
*/
|
||
init: function(userId, config){
|
||
'use strict';
|
||
if (isObject(userId)) {
|
||
config = userId;
|
||
userId = config.id;
|
||
}
|
||
//当前检测的用户id
|
||
this.userId = userId;
|
||
//这里不能使用默认的深度复制,因为http对象包含了一些循环引用的对象
|
||
this.config = extend(false, {
|
||
type: 1, //认证方式,1为实时认证,2为SESSION认证。如果检测非当前登录用户,则不能使用SESSION认证。
|
||
http: null, //如果type为2,那么必须传入http对象
|
||
user: 'user', //用户信息表
|
||
role: 'auth_role', //角色表
|
||
rule: 'auth_rule', //规则表
|
||
user_role: 'auth_user_role', //用户-角色关系表
|
||
userInfo: null //用户详细信息,用户condition判断。如果没有自动从User表里查询
|
||
}, config);
|
||
},
|
||
/**
|
||
* 检测权限,可以一次检测多个权限
|
||
* @param {[type]} name [description]
|
||
* @param {[type]} and [description]
|
||
* @return {[type]} [description]
|
||
*/
|
||
check: function(name, and){
|
||
'use strict';
|
||
if (isString(name)) {
|
||
name = name.split(',');
|
||
}
|
||
return this.getAuthList().then(function(authList){
|
||
if (name.length === 1) {
|
||
return authList.indexOf(name[0]) > -1;
|
||
}
|
||
var logic = and ? 'every' : 'some';
|
||
return name[logic](function(item){
|
||
return authList.indexOf(item) > -1;
|
||
})
|
||
});
|
||
},
|
||
/**
|
||
* 获取权限列表
|
||
* @return {[type]} [description]
|
||
*/
|
||
getAuthList: function(){
|
||
'use strict';
|
||
var authPromise;
|
||
if (this.config.type === 1) {
|
||
authPromise = this.flushAuthList();
|
||
}else{
|
||
var http = this.config.http;
|
||
var self = this;
|
||
//存在Session里的authList Key
|
||
var key = 'think_auth_list';
|
||
if (!http) {
|
||
return getPromise("config.http can't be null", true);
|
||
}
|
||
thinkRequire('Session').start(http);
|
||
authPromise = http.session.get(key).then(function(data){
|
||
if (!isEmpty(data)) {
|
||
return data;
|
||
}
|
||
return self.flushAuthList().then(function(data){
|
||
http.session.set(key, data);
|
||
return data;
|
||
})
|
||
})
|
||
}
|
||
var userInfoPromise = this.getUserInfo();
|
||
return Promise.all([authPromise, userInfoPromise]).then(function(data){
|
||
var authList = data[0];
|
||
var userInfo = data[1];
|
||
var result = [];
|
||
authList.forEach(function(item){
|
||
if (!item.condition) {
|
||
result.push(item.name);
|
||
}else{
|
||
var condition = item.condition.replace(/\w+/, function(a){
|
||
return 'userInfo.' + a;
|
||
});
|
||
/*jslint evil: true */
|
||
var fn = new Function('userInfo', 'return ' + condition);
|
||
var flag = fn(userInfo);
|
||
if (flag) {
|
||
result.push(item.name);
|
||
}
|
||
}
|
||
})
|
||
return result;
|
||
})
|
||
},
|
||
/**
|
||
* 刷新权限列表,从数据库中拉取
|
||
* @return {[type]} [description]
|
||
*/
|
||
flushAuthList: function(){
|
||
'use strict';
|
||
var self = this;
|
||
return this.getRuleIds().then(function(ids){
|
||
return M().field('name,condition').table(self.config.rule).where({id: ['IN', ids], status: 1}).select();
|
||
});
|
||
},
|
||
/**
|
||
* 获取用户信息
|
||
* @return {[type]} [description]
|
||
*/
|
||
getUserInfo: function(){
|
||
'use strict';
|
||
if (!isEmpty(this.config.userInfo)) {
|
||
return getPromise(this.config.userInfo);
|
||
}
|
||
var self = this;
|
||
return M().table(self.config.user).where({id: this.userId}).find().then(function(data){
|
||
self.config.userInfo = data;
|
||
return data;
|
||
})
|
||
},
|
||
/**
|
||
* 获取用户权限rule id列表
|
||
* @return {[type]} [description]
|
||
*/
|
||
getRuleIds: function(){
|
||
'use strict';
|
||
return this.getRoles().then(function(data){
|
||
var ids = [];
|
||
data.forEach(function(item){
|
||
var ruleIds = (item.rule_ids || '').split(',');
|
||
ids = ids.concat(ruleIds);
|
||
})
|
||
return ids;
|
||
})
|
||
},
|
||
/**
|
||
* 获取用户角色列表
|
||
* @return {[type]} [description]
|
||
*/
|
||
getRoles: function(){
|
||
'use strict';
|
||
var model = M();
|
||
return model.table(this.config.user_role).alias('a').join({
|
||
table: this.config.role,
|
||
as: 'b',
|
||
on: ['role_id', 'id']
|
||
}).where({
|
||
'a.user_id': this.userId,
|
||
'b.status': 1
|
||
}).select();
|
||
}
|
||
}); |