是否可以以及如何根据角色过滤数据?
例如,我有一个实体Customer和Salesrep的应用程序。每个客户只分配一个Salesrep。我需要一个具有角色"销售"的Salesrep。只查看/编辑分配给她的客户,但她的老板(有角色"主管")列出但不编辑分配给他的一名员工的所有客户。
在SQL中,我会为每个查询添加WHERE role="sales" AND employee.name=user.name OR role="supervisor" AND employee.group=user.group
。
答案 0 :(得分:1)
首先,您可以定义sales
角色以具有读/写权限(请参阅/编辑),并将角色supervisor
定义为具有正确读取(不写入)。
话虽如此,答案是否定的,您不能仅使用角色过滤客户列表。角色仅为您提供对实体的基本CRUD操作控制。
为此,您需要在客户实体的路线上使用一些自定义开发
控制器/customer/datalist
。
默认情况下,此路线如下所示:
router.post('/datalist', block_access.isLoggedIn, block_access.actionAccessMiddleware("customer", "read"), function(req, res) {
filterDataTable("E_customer", req.body).then(function(data) {
res.send(data).end();
}).catch(function(err) {
logger.debug(err);
res.end();
});
});
从客户实体的列表视图中使用ajax调用它。
filterDataTable
函数处理数据列表的过滤/排序/分页。它需要两个可选参数:speInclude
和speWhere
,允许您自定义将生成的续集ORM查询(请参阅Sequelize where和Sequelize include)。
根据您的关系/外键的定义方式,您可以选择这些解决方案。您可以根据自己的情况使用最好的一个:
使用speWhere
参数:
router.post('/datalist', block_access.isLoggedIn, block_access.actionAccessMiddleware("customer", "read"), function(req, res) {
var user = req.session.passport.user;
var speWhere;
if (user.r_role.f_label == 'sales')
speWhere = {f_id_salesrep: user.id};
filterDataTable("E_customer", req.body, null, speWhere).then(function(data) {
res.send(data).end();
}).catch(function(err) {
logger.debug(err);
res.end();
});
});
使用speWhere
参数,只会从数据库中提取与salesrep关联的客户。
使用speInclude
参数:
您可以更改执行查询的实体(salesrep
),并要求包含与此实体关联的每个客户。
router.post('/datalist', block_access.isLoggedIn, block_access.actionAccessMiddleware("customer", "read"), function(req, res) {
var user = req.session.passport.user;
var speInclude;var targetEntity = 'E_customer';
if (user.r_role.f_label == 'sales') {
targetEntity = 'E_salesrep';
speInclude = [
model: models.E_customer,
as: 'r_customer'
];
}
filterDataTable(targetEntity, req.body, speInclude).then(function(data) {
if (speInclude)
data.data = data.data.r_customer; // Set the salesrep's customers to the returned data
res.send(data).end();
}).catch(function(err) {
logger.debug(err);
res.end();
});
});
使用此解决方案,您将查询salesrep模型而不是客户模型,并获得与salesrep相关联的客户数组。
过滤查询结果
router.post('/datalist', block_access.isLoggedIn, block_access.actionAccessMiddleware("customer", "read"), function(req, res) {
filterDataTable("E_customer", req.body).then(function(data) {
var filteredCustomers = [];
var user = req.session.passport.user;
for (var i = 0; i < data.data.length; i++)
if (data.data[i].f_id_salesrep == user.id)
filteredCustomers.push(data.data[i]);
data.data = filteredCustomers;
res.send(data).end();
}).catch(function(err) {
logger.debug(err);
res.end();
});
});
此方法应仅用作最后一个解决方案,因为您需要重新定义分页。
这些代码片段尚未经过测试,可能需要一些调整。它们仅显示可能的内容以及如何继续。