Overview

Packages

  • Auth
  • Core
  • Horde
    • Imsp
  • None
  • Notification

Classes

  • Horde
  • Horde_Config
  • Horde_Config_Form
  • Horde_Core_ActiveSync_Connector
  • Horde_Core_ActiveSync_Driver
  • Horde_Core_Ajax_Application
  • Horde_Core_Ajax_Imple
  • Horde_Core_Ajax_Imple_AutoCompleter
  • Horde_Core_Ajax_Imple_Geocoder_Geonames
  • Horde_Core_Ajax_Imple_SpellChecker
  • Horde_Core_Alarm_Handler_Notify
  • Horde_Core_Auth_Application
  • Horde_Core_Auth_Composite
  • Horde_Core_Auth_Ldap
  • Horde_Core_Auth_Msad
  • Horde_Core_Auth_Shibboleth
  • Horde_Core_Auth_Signup_Base
  • Horde_Core_Auth_Signup_Form
  • Horde_Core_Auth_Signup_Null
  • Horde_Core_Auth_Signup_Sql
  • Horde_Core_Auth_Signup_SqlObject
  • Horde_Core_Autoloader_Callback_Mime
  • Horde_Core_Autoloader_Callback_Nls
  • Horde_Core_Block
  • Horde_Core_Block_Collection
  • Horde_Core_Block_Layout
  • Horde_Core_Block_Layout_Manager
  • Horde_Core_Block_Layout_View
  • Horde_Core_Block_Upgrade
  • Horde_Core_Browser
  • Horde_Core_Bundle
  • Horde_Core_Cli
  • Horde_Core_Controller_NotFound
  • Horde_Core_Controller_RequestConfiguration
  • Horde_Core_Controller_RequestMapper
  • Horde_Core_Controller_SettingsFinder
  • Horde_Core_Db_Migration
  • Horde_Core_Factory_ActiveSyncBackend
  • Horde_Core_Factory_ActiveSyncServer
  • Horde_Core_Factory_ActiveSyncState
  • Horde_Core_Factory_Ajax
  • Horde_Core_Factory_Alarm
  • Horde_Core_Factory_Auth
  • Horde_Core_Factory_AuthSignup
  • Horde_Core_Factory_Base
  • Horde_Core_Factory_BlockCollection
  • Horde_Core_Factory_Browser
  • Horde_Core_Factory_Cache
  • Horde_Core_Factory_Crypt
  • Horde_Core_Factory_Data
  • Horde_Core_Factory_Db
  • Horde_Core_Factory_DbBase
  • Horde_Core_Factory_DbPear
  • Horde_Core_Factory_Dns
  • Horde_Core_Factory_Editor
  • Horde_Core_Factory_Facebook
  • Horde_Core_Factory_Group
  • Horde_Core_Factory_History
  • Horde_Core_Factory_HttpClient
  • Horde_Core_Factory_Identity
  • Horde_Core_Factory_Image
  • Horde_Core_Factory_Imple
  • Horde_Core_Factory_Imsp
  • Horde_Core_Factory_ImspAuth
  • Horde_Core_Factory_Injector
  • Horde_Core_Factory_KolabServer
  • Horde_Core_Factory_KolabSession
  • Horde_Core_Factory_KolabStorage
  • Horde_Core_Factory_Ldap
  • Horde_Core_Factory_Lock
  • Horde_Core_Factory_Logger
  • Horde_Core_Factory_LoginTasks
  • Horde_Core_Factory_Mail
  • Horde_Core_Factory_Mapper
  • Horde_Core_Factory_Matcher
  • Horde_Core_Factory_Memcache
  • Horde_Core_Factory_MimeViewer
  • Horde_Core_Factory_Notification
  • Horde_Core_Factory_Perms
  • Horde_Core_Factory_PermsCore
  • Horde_Core_Factory_Prefs
  • Horde_Core_Factory_Request
  • Horde_Core_Factory_Secret
  • Horde_Core_Factory_SessionHandler
  • Horde_Core_Factory_Share
  • Horde_Core_Factory_ShareBase
  • Horde_Core_Factory_Template
  • Horde_Core_Factory_TextFilter
  • Horde_Core_Factory_ThemesCache
  • Horde_Core_Factory_Token
  • Horde_Core_Factory_Tree
  • Horde_Core_Factory_Twitter
  • Horde_Core_Factory_UrlShortener
  • Horde_Core_Factory_Vfs
  • Horde_Core_Factory_View
  • Horde_Core_Factory_Weather
  • Horde_Core_Group_Ldap
  • Horde_Core_Log_Logger
  • Horde_Core_LoginTasks
  • Horde_Core_LoginTasks_Backend_Horde
  • Horde_Core_LoginTasks_SystemTask_Upgrade
  • Horde_Core_Mime_Viewer_Syntaxhighlighter
  • Horde_Core_Mime_Viewer_Vcard
  • Horde_Core_Notification_Event_Status
  • Horde_Core_Notification_Handler_Decorator_Hordelog
  • Horde_Core_Notification_Storage_Session
  • Horde_Core_Perms
  • Horde_Core_Perms_Ui
  • Horde_Core_Prefs_Cache_Session
  • Horde_Core_Prefs_Identity
  • Horde_Core_Prefs_Storage_Configuration
  • Horde_Core_Prefs_Storage_Hooks
  • Horde_Core_Prefs_Storage_Upgrade
  • Horde_Core_Prefs_Ui
  • Horde_Core_Prefs_Ui_Widgets
  • Horde_Core_Share_Driver
  • Horde_Core_Share_FactoryCallback
  • Horde_Core_Sidebar
  • Horde_Core_Text_Filter_Bbcode
  • Horde_Core_Text_Filter_Emails
  • Horde_Core_Text_Filter_Emoticons
  • Horde_Core_Text_Filter_Highlightquotes
  • Horde_Core_Translation
  • Horde_Core_Tree_Html
  • Horde_Core_Tree_Javascript
  • Horde_Core_Tree_Simplehtml
  • Horde_Core_Ui_FlagImage
  • Horde_Core_Ui_JsCalendar
  • Horde_Core_Ui_Language
  • Horde_Core_Ui_Layout
  • Horde_Core_Ui_ModalFormRenderer
  • Horde_Core_Ui_Pager
  • Horde_Core_Ui_Tabs
  • Horde_Core_Ui_TagCloud
  • Horde_Core_Ui_VarRenderer
  • Horde_Core_Ui_VarRenderer_Html
  • Horde_Core_Ui_VarRenderer_TablesetHtml
  • Horde_Core_Ui_Widget
  • Horde_ErrorHandler
  • Horde_Help
  • Horde_Menu
  • Horde_Registry
  • Horde_Registry_Api
  • Horde_Registry_Application
  • Horde_Registry_Caller
  • Horde_Registry_Nlsconfig
  • Horde_Script_Files
  • Horde_Session
  • Horde_Session_Null
  • Horde_Themes
  • Horde_Themes_Cache
  • Horde_Themes_Css
  • Horde_Themes_Element
  • Horde_Themes_Image
  • Horde_Themes_Sound

Exceptions

  • Horde_Exception_HookNotSet
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The Horde_Core_Auth_Application class provides application-specific
  4:  * authentication built on top of the horde/Auth API.
  5:  *
  6:  * Copyright 2002-2012 Horde LLC (http://www.horde.org/)
  7:  *
  8:  * See the enclosed file COPYING for license information (LGPL). If you did
  9:  * not receive this file, see http://opensource.org/licenses/lgpl-2.1.php
 10:  *
 11:  * @author   Chuck Hagenbuch <chuck@horde.org>
 12:  * @author   Michael Slusarz <slusarz@horde.org>
 13:  * @category Horde
 14:  * @license  http://opensource.org/licenses/lgpl-2.1.php LGPL
 15:  * @package  Core
 16:  */
 17: class Horde_Core_Auth_Application extends Horde_Auth_Base
 18: {
 19:     /**
 20:      * Authentication failure reasons (additions to Horde_Auth:: reasons).
 21:      *
 22:      * <pre>
 23:      * REASON_BROWSER - A browser change was detected
 24:      * REASON_SESSIONIP - Logout due to change of IP address during session
 25:      * </pre>
 26:      */
 27:     const REASON_BROWSER = 100;
 28:     const REASON_SESSIONIP = 101;
 29: 
 30:     /**
 31:      * Application for authentication.
 32:      *
 33:      * @var string
 34:      */
 35:     protected $_app = 'horde';
 36: 
 37:     /**
 38:      * The list of application capabilities.
 39:      *
 40:      * @var array
 41:      */
 42:     protected $_appCapabilities;
 43: 
 44:     /**
 45:      * The base auth driver, used for Horde authentication.
 46:      *
 47:      * @var Horde_Auth_Base
 48:      */
 49:     protected $_base;
 50: 
 51:     /**
 52:      * The view mode, used to determine if we show dynamic, mobile, traditional
 53:      * views.
 54:      *
 55:      * @var string
 56:      */
 57:     protected $_mode = 'auto';
 58: 
 59:     /**
 60:      * Available capabilities.
 61:      *
 62:      * @var array
 63:      */
 64:     protected $_capabilities = array(
 65:         'add',
 66:         'authenticate',
 67:         'exists',
 68:         'list',
 69:         'remove',
 70:         'resetpassword',
 71:         'transparent',
 72:         'update',
 73:         'validate'
 74:     );
 75: 
 76:     /**
 77:      * Constructor.
 78:      *
 79:      * @param array $params  Required parameters:
 80:      * <pre>
 81:      * 'app' - (string) The application which is providing authentication.
 82:      * 'base' - (Horde_Auth_Base) The base Horde_Auth driver. Only needed if
 83:      *          'app' is 'horde'.
 84:      * </pre>
 85:      *
 86:      * @throws InvalidArgumentException
 87:      */
 88:     public function __construct(array $params = array())
 89:     {
 90:         if (!isset($params['app'])) {
 91:             throw new InvalidArgumentException('Missing app parameter.');
 92:         }
 93:         $this->_app = $params['app'];
 94:         unset($params['app']);
 95: 
 96:         if ($this->_app == 'horde') {
 97:             if (!isset($params['base'])) {
 98:                 throw new InvalidArgumentException('Missing base parameter.');
 99:             }
100: 
101:             $this->_base = $params['base'];
102:             unset($params['base']);
103:         }
104: 
105:         parent::__construct($params);
106:     }
107: 
108:     /**
109:      * Finds out if a set of login credentials are valid, and if requested,
110:      * mark the user as logged in in the current session.
111:      *
112:      * @param string $userId      The user ID to check.
113:      * @param array $credentials  The credentials to check.
114:      * @param boolean $login      Whether to log the user in. If false, we'll
115:      *                            only test the credentials and won't modify
116:      *                            the current session. Defaults to true.
117:      *
118:      * @return boolean  Whether or not the credentials are valid.
119:      */
120:     public function authenticate($userId, $credentials, $login = true)
121:     {
122:         try {
123:             list($userId, $credentials) = $this->runHook(trim($userId), $credentials, 'preauthenticate', 'authenticate');
124:          } catch (Horde_Auth_Exception $e) {
125:             return false;
126:         }
127: 
128:         if ($this->_base) {
129:             if (!$this->_base->authenticate($userId, $credentials, $login)) {
130:                 return false;
131:             }
132:         } elseif (!parent::authenticate($userId, $credentials, $login)) {
133:             return false;
134:         }
135: 
136:         /* Remember the user's mode choice, if applicable */
137:         if (!empty($credentials['mode'])) {
138:             $this->_mode = $credentials['mode'];
139:         }
140: 
141:         return $this->_setAuth();
142:     }
143: 
144:     /**
145:      * Find out if a set of login credentials are valid.
146:      *
147:      * @param string $userId      The user ID to check.
148:      * @param array $credentials  The credentials to use. This object will
149:      *                            always be available in the 'auth_ob' key.
150:      *
151:      * @throws Horde_Auth_Exception
152:      */
153:     protected function _authenticate($userId, $credentials)
154:     {
155:         if (!$this->hasCapability('authenticate')) {
156:             throw new Horde_Auth_Exception($this->_app . ' does not provide an authenticate() method.');
157:         }
158: 
159:         $credentials['auth_ob'] = $this;
160: 
161:         $GLOBALS['registry']->callAppMethod($this->_app, 'authAuthenticate', array('args' => array($userId, $credentials), 'noperms' => true));
162:     }
163: 
164:     /**
165:      * Checks for triggers that may invalidate the current auth.
166:      * These triggers are independent of the credentials.
167:      *
168:      * @return boolean  True if the results of authenticate() are still valid.
169:      */
170:     public function validateAuth()
171:     {
172:         if ($this->_base) {
173:             return $this->_base->validateAuth();
174:         }
175: 
176:         return $this->hasCapability('validate')
177:             ? $GLOBALS['registry']->callAppMethod($this->_app, 'authValidate', array('noperms' => true))
178:             : parent::validateAuth();
179:     }
180: 
181:     /**
182:      * Add a set of authentication credentials.
183:      *
184:      * @param string $userId      The user ID to add.
185:      * @param array $credentials  The credentials to use.
186:      *
187:      * @throws Horde_Auth_Exception
188:      */
189:     public function addUser($userId, $credentials)
190:     {
191:         if ($this->_base) {
192:             $this->_base->addUser($userId, $credentials);
193:             return;
194:         }
195: 
196:         if ($this->hasCapability('add')) {
197:             $GLOBALS['registry']->callAppMethod($this->_app, 'authAddUser', array('args' => array($userId, $credentials)));
198:         } else {
199:             parent::addUser($userId, $credentials);
200:         }
201:     }
202:     /**
203:      * Locks a user indefinitely or for a specified time
204:      *
205:      * @param string $userId      The userId to lock.
206:      * @param integer $time       The duration in seconds, 0 = permanent
207:      *
208:      * @throws Horde_Auth_Exception
209:      */
210:     public function lockUser($userId, $time = 0)
211:     {
212:         if ($this->_base) {
213:             $this->_base->lockUser($userId, $time);
214:             return;
215:         }
216: 
217:         if ($this->hasCapability('lock')) {
218:             $GLOBALS['registry']->callAppMethod($this->_app, 'authLockUser', array('args' => array($userId, $time)));
219:         } else {
220:             parent::lockUser($userId, $time);
221:         }
222:     }
223: 
224:     /**
225:      * Unlocks a user and optionally resets bad login count
226:      *
227:      * @param string  $userId          The userId to unlock.
228:      * @param boolean $resetBadLogins  Reset bad login counter, default no.
229:      *
230:      * @throws Horde_Auth_Exception
231:      */
232:     public function unlockUser($userId, $resetBadLogins = false)
233:     {
234:         if ($this->_base) {
235:             $this->_base->unlockUser($userId, $resetBadLogins);
236:             return;
237:         }
238: 
239:         if ($this->hasCapability('lock')) {
240:             $GLOBALS['registry']->callAppMethod($this->_app, 'authUnlockUser', array('args' => array($userId, $resetBadLogins)));
241:         } else {
242:             parent::unlockUser($userId, $resetBadLogins);
243:         }
244:     }
245: 
246:     /**
247:      * Checks if $userId is currently locked.
248:      *
249:      * @param string  $userId      The userId to check.
250:      * @param boolean $show_details     Toggle array format with timeout.
251:      *
252:      * @throws Horde_Auth_Exception
253:      */
254:     public function isLocked($userId, $show_details = false)
255:     {
256:         if ($this->_base) {
257:             return $this->_base->isLocked($userId, $show_details);
258:         }
259: 
260:         if ($this->hasCapability('lock')) {
261:             return $GLOBALS['registry']->callAppMethod($this->_app, 'authIsLocked', array('args' => array($userId, $show_details)));
262:         } else {
263:             return parent::isLocked($userId, $show_details);
264:         }
265:     }
266:     /**
267:      * Update a set of authentication credentials.
268:      *
269:      * @param string $oldID       The old user ID.
270:      * @param string $newID       The new user ID.
271:      * @param array $credentials  The new credentials
272:      *
273:      * @throws Horde_Auth_Exception
274:      */
275:     public function updateUser($oldID, $newID, $credentials)
276:     {
277:         if ($this->_base) {
278:             $this->_base->updateUser($oldID, $newID, $credentials);
279:             return;
280:         }
281: 
282:         if ($this->hasCapability('update')) {
283:             $GLOBALS['registry']->callAppMethod($this->_app, 'authUpdateUser', array('args' => array($oldID, $newID, $credentials)));
284:         } else {
285:             parent::updateUser($oldID, $newID, $credentials);
286:         }
287:     }
288: 
289:     /**
290:      * Delete a set of authentication credentials.
291:      *
292:      * @param string $userId  The user ID to delete.
293:      *
294:      * @throws Horde_Auth_Exception
295:      */
296:     public function removeUser($userId)
297:     {
298:         if ($this->_base) {
299:             $this->_base->removeUser($userId);
300:         } else {
301:             if ($this->hasCapability('remove')) {
302:                 $GLOBALS['registry']->callAppMethod($this->_app, 'authRemoveUser', array('args' => array($userId)));
303:             } else {
304:                 parent::removeUser($userId);
305:             }
306:         }
307:     }
308: 
309:     /**
310:      * List all users in the system.
311:      *
312:      * @return array  The array of user IDs.
313:      * @throws Horde_Auth_Exception
314:      */
315:     public function listUsers()
316:     {
317:         if ($this->_base) {
318:             return $this->_base->listUsers();
319:         }
320: 
321:         return $this->hasCapability('list')
322:             ? $GLOBALS['registry']->callAppMethod($this->_app, 'authUserList')
323:             : parent::listUsers();
324:     }
325: 
326:     /**
327:      * Checks if a user ID exists in the system.
328:      *
329:      * @param string $userId  User ID to check.
330:      *
331:      * @return boolean  Whether or not the user ID already exists.
332:      */
333:     public function exists($userId)
334:     {
335:         if ($this->_base) {
336:             return $this->_base->exists($userId);
337:         }
338: 
339:         return $this->hasCapability('exists')
340:             ? $GLOBALS['registry']->callAppMethod($this->_app, 'authUserExists', array('args' => array($userId)))
341:             : parent::exists($userId);
342:     }
343: 
344:     /**
345:      * Automatic authentication.
346:      *
347:      * @return boolean  Whether or not the client is allowed.
348:      * @throws Horde_Auth_Exception
349:      */
350:     public function transparent()
351:     {
352:         global $registry;
353: 
354:         if (!($userId = $this->getCredential('userId'))) {
355:             $userId = $registry->getAuth();
356:         }
357:         if (!($credentials = $this->getCredential('credentials'))) {
358:             $credentials = $registry->getAuthCredential();
359:         }
360: 
361:         list($userId, $credentials) = $this->runHook($userId, $credentials, 'preauthenticate', 'transparent');
362: 
363:         $this->setCredential('userId', $userId);
364:         $this->setCredential('credentials', $credentials);
365: 
366:         if ($this->_base) {
367:             $result = $this->_base->transparent();
368:         } elseif ($this->hasCapability('transparent')) {
369:             $result = $registry->callAppMethod($this->_app, 'authTransparent', array('args' => array($this), 'noperms' => true));
370:         } else {
371:             /* If this application contains neither transparent nor
372:              * authenticate capabilities, it does not require any
373:              * authentication if already authenticated to Horde. */
374:             $result = ($registry->getAuth() && !$this->hasCapability('authenticate'));
375:         }
376: 
377:         return $result && $this->_setAuth();
378:     }
379: 
380:     /**
381:      * Reset a user's password. Used for example when the user does not
382:      * remember the existing password.
383:      *
384:      * @param string $userId  The user ID for which to reset the password.
385:      *
386:      * @return string  The new password on success.
387:      * @throws Horde_Auth_Exception
388:      */
389:     public function resetPassword($userId)
390:     {
391:         if ($this->_base) {
392:             return $this->_base->resetPassword($userId);
393:         }
394: 
395:         return $this->hasCapability('resetpassword')
396:             ? $GLOBALS['registry']->callAppMethod($this->_app, 'authResetPassword', array('args' => array($userId)))
397:             : parent::resetPassword();
398:     }
399: 
400:     /**
401:      * Queries the current driver to find out if it supports the given
402:      * capability.
403:      *
404:      * @param string $capability  The capability to test for.
405:      *
406:      * @return boolean  Whether or not the capability is supported.
407:      */
408:     public function hasCapability($capability)
409:     {
410:         if ($this->_base) {
411:             return $this->_base->hasCapability($capability);
412:         }
413: 
414:         if (!isset($this->_appCapabilities)) {
415:             $this->_appCapabilities = $GLOBALS['registry']->getApiInstance($this->_app, 'application')->auth;
416:         }
417: 
418:         return in_array(strtolower($capability), $this->_appCapabilities);
419:     }
420: 
421:     /**
422:      * Returns the named parameter for the current auth driver.
423:      *
424:      * @param string $param  The parameter to fetch.
425:      *
426:      * @return string  The parameter's value, or null if it doesn't exist.
427:      */
428:     public function getParam($param)
429:     {
430:         return $this->_base
431:             ? $this->_base->getParam($param)
432:             : parent::getParam($param);
433:     }
434: 
435:     /**
436:      * Retrieve internal credential value(s).
437:      *
438:      * @param mixed $name  The credential value to get. If null, will return
439:      *                     the entire credential list. Valid names:
440:      * <pre>
441:      * 'change' - (boolean) Do credentials need to be changed?
442:      * 'credentials' - (array) The credentials needed to authenticate.
443:      * 'expire' - (integer) UNIX timestamp of the credential expiration date.
444:      * 'userId' - (string) The user ID.
445:      * </pre>
446:      *
447:      * @return mixed  Return the credential information, or null if the
448:      *                credential doesn't exist.
449:      */
450:     public function getCredential($name = null)
451:     {
452:         return $this->_base
453:             ? $this->_base->getCredential($name)
454:             : parent::getCredential($name);
455:     }
456: 
457:     /**
458:      * Set internal credential value.
459:      *
460:      * @param string $name  The credential name to set.
461:      * @param mixed $value  The credential value to set. See getCredential()
462:      *                      for the list of valid credentials/types.
463:      */
464:     public function setCredential($type, $value)
465:     {
466:         if ($this->_base) {
467:             $this->_base->setCredential($type, $value);
468:         } else {
469:             parent::setCredential($type, $value);
470:         }
471:     }
472: 
473:     /**
474:      * Sets the error message for an invalid authentication.
475:      *
476:      * @param string $type  The type of error (Horde_Auth::REASON_* constant).
477:      * @param string $msg   The error message/reason for invalid
478:      *                      authentication.
479:      */
480:     public function setError($type, $msg = null)
481:     {
482:         if ($this->_base) {
483:             $this->_base->setError($type, $msg);
484:         } else {
485:             parent::setError($type, $msg);
486:         }
487:     }
488: 
489:     /**
490:      * Returns the error type or message for an invalid authentication.
491:      *
492:      * @param boolean $msg  If true, returns the message string (if set).
493:      *
494:      * @return mixed  Error type, error message (if $msg is true) or false
495:      *                if entry doesn't exist.
496:      */
497:     public function getError($msg = false)
498:     {
499:         return $this->_base
500:             ? $this->_base->getError($msg)
501:             : parent::getError($msg);
502:     }
503: 
504:     /**
505:      * Returns information on what login parameters to display on the login
506:      * screen.
507:      *
508:      * @return array  An array with the following keys:
509:      * <pre>
510:      * 'js_code' - (array) A list of javascript statements to be included via
511:      *             Horde::addInlineScript().
512:      * 'js_files' - (array) A list of javascript files to be included via
513:      *              Horde::addScriptFile().
514:      * 'params' - (array) A list of parameters to display on the login screen.
515:      *            Each entry is an array with the following entries:
516:      *            'label' - (string) The label of the entry.
517:      *            'type' - (string) 'select', 'text', or 'password'.
518:      *            'value' - (mixed) If type is 'text' or 'password', the
519:      *                      text to insert into the field by default. If type
520:      *                      is 'select', an array with they keys as the
521:      *                      option values and an array with the following keys:
522:      *                      'hidden' - (boolean) If true, the option will be
523:      *                                 hidden.
524:      *                      'name' - (string) The option label.
525:      *                      'selected' - (boolean) If true, will be selected
526:      *                                   by default.
527:      * </pre>
528:      *
529:      * @throws Horde_Exception
530:      */
531:     public function getLoginParams()
532:     {
533:         return ($this->_base && method_exists($this->_base, 'getLoginParams'))
534:             ? $this->_base->getLoginParams()
535:             : $GLOBALS['registry']->callAppMethod($this->_app, 'authLoginParams', array('noperms' => true));
536:     }
537: 
538:     /**
539:      * Indicate whether the application requires authentication.
540:      *
541:      * @return boolean  True if application requires authentication.
542:      */
543:     public function requireAuth()
544:     {
545:         return !$this->_base &&
546:                ($this->hasCapability('authenticate') ||
547:                 $this->hasCapability('transparent'));
548:     }
549: 
550:     /**
551:      * Runs the pre/post-authenticate hook and parses the result.
552:      *
553:      * @param string $userId      The userId who has been authorized.
554:      * @param array $credentials  The credentials of the user.
555:      * @param string $type        Either 'preauthenticate' or
556:      *                            'postauthenticate'.
557:      * @param string $method      The triggering method (preauthenticate only).
558:      *                            Either 'authenticate' or 'transparent'.
559:      *
560:      * @return array  Two element array, $userId and $credentials.
561:      * @throws Horde_Auth_Exception
562:      */
563:     public function runHook($userId, $credentials, $type, $method = null)
564:     {
565:         if (!is_array($credentials)) {
566:             $credentials = empty($credentials)
567:                 ? array()
568:                 : array($credentials);
569:         }
570: 
571:         $ret_array = array($userId, $credentials);
572: 
573:         if ($type == 'preauthenticate') {
574:             $credentials['authMethod'] = $method;
575:         }
576: 
577:         try {
578:             $result = Horde::callHook($type, array($userId, $credentials), $this->_app);
579:         } catch (Horde_Exception $e) {
580:             throw new Horde_Auth_Exception($e);
581:         } catch (Horde_Exception_HookNotSet $e) {
582:             return $ret_array;
583:         }
584: 
585:         unset($credentials['authMethod']);
586: 
587:         if ($result === false) {
588:             if ($this->getError() != Horde_Auth::REASON_MESSAGE) {
589:                 $this->setError(Horde_Auth::REASON_FAILED);
590:             }
591:             throw new Horde_Auth_Exception($type . ' hook failed');
592:         }
593: 
594:         if (is_array($result)) {
595:             if ($type == 'postauthenticate') {
596:                 $ret_array[1] = $result;
597:             } else {
598:                 if (isset($result['userId'])) {
599:                     $ret_array[0] = $result['userId'];
600:                 }
601: 
602:                 if (isset($result['credentials'])) {
603:                     $ret_array[1] = $result['credentials'];
604:                 }
605:             }
606:         }
607: 
608:         return $ret_array;
609:     }
610: 
611:     /**
612:      * Set authentication credentials in the Horde session.
613:      *
614:      * @return boolean  True on success, false on failure.
615:      */
616:     protected function _setAuth()
617:     {
618:         global $registry;
619: 
620:         if ($registry->isAuthenticated(array('app' => $this->_app, 'notransparent' => true))) {
621:             return true;
622:         }
623: 
624:         /* Grab the current language before we destroy the session. */
625:         $language = $registry->preferredLang();
626: 
627:         /* Destroy any existing session on login and make sure to use a
628:          * new session ID, to avoid session fixation issues. */
629:         if (($userId = $registry->getAuth()) === false) {
630:             $registry->getCleanSession();
631:             $userId = $this->getCredential('userId');
632:         }
633: 
634:         $credentials = $this->getCredential('credentials');
635: 
636:         try {
637:             list(,$credentials) = $this->runHook($userId, $credentials, 'postauthenticate');
638:         } catch (Horde_Auth_Exception $e) {
639:             return false;
640:         }
641: 
642:         $registry->setAuth($userId, $credentials, array(
643:             'app' => $this->_app,
644:             'change' => $this->getCredential('change'),
645:             'language' => $language
646:         ));
647: 
648:         /* Only set the view mode on initial authentication */
649:         if (!$GLOBALS['session']->get('horde', 'mode')) {
650:             $this->_setMode();
651:         }
652:         if ($this->_base &&
653:             isset($GLOBALS['notification']) &&
654:             ($expire = $this->_base->getCredential('expire'))) {
655:             $toexpire = ($expire - time()) / 86400;
656:             $GLOBALS['notification']->push(sprintf(Horde_Core_Translation::ngettext("%d day until your password expires.", "%d days until your password expires.", $toexpire), $toexpire), 'horde.warning');
657:         }
658: 
659:         $registry->callAppMethod($this->_app, 'authAuthenticateCallback', array('noperms' => true));
660: 
661:         return true;
662:     }
663: 
664:     /**
665:      * Sets the default global view mode in the horde session. This can be
666:      * checked by applications, and  overridden if desired. Also sets a cookie
667:      * to remember the last view selection if applicable.
668:      */
669:     protected function _setMode()
670:     {
671:         global $conf, $browser, $prefs, $registry;
672: 
673:         if (empty($conf['user']['force_view'])) {
674:             if (empty($conf['user']['select_view'])) {
675:                 // No value from login form, try to detect.
676:                 // THIS IS A HACK. DO PROPER SMARTPHONE DETECTION.
677:                 if ($browser->isMobile()) {
678:                     $this->_mode = $browser->getBrowser() == 'webkit' ? 'smartmobile' : 'mobile';
679:                 }
680:             } else {
681:                 setcookie('default_horde_view', $this->_mode, time() + 30 * 86400, $conf['cookie']['path'], $conf['cookie']['domain']);
682:                 if ($browser->isMobile() && $this->_mode == 'auto') {
683:                     $this->_mode = $browser->getBrowser() == 'webkit' ? 'smartmobile' : 'mobile';
684:                 }
685:             }
686:         } else {
687:             // Forcing mode as per config.
688:             $this->_mode = $conf['user']['force_view'];
689:         }
690: 
691:         // Set it in the session.
692:         $GLOBALS['session']->set('horde', 'mode', $this->_mode);
693:     }
694: 
695: }
696: 
697: 
API documentation generated by ApiGen