Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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: sfBasicSecurityUser.class.php 29528 2010-05-19 13:12:27Z fabien $
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 = array();
41
  }
42
 
43
  /**
44
   * Returns the current user's credentials.
45
   *
46
   * @return array
47
   */
48
  public function getCredentials()
49
  {
50
    return $this->credentials;
51
  }
52
 
53
  /**
54
   * Removes a credential.
55
   *
56
   * @param  mixed $credential credential
57
   */
58
  public function removeCredential($credential)
59
  {
60
    if ($this->hasCredential($credential))
61
    {
62
      foreach ($this->credentials as $key => $value)
63
      {
64
        if ($credential == $value)
65
        {
66
          if ($this->options['logging'])
67
          {
68
            $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Remove credential "%s"', $credential))));
69
          }
70
 
71
          unset($this->credentials[$key]);
72
 
73
          $this->storage->regenerate(false);
74
 
75
          return;
76
        }
77
      }
78
    }
79
  }
80
 
81
  /**
82
   * Adds a credential.
83
   *
84
   * @param mixed $credential
85
   */
86
  public function addCredential($credential)
87
  {
88
    $this->addCredentials(func_get_args());
89
  }
90
 
91
  /**
92
   * Adds several credential at once.
93
   *
94
   * @param  mixed array or list of credentials
95
   */
96
  public function addCredentials()
97
  {
98
    if (func_num_args() == 0) return;
99
 
100
    // Add all credentials
101
    $credentials = (is_array(func_get_arg(0))) ? func_get_arg(0) : func_get_args();
102
 
103
    if ($this->options['logging'])
104
    {
105
      $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Add credential(s) "%s"', implode(', ', $credentials)))));
106
    }
107
 
108
    $added = false;
109
    foreach ($credentials as $aCredential)
110
    {
111
      if (!in_array($aCredential, $this->credentials))
112
      {
113
        $added = true;
114
        $this->credentials[] = $aCredential;
115
      }
116
    }
117
 
118
    if ($added)
119
    {
120
      $this->storage->regenerate(false);
121
    }
122
  }
123
 
124
  /**
125
   * Returns true if user has credential.
126
   *
127
   * @param  mixed $credentials
128
   * @param  bool  $useAnd       specify the mode, either AND or OR
129
   * @return bool
130
   *
131
   * @author Olivier Verdier <Olivier.Verdier@free.fr>
132
   */
133
  public function hasCredential($credentials, $useAnd = true)
134
  {
135
    if (null === $this->credentials)
136
    {
137
      return false;
138
    }
139
 
140
    if (!is_array($credentials))
141
    {
142
      return in_array($credentials, $this->credentials);
143
    }
144
 
145
    // now we assume that $credentials is an array
146
    $test = false;
147
 
148
    foreach ($credentials as $credential)
149
    {
150
      // recursively check the credential with a switched AND/OR mode
151
      $test = $this->hasCredential($credential, $useAnd ? false : true);
152
 
153
      if ($useAnd)
154
      {
155
        $test = $test ? false : true;
156
      }
157
 
158
      if ($test) // either passed one in OR mode or failed one in AND mode
159
      {
160
        break; // the matter is settled
161
      }
162
    }
163
 
164
    if ($useAnd) // in AND mode we succeed if $test is false
165
    {
166
      $test = $test ? false : true;
167
    }
168
 
169
    return $test;
170
  }
171
 
172
  /**
173
   * Returns true if user is authenticated.
174
   *
175
   * @return boolean
176
   */
177
  public function isAuthenticated()
178
  {
179
    return $this->authenticated;
180
  }
181
 
182
  /**
183
   * Sets authentication for user.
184
   *
185
   * @param  bool $authenticated
186
   */
187
  public function setAuthenticated($authenticated)
188
  {
189
    if ($this->options['logging'])
190
    {
191
      $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('User is %sauthenticated', $authenticated === true ? '' : 'not '))));
192
    }
193
 
194
    if ((bool) $authenticated !== $this->authenticated)
195
    {
196
      if ($authenticated === true)
197
      {
198
        $this->authenticated = true;
199
      }
200
      else
201
      {
202
        $this->authenticated = false;
203
        $this->clearCredentials();
204
      }
205
 
206
      $this->dispatcher->notify(new sfEvent($this, 'user.change_authentication', array('authenticated' => $this->authenticated)));
207
 
208
      $this->storage->regenerate(false);
209
    }
210
  }
211
 
212
  public function setTimedOut()
213
  {
214
    $this->timedout = true;
215
  }
216
 
217
  public function isTimedOut()
218
  {
219
    return $this->timedout;
220
  }
221
 
222
  /**
223
   * Returns the timestamp of the last user request.
224
   *
225
   * @return  int
226
   */
227
  public function getLastRequestTime()
228
  {
229
    return $this->lastRequest;
230
  }
231
 
232
  /**
233
   * Available options:
234
   *
235
   *  * timeout: Timeout to automatically log out the user in seconds (1800 by default)
236
   *             Set to false to disable
237
   *
238
   * @param sfEventDispatcher $dispatcher  An sfEventDispatcher instance.
239
   * @param sfStorage         $storage     An sfStorage instance.
240
   * @param array             $options     An associative array of options.
241
   *
242
   * @see sfUser
243
   */
244
  public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array())
245
  {
246
    // initialize parent
247
    parent::initialize($dispatcher, $storage, $options);
248
 
249
    if (!array_key_exists('timeout', $this->options))
250
    {
251
      $this->options['timeout'] = 1800;
252
    }
253
 
254
    // force the max lifetime for session garbage collector to be greater than timeout
255
    if (ini_get('session.gc_maxlifetime') < $this->options['timeout'])
256
    {
257
      ini_set('session.gc_maxlifetime', $this->options['timeout']);
258
    }
259
 
260
    // read data from storage
261
    $this->authenticated = $storage->read(self::AUTH_NAMESPACE);
262
    $this->credentials   = $storage->read(self::CREDENTIAL_NAMESPACE);
263
    $this->lastRequest   = $storage->read(self::LAST_REQUEST_NAMESPACE);
264
 
265
    if (null === $this->authenticated)
266
    {
267
      $this->authenticated = false;
268
      $this->credentials   = array();
269
    }
270
    else
271
    {
272
      // Automatic logout logged in user if no request within timeout parameter seconds
273
      $timeout = $this->options['timeout'];
274
      if (false !== $timeout && null !== $this->lastRequest && time() - $this->lastRequest >= $timeout)
275
      {
276
        if ($this->options['logging'])
277
        {
278
          $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Automatic user logout due to timeout')));
279
        }
280
 
281
        $this->setTimedOut();
282
        $this->setAuthenticated(false);
283
      }
284
    }
285
 
286
    $this->lastRequest = time();
287
  }
288
 
289
  public function shutdown()
290
  {
291
    // write the last request time to the storage
292
    $this->storage->write(self::LAST_REQUEST_NAMESPACE, $this->lastRequest);
293
 
294
    $this->storage->write(self::AUTH_NAMESPACE,         $this->authenticated);
295
    $this->storage->write(self::CREDENTIAL_NAMESPACE,   $this->credentials);
296
 
297
    // call the parent shutdown method
298
    parent::shutdown();
299
  }
300
}