title: Yii's accessRules misconception
body: <p>I'm trying to build a site using Yii, and found myself in a situation which requires some clarifications on access control metaphor in Yii. Specifically, one can override <a href="http://www.yiiframework.com/doc/api/1.1/CController#accessRules-detail" rel="nofollow">accessRules</a> method in <code>CController</code>'s descendant.</p>
  
  <p><strong>Prerequisite:</strong></p>
  
  <p>Here is a code generated by default by Gii, much similar to the <a href="http://www.yiiframework.com/doc/guide/1.1/en/topics.auth" rel="nofollow">documentation</a>:</p>
  
  <pre><code>public function accessRules()
  {
      return array(
          array('allow',  // allow all users to perform 'index' and 'view' actions
              'actions'=&gt;array('index','view'),
              'users'=&gt;array('*'),
          ),
          array('allow', // allow authenticated user to perform 'create' and 'update' actions
              'actions'=&gt;array('create','update'),
              'users'=&gt;array('@'),
          ),
          array('allow', // allow admin user to perform 'admin' and 'delete' actions
              'actions'=&gt;array('admin','delete'),
              'roles'=&gt; array('admin'),
          ),
          array('deny',  // deny all users
              'users'=&gt;array('*'),
          ),
      );
  }
  </code></pre>
  
  <p><strong>The Question:</strong></p>
  
  <p>What is not clear here to me, is -- <em>why we need to define access rules for many different users and groups, and different actions instead of checking rights of only one current user and action?</em> -- here in italics my main question is highlighted, just in case it may not so clear for readers (answer authors).</p>
  
  <p>This code is executed in a context of specific request, for which <strong>a specific <code>controller</code>, a specific <code>action</code>, and a specific <code>user</code> are already known</strong>. If, for example, the user is a guest, I don't see any reason to define rules for "admin" role or authenticated users.</p>
  
  <p><strong>Reasoning:</strong></p>
  
  <p>After some elaboration I came up to the following implementation:</p>
  
  <pre><code>public function accessRules()
  {
      return array(
        array(Yii::app()-&gt;user-&gt;hasRights()?'allow':'deny'),
        );
  }
  </code></pre>
  
  <p>where <code>hasRights</code> is a simple custom method added into a <code>CWebUser</code> descendant:</p>
  
  <pre><code>class WebUser extends CWebUser
  {
    private $ACL = // ACL example
      array('user' =&gt; // controller id
        array('index' =&gt; User::AC_MODERATOR, // action ids
              'view' =&gt; User::AC_MODERATOR,
              'create' =&gt; User::AC_MODERATOR,
              'update' =&gt; User::AC_ADMIN,
              'delete' =&gt; User::AC_ADMIN,
              'admin' =&gt; User::AC_ADMIN),
             // ...
        );
  
    public function hasRights()
    {
      return (Yii::app()-&gt;user-&gt;getState('accessRights') &gt;=
        $this-&gt;ACL[Yii::app()-&gt;controller-&gt;id][Yii::app()-&gt;controller-&gt;action-&gt;id]);
    }
  }
  </code></pre>
  
  <p>As you may see, <code>hasRights</code> uses current user "rights" (read from DB as usual), current controller and action to calculate single boolean <code>true</code> or <code>false</code> value as a decision about access.</p>
  
  <p>What is wrong with this approach? Why Yii does not use something simple like that by default?</p>
  
  <p>The Gii-generated <code>accessRules</code> above do not only look excessive, but also imply that access rules are scattered among many controllers. In my approach a single and compact ACL is used.</p>