5 * Copyright (C) 2008 Vincent Tunru
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 * @license http://www.fsf.org/licensing/licenses/info/GPLv2.html GPL v.2
21 * @category PivipModulesDefault
22 * @package Module_Openid
23 * @copyright (C) 2008 Vincent Tunru
24 * @author Vincent Tunru <email@vincentt.org>
28 * Manage the Openid module
30 * The Openid module allows for authentication using OpenID.
32 * @see /library/Pivip/Module/Abstract.php
33 * @link http://openid.net/ OpenID.net
35 class Openid_Module
extends Pivip_Module_Abstract
38 * @var Vogel_Config_Ini The OpenID configuration
40 protected static $_config;
43 * Load the OpenID configuration
45 protected static function _loadConfig()
47 if(empty(self
::$_config))
49 self
::$_config = new Vogel_Config_Ini('./modules/openid/config.ini');
51 return self
::$_config;
55 * Defines the dependencies
57 * Openid depends on Pivip and the Page module
59 public function __construct()
64 * Checks whether the OpenID database table exists
66 * Will check whether a superuser is defined and whether the database tables
69 * @return boolean Whether Openid is already installed.
71 public static function isInstalled()
73 if(!file_exists(CODE_PATH
74 . 'application/models/generated/BaseOpenid.php'))
78 $config = self
::_loadConfig();
79 if(empty($config->administration
->superuser
))
87 * Check whether the authentication form has been added to the pages
89 * @return boolean Whether the form has been added.
91 public static function blockAdded()
93 if(!file_exists(CODE_PATH
. 'application/models/generated/BaseBlock.php'))
97 $cache = Page_Module
::loadCache();
98 if(!$rows = $cache->load('core'))
102 $query = new Doctrine_Query();
103 $query->from('Block b')
104 ->where('b.location=?', 'core')
105 ->orderby('b.priority ASC');
106 $rows = $query->execute();
107 } catch(Exception
$e) {
111 foreach($rows as $row)
113 if('openid' == $row->module
&&
114 'authentication' == $row->controller
&&
115 'menu' == $row->action
&&
116 'core' == $row->location
)
125 * Communicate that Openid needs configuration if true
127 * If the superuser has not been defined, returns true.
129 * @return boolean True if OpenID still needs to be configured
131 public static function needsConfiguring()
133 $config = self
::_loadConfig();
134 if(empty($config->administration
->superuser
))
142 * Creates the table in the database and perform the first authentication
144 * @throws Pivip_Install_Exception
145 * @return boolean Whether the installation succeeded
147 public function install()
149 if($this->isInstalled())
153 $nextRequest = new Zend_Controller_Request_Simple('index',
156 $this->_pushStack($nextRequest);
160 * Remove the table from the database
162 * @throws Pivip_Install_Exception
163 * @return boolean Whether uninstallation succeeded
165 public function uninstall()
170 * Convert OpenID's to cache ID's
172 * @param string $openid OpenID
173 * @return string Cache id
175 public static function openidToCacheId($openid)
177 return 'openid_id_' . Pivip_Utility_Cache
::toCacheId($openid);
181 * Change details retreived using Sreg to the Identity Properties format
183 * @param array $details Details retrieved using Sreg
184 * @return array Array containing the Identity Properties
186 public static function sregToProperties(array $details)
188 if(empty($details['nickname']) ||
empty($details['id']))
190 throw new InvalidArgumentException();
192 $data = array('nickname' => $details['nickname'],
193 'uid' => $details['id']);
194 if(!empty($details['fullname']))
196 $data['fn'] = $details['fullname'];
198 $data['fn'] = $details['nickname'];
200 if(!empty($details['email']))
202 $data['email'] = $details['email'];
204 if(!empty($details['dob']) && 10 == strlen($details['dob']))
206 $data['bday'] = $details['dob'];
208 if(!empty($details['gender']))
210 $data['sex'] = strtolower($details['gender']);
212 if(!empty($details['postcode']))
214 $data['adr'] = ';;;;;' . $details['postcode'];
216 $data['adr'] = ';;;;;';
218 if(!empty($details['country']))
220 $locale = new Zend_Locale();
221 $data['adr'] .= ';' . $locale->getCountryTranslation(
222 $details['country']);
226 if(!empty($details['language']))
228 $data['locale'] = $details['language'];
229 if(!empty($details['country']))
231 $data['locale'] .= '_' . $details['country'];
234 if(!empty($details['timezone']))
236 $data['tz'] = 'VALUE=text:' . $details['timezone'];
242 * Load the OpenID cache
246 public static function loadCache()
248 $cacheConfig = Zend_Registry
::get('cacheConfig');
249 $options = $cacheConfig->toArray();
251 if('/' != substr($options['cache']['cache_root'], -1))
255 $options['backendOptions']['cache_dir'] = $options['cache']['cache_root']
258 $frontendOptions = array('cache_id_prefix' => 'openid_',
259 'automatic_serialization' => true);
260 $cache = Zend_Cache
::factory('Page',
261 $cacheConfig->cache
->backend
,
263 $options['backendOptions']);
270 * Register the OpenID Authentication adapter with Zend_Auth, process a login
271 * form if submitted and, if no superuser has been set yet, prompt the user
274 * @todo Allow the admins to edit the ACL.
275 * @todo Do not add a block unasked if the Page module is installed
276 * @todo If the Page module has not yet been installed, load the login form
277 * in the main section instead of the menu.
279 public function bootstrap()
281 // If Pivip has been installed but this module has not,
282 // commence installation so we can authenticate and authorize users
283 if(!$this->isInstalled())
285 if(Install_Module
::isInstalled())
291 // If the Page module has been installed, make sure that a login
293 if(!$this->blockAdded() && Page_Module
::isInstalled())
295 $nextRequest = new Zend_Controller_Request_Simple('block',
298 self
::_pushStack($nextRequest);
300 // If the Page module has not yet been installed, make sure the visitor
302 if(!Page_Module
::isInstalled())
304 $nextRequest = new Zend_Controller_Request_Simple('menu',
307 self
::_pushStack($nextRequest);
309 $request = new Zend_Controller_Request_Http();
310 $openid_identifier = $request->getPost('openid_identifier');
311 $openid_action = $request->getPost('openid_action');
312 $openid_mode = $request->getQuery('openid_mode');
313 if(($request->isPost() &&
314 !empty($openid_identifier) &&
315 !empty($openid_action)) ||
316 !empty($openid_mode))
318 $nextRequest = new Zend_Controller_Request_Simple('process',
321 self
::_pushStack($nextRequest);
324 $router = Zend_Controller_Front
::getInstance()->getRouter();
325 $options = array('module' => 'openid', 'controller' => 'authentication',
326 'action' => 'logout');
327 $route = new Zend_Controller_Router_Route_Static('account/logout',
329 $router->addRoute('openidLogout', $route);