如何编码和存储动态权限约束?
我之前已经解决过这个问题,但还没有找到一个简洁的解决方案。
假设我们有一个应用程序,客户可以使用该网站预订课程,管理人员也可以使用后端系统代表客户预订课程。我正在尝试建立一种方法,让人力资源管理员对应用于诸如 can_make_booking
之类的权限的约束进行编码,因为权限不仅仅是一个布尔值,也不应该被硬编码到应用程序中。
目前,只要课程日期是未来至少“n”天标准通知的日期,客户就可以进行预订,他们的预订不超过可用名额的数量,并且至少支付应付金额(如果他们的帐户设置为发票,则为零)。经理可以使用后端应用程序进行预订,只要预约日期是现在之后的任何时间即可。
我设想这样的事情。让人力资源管理员添加如下所示的权限约束:
role permission constraint
-------- ------------ ----------
customer make_booking 1
customer make_booking 2
customer make_booking 3
manager make_booking 5
然后是一个约束表,
constraint property operator value OR_parent
---------- ------------ -------- -------------------------- ---------
1 $course_date >= strtotime("+$notice days") NULL
2 $places_booked <= $places_available NULL
3 $paid >= $total NULL
4 $send_invoice == TRUE 3
5 $course_date >= strtotime("now") NULL
链接客户角色的这些约束将构建类似于以下eval
代码(约束#4与#3配对作为一部分) OR 序列):
if($course_date >= strtotime("+$notice days") && $places_booked <= $places_available && ($paid >= $total || $send_invoice == TRUE)){
// make the booking
}
每个规则可以在每个阶段独立使用,例如 JavaScript 和表单验证,以便在由于某种原因无法进行预订时提供反馈。
但是,假设 HR 想要更改客户的规则,以便他们一次只能预订 3 个位置,并且 $paid
金额必须至少为 $deposit
金额?理想情况下,我希望允许他们动态构建这些 php 规则,而不允许他们访问硬写的代码。可以对属性和值进行清理,以便eval
代码不会出现问题。我不想对每个规则的每个组合进行硬编码,因为在某些情况下,没有明确的方法可以提前猜测人力资源管理员的逻辑。
我查看了 断言 的 Zend_ACL 版本,但是它们似乎没有提供我正在寻找的活力。实现这些动态约束的好方法是什么?其他环境有什么想法吗?谢谢!
Zed Shaw 在 CUSEC 演讲中谈到了为什么“ACL 已死”,对此问题有更深入的了解 - http://vimeo。 com/2723800
I have been through this subject before, but haven't found a neat solution yet.
Say we have an application where customers can book a course using the website, and admin staff can also book courses on customers' behalf using a backend system. I'm trying to establish a way to let HR administrators codify constraints applied to permissions like can_make_booking
, as the permission isn't just a boolean and shouldn't be hard-coded into the application.
At the moment, customers can make a booking as long as the course date is a date at least 'n' days standard notice in the future, they are booking no more than the number of places available and they are paying at least the amount due (or nil if their account is set to invoice). Managers can book using the backend application, as long as the appointment date is any time after now.
I envision something like this. Let HR administrators add permission constraints like the following:
role permission constraint
-------- ------------ ----------
customer make_booking 1
customer make_booking 2
customer make_booking 3
manager make_booking 5
Then a table of constraints,
constraint property operator value OR_parent
---------- ------------ -------- -------------------------- ---------
1 $course_date >= strtotime("+$notice days") NULL
2 $places_booked <= $places_available NULL
3 $paid >= $total NULL
4 $send_invoice == TRUE 3
5 $course_date >= strtotime("now") NULL
Chaining these constraints for the customer role would build something like the following eval
ed code (constraint #4 is paired with #3 as part of an OR sequence):
if($course_date >= strtotime("+$notice days") && $places_booked <= $places_available && ($paid >= $total || $send_invoice == TRUE)){
// make the booking
}
Each rule could be used independently at each stage, such as JavaScript and form validation, to give feedback if the booking can't be made for some reason.
However, say HR want to change the rule for customers so that they are only allowed to book 3 places at a time, and the $paid
amount must be at least the $deposit
amount? Ideally, I'd like to allow them to build these php rules dynamically, without giving them access to the hard-written code. The properties and values could be sanitized so that eval
ing code isn't a problem. I don't want to hard-code every combination of each rule as for some cases, there would be no clear way to guess an HR admin's logic in advance.
I've looked at the Zend_ACL version of assertions, but they don't seem to offer the dynamism I'm looking for. What would be a good way to implement these dynamic constraints? Any thoughts from other environments? Thanks!
Some more insight into the problem from a CUSEC presentation by Zed Shaw talking about why "the ACL is dead" - http://vimeo.com/2723800
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,这是仍然引起大量讨论的领域之一。正如有些人所说[谁? - 认为这是 Atwood 等人,但我忘记了一个链接],一个可以做所有事情的应用程序已经制成;它被称为 C。您想要做的事情几乎与“过于笼统”的区域接壤,尽管我可以看到每次业务规则更改时不需要程序员的价值。
如果我必须实现这样一个系统,我想我会尝试将其分解为多个域。您已经在第二个表中完成了相对较好的工作。只需将其规范化为用于复合业务规则的单独域即可。您创建的业务规则由 1 个或多个约束通过 OR 组合在一起组成。每个约束都需要一个属性,该属性通过针对某个术语的运算符进行限制。术语可能很棘手,因为它们可以是从属性到函数再到复合函数的任何内容。检查您的业务规则以了解您需要什么可能是最简单的方法。例如,从属性、布尔值和诸如“NOW”之类的常见事物开始。
因此,模式本身将由
规则
组成,其中包含多个约束
(明显的好处是您可以将这些规则与任何[用户组/优惠/你想要的时间跨度/其他域)。这些又由属性
组成,它将与运算符
之一进行比较(主要参考表,以便您可以为非程序员输入自定义描述性名称,但是您可以选择在某个时刻在其中输入自定义函数),当然还有术语
之一。最后一部分是最复杂的部分,因此您可能必须使用term_types
中的 ID 对其进行限定,以便您知道是否正在与另一个属性或函数进行比较。您也可以使用 VARCHAR 并使用 PHP 创建字段,考虑到您拥有properties
和/或中的所有选项,这应该不会太困难功能
。这是一个非常开放的系统(并且可能有更好的方法来实现它),因此除非您知道业务规则需要高度的活力,否则可能不值得这样做。
Well, this is one of the areas that still elicit a rather big deal of discussion. As some say[who? - think it was Atwood among other people, but a link escapes me], an application that can do everything has already been made; it's called C. What you want to do borders quite nearly the 'too generalized' area, although I can see the value in not needing a programmer every time a business rule changes.
If I'd have to implement such a system, I guess I'd try and break it down into domains. You've done a relatively good job of it already with the second table. Just normalise that into separate domains that are used to compound business rules. You create a business rule which is comprised of 1 or many constraints OR-ed together. Each constraint needs a property that is restricted with an operator against a term. Terms can be tricky, since they can be anything from a property to a function, to a compound function. It's probably easiest to check your business rules to see what you need. Start with, say, properties, booleans and commonplace things like 'NOW'.
So the schema itself would, for example, be comprised of the
rules
, which contain multipleconstraints
(obvious benefit being that you could tie these to any [user group/offer/timespan/other domain] you want). These are, in turn, comprised ofproperties
, which would compare with one of theoperators
(reference table mostly so you can enter custom descriptive names for non-programmers, but you may choose to enter a custom functions in it at some point) and, of course one of theterms
. The last part being the most complex one, so you'd probably have to qualify it with an ID interm_types
so you'd know whether you're comparing to another property or a function. You can also justVARCHAR
it and create the field with PHP, which shouldn't be too difficult, given how you have all the options inproperties
and/orfunctions
.It's a very open-ended system (and there are probably better ways of going at it), so it's probably not worth doing unless you know that you'll need a high degree of dynamism in business rules.