Quantcast
Channel: Live News for Yii Framework
Viewing all articles
Browse latest Browse all 3375

[Wiki] Control de Usuarios y Roles (RBAC) - en español

$
0
0

CRUGE

Extensión para el Control de Usuarios y Roles.

Ir al repositorio de Cruge Bitbucket

visita mi blog

Comunidad de Yii Framework en Español

screenshots

Que es Cruge ?

Cruge te permite administrar y controlar de forma muy eficiente y segura a tus usuarios y los roles que ellos deban tener en tu aplicacion.

Cruge tiene una alta Arquitectura OOP, basada en interfaces, lo que ayuda enormemente a usarla sin modificar en lo absoluto su propio core. Si necesitas cambiar de ORDBM, cruge lo permite. Si necesitas extender el funcionamiento de autenticacion para admitir nuevos metodos tambien lo permite mediante la implantacion de filtros de autenticacion, incluso dispones ademas de filtros insertables para controlar el otorgamiento de una sesion a un usuario y finalmente para controlar los registros y actualizaciones de perfil de tus usuarios. Todo eso sin tocar en lo absoluto el core de Cruge.

Cruge es un API, que incluye una interfaz de usuario predeterminada con el objeto que puedas usar el sistema como viene ahorrandote mucho tiempo. Esta interfaz hace uso del API de forma estricta, es decir, no hay "dependencias espaguetti" las cuales son las primeras destructoras de todo software.

La arquitectura que tu usarás en Cruge es asi:

[Tu Aplicacion]--->[Yii::app()->user]           acceso a funciones muy basicas de autenticacion
[Tu Aplicacion]--->[Yii::app()->user->ui]       provee enlaces a funciones de la interfaz
[Tu Aplicacion]--->[Yii::app()->user->um]       provee acceso al control de los usuarios
[Tu Aplicacion]--->[Yii::app()->user->rbac]     provee acceso a las funciones de RBAC

internamente esta arquitectura dentro de Cruge es asi:

[Tu Aplicacion]--->[Cruge]--->[API]---->[Factory]---->[modelos]

esto significa, que aun dentro de Cruge las dependencias son estrictamente organizadas, es decir, no verás en ningun lado que el API vaya a instanciar a un modelo cualquiera, si eso fuera asi estariamos hablando de otra "extension" espaguetti, como aquellas que solo le funcionan a su creador, o que en el mejor de los casos, funcionan...pero manipulandoles el core.

Cruge es una extension en todo lo ancho de la palabra, realmente extiende las funciones basicas de manejo de usuario de Yii Framework, incorporando mas funciones en los paquetes originales.

La interfaz de usuario de Cruge es opcional, con esto quiero decirte que puedes usar Cruge en modo API, para lo cual debes conocer el modelo con detalles, aunque es muy intuitivo y de referencias cortas, para hacerlo entendible.


Instalación

Primero voy a asumir que Cruge ha sido descargado a tu carpeta:

/protected/modules/cruge/

puedes descargar cruge directamente desde un ZIP, o mediante un comando GIT como: git clone [URL DE GIT].

En el archivo de configuración de tu aplicacion (config/main.php) deberas colocar lo siguiente:

1.  dentro de 'import' agregar:
        'application.modules.cruge.components.*',
        'application.modules.cruge.extensions.crugemailer.*',

2.  dentro de 'modules' agregar:
        'cruge'=>array(
            'tableprefix'=>'cruge_',
            'availableAuthMethods'=>array('default'),
            'availableAuthModes'=>array('username','email'),
            'baseUrl'=>'http://coco.com/',

             // NO OLVIDES PONER EN FALSE TRAS INSTALAR
             'debug'=>true,
             'rbacSetupEnabled'=>true,
             'allowUserAlways'=>true,

            // MIENTRAS INSTALAS..PONLO EN: false
            'useEncryptedPassword' => false,    


            // manejo del layout con cruge.
            // 
            'loginLayout'=>'//layouts/main',
            'registrationLayout'=>'//layouts/main',
            'activateAccountLayout'=>'//layouts/main',
            'editProfileLayout'=>'//layouts/main',
            // en la siguiente puedes especificar el valor "ui" o "column2" para que use el layout 
            // de fabrica, es basico pero funcional.  si pones otro valor considera que cruge 
            // requerirá de un portlet para desplegar un menu con las opciones de administrador.
            // 
            'generalUserManagementLayout'=>'//layouts/column2', 
        ),

3.  dentro de 'components' agregar:
        'user'=>array(
            'allowAutoLogin'=>true,
            'class' => 'application.modules.cruge.components.CrugeWebUser',
            'loginUrl' => array('/cruge/ui/login'),
        ),
        'authManager' => array(
            'class' => 'application.modules.cruge.components.CrugeAuthManager',
        ),
        'crugemailer'=>array(
            'class' => 'application.modules.cruge.components.CrugeMailer',
            'mailfrom' => 'email-desde-donde-quieres-enviar-los-mensajes@xxxx.com',
            'subjectprefix' => 'Tu Encabezado del asunto - ',
            'debug' => true,
        ),
        'format' => array(
            'datetimeFormat'=>"d M, Y h:m:s a",
        ),

4.  crea las tablas requeridas en la base de datos de tu aplicacion, usa el script:

    <tuaplicacion>/protected/modules/cruge/data/cruge-data-model.sql

    aqui se va a crear automaticamente un usuario para que puedas comenzar, toma nota:
usuario=admin clave=admin
5.  Configura el menu de tu aplicacion para que incopore a Cruge, para ello 
edita tu archivo: 
    /protected/views/layouts/main.php 
y sustituye el componente CMenu por el que te doy a continuacion. 

    <?php $this->widget('zii.widgets.CMenu',array(
        'items'=>array(
            array('label'=>'Home', 'url'=>array('/site/index')),
            array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')),
            array('label'=>'Contact', 'url'=>array('/site/contact')),
            array('label'=>'Administrar Usuarios'
                , 'url'=>Yii::app()->user->ui->userManagementAdminUrl
                , 'visible'=>!Yii::app()->user->isGuest),
            array('label'=>'Login'
                , 'url'=>Yii::app()->user->ui->loginUrl
                , 'visible'=>Yii::app()->user->isGuest),
            array('label'=>'Logout ('.Yii::app()->user->name.')'
                , 'url'=>Yii::app()->user->ui->logoutUrl
                , 'visible'=>!Yii::app()->user->isGuest),
        ),
    )); ?>

Uso básico de Cruge

Obtener un usuario:

 <?php 
    $usuario = Yii::app()->user->um->loadUser('admin@gmail.com',true);
    echo $usuario->username;

    // true: es para indicar que cargue los valores de los campos personalizados.
    // por defecto es : false.
 ?>

Campos Personalizados:

<?php
    echo "Su nombre es: ";
    echo Yii::app()->user->getField('nombre');

    // en el caso del email use:
    // (esto es porque cruge incopora el metodo getEmail a Yii::app()->user )
    echo "Su email es:";
    echo Yii::app()->user->email;

    // para acceder al objeto usuario (el CrugeStoredUser)
    //
    $usuario = Yii::app()->user->user;

    // para listar todos los campos personalizados del usuario indicado:
    //
    foreach(Yii::app()->user->user->fields as $campo)
        echo "<p>campo: ".$campo->longname." es: ".$campo->fieldvalue;"</p>";

?>

Verificar un permiso de acceso:

    aqui se pretende verificar si el usuario activo tiene asignado el rol 'admin':

    <?php if(Yii::app()->user->checkAccess('admin')){ ... } ?>

Acceder a las variables del sistema:

    <?php if(Yii::app()->user->um->getDefaultSystem()->getn('registerusingcaptcha')==1){...} ?>

Acceder a la Interfaz de Usuario de Cruge:

Puedes invocar al API UI de Cruge para acceder a los enlaces:

    <?php echo Yii::app()->user->ui->getLoginLink('iniciar sesion'); ?>

o simplemente:

    <?php echo Yii::app()->user->ui->loginLink; ?>

La lista de enlaces disponibles es:

<?php echo Yii::app()->user->ui->loginLink; ?>
<?php echo Yii::app()->user->ui->logoutLink; ?>
<?php echo Yii::app()->user->ui->passwordRecoveryLink; ?>
<?php echo Yii::app()->user->ui->userManagementAdminLink; ?>
<?php echo Yii::app()->user->ui->registrationLink; ?>

Personalizando el Layout

Cruge te permite que su interfaz de usuario predeterminada pueda ajustarse a tu sitio web usando lo que en Yii se conoce como Layouts.

Por ejemplo, quieres que el formulario de registro de nuevo usuario se presente en un esquema de diseño distinto al que yii trae por defecto, entonces tu podrias crear un nuevo layout que se ajuste a tus necesidades y luego indicarle a Cruge mediante la configuracion del componente cual seria ese layout a usar cuando un usuario quiera registrarse, asi:

'components'=> array(
    ..otros ajustes aqui...
    'loginLayout'=>'//layouts/bootstrap',
    'registrationLayout'=>'//layouts/bootstrap',
    'activateAccountLayout'=>'//layouts/bootstrap',
    'generalUserManagementLayout'=>'//layouts/bootstrap',
),

Te cuidado especial con "generalUserManagementLayout": este es un layout especial, porque las funciones de administracion de usuarios requieren un Portlet para presentar las opciones administrativas, por defecto Cruge apunta este valor a: "ui", el cual es el nombre de un layout prefabricado que ya trae un Portlet, practicamente idendico al que Yii trae por defecto llamado //layouts/column2.

El Layout para UI de Cruge por defecto es:

tuapp/protected/modules/cruge/views/layouts/ui.php

En este layout (ui.php) hay un Portlet, que será llenado con los items de administracion en linea de Cruge, estos items salen del modulo UI de Cruge, el cual es accesible usando:

Yii::app()->user->ui->adminItems

Usando RBAC

RBAC es el sistema de control de acceso basado en roles (por sus siglas en ingles). Todo el mecanismo RBAC puede ser manejado mediante la interfaz (UI) de Cruge, o mediante su API. Las dos modalidades para usar en este mecanismo son:

  1. Consulta Manual de Permisos. Es basicamente el mismo mecanismo que provee Yii, pero en Cruge se ha ampliado un poco mas. Para usar este mecanismo: en cualquier parte de tu codigo fuente puedes poner lo siguiente:

    <?php if(Yii::app()->user->checkAccess('puede_ver_menu_sistema')) { ...mostar menu sistema... } ?>
  2. Consulta Automatizada segun controller/action. Este mecanismo es muy util, porque permite controlar el acceso a tus controllers/actions de forma totalmente automatizada y controlada mediante la UI de Cruge. Para usar este mecanismo, necesitarás incluir en tu Controller (cualquiera que tu uses y que desees controlar a nivel de permisos) el siguiente codigo:

    <?php ..cuerpo de tu controladora... public function filters() { return array( array('CrugeAccessControlFilter'), ); } ..cuerpo de tu controladora... ?>

Al usar CrugeAccessControlFilter estas permitiendo que Cruge controle el acceso tanto al controller en general como al action especifico.

Ejemplo:

Un usuario cualquiera, incluso un invitado, intenta acceder a la siguiente URL: 

    index.php?r=empleado/vernomina.

pues bien, Cruge verificara dos cosas:

    a) el acceso a la controladora: 'Empleado'.

    b) el acceso al action 'Vernomina'.

lo hara de esta forma:

    a) verifica si el usuario (aun invitado) tiene asignada la operacion: 'controller_empleado'

    b) verifica si el usuario (aun invitado) tiene asignada la operacion: 'action_empleado_vernomina'

si ambas condiciones se cumplen (a y b) entonces tendrá acceso al action.

Si tu quieres denegar el total acceso a un controller simplemente no le asignas al usuario la operacion que tenga el nombre del controller antecedido de la palabra 'controller_'.

Si tu quieres denegar el acceso a un action de un controller simplemente no le asignas al usuario la operacion que tenga el nombre del action: 'action_nombrecontroller_nombreaction'.

Modo de Programacion del RBAC

Para activarlo, en la configuracion de tu aplicacion debes considerar estos dos argumentos:

'rbacSetupEnabled'=>true,

    Permitira que las operaciones se vayan creando (valor true) a medida que vas probando el sistema, de lo
    contrario deberas crear las operaciones a mano. Las operaciones que se crearan automaticamente
    seran: 'controller_nombredetucontroller' y 'action_tucontroller_tuaction'.

'allowUserAlways'=>true,

    Permitira el paso (valor true) al usuario aunque este no tenga permiso. Cuando estás
    en produccion ponlo en 'false' lo que causara que el usuario reciba una excepcion.

Para conocer que operaciones se requieren para un usuario especifico debes poner en tu layout principal la siguiente linea:

<?php 
    echo Yii::app()->user->ui->displayErrorConsole(); 
?>

(no siempre se veran los mensajes de permisos requeridos, para ello usa el log, lee el item a continuacion)

Usando el LOG

Adicionalmente todos los errores de permiso que se generen seran reportados en el log bajo el key 'rbac', para poder visualizar los errores en protected/runtime/application.log deberas configurar tu config/main.php para indicar el key del log:

<?php
    'log'=>array(
        'class'=>'CLogRouter',
        'routes'=>array(
            array(
                'class'=>'CFileLogRoute',
                'levels'=>'error, info, rbac',  // <--- agregar 'rbac'
            ),
            // uncomment the following to show log messages on web pages
            //array('class'=>'CWebLogRoute'),
        ),
    ),
?>

eso causara que en:

    protected/runtime/application.log

se emitan mensajes como estos:

    2012/07/27 15:24:25 [rbac] [application] PERMISO REQUERIDO:
    invitado
    iduser=2
    tipo:operacion
    itemName:action_catalog_imageh

EL usuario Invitado

Cruge hace especial tratamiento al usuario invitado. Para esto CrugeModule contiene un atributo llamado guestUserId , el cual es usado para indicarle al sistema Cruge cual de sus usuarios existentes en la base de datos de usuarios es el invitado.

Por defecto cuando Cruge es instalado desde el script de base de datos (protected/modules/cruge/data), se crean dos usuarios:

insert into `cruge_user`(username, email, password, state) values
 ('admin', 'admin@tucorreo.com','admin',1)
 ,('invitado', 'invitado','nopassword',1)
;

Siendo 'admin' el usuario con ID 1, y siendo 'invitado' el usuario con ID 2. Por esto veras que por defecto en CrugeModule.php ya esta predefinido el atributo guestUserId en 2. No lo cambies a menos que cambies el ID del usuario invitado.

Roles para el usuario Invitado

Si no asignas al usuario invitado a ningun rol entonces no tendrá acceso a ninguna parte. Por tanto debes:

  1. Crea un rol llamado 'invitado'.

  2. Asignale a ese rol las operaciones necesarias, por ejemplo 'controller_site', 'action_site_index', 'action_site_contact', 'action_site_login' y otras que vayas viendo que se requieran (usa el LOG, ver tema anterior).

  3. Asigna este rol creado al usuario invitado.

No necesariamente el rol del 'invitado' debe llamarse 'invitado'. Por conveniencia es sano que asi sea pero no es indispensable.

Como trata el sistema de usuarios al inviatdo

Por defecto en YII cuando tu llamas a Yii::app()->user->id esta devuelve 0 (cero) cuando un usuario es invitado.

En Cruge esta misma llamada a Yii::app()->user->id devolverá al valor de: CrugeModule::guestUserId, por defecto 2.

Puedes confiar en Yii::app()->user->isGuest. ya que ésta considera todo esto para saber si el usuario es un invitado.

Filtros

Cruge permite que se pueda extender mas alla usando filtros. Existen varios tipos de filtros, todos se instalan en config/main y disponen de una interfaz (interface) que debes respetar, a continuación la lista de filtros, si necesitas crear un filtro nuevo fijate en como esta hecho el filtro por defecto:

  • **filtros de autenticacion: ** permite que amplies como se busca un usuario para ser autenticado. protected\modules\cruge\models\auth\CrugeAuthDefault.php

  • filtros de sesion: permite que puedas controlar como se entrega una sesion a un usuario, inclusive puedes denegarla. protected\modules\cruge\models\filters\DefaultSessionFilter.php

  • filtro de actualizacion: permite saber si un usuario actualizo su perfil. protected\modules\cruge\models\filters\DefaultUserFilter.php

Debido a lo extenso de Cruge no he tenido tiempo de documentar bien estos filtros, pero es bastante intuitivo.

Traduccion

Si ves, Cruge escribe los mensajes en español, mientras que su codigo esta en inglés. Todos los mensajes se dirigen a la clase CrugeTranslator::t("mensaje en español"), por tanto ese es el punto para traducir a otro idioma. En un futuro nuevo commit hare un nuevo filtro, para traducir, sin que tengas que tocar nada dentro de CrugeTranslator.


Viewing all articles
Browse latest Browse all 3375

Trending Articles