Development

/branches/1.1/lib/user/sfBasicSecurityUser.class.php

You must first sign up to be able to contribute.

root/branches/1.1/lib/user/sfBasicSecurityUser.class.php

Revision 10040, 7.0 kB (checked in by fabien, 6 years ago)

fixed session id regeneration to only regenerate the id if there is a change

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  * (c) 2004-2006 Sean Kerr <sean@code-box.org>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 /**
13  * sfBasicSecurityUser will handle any type of data as a credential.
14  *
15  * @package    symfony
16  * @subpackage user
17  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
18  * @author     Sean Kerr <sean@code-box.org>
19  * @version    SVN: $Id$
20  */
21 class sfBasicSecurityUser extends sfUser implements sfSecurityUser
22 {
23   const LAST_REQUEST_NAMESPACE = 'symfony/user/sfUser/lastRequest';
24   const AUTH_NAMESPACE = 'symfony/user/sfUser/authenticated';
25   const CREDENTIAL_NAMESPACE = 'symfony/user/sfUser/credentials';
26
27   protected $lastRequest = null;
28
29   protected $credentials = null;
30   protected $authenticated = null;
31
32   protected $timedout = false;
33
34   /**
35    * Clears all credentials.
36    *
37    */
38   public function clearCredentials()
39   {
40     $this->credentials = null;
41     $this->credentials = array();
42   }
43
44   /**
45    * returns an array containing the credentials
46    */
47   public function listCredentials()
48   {
49     return $this->credentials;
50   }
51
52   /**
53    * Removes a credential.
54    *
55    * @param  mixed credential
56    */
57   public function removeCredential($credential)
58   {
59     if ($this->hasCredential($credential))
60     {
61       foreach ($this->credentials as $key => $value)
62       {
63         if ($credential == $value)
64         {
65           if ($this->options['logging'])
66           {
67             $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Remove credential "%s"', $credential))));
68           }
69
70           unset($this->credentials[$key]);
71
72           $this->storage->regenerate(false);
73
74           return;
75         }
76       }
77     }
78   }
79
80   /**
81    * Adds a credential.
82    *
83    * @param mixed $credential
84    */
85   public function addCredential($credential)
86   {
87     $this->addCredentials(func_get_args());
88   }
89
90   /**
91    * Adds several credential at once.
92    *
93    * @param  mixed array or list of credentials
94    */
95   public function addCredentials()
96   {
97     if (func_num_args() == 0) return;
98
99     // Add all credentials
100     $credentials = (is_array(func_get_arg(0))) ? func_get_arg(0) : func_get_args();
101
102     if ($this->options['logging'])
103     {
104       $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Add credential(s) "%s"', implode(', ', $credentials)))));
105     }
106
107     $added = false;
108     foreach ($credentials as $aCredential)
109     {
110       if (!in_array($aCredential, $this->credentials))
111       {
112         $added = true;
113         $this->credentials[] = $aCredential;
114       }
115     }
116
117     if ($added)
118     {
119       $this->storage->regenerate(false);
120     }
121   }
122
123   /**
124    * Returns true if user has credential.
125    *
126    * @param  mixed $credentials
127    * @param  bool  $useAnd       specify the mode, either AND or OR
128    * @return bool
129    *
130    * @author Olivier Verdier <Olivier.Verdier@free.fr>
131    */
132   public function hasCredential($credentials, $useAnd = true)
133   {
134     if (!is_array($credentials))
135     {
136       return in_array($credentials, $this->credentials);
137     }
138
139     // now we assume that $credentials is an array
140     $test = false;
141
142     foreach ($credentials as $credential)
143     {
144       // recursively check the credential with a switched AND/OR mode
145       $test = $this->hasCredential($credential, $useAnd ? false : true);
146
147       if ($useAnd)
148       {
149         $test = $test ? false : true;
150       }
151
152       if ($test) // either passed one in OR mode or failed one in AND mode
153       {
154         break; // the matter is settled
155       }
156     }
157
158     if ($useAnd) // in AND mode we succeed if $test is false
159     {
160       $test = $test ? false : true;
161     }
162
163     return $test;
164   }
165
166   /**
167    * Returns true if user is authenticated.
168    *
169    * @return boolean
170    */
171   public function isAuthenticated()
172   {
173     return $this->authenticated;
174   }
175
176   /**
177    * Sets authentication for user.
178    *
179    * @param  bool $authenticated
180    */
181   public function setAuthenticated($authenticated)
182   {
183     if ($this->options['logging'])
184     {
185       $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('User is %sauthenticated', $authenticated === true ? '' : 'not '))));
186     }
187
188     if ((bool) $authenticated !== $this->authenticated)
189     {
190       if ($authenticated === true)
191       {
192         $this->authenticated = true;
193       }
194       else
195       {
196         $this->authenticated = false;
197         $this->clearCredentials();
198       }
199
200       $this->storage->regenerate(false);
201     }
202   }
203
204   public function setTimedOut()
205   {
206     $this->timedout = true;
207   }
208
209   public function isTimedOut()
210   {
211     return $this->timedout;
212   }
213
214   /**
215    * Returns the timestamp of the last user request.
216    *
217    * @param  int
218    */
219   public function getLastRequestTime()
220   {
221     return $this->lastRequest;
222   }
223
224   /**
225    * Available options:
226    *
227    *  * timeout: Timeout to automatically log out the user in seconds (1800 by default)
228    *             Set to false to disable
229    *
230    * @param sfEventDispatcher $dispatcher  An sfEventDispatcher instance.
231    * @param sfStorage         $storage     An sfStorage instance.
232    * @param array             $options     An associative array of options.
233    *
234    * @see sfUser
235    */
236   public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array())
237   {
238     // initialize parent
239     parent::initialize($dispatcher, $storage, $options);
240
241     if (!array_key_exists('timeout', $this->options))
242     {
243       $this->options['timeout'] = 1800;
244     }
245
246     // force the max lifetime for session garbage collector to be greater than timeout
247     if (ini_get('session.gc_maxlifetime') < $this->options['timeout'])
248     {
249       ini_set('session.gc_maxlifetime', $this->options['timeout']);
250     }
251
252     // read data from storage
253     $this->authenticated = $storage->read(self::AUTH_NAMESPACE);
254     $this->credentials   = $storage->read(self::CREDENTIAL_NAMESPACE);
255     $this->lastRequest   = $storage->read(self::LAST_REQUEST_NAMESPACE);
256
257     if (is_null($this->authenticated))
258     {
259       $this->authenticated = false;
260       $this->credentials   = array();
261     }
262     else
263     {
264       // Automatic logout logged in user if no request within timeout parameter seconds
265       $timeout = $this->options['timeout'];
266       if (false !== $timeout && !is_null($this->lastRequest) && time() - $this->lastRequest >= $timeout)
267       {
268         if ($this->options['logging'])
269         {
270           $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Automatic user logout due to timeout')));
271         }
272
273         $this->setTimedOut();
274         $this->setAuthenticated(false);
275       }
276     }
277
278     $this->lastRequest = time();
279   }
280
281   public function shutdown()
282   {
283     // write the last request time to the storage
284     $this->storage->write(self::LAST_REQUEST_NAMESPACE, $this->lastRequest);
285
286     $this->storage->write(self::AUTH_NAMESPACE,         $this->authenticated);
287     $this->storage->write(self::CREDENTIAL_NAMESPACE,   $this->credentials);
288
289     // call the parent shutdown method
290     parent::shutdown();
291   }
292 }
293
Note: See TracBrowser for help on using the browser.