bugie.cz

Sniperův blog o věcech webových i newebových

27 prosince

Zend_Auth a povolení/zakázaní uživatelé

Jakmile jsem začal používat Zend Framework, vyvstala potřeba autentizace a autorizace uživatelů. U jednoduchých systémů (např. Tomto blogu) jsou všichni uživatelé aktivní a je jim umožněno přihlášení. Postupem času jsem ale narazil na nutnost mít v systému uživatele, kterým ale přihlášení nebude umožněno.

Nikde jsem nenašel zmínku o přímé podpoře v Zend_Auth, tak jsem si ji jednoduše připsal. Celý fígl je v tom, že u uživatele krom klasického loginu a hesla uchovávám ještě příznak povolení. Do dotazu pro výběr uživatele se pak přidá filtr podle tohoto příznaku. Já si na to napsal následující jednoduchý adaptér:

<?php
/**
 * Podpora pro Zakazane a povolene uzivatele v Zend_Auth
 *
 * Obcas je potreba, aby system dokazal odlisit nejen existujici/neexistujici uzivatele
 * ale zaroven i povolene/zakazane uzivatele. Jelikoz to neumi zakladni Zend_Auth, musel
 * jsem jej takto rozsirit. Rozhodne se imho jedna o lepsi opatreni nez s Zend_Acl, akort
 * pokud uzivatele maji pouze jednu roli.
 *
 * @author Ondrej Flidr, Sniper's Softworks
 * @version 1.0
 * @copyright Sniper's Softworks, 2008
 */
class SS_Auth_Adapter_DbTableWithEnabled extends Zend_Auth_Adapter_DbTable {

    /**
     * Sloupec s priznakem, zda je dany zaznam aktivni
     *
     * @var string
     */
    protected $_enabledColumn = null;
    
    /**
     * Hodnota, ktera znamena, ze dany zaznam je aktivni. Vychozi je pgSQL true
     * 
     * @var string
     */
    protected $_enabledValue = "t";
    
    /**
     * __construct() - Sets configuration options
     *
     * Mirne upraveny konstruktor rodice
     *
     * @param  Zend_Db_Adapter_Abstract $zendDb
     * @param  string                   $tableName
     * @param  string                   $identityColumn
     * @param  string                   $credentialColumn
     * @param  string                   $credentialTreatment
     * @param  string                   $enabledColumn
     * @param  string                   $enabledValue
     * @return void
     */
    public function __construct(Zend_Db_Adapter_Abstract $zendDb, $tableName = null, $identityColumn = null,
                                $credentialColumn = null, $credentialTreatment = null, $enabledColumn = null,
                                $enabledValue = null)
    {
        $this->_zendDb = $zendDb;

        if (null !== $tableName) {
            $this->setTableName($tableName);
        }

        if (null !== $identityColumn) {
            $this->setIdentityColumn($identityColumn);
        }

        if (null !== $credentialColumn) {
            $this->setCredentialColumn($credentialColumn);
        }

        if (null !== $credentialTreatment) {
            $this->setCredentialTreatment($credentialTreatment);
        }
        
        if (null !== $enabledColumn) {
            $this->setEnabledColumn($enabledColumn);
        }
        
        if (null !== $enabledValue) {
            $this->setEnabledValue($enabledValue);
        }
        
    }
    
    /**
     * Nastavi hodnotu, ktera znamena, ze dany uzivatel je aktivni/povoleny
     * @param string $enabledValue
     * @return Honey_Auth_Adapter_DbTableWithEnabled
     */
    public function setEnabledValue($enabledValue = "t")
    {
        $this->_enabledValue = (string)$enabledValue;
        return $this;
    }
    
    /**
     * Nastavi sloupec s priznakem pro povolene/zakazane uzivatele
     * @param string $enabledColumn
     * @return Honey_Auth_Adapter_DbTableWithEnabled
     */
    public function setEnabledColumn($enabledColumn)
    {
        $this->_enabledColumn = (string)$enabledColumn;
        return $this;
    }
    
    /**
     * _authenticateCreateSelect() - This method creates a Zend_Db_Select object that
     * is completely configured to be queried against the database.
     *
     * Mirne upravene sestavovani selectu z rodice
     *
     * @return Zend_Db_Select
     */
    protected function _authenticateCreateSelect()
    {
        // build credential expression
        if (empty($this->_credentialTreatment) || (strpos($this->_credentialTreatment, "?") === false)) {
            $this->_credentialTreatment = '?';
        }

        $credentialExpression = new Zend_Db_Expr(
            '(CASE WHEN ' . 
            $this->_zendDb->quoteInto(
                $this->_zendDb->quoteIdentifier($this->_credentialColumn, true)
                . ' = ' . $this->_credentialTreatment, $this->_credential
                )
            . ' THEN 1 ELSE 0 END) AS '
            . $this->_zendDb->quoteIdentifier('zend_auth_credential_match')
            );

        // get select
        $dbSelect = $this->_zendDb->select();
        $dbSelect->from($this->_tableName, array('*', $credentialExpression))
                 ->where($this->_zendDb->quoteIdentifier($this->_identityColumn, true) . ' = ?', $this->_identity);
                 
        if (!is_null($this->_enabledColumn)) // pokud je nastaven sloupec s enable priznakem, pouzije se. Jinak se adapter chova jako normalni dbTable
            $dbSelect->where($this->_zendDb->quoteIdentifier($this->_enabledColumn, true) . ' = ?', $this->_enabledValue);

        return $dbSelect;
    }

    /**
     * Abych mohl pouzit dbSelect z teto metody, musim v ni pretizit i authenticate :(
     * @return Zend_Auth_Result
     */
    public function authenticate() { return parent::authenticate(); }

}

Použití je stejné jako normální Zendí adaptéry.

Jo a abych nezapomněl: PF09 :)


Sdílet