* [Html] You can now only add an HTML block if you have the rights to write HTML...
[pivip.git] / project / modules / openid / Module.php
blobe0042ef4d6e1e99035abb8e2333c1d9dea09a8a8
1 <?php
3 /**
4 * Pivip
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>
27 /**
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
37 /**
38 * @var Vogel_Config_Ini The OpenID configuration
40 protected static $_config;
42 /**
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;
54 /**
55 * Defines the dependencies
57 * Openid depends on Pivip and the Page module
59 public function __construct()
63 /**
64 * Checks whether the OpenID database table exists
66 * Will check whether a superuser is defined and whether the database tables
67 * exist.
69 * @return boolean Whether Openid is already installed.
71 public static function isInstalled()
73 $config = self::_loadConfig();
74 if(empty($config->administration->superuser))
76 return false;
78 // We need to be able to connect to the database for OpenID to work
79 if(null === Pivip_Db_Table_Abstract::getDefaultAdapter())
81 return false;
83 try
85 $openid = new Openid();
86 } catch(Exception $e) {
87 return false;
89 return true;
92 /**
93 * Communicate that Openid needs configuration if true
95 * If the superuser has not been defined, returns true.
97 * @return boolean True if OpenID still needs to be configured
99 public static function needsConfiguring()
101 $config = self::_loadConfig();
102 if(empty($config->administration->superuser))
104 return true;
106 return false;
110 * Create and process a form to configure the OpenID module
112 * @param string $action The action of the form
113 * @return Zend_Form The form to configure the OpenID module
114 * @todo Display error messages instead of silently failing
115 * @todo Check the superuser from the db instead of a configuration file
117 public static function configure($action)
119 $translate = Zend_Registry::get('Zend_Translate');
120 $logger = Zend_Registry::get('logger');
121 $flashMessenger = new Zend_Controller_Action_Helper_FlashMessenger();
122 $config = self::_loadConfig();
123 $request = Zend_Controller_Front::getInstance()->getRequest();
124 $requirements = array('nickname' => true, 'email' => false,
125 'fullname' => false, 'dob' => false,
126 'gender' => false, 'postcode' => false,
127 'country' => false, 'language' => false,
128 'timezone' => false);
129 $sreg = new Zend_OpenId_Extension_Sreg($requirements, null, 1.1);
130 if($request->isPost())
132 $id = $request->getParam('superuser');
133 $consumer = new Zend_OpenId_Consumer();
134 if(!$consumer->login($id, null, null, $sreg))
136 $error = sprintf($translate->_('OpenID %s is invalid.'), $id);
137 $logger->err($error);
138 $flashMessenger->setNamespace('error')->addMessage($error);
141 if('id_res' == $request->getParam('openid_mode'))
143 $consumer = new Zend_OpenId_Consumer();
144 if($consumer->verify($request->getParams(), $id, $sreg))
146 $config->administration->superuser = $id;
147 $details = $sreg->getProperties();
148 $details['id'] = $id;
149 if(!empty($details['nickname']))
151 $data = $this->sregToProperties($details);
154 $openid = new Openid();
155 foreach($data as $k => $v)
157 $openid->$k = $v;
159 $openid->save();
160 } catch(Exception $e) {
161 $error = $translate->_(
162 'Could not save OpenID data to the database.');
163 $logger->err($error);
164 $flashMessenger->setNamespace('error')->addMessage($error);
169 $config->save();
170 $success = $translate->_('OpenID set.');
171 $flashMessenger->resetNamespace()->addMessage($success);
172 return;
173 } catch(Exception $e) {
174 $error = $translate->_(
175 'Could not save the OpenID configuration to file.');
176 $logger->err($error);
177 $flashMessenger->setNamespace('error')->addMessage($error);
179 } else {
180 $error = sprintf($translate->_('Could not authenticate OpenID %s.'),
181 $id);
182 $logger->err($error);
183 $flashMessenger->setNamespace('error')->addMessage($error);
186 $superuser = new Zend_Form_Element_Text('superuser');
187 $superuser->setLabel('Administration OpenID')
188 ->setRequired(true);
189 $form = new Zend_Form();
190 $form->setAction($action)
191 ->setMethod('post')
192 ->setAttrib('id', 'configureOpenid')
193 ->setAttrib('class', 'install configure openid')
194 ->addElement($superuser);
195 $submit = new Zend_Form_Element_Submit('submit');
196 $submit->setLabel('Configure');
197 $form->addElement($submit);
198 $data['superuser'] = $config->administration->superuser;
199 $form->populate($data);
200 return $form;
204 * Creates the table in the database and perform the first authentication
206 * @throws Pivip_Install_Exception
207 * @return boolean Whether the installation succeeded
209 public function install()
214 * Remove the table from the database
216 * @throws Pivip_Install_Exception
217 * @return boolean Whether uninstallation succeeded
219 public function uninstall()
224 * Convert OpenID's to cache ID's
226 * @param string $openid OpenID
227 * @return string Cache id
229 public static function openidToCacheId($openid)
231 return 'openid_id_' .
232 str_replace(':', '__colon__',
233 str_replace('.', '__fullstop__',
234 str_replace(';', '__semicolon__',
235 str_replace('%', '__percent__',
236 str_replace('/', '__fwdslash__',
237 str_replace('\\', '__bwdslash__',
238 str_replace('#', '__hash__',
239 str_replace('?', '__qmark__',
240 str_replace('&', '__amp__',
241 str_replace('-', '__hyphen__',
242 str_replace('=', '__equal__',
243 Zend_Filter::get($openid, 'HtmlEntities'))))))))))));
247 * Change details retreived using Sreg to the Identity Properties format
249 * @param array $details Details retrieved using Sreg
250 * @return array Array containing the Identity Properties
252 public static function sregToProperties(array $details)
254 if(empty($details['nickname']) || empty($details['id']))
256 throw new InvalidArgumentException();
258 $data = array('nickname' => $details['nickname'],
259 'uid' => $details['id']);
260 if(!empty($details['fullname']))
262 $data['fn'] = $details['fullname'];
263 } else {
264 $data['fn'] = $details['nickname'];
266 if(!empty($details['email']))
268 $data['email'] = $details['email'];
270 if(!empty($details['dob']) && 10 == strlen($details['dob']))
272 $data['bday'] = $details['dob'];
274 if(!empty($details['gender']))
276 $data['sex'] = strtolower($details['gender']);
278 if(!empty($details['postcode']))
280 $data['adr'] = ';;;;;' . $details['postcode'];
281 } else {
282 $data['adr'] = ';;;;;';
284 if(!empty($details['country']))
286 $locale = new Zend_Locale();
287 $data['adr'] .= ';' . $locale->getCountryTranslation(
288 $details['country']);
289 } else {
290 $data['adr'] .= ';';
292 if(!empty($details['language']))
294 $data['locale'] = $details['language'];
295 if(!empty($details['country']))
297 $data['locale'] .= '_' . $details['country'];
300 if(!empty($details['timezone']))
302 $data['tz'] = 'VALUE=text:' . $details['timezone'];
304 return $data;
308 * Load the OpenID cache
310 * @return Zend_Cache
312 public static function loadCache()
314 $cacheConfig = Zend_Registry::get('cacheConfig');
315 $options = $cacheConfig->toArray();
316 $separator = '';
317 if('/' != substr($options['cache']['cache_root'], -1))
319 $separator = '/';
321 $options['backendOptions']['cache_dir'] = $options['cache']['cache_root']
322 . $separator
323 . 'modules/openid';
324 $frontendOptions = array('cache_id_prefix' => 'openid_',
325 'automatic_serialization' => true);
326 $cache = Zend_Cache::factory('Page',
327 $cacheConfig->cache->backend,
328 $frontendOptions,
329 $options['backendOptions']);
330 return $cache;
334 * Load the module
336 * Register the OpenID Authentication adapter with Zend_Auth, process a login
337 * form if submitted and, if no superuser has been set yet, prompt the user
338 * to assign one.
340 * @todo Allow the admins to edit the ACL.
342 public static function bootstrap()
344 if(!self::isInstalled())
348 $openid = new Openid();
349 $params = array('target' => 'openid');
350 $nextRequest = new Zend_Controller_Request_Simple('modules',
351 'install',
352 'install',
353 $params);
354 self::_pushStack($nextRequest);
355 } catch(Exception $e) {
356 // Could not connect to the database, do not install this module
360 $nextRequest = new Zend_Controller_Request_Simple('process',
361 'authentication',
362 'openid');
363 self::_pushStack($nextRequest);
365 $options = array('module' => 'openid', 'controller' => 'authentication',
366 'action' => 'logout');
367 $route = new Zend_Controller_Router_Route_Static('account/logout',
368 $options);
369 $router = Zend_Controller_Front::getInstance()->getRouter();
370 $router->addRoute('openidLogout', $route);