DataMapper ORM中的深层访问控制

时间:2014-01-18 10:26:04

标签: orm codeigniter-2 codeigniter-datamapper

简介

我目前正在我的DataMapper ORM安装中构建一个访问控制系统(使用CodeIgniter 2. *)。我最初注入了用户权限(Root / Anonymous图层)也能正常工作。当用户登录DataMapper时,系统中完成的调用将自动标记为用户拥有的Userrights。

所以直到这一点它完美无缺,但现在我有点陷入困境。问题是我需要一些方法来捕获和过滤每个方法调用实例化的对象。

我有两个特殊的电话,所以我也可以禁用Userrights-检查。这在我想要登录用户并需要进行初步检查的确切时刻特别方便;

DataMapper::disable_userrights();

$this->_user = new User($this->session->userdata('_user_id'));
$this->_userrights = ($this->_user ? $this->_user->userrights(TRUE) : NULL);

DataMapper::enable_userrights();

以上确保我可以执行初始User(及其Userrights)注入。在DataMapper库中,我使用$CI =& get_instance();来访问我使用的_全局变量。我正在构建的这一部分中的一般规则是$this->_保留用于总是被加载的“全局”系统(或者有时可以是NULL / FALSE),因此我可以轻松访问每个上面几乎总是需要的信息。页/呼叫。

详情

好的,所以我的登录用户上面的图片在Create/Read/Update实体上有Userrights:User。所以现在如果我称之为简单:

$test = new User();
$test->get_where('name', 'Allendar');

DataMapper实例中的$_rights数组将知道当前登录的用户是否可以在“this”实例上执行某些任务;

protected $_rights = array(
    'Create' => TRUE,
    'Read' => TRUE,
    'Update' => TRUE,
    'Delete' => FALSE,
);

问题

现在出现了我的问题。我想通过在执行的每个操作上验证这些Userrights来控制它们。我有以下想法;

  1. 超级冗余;创建一个全局验证方法,该方法在DataMapper类中的每个其他方法的开头执行。
    • 问题1:我必须使用相同的调用
    • 向整个DataMapper类发送垃圾邮件
    • 问题2:我无法控制DataMapper扩展方法
    • 问题3:如何检测关系包含?它们也应该得到验证
  2. 对某些Core DataMapper调用的低级绑定,我可以清楚地检测在数据库上执行的操作类型(C/R/U/D)。
  3. 所以我的目标是选项2(和1.) Problem 2),因为它也会解决1.) Problem 2

    问题是DataMapper是如此庞大,并且在它最深的调用级别上辨别实际发生的事情是相当复杂的。此外,看起来所有方法都非常分散,几乎没有相互使用($this->get()通常不会用于最终调用来获取数据集)。

    所以我的目标是:

    • 用户(登录,匿名,Root)生成DataMapper
      • $user_test = new User;
    • 用户希望获得$user-testRead
      • $user_test->get(1);
    • DataMapper将验证在数据库中完成的实际调用
      • 如果它只是SELECT;行
      • 如果不是SELECT(或者联系到其他模型的用户无权访问那些/那些模型,它将失败,并显示明确的错误消息)
      • IF JOINed Models也验证;行
    • 返回实际的实例;
      • 如果确定:继续DataMapper的正常工作流程
      • 如果不正常:通知用户并返回该模型的正常空DataMapper实例

    此外,对于这个系统,我想我需要为raw_sql(等)SQL调用添加一些自定义,这样我就必须手动注入与该SQL语句相关的权限,或者仅允许{{ 1}}用户做这些事情。

    小结

    我很好奇是否有人在DataMapper中尝试过类似的东西,或者有一些提示我如何在DataMapper中使用/拦截那些最低级别的调用。

    如果我可以在最深层次的DataMapper的实际最终查询调用上获得一些许可,我自己也可能会有很长的路要走。

1 个答案:

答案 0 :(得分:2)

我建议不要在Datamapper本身中这样做(主要是由于代码的复杂性,正如您已经注意到的那样)。

相反,使用基本模型,并扩展Datamapper。然后将代码添加到ACL检查所需的基本模型中,然后重载需要ACL检查的每个Datamapper方法。让它调用您的ACL,处理拒绝访问,如果授予访问权限,只需返回parent::method();的结果。

您的应用程序模型应该扩展此基本模型,而不是扩展Datamapper,因此它们将继承ACL功能。