Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>My implementation:</p> <p>Question #1</p> <pre><code>class App_Model_Acl extends Zend_Acl { const ROLE_GUEST = 'guest'; const ROLE_USER = 'user'; const ROLE_PUBLISHER = 'publisher'; const ROLE_EDITOR = 'editor'; const ROLE_ADMIN = 'admin'; const ROLE_GOD = 'god'; protected static $_instance; /* Singleton pattern */ protected function __construct() { $this-&gt;addRole(new Zend_Acl_Role(self::ROLE_GUEST)); $this-&gt;addRole(new Zend_Acl_Role(self::ROLE_USER), self::ROLE_GUEST); $this-&gt;addRole(new Zend_Acl_Role(self::ROLE_PUBLISHER), self::ROLE_USER); $this-&gt;addRole(new Zend_Acl_Role(self::ROLE_EDITOR), self::ROLE_PUBLISHER); $this-&gt;addRole(new Zend_Acl_Role(self::ROLE_ADMIN), self::ROLE_EDITOR); //unique role for superadmin $this-&gt;addRole(new Zend_Acl_Role(self::ROLE_GOD)); $this-&gt;allow(self::ROLE_GOD); /* Adding new resources */ $this-&gt;add(new Zend_Acl_Resource('mvc:users')) -&gt;add(new Zend_Acl_Resource('mvc:users.auth'), 'mvc:users') -&gt;add(new Zend_Acl_Resource('mvc:users.list'), 'mvc:users'); $this-&gt;allow(null, 'mvc:users', array('index', 'list')); $this-&gt;allow('guest', 'mvc:users.auth', array('index', 'login')); $this-&gt;allow('guest', 'mvc:users.list', array('index', 'list')); $this-&gt;deny(array('user'), 'mvc:users.auth', array('login')); /* Adding new resources */ $moduleResource = new Zend_Acl_Resource('mvc:snippets'); $this-&gt;add($moduleResource) -&gt;add(new Zend_Acl_Resource('mvc:snippets.crud'), $moduleResource) -&gt;add(new Zend_Acl_Resource('mvc:snippets.list'), $moduleResource); $this-&gt;allow(null, $moduleResource, array('index', 'list')); $this-&gt;allow('user', 'mvc:snippets.crud', array('create', 'update', 'delete', 'read', 'list')); $this-&gt;allow('guest', 'mvc:snippets.list', array('index', 'list')); return $this; } protected static $_user; public static function setUser(Users_Model_User $user = null) { if (null === $user) { throw new InvalidArgumentException('$user is null'); } self::$_user = $user; } /** * * @return App_Model_Acl */ public static function getInstance() { if (null === self::$_instance) { self::$_instance = new self(); } return self::$_instance; } public static function resetInstance() { self::$_instance = null; self::getInstance(); } } class Smapp extends Bootstrap // class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { /** * @var App_Model_User */ protected static $_currentUser; public function __construct($application) { parent::__construct($application); } public static function setCurrentUser(Users_Model_User $user) { self::$_currentUser = $user; } /** * @return App_Model_User */ public static function getCurrentUser() { if (null === self::$_currentUser) { self::setCurrentUser(Users_Service_User::getUserModel()); } return self::$_currentUser; } /** * @return App_Model_User */ public static function getCurrentUserId() { $user = self::getCurrentUser(); return $user-&gt;getId(); } } </code></pre> <p>in <code>class bootstrap</code></p> <pre><code>protected function _initUser() { $auth = Zend_Auth::getInstance(); if ($auth-&gt;hasIdentity()) { if ($user = Users_Service_User::findOneByOpenId($auth-&gt;getIdentity())) { $userLastAccess = strtotime($user-&gt;last_access); //update the date of the last login time in 5 minutes if ((time() - $userLastAccess) &gt; 60*5) { $date = new Zend_Date(); $user-&gt;last_access = $date-&gt;toString('YYYY-MM-dd HH:mm:ss'); $user-&gt;save(); } Smapp::setCurrentUser($user); } } return Smapp::getCurrentUser(); } protected function _initAcl() { $acl = App_Model_Acl::getInstance(); Zend_View_Helper_Navigation_HelperAbstract::setDefaultAcl($acl); Zend_View_Helper_Navigation_HelperAbstract::setDefaultRole(Smapp::getCurrentUser()-&gt;role); Zend_Registry::set('Zend_Acl', $acl); return $acl; } </code></pre> <p>and <code>Front_Controller_Plugin</code></p> <pre><code>class App_Plugin_Auth extends Zend_Controller_Plugin_Abstract { private $_identity; /** * the acl object * * @var zend_acl */ private $_acl; /** * the page to direct to if there is a current * user but they do not have permission to access * the resource * * @var array */ private $_noacl = array('module' =&gt; 'admin', 'controller' =&gt; 'error', 'action' =&gt; 'no-auth'); /** * the page to direct to if there is not current user * * @var unknown_type */ private $_noauth = array('module' =&gt; 'users', 'controller' =&gt; 'auth', 'action' =&gt; 'login'); /** * validate the current user's request * * @param zend_controller_request $request */ public function preDispatch(Zend_Controller_Request_Abstract $request) { $this-&gt;_identity = Smapp::getCurrentUser(); $this-&gt;_acl = App_Model_Acl::getInstance(); if (!empty($this-&gt;_identity)) { $role = $this-&gt;_identity-&gt;role; } else { $role = null; } $controller = $request-&gt;controller; $module = $request-&gt;module; $controller = $controller; $action = $request-&gt;action; //go from more specific to less specific $moduleLevel = 'mvc:'.$module; $controllerLevel = $moduleLevel . '.' . $controller; $privelege = $action; if ($this-&gt;_acl-&gt;has($controllerLevel)) { $resource = $controllerLevel; } else { $resource = $moduleLevel; } if ($module != 'default' &amp;&amp; $controller != 'index') { if ($this-&gt;_acl-&gt;has($resource) &amp;&amp; !$this-&gt;_acl-&gt;isAllowed($role, $resource, $privelege)) { if (!$this-&gt;_identity) { $request-&gt;setModuleName($this-&gt;_noauth['module']); $request-&gt;setControllerName($this-&gt;_noauth['controller']); $request-&gt;setActionName($this-&gt;_noauth['action']); //$request-&gt;setParam('authPage', 'login'); } else { $request-&gt;setModuleName($this-&gt;_noacl['module']); $request-&gt;setControllerName($this-&gt;_noacl['controller']); $request-&gt;setActionName($this-&gt;_noacl['action']); //$request-&gt;setParam('authPage', 'noauth'); } throw new Exception('Access denied. ' . $resource . '::' . $role); } } } } </code></pre> <p>and finnaly - Auth_Controller` :)</p> <pre><code>class Users_AuthController extends Smapp_Controller_Action { //sesssion protected $_storage; public function getStorage() { if (null === $this-&gt;_storage) { $this-&gt;_storage = new Zend_Session_Namespace(__CLASS__); } return $this-&gt;_storage; } public function indexAction() { return $this-&gt;_forward('login'); } public function loginAction() { $openId = null; if ($this-&gt;getRequest()-&gt;isPost() and $openId = ($this-&gt;_getParam('openid_identifier', false))) { //do nothing } elseif (!isset($_GET['openid_mode'])) { return; } //$userService = $this-&gt;loadService('User'); $userService = new Users_Service_User(); $result = $userService-&gt;authenticate($openId, $this-&gt;getResponse()); if ($result-&gt;isValid()) { $identity = $result-&gt;getIdentity(); if (!$identity['Profile']['display_name']) { return $this-&gt;_helper-&gt;redirector-&gt;gotoSimpleAndExit('update', 'profile'); } $this-&gt;_redirect('/'); } else { $this-&gt;view-&gt;errorMessages = $result-&gt;getMessages(); } } public function logoutAction() { $auth = Zend_Auth::getInstance(); $auth-&gt;clearIdentity(); //Zend_Session::destroy(); $this-&gt;_redirect('/'); } } </code></pre> <p>Question #2</p> <p>keep it inside <code>Zend_Auth</code>.</p> <p>after succesfull auth - write identity in storage. <code>$auth-&gt;getStorage()-&gt;write($result-&gt;getIdentity());</code></p> <p>the <code>identity</code> - is simply <code>user_id</code></p> <p>DB design</p> <pre><code>CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `open_id` varchar(255) NOT NULL, `role` varchar(20) NOT NULL, `last_access` datetime NOT NULL, `created_at` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `open_id` (`open_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `user_profile` ( `user_id` bigint(20) NOT NULL, `display_name` varchar(100) DEFAULT NULL, `email` varchar(100) DEFAULT NULL, `real_name` varchar(100) DEFAULT NULL, `website_url` varchar(255) DEFAULT NULL, `location` varchar(100) DEFAULT NULL, `birthday` date DEFAULT NULL, `about_me` text, `view_count` int(11) NOT NULL DEFAULT '0', `updated_at` datetime NOT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; </code></pre> <p>some sugar</p> <pre><code>/** * SM's code library * * @category * @package * @subpackage * @copyright Copyright (c) 2009 Pavel V Egorov * @author Pavel V Egorov * @link http://epavel.ru/ * @since 08.09.2009 */ class Smapp_View_Helper_IsAllowed extends Zend_View_Helper_Abstract { protected $_acl; protected $_user; public function isAllowed($resource = null, $privelege = null) { return (bool) $this-&gt;getAcl()-&gt;isAllowed($this-&gt;getUser(), $resource, $privelege); } /** * @return App_Model_Acl */ public function getAcl() { if (null === $this-&gt;_acl) { $this-&gt;setAcl(App_Model_Acl::getInstance()); } return $this-&gt;_acl; } /** * @return App_View_Helper_IsAllowed */ public function setAcl(Zend_Acl $acl) { $this-&gt;_acl = $acl; return $this; } /** * @return Users_Model_User */ public function getUser() { if (null === $this-&gt;_user) { $this-&gt;setUser(Smapp::getCurrentUser()); } return $this-&gt;_user; } /** * @return App_View_Helper_IsAllowed */ public function setUser(Users_Model_User $user) { $this-&gt;_user = $user; return $this; } } </code></pre> <p>for things like this in any view script</p> <pre><code> &lt;?php if ($this-&gt;isAllowed('mvc:snippets.crud', 'update')) : ?&gt; &lt;a title="Edit &amp;laquo;&lt;?=$this-&gt;escape($snippetInfo['title'])?&gt;&amp;raquo; snippet"&gt;Edit&lt;/a&gt; &lt;?php endif?&gt; </code></pre> <p>Questions? :)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload