Elgg  Version 7.1
ElggSession.php
Go to the documentation of this file.
1 <?php
2 
3 use Elgg\Config;
4 use Elgg\Database;
5 use Elgg\Database\SessionHandler as ElggSessionHandler;
8 use Symfony\Component\HttpFoundation\Session\Session;
9 use Symfony\Component\HttpFoundation\Session\SessionInterface;
10 use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
11 use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
12 
20 class ElggSession {
21 
22  use Profilable;
23 
27  protected $storage;
28 
34  public function __construct(SessionInterface $storage) {
35  $this->storage = $storage;
36  }
37 
44  public function boot(): void {
45  $this->beginTimer([__METHOD__]);
46 
47  $this->start();
48 
49  $migrate_session = false;
50 
51  // test whether we have a user session
52  if ($this->has('guid')) {
53  $user = _elgg_services()->entityTable->get($this->get('guid'), 'user');
54  if (!$user instanceof \ElggUser) {
55  // OMG user has been deleted.
56  $this->invalidate();
57 
58  // redirect to homepage
59  $this->endTimer([__METHOD__]);
60  _elgg_services()->responseFactory->redirect('');
61  }
62  } else {
63  $user = _elgg_services()->persistentLogin->bootSession();
64  if ($user instanceof \ElggUser) {
65  _elgg_services()->persistentLogin->updateTokenUsage($user);
66  $migrate_session = true;
67  }
68  }
69 
70  if ($user instanceof \ElggUser) {
71  _elgg_services()->session_manager->setLoggedInUser($user, $migrate_session);
72  $user->setLastAction();
73 
74  // logout a user with open session who has been banned
75  if ($user->isBanned()) {
76  _elgg_services()->session_manager->logout();
77  }
78 
79  // make sure the user hasn't changed in between requests
80  // e.g. password reset
81  try {
82  _elgg_services()->session_manager->validateUserToken($user);
83  } catch (SecurityException $e) {
84  elgg_register_error_message($e->getMessage());
85  _elgg_services()->session_manager->logout();
86  }
87  }
88 
89  $this->endTimer([__METHOD__]);
90  }
91 
99  public function start() {
100 
101  if ($this->storage->getId()) {
102  return true;
103  }
104 
105  $result = $this->storage->start();
106  $this->generateSessionToken();
107  return $result;
108  }
109 
117  public function migrate(bool $destroy = true) {
118  return $this->storage->migrate($destroy);
119  }
120 
129  public function invalidate() {
130  $this->storage->clear();
131  $result = $this->migrate(true);
132  $this->generateSessionToken();
133  _elgg_services()->accessCache->clear();
134  return $result;
135  }
136 
143  public function save() {
144  $this->storage->save();
145  }
146 
153  public function isStarted() {
154  return $this->storage->isStarted();
155  }
156 
163  public function getID() {
164  return $this->storage->getId();
165  }
166 
174  public function setId($id) {
175  $this->storage->setId($id);
176  }
177 
184  public function getName() {
185  return $this->storage->getName();
186  }
187 
195  public function setName($name) {
196  $this->storage->setName($name);
197  }
198 
206  public function get($name, $default = null) {
207  return $this->storage->get($name, $default);
208  }
209 
217  public function set($name, $value) {
218  $this->storage->set($name, $value);
219  }
220 
228  public function remove($name) {
229  return $this->storage->remove($name);
230  }
231 
239  public function has($name) {
240  return $this->storage->has($name);
241  }
242 
251  protected function generateSessionToken() {
252  // Generate a simple token that we store server side
253  if (!$this->has('__elgg_session')) {
254  $this->set('__elgg_session', _elgg_services()->crypto->getRandomString(22));
255  }
256  }
257 
265  public static function getMock() {
266  $storage = new MockArraySessionStorage();
267  $session = new Session($storage);
268  return new self($session);
269  }
270 
281  public static function fromDatabase(Config $config, Database $db) {
282  $params = $config->getCookieConfig()['session'];
283  $options = [
284  // session.cache_limiter is unfortunately set to "" by the NativeSessionStorage
285  // constructor, so we must capture and inject it directly.
286  'cache_limiter' => session_cache_limiter(),
287 
288  'name' => $params['name'],
289  'cookie_path' => $params['path'],
290  'cookie_domain' => $params['domain'],
291  'cookie_secure' => $params['secure'],
292  'cookie_httponly' => $params['httponly'],
293  'cookie_lifetime' => $params['lifetime'],
294  'cookie_samesite' => $params['samesite'],
295  ];
296 
297  $handler = new ElggSessionHandler($db);
298  $storage = new NativeSessionStorage($options, $handler);
299  $session = new Session($storage);
300  return new self($session);
301  }
302 
312  public static function fromFiles(Config $config) {
313  $params = $config->getCookieConfig()['session'];
314  $options = [
315  // session.cache_limiter is unfortunately set to "" by the NativeSessionStorage
316  // constructor, so we must capture and inject it directly.
317  'cache_limiter' => session_cache_limiter(),
318 
319  'name' => $params['name'],
320  'cookie_path' => $params['path'],
321  'cookie_domain' => $params['domain'],
322  'cookie_secure' => $params['secure'],
323  'cookie_httponly' => $params['httponly'],
324  'cookie_lifetime' => $params['lifetime'],
325  ];
326 
327  $storage = new NativeSessionStorage($options);
328  $session = new Session($storage);
329  return new self($session);
330  }
331 }
if(! $user||! $user->canDelete()) $name
Definition: delete.php:22
$id
Generic annotation delete action.
Definition: delete.php:6
$params
Saves global plugin settings.
Definition: save.php:13
$handler
Definition: add.php:7
$user
Definition: ban.php:7
Elgg Session Management.
Definition: ElggSession.php:20
has($name)
Has the attribute been defined.
static getMock()
Get an isolated ElggSession that does not persist between requests.
invalidate()
Invalidates the session.
save()
Save the session data and closes the session.
__construct(SessionInterface $storage)
Constructor.
Definition: ElggSession.php:34
migrate(bool $destroy=true)
Migrates the session to a new session id while maintaining session attributes.
boot()
Initializes the session and checks for the remember me cookie.
Definition: ElggSession.php:44
generateSessionToken()
Adds a token to the session.
static fromFiles(Config $config)
Create a session stored in files.
static fromDatabase(Config $config, Database $db)
Create a session stored in the DB.
setId($id)
Set the session ID.
isStarted()
Has the session been started.
getID()
Get the session ID.
start()
Start the session.
Definition: ElggSession.php:99
getName()
Get the session name.
setName($name)
Set the session name.
Database session handler.
The Elgg database.
Definition: Database.php:26
Throw when a Security Exception occurs.
if(count($css_vars)< 2) $options
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
foreach($recommendedExtensions as $extension) if(empty(ini_get('session.gc_probability'))||empty(ini_get('session.gc_divisor'))) $db
_elgg_services()
Get the global service provider.
Definition: elgglib.php:347
elgg_register_error_message(string|array $options)
Registers a error system message.
Definition: elgglib.php:72
$value
Definition: generic.php:51
$default
Definition: checkbox.php:30
if(isset($_COOKIE['elggperm'])) $session
Definition: login_as.php:29
endTimer(array $keys)
Ends the timer (when enabled)
Definition: Profilable.php:59
trait Profilable
Make an object accept a timer.
Definition: Profilable.php:12
beginTimer(array $keys)
Start the timer (when enabled)
Definition: Profilable.php:43