Joomla Platform  13.1
Documentation des API du framework Joomla Platform
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
authentication.php
Aller à la documentation de ce fichier.
1 <?php
2 /**
3  * @package Joomla.Platform
4  * @subpackage User
5  *
6  * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
7  * @license GNU General Public License version 2 or later; see LICENSE
8  */
9 
10 defined('JPATH_PLATFORM') or die;
11 
12 /**
13  * Authentication class, provides an interface for the Joomla authentication system
14  *
15  * @package Joomla.Platform
16  * @subpackage User
17  * @since 11.1
18  */
19 class JAuthentication extends JObject
20 {
21  // Shared success status
22  /**
23  * This is the status code returned when the authentication is success (permit login)
24  * @const STATUS_SUCCESS successful response
25  * @since 11.2
26  */
27  const STATUS_SUCCESS = 1;
28 
29  // These are for authentication purposes (username and password is valid)
30  /**
31  * Status to indicate cancellation of authentication (unused)
32  * @const STATUS_CANCEL cancelled request (unused)
33  * @since 11.2
34  */
35  const STATUS_CANCEL = 2;
36 
37  /**
38  * This is the status code returned when the authentication failed (prevent login if no success)
39  * @const STATUS_FAILURE failed request
40  * @since 11.2
41  */
42  const STATUS_FAILURE = 4;
43 
44  // These are for authorisation purposes (can the user login)
45  /**
46  * This is the status code returned when the account has expired (prevent login)
47  * @const STATUS_EXPIRED an expired account (will prevent login)
48  * @since 11.2
49  */
50  const STATUS_EXPIRED = 8;
51 
52  /**
53  * This is the status code returned when the account has been denied (prevent login)
54  * @const STATUS_DENIED denied request (will prevent login)
55  * @since 11.2
56  */
57  const STATUS_DENIED = 16;
58 
59  /**
60  * This is the status code returned when the account doesn't exist (not an error)
61  * @const STATUS_UNKNOWN unknown account (won't permit or prevent login)
62  * @since 11.2
63  */
64  const STATUS_UNKNOWN = 32;
65 
66  /**
67  * An array of Observer objects to notify
68  *
69  * @var array
70  * @since 12.1
71  */
72  protected $observers = array();
73 
74  /**
75  * The state of the observable object
76  *
77  * @var mixed
78  * @since 12.1
79  */
80  protected $state = null;
81 
82  /**
83  * A multi dimensional array of [function][] = key for observers
84  *
85  * @var array
86  * @since 12.1
87  */
88  protected $methods = array();
89 
90  /**
91  * @var JAuthentication JAuthentication instances container.
92  * @since 11.3
93  */
94  protected static $instance;
95 
96  /**
97  * Constructor
98  *
99  * @since 11.1
100  */
101  public function __construct()
102  {
103  $isLoaded = JPluginHelper::importPlugin('authentication');
104 
105  if (!$isLoaded)
106  {
107  JLog::add(JText::_('JLIB_USER_ERROR_AUTHENTICATION_LIBRARIES'), JLog::WARNING, 'jerror');
108  }
109  }
110 
111  /**
112  * Returns the global authentication object, only creating it
113  * if it doesn't already exist.
114  *
115  * @return JAuthentication The global JAuthentication object
116  *
117  * @since 11.1
118  */
119  public static function getInstance()
120  {
121  if (empty(self::$instance))
122  {
123  self::$instance = new JAuthentication;
124  }
125 
126  return self::$instance;
127  }
128 
129  /**
130  * Get the state of the JAuthentication object
131  *
132  * @return mixed The state of the object.
133  *
134  * @since 11.1
135  */
136  public function getState()
137  {
138  return $this->state;
139  }
140 
141  /**
142  * Attach an observer object
143  *
144  * @param object $observer An observer object to attach
145  *
146  * @return void
147  *
148  * @since 11.1
149  */
150  public function attach($observer)
151  {
152  if (is_array($observer))
153  {
154  if (!isset($observer['handler']) || !isset($observer['event']) || !is_callable($observer['handler']))
155  {
156  return;
157  }
158 
159  // Make sure we haven't already attached this array as an observer
160  foreach ($this->observers as $check)
161  {
162  if (is_array($check) && $check['event'] == $observer['event'] && $check['handler'] == $observer['handler'])
163  {
164  return;
165  }
166  }
167 
168  $this->observers[] = $observer;
169  end($this->observers);
170  $methods = array($observer['event']);
171  }
172  else
173  {
174  if (!($observer instanceof JAuthentication))
175  {
176  return;
177  }
178 
179  // Make sure we haven't already attached this object as an observer
180  $class = get_class($observer);
181 
182  foreach ($this->observers as $check)
183  {
184  if ($check instanceof $class)
185  {
186  return;
187  }
188  }
189 
190  $this->observers[] = $observer;
191  $methods = array_diff(get_class_methods($observer), get_class_methods('JPlugin'));
192  }
193 
194  $key = key($this->observers);
195 
196  foreach ($methods as $method)
197  {
198  $method = strtolower($method);
199 
200  if (!isset($this->methods[$method]))
201  {
202  $this->methods[$method] = array();
203  }
204 
205  $this->methods[$method][] = $key;
206  }
207  }
208 
209  /**
210  * Detach an observer object
211  *
212  * @param object $observer An observer object to detach.
213  *
214  * @return boolean True if the observer object was detached.
215  *
216  * @since 11.1
217  */
218  public function detach($observer)
219  {
220  $retval = false;
221 
222  $key = array_search($observer, $this->observers);
223 
224  if ($key !== false)
225  {
226  unset($this->observers[$key]);
227  $retval = true;
228 
229  foreach ($this->methods as &$method)
230  {
231  $k = array_search($key, $method);
232 
233  if ($k !== false)
234  {
235  unset($method[$k]);
236  }
237  }
238  }
239 
240  return $retval;
241  }
242 
243  /**
244  * Finds out if a set of login credentials are valid by asking all observing
245  * objects to run their respective authentication routines.
246  *
247  * @param array $credentials Array holding the user credentials.
248  * @param array $options Array holding user options.
249  *
250  * @return JAuthenticationResponse Response object with status variable filled in for last plugin or first successful plugin.
251  *
252  * @see JAuthenticationResponse
253  * @since 11.1
254  */
255  public function authenticate($credentials, $options = array())
256  {
257  // Get plugins
258  $plugins = JPluginHelper::getPlugin('authentication');
259 
260  // Create authentication response
261  $response = new JAuthenticationResponse;
262 
263  /*
264  * Loop through the plugins and check if the credentials can be used to authenticate
265  * the user
266  *
267  * Any errors raised in the plugin should be returned via the JAuthenticationResponse
268  * and handled appropriately.
269  */
270  foreach ($plugins as $plugin)
271  {
272  $className = 'plg' . $plugin->type . $plugin->name;
273 
274  if (class_exists($className))
275  {
276  $plugin = new $className($this, (array) $plugin);
277  }
278  else
279  {
280  // Bail here if the plugin can't be created
281  JLog::add(JText::sprintf('JLIB_USER_ERROR_AUTHENTICATION_FAILED_LOAD_PLUGIN', $className), JLog::WARNING, 'jerror');
282  continue;
283  }
284 
285  // Try to authenticate
286  $plugin->onUserAuthenticate($credentials, $options, $response);
287 
288  // If authentication is successful break out of the loop
289  if ($response->status === self::STATUS_SUCCESS)
290  {
291  if (empty($response->type))
292  {
293  $response->type = isset($plugin->_name) ? $plugin->_name : $plugin->name;
294  }
295  break;
296  }
297  }
298 
299  if (empty($response->username))
300  {
301  $response->username = $credentials['username'];
302  }
303 
304  if (empty($response->fullname))
305  {
306  $response->fullname = $credentials['username'];
307  }
308 
309  if (empty($response->password) && isset($credentials['password']))
310  {
311  $response->password = $credentials['password'];
312  }
313 
314  return $response;
315  }
316 
317  /**
318  * Authorises that a particular user should be able to login
319  *
320  * @param JAuthenticationResponse $response response including username of the user to authorise
321  * @param array $options list of options
322  *
323  * @return array[JAuthenticationResponse] results of authorisation
324  *
325  * @since 11.2
326  */
327  public static function authorise($response, $options = array())
328  {
329  // Get plugins in case they haven't been imported already
330  JPluginHelper::importPlugin('user');
331 
332  JPluginHelper::importPlugin('authentication');
333  $dispatcher = JEventDispatcher::getInstance();
334  $results = $dispatcher->trigger('onUserAuthorisation', array($response, $options));
335 
336  return $results;
337  }
338 }
339 
340 /**
341  * Authentication response class, provides an object for storing user and error details
342  *
343  * @package Joomla.Platform
344  * @subpackage User
345  * @since 11.1
346  */
348 {
349  /**
350  * Response status (see status codes)
351  *
352  * @var string
353  * @since 11.1
354  */
356 
357  /**
358  * The type of authentication that was successful
359  *
360  * @var string
361  * @since 11.1
362  */
363  public $type = '';
364 
365  /**
366  * The error message
367  *
368  * @var string
369  * @since 11.1
370  */
371  public $error_message = '';
372 
373  /**
374  * Any UTF-8 string that the End User wants to use as a username.
375  *
376  * @var string
377  * @since 11.1
378  */
379  public $username = '';
380 
381  /**
382  * Any UTF-8 string that the End User wants to use as a password.
383  *
384  * @var string
385  * @since 11.1
386  */
387  public $password = '';
388 
389  /**
390  * The email address of the End User as specified in section 3.4.1 of [RFC2822]
391  *
392  * @var string
393  * @since 11.1
394  */
395  public $email = '';
396 
397  /**
398  * UTF-8 string free text representation of the End User's full name.
399  *
400  * @var string
401  * @since 11.1
402  *
403  */
404  public $fullname = '';
405 
406  /**
407  * The End User's date of birth as YYYY-MM-DD. Any values whose representation uses
408  * fewer than the specified number of digits should be zero-padded. The length of this
409  * value MUST always be 10. If the End User user does not want to reveal any particular
410  * component of this value, it MUST be set to zero.
411  *
412  * For instance, if a End User wants to specify that his date of birth is in 1980, but
413  * not the month or day, the value returned SHALL be "1980-00-00".
414  *
415  * @var string
416  * @since 11.1
417  */
418  public $birthdate = '';
419 
420  /**
421  * The End User's gender, "M" for male, "F" for female.
422  *
423  * @var string
424  * @since 11.1
425  */
426  public $gender = '';
427 
428  /**
429  * UTF-8 string free text that SHOULD conform to the End User's country's postal system.
430  *
431  * @var string
432  * @since 11.1
433  */
434  public $postcode = '';
435 
436  /**
437  * The End User's country of residence as specified by ISO3166.
438  *
439  * @var string
440  * @since 11.1
441  */
442  public $country = '';
443 
444  /**
445  * End User's preferred language as specified by ISO639.
446  *
447  * @var string
448  * @since 11.1
449  */
450  public $language = '';
451 
452  /**
453  * ASCII string from TimeZone database
454  *
455  * @var string
456  * @since 11.1
457  */
458  public $timezone = '';
459 }