Yii 1.1: Console Based CAuthManager Helper

1 follower

What is For

This behavior enable you to command the RBAC via console. This avoids you to install a entire rbac graphic toolkit to set up some rules in the rbac, maybe you are running inside a ssh console.

Let start by supposing you currently have a "foo" console command application, as you may already know the console based applications resides in the "protected/commands" directory and each class under this directory must extends from CConsoleCommand, by having this class: "class FooCommand extends CConsoleCommand { ... }". Read more about CConsoleCommand Applications in the Yii Framework documentation.

Command Line Usage

This is a sample command line, it creates a operation in your RBAC system either implemented by CDbAuthManager, CPhpAuthManager or other compatible with CAuthManager.

  cd /your-app-path/protected
  #display a help screen
  ./yiic foo rbac   
  #create a single operation
  ./yiic foo rbac --c="create operation someopr"
  #create a task (or role)
  ./yiic foo rbac --c="create task sometask"
  #make the operation to be inside the task
  ./yiic foo rbac --c="addchild sometask someopr"
  #finally assign the task to a speficied user
  ./yiic foo rbac --c="assign sometask admin"
  #test if the user admin has access to the operation
  ./yiic foo rbac --c="check someopr admin"

How to create a Batch file for better usability:

As i mention before the original yii-based command line usage is not appropiated for this kind of task:

   ./yiic foo rbac --c="list operation"

In order to help you when using the command line, i suggest you to write a batch file:

  $yourshell cd /yourapp/protected 
  $yourshell touch rbac  #create a empty file.
  $yourshell chmod +x rbac  #assign execution privilegies
  $yourshell echo "./yiic foo rbac --c=\"$1 $2 $3 $4\"" >> rbac

As result, you can do it in this way:

  $yourshell cd /yourapp/protected 
  $yourshell ./rbac list operation
  $yourshell ./rbac query somerole
  $yourshell ./rbac create operation someoper
  ...

How to Setup

The following steps will enable you to have basic console including a behavior designed to command your currently installed rbac feature. Read more about install a CAuthManager based authentication manager.

Step1: Configure a CConsoleCommand

Define a behavior in your current CConsoleCommand application, the behavior class should point to the newly created class speficied in the step2. I will start by supposing you have a "Foo" console command defined in:

  /path-to-your-app/protected/commands/FooCommand.php

Then, make a reference to the behavior and create a wrapper action.

<?php
    class FooCommand extends CConsoleCommand {
        public function behaviors(){
            return array(
                'rbac'=>array(
                    'class'=>'application.components.ConsoleAuthManager',
                ),
            );  
        }
        public function actionRbac($c=""){ // <--The wrapper action
            $this->rbac->run($c);   
        }
    }

Step2: Define the Behavior Class

Copy the following class body into this file:

  protected/components/ConsoleAuthManager.php
<?php
/**
 * ConsoleAuthManager
    Enable a command line based wrapper for CDbAuthManager,
 
    <?php
    class FooCommand extends CConsoleCommand {
        public function behaviors(){
            return array(
                'rbac'=>array(
                    'class'=>'application.components.ConsoleAuthManager',
                ),
            );  
        }
        public function actionRbac($c=""){
            $this->rbac->run($c);   
        }
    }
 
    usage:
 
        ./yiic foo rbac --c="some command"
 * 
 * @uses CBehavior
 * @author Cristian Salazar H. <christiansalazarh@gmail.com> @salazarchris74 
 * @license FreeBSD {@link http://www.freebsd.org/copyright/freebsd-license.html}
 */
class ConsoleAuthManager extends CBehavior {
    private $_lazyAuth;
 
    protected function getAuthManager(){
        // way 1: you may want to return the auth manager defined in
        // your config/main.php:
        // return Yii::app()->authManager;
 
        // way2: return a new one and remember to initialize:
        if(null == $this->_lazyAuth){
            $this->_lazyAuth = new CDbAuthManager();
            $this->_lazyAuth->init();
        }
        return $this->_lazyAuth;
    }
 
    public function run($c=""){
        if(preg_match_all("/([a-z\-\_0-9]+)/is",$c,$m)){
            $a = isset($m[0][0]) ? $m[0][0] : "";
            $b = isset($m[0][1]) ? $m[0][1] : "";
            $c = isset($m[0][2]) ? $m[0][2] : "";
            $this->rbac($this->getAuthManager(), $a,$b,$c);
        }else{
            printf("usage: ./yiic rbac --c=\"command\"\n");
            printf("command is:\n");
            printf("\tcreate operation|task|role itemname\n");
            printf("\tlist operation|task|role\n");
            printf("\tquery authitemname\n");
            printf("\taddchild parent child\n");
            printf("\tremchild parent child\n");
            printf("\tremove authitem\n");
            printf("\tassign authitem username\n");
            printf("\tassigns username\n");
            printf("\trevoke authitem username\n");
            printf("\tcheck authitem username\n");
            printf("\t\n");
        }
    }
    private function rbac($auth, $a, $b='', $c=''){
        printf("(%s,%s,%s)\n",$a,$b,$c);
        if("create"==$a){
            if("operation"==$b) $item = $auth->createOperation($c);
            if("task"==$b) $item = $auth->createTask($c);
            if("role"==$b) $item = $auth->createRole($c);
        }
        if("list"==$a){
            $items = array();
            if("operation"==$b) $items = $auth->getOperations();
            if("task"==$b) $items = $auth->getTasks();
            if("role"==$b) $items = $auth->getRoles();
            foreach($items as $item=>$obj)
                printf("%s\t%s\n",$this->_getType($obj),$item);
        }
        if("query"==$a){
            $item = $auth->getAuthItem($b);
            if(is_object($item)){
                printf("%s\t%s\n",$this->_getType($item),$item->name);
                foreach($item->getChildren() as $citem)
                    printf("\t%s\t%s\n",$this->_getType($citem),$citem->name);
            }else
            printf("invalid authitem name\n");
        }
        if("addchild"==$a){
            $item_1 = $auth->getAuthItem($b);
            $item_1->addChild($c);
            printf("OK\n");
        }
        if("remchild"==$a){
            $item_1 = $auth->getAuthItem($b);
            $item_1->removeChild($c);
            printf("OK\n");
        }
        if("remove"==$a){
            $auth->removeAuthItem($b);
            printf("OK\n");
        }
        if("assign"==$a){
            $item = $auth->getAuthItem($b);
            if(is_object($item)){
                printf("assign: %s\t%s to: %s\t",
                    $this->_getType($item),$item->name, $c);
                if($auth->assign($item->name, $c))
                    printf("[OK]\n");
            }else
            die("invalid auth item\n");
        }
        if("revoke"==$a){
            $item = $auth->getAuthItem($b);
            if(is_object($item)){
                printf("revoke: %s\t%s to: %s\t",
                    $this->_getType($item),$item->name, $c);
                if($auth->revoke($item->name, $c))
                    printf("[OK]\n");
            }else
            die("invalid auth item\n");
        }
        if("assigns"==$a){
            $list = $auth->getAuthAssignments($b);
            if($list){
                foreach($list as $aa){
                    $item = $auth->getAuthItem($aa->itemName);
                    printf("%s\t%s\n",$this->_getType($item),$item->name);
                }
            }
        }
        if("check"==$a){
            $item = $auth->getAuthItem($b);
            if(is_object($item)){
                printf("check: %s\t%s to: %s\t%s\n",
                    $this->_getType($item),$item->name, $c,
                    $auth->checkAccess($item->name, $c) ? "ALLOWED" : "DENIED");
            }else
            die("invalid auth item\n");
        }
    }
    private function _getType($obj){
        if(0 == $obj->type) return "OPER";
        if(1 == $obj->type) return "TASK";
        if(2 == $obj->type) return "ROLE";
        return "????";
    }
}

Total 1 comment

#19141 report it
bluyell at 2015/03/28 09:51pm
EN ESPAÑOL.

para la comunidad en español, esta Behavior permite usar el RBAC basado (estandar) en CAuthManager bajo linea de comando mediante una aplicacion de comandos Yii basada de CConsoleCommand.

Es útil en el sentido de que con solo usar esta linea de comandos puedes administrar el RBAC sin necesidad de recurrir a herramientas visuales basadas en HTML (como el modulo Cruge o la extension Rights).

Primero debes saber usar CConsoleCommand.

Leave a comment

Please to leave your comment.

Write new article