sfContext::getInstance()->getUser() 在验证器的 createQuery 中不起作用

发布于 2024-11-26 18:47:44 字数 2209 浏览 1 评论 0原文

现在:已解决 - 不再可重现

对于某些特定的应用程序安全性,我在表上有以下 createQuery 函数,即,如果您具有“管理员”凭据或者您是存储在会员代理关系。

class OrganisationTable extends Doctrine_Table
function createQuery($alias = ''){

    if (!$alias){
        $alias = 'o';
    }

    $query = parent::createQuery($alias);
    try {
        $user = sfContext::getInstance()->getUser();
    }catch(Exception $e){
        if ($e->getMessage() == 'The "default" context does not exist.'){
            return $query;
        }else{
            throw $e;
        }
    }

    if ($user->hasCredential('Administrator')){
        //all good

    }else{


        $userId = $user->getAttribute('userId');
        print "<!--testaa ".print_r($user->getCredentials(),1).'-->';
        $query->
        leftJoin("$alias.MembershipDelegate mdelsec")->
        addWhere ("mdelsec.joomla_user_id=$userId");
    }

    return $query;
}

这似乎在所有级别上都工作得很好,但是有一个选择验证器,$user 对象似乎返回为空,

    /**
     * Person form base class.
     *
     */
     ...
    abstract class BasePersonForm extends BaseFormDoctrine
    {
      public function setup()
      {
        $this->setWidgets(array(

    ...
          'organisation_id'                          => new sfWidgetFormDoctrineChoice(array('model' => $this->getRelatedModelName('Organisation'), 'add_empty' => true)),


    class PersonForm extends BasePersonForm{

        public function configure(){

            $this->widgetSchema['organisation_id']->setOption('renderer_class', 'sfWidgetFormDoctrineJQueryAutocompleter');
            $this->widgetSchema['organisation_id']->setOption('renderer_options', array(
            'model' => 'Organisation',
            'url' => NZGBCTools::makeUriJoomlaCompatible(
                    sfContext::getInstance()->getController()->genUrl('organisation/jsonList'))
            ));
            $this->validatorSchema['organisation_id']->setOption('required',false);

是否有其他方法可以在模型中获取用户对象?

这种行级安全性的方法可能不是按惯例的 MVC,但在我看来比在操作中实现相同的安全概念更安全和优越:

  • 它可以与开箱即用的管理生成器模块一起使用,
  • 但要实现这一点要困难得多。忘记在某个地方实现
  • 它有时可能不需要任何凭据,只需要超级管理员访问权限

Now: resolved - no reproducible anymore

For some specific application security, I have the following createQuery function on a table, ie you can only access the table record if you have the "Administrator" credential or if you are the user that is stored in the MembershipDelegate relation.

class OrganisationTable extends Doctrine_Table
function createQuery($alias = ''){

    if (!$alias){
        $alias = 'o';
    }

    $query = parent::createQuery($alias);
    try {
        $user = sfContext::getInstance()->getUser();
    }catch(Exception $e){
        if ($e->getMessage() == 'The "default" context does not exist.'){
            return $query;
        }else{
            throw $e;
        }
    }

    if ($user->hasCredential('Administrator')){
        //all good

    }else{


        $userId = $user->getAttribute('userId');
        print "<!--testaa ".print_r($user->getCredentials(),1).'-->';
        $query->
        leftJoin("$alias.MembershipDelegate mdelsec")->
        addWhere ("mdelsec.joomla_user_id=$userId");
    }

    return $query;
}

This seems to work fine at all levels, however there is a choice validator for which the $user object seems to come back empty

    /**
     * Person form base class.
     *
     */
     ...
    abstract class BasePersonForm extends BaseFormDoctrine
    {
      public function setup()
      {
        $this->setWidgets(array(

    ...
          'organisation_id'                          => new sfWidgetFormDoctrineChoice(array('model' => $this->getRelatedModelName('Organisation'), 'add_empty' => true)),


    class PersonForm extends BasePersonForm{

        public function configure(){

            $this->widgetSchema['organisation_id']->setOption('renderer_class', 'sfWidgetFormDoctrineJQueryAutocompleter');
            $this->widgetSchema['organisation_id']->setOption('renderer_options', array(
            'model' => 'Organisation',
            'url' => NZGBCTools::makeUriJoomlaCompatible(
                    sfContext::getInstance()->getController()->genUrl('organisation/jsonList'))
            ));
            $this->validatorSchema['organisation_id']->setOption('required',false);

is there any other way to get the user object in the model?

This approach to row level security may not be MVC by-the-book, but is IMO safer and superior than implementing the same security concepts in the actions:

  • It can be used with out of the box admin-generator modules
  • It is much harder to forget to implement it somewhere
  • It may at times not require any credentials, only Super Admin access

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拒绝两难 2024-12-03 18:47:44

我不知道在模型中获取会话用户的另一种方法(我认为没有),但如果可以的话,您应该将用户对象传递给模型。

I'm not aware of another way to get the session user in the models (I don't think there is one), but if you're able to, you ought to pass the user object down to the models.

溺深海 2024-12-03 18:47:44

我认为你在这里遗漏了一些东西,你已经混合了很多 MVC 层。我的建议是使模型独立于控制器(将特定于上下文的情况委托给控制器)​​,并且验证也应该由控制器完成(应该有一个接收请求、绑定表单并验证它的操作。在那里你必须定义任何特定于上下文的东西)。这是我要做的:

  1. OrganizationTable 类应该有 2 个方法: createQueryForAdministrator 和 createQueryForMembershipDelegate 。每个人都做它应该做的事情,现在您应该更改控制器(处理它的操作)并执行以下操作:

    公共函数executeAction(sfWebRequest $request)
    {
      if ($this->getUser()->hasCredential('管理员'))
      {
        //调用管理员方法
       } 别的 {
        //调用另一个方法
       }
     }
    
  2. 实例化表单的操作还应该检查用户凭据并执行以下操作:

    If ($user->hasCredential("管理员"))
    {
       sfContext::getInstance()->getConfiguration()->loadHelper("Url");
       $form->getValidator("organization_id")->setOption("url",url_for("@action"));
       [..]
    } 别的 {
       [..]
    }
    

检查 url 帮助器参考,您可以考虑在操作上加载帮助器等,您也可以创建自己的帮助器。希望这有帮助!

编辑:查看这篇关于 sfContext 类和替代方案的文章

I think you are missing something here, you have mixed the MVC layers quite a lot. My suggestion is to make the Model independent from the Controller (delegate to the Controller the Context-specific situations), and validation should be done by the Controller also ( there should be an action that receives the request , binds the form and validates it. There is where you have to definy anithing thats context speficif). Here is what i would do:

  1. The OrganisationTable class should have 2 methods: createQueryForAdministrator , and createQueryForMembershipDelegate . Each one does the things it should do, and now you should change the Controller (the action that handles it) and do something like:

    public function executeAction(sfWebRequest $request)
    {
      if ($this->getUser()->hasCredential('administrator'))
      {
        //call the administrator method
       } else {
        //call the other method
       }
     }
    
  2. The action that instances the Form should also check the user credentials and do something like:

    If ($user->hasCredential("administrator"))
    {
       sfContext::getInstance()->getConfiguration()->loadHelper("Url");
       $form->getValidator("organization_id")->setOption("url",url_for("@action"));
       [..]
    } else {
       [..]
    }
    

Check the url helper reference, you can do thinks like loading helpers on actions etc and you could also create your own helpers too. Hope this helps!

EDITED: Check this post about sfContext class and alternatives

失退 2024-12-03 18:47:44

现在看来,这个问题是一个侥幸,因为在修复有关用户身份验证的其他问题后,我无法重现该问题。

It now appears that this question was a fluke as I can't reproduce the problem after fixing other issues around the user authentication.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文