Elgg  Version master
SessionManagerService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
10 
17 
18  protected bool $ignore_access = false;
19 
20  protected ?\ElggUser $logged_in_user = null;
21 
22  protected bool $show_disabled_entities = false;
23 
34  public function __construct(
35  protected \ElggSession $session,
36  protected EventsService $events,
37  protected Translator $translator,
38  protected PersistentLoginService $persistent_login,
39  protected SessionCache $session_cache,
40  protected EntityCache $entity_cache
41  ) {
42  }
43 
49  public function getIgnoreAccess(): bool {
50  return $this->ignore_access;
51  }
52 
60  public function setIgnoreAccess(bool $ignore = true): bool {
61  $prev = $this->ignore_access;
62  $this->ignore_access = $ignore;
63 
64  return $prev;
65  }
66 
72  public function getDisabledEntityVisibility(): bool {
73  return $this->show_disabled_entities;
74  }
75 
83  public function setDisabledEntityVisibility(bool $show = true): bool {
84  $prev = $this->show_disabled_entities;
85  $this->show_disabled_entities = $show;
86 
87  return $prev;
88  }
89 
100  public function setUserToken(\ElggUser $user = null): void {
101  if (!$user instanceof \ElggUser) {
102  $user = $this->getLoggedInUser();
103  }
104 
105  if (!$user instanceof \ElggUser) {
106  return;
107  }
108 
109  $this->session->set('__user_token', $this->generateUserToken($user));
110  }
111 
121  public function validateUserToken(\ElggUser $user): void {
122  $session_token = $this->session->get('__user_token');
123  $user_token = $this->generateUserToken($user);
124 
125  if ($session_token !== $user_token) {
126  throw new SecurityException($this->translator->translate('session_expired'));
127  }
128  }
129 
138  protected function generateUserToken(\ElggUser $user): string {
139  $hmac = _elgg_services()->hmac->getHmac([
140  $user->time_created,
141  $user->guid,
142  ], 'sha256', $user->password_hash);
143 
144  return $hmac->getToken();
145  }
146 
157  public function login(\ElggUser $user, bool $persistent = false): void {
158  if ($user->isBanned()) {
159  throw new LoginException($this->translator->translate('LoginException:BannedUser'));
160  }
161 
162  // check before updating last login to determine first login
163  $first_login = empty($user->last_login);
164 
165  $this->events->triggerSequence('login', 'user', $user, function(\ElggUser $user) use ($persistent) {
166  if (!$user->isEnabled()) {
167  return false;
168  }
169 
170  $this->setLoggedInUser($user, true);
171  $this->setUserToken($user);
172 
173  // re-register at least the core language file for users with language other than site default
174  $this->translator->registerTranslations(\Elgg\Project\Paths::elgg() . 'languages/');
175 
176  // if remember me checked, set cookie with token and store hash(token) for user
177  if ($persistent) {
178  $this->persistent_login->makeLoginPersistent($user);
179  }
180 
181  // User's privilege has been elevated, so change the session id (prevents session fixation)
182  $this->session->migrate();
183 
184  $user->setLastLogin();
185 
186  _elgg_services()->accounts->resetAuthenticationFailures($user); // can't inject DI service because of circular reference
187 
188  return true;
189  });
190 
191  if (!$user->isEnabled()) {
192  $this->removeLoggedInUser();
193 
194  throw new LoginException($this->translator->translate('LoginException:DisabledUser'));
195  }
196 
197  if (!elgg_is_logged_in()) {
198  // login might be prevented without throwing a custom exception
199  throw new LoginException($this->translator->translate('LoginException:Unknown'));
200  }
201 
202  if ($first_login) {
203  $this->events->trigger('login:first', 'user', $user);
204  $user->first_login = time();
205  }
206  }
207 
214  public function logout(): bool {
215  $user = $this->getLoggedInUser();
216  if (!$user instanceof \ElggUser) {
217  return false;
218  }
219 
220  if (!$this->events->triggerBefore('logout', 'user', $user)) {
221  return false;
222  }
223 
224  $this->persistent_login->removePersistentLogin();
225 
226  // pass along any messages into new session
227  $old_msg = $this->session->get(SystemMessagesService::SESSION_KEY, []);
228  $this->session->invalidate();
229 
230  $this->logged_in_user = null;
231 
232  $this->session->set(SystemMessagesService::SESSION_KEY, $old_msg);
233 
234  $this->events->triggerAfter('logout', 'user', $user);
235 
236  return true;
237  }
238 
248  public function setLoggedInUser(\ElggUser $user, bool $migrate = null): void {
249  $current_user = $this->getLoggedInUser();
250  if ($current_user != $user) {
251  if (!isset($migrate)) {
252  $migrate = !\Elgg\Application::isCli();
253  }
254 
255  if ($migrate) {
256  $this->session->migrate(true);
257  }
258 
259  $this->session->set('guid', $user->guid);
260  $this->logged_in_user = $user;
261  $this->session_cache->clear();
262  $this->entity_cache->save($user);
263  $this->translator->setCurrentLanguage($user->language);
264  }
265  }
266 
274  public function getLoggedInUser(): ?\ElggUser {
275  return $this->logged_in_user;
276  }
277 
283  public function getLoggedInUserGuid(): int {
284  $user = $this->getLoggedInUser();
285  return $user ? $user->guid : 0;
286  }
287 
293  public function isAdminLoggedIn(): bool {
294  $user = $this->getLoggedInUser();
295 
296  return $user && $user->isAdmin();
297  }
298 
304  public function isLoggedIn(): bool {
305  return (bool) $this->getLoggedInUser();
306  }
307 
314  public function removeLoggedInUser(): void {
315  $this->logged_in_user = null;
316  $this->session->remove('guid');
317  $this->session_cache->clear();
318  }
319 }
elgg
Definition: install.js:27
getLoggedInUser()
Gets the logged in user.
elgg_is_logged_in()
Returns whether or not the user is currently logged in.
Definition: sessions.php:43
Generic parent class for login exceptions.
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is void
Definition: LICENSE.txt:215
login(\ElggUser $user, bool $persistent=false)
Log in a user.
Events service.
isAdminLoggedIn()
Returns whether or not the viewer is currently logged in and an admin user.
logout()
Log the current user out.
setLastLogin()
Sets the last logon time of the user to right now.
Definition: ElggUser.php:240
getDisabledEntityVisibility()
Are disabled entities shown?
removeLoggedInUser()
Remove the logged in user.
setUserToken(\ElggUser $user=null)
Set a user specific token in the session for the currently logged in user.
isLoggedIn()
Returns whether or not the user is currently logged in.
setDisabledEntityVisibility(bool $show=true)
Include disabled entities in queries.
Elgg Session Management.
Definition: ElggSession.php:19
Throw when a Security Exception occurs.
if(empty($entity_guid)||empty($recipient)||empty($muted_settings)||empty($hmac_token)) $hmac
Definition: mute.php:18
static isCli()
Is application running in CLI.
Volatile cache for entities.
Definition: EntityCache.php:10
validateUserToken(\ElggUser $user)
Validate the user token stored in the session.
$user
Definition: ban.php:7
getLoggedInUserGuid()
Return the current logged in user by guid.
isEnabled()
Is this entity enabled?
__construct(protected\ElggSession $session, protected EventsService $events, protected Translator $translator, protected PersistentLoginService $persistent_login, protected SessionCache $session_cache, protected EntityCache $entity_cache)
Constructor.
if(isset($_COOKIE['elggperm'])) $session
Definition: login_as.php:29
setLoggedInUser(\ElggUser $user, bool $migrate=null)
Sets the logged in user.
setIgnoreAccess(bool $ignore=true)
Set ignore access.
_elgg_services()
Get the global service provider.
Definition: elgglib.php:346
$persistent
Definition: login_as.php:21
getIgnoreAccess()
Get current ignore access setting.
isBanned()
Is this user banned or not?
Definition: ElggUser.php:178
Login as the specified user.
generateUserToken(\ElggUser $user)
Generate a token for a specific user.