Skip to content

Commit

Permalink
Fix: Prevent session errors
Browse files Browse the repository at this point in the history
Prevent exceptions when the session is not started yet.
  • Loading branch information
markusguenther committed May 20, 2022
1 parent eec52e1 commit c785adc
Showing 1 changed file with 60 additions and 8 deletions.
68 changes: 60 additions & 8 deletions Classes/Service/ImpersonateService.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,49 +57,75 @@ class ImpersonateService
public function impersonate($account): void
{
$currentAccount = $this->securityContext->getAccount();
$this->session->putData('OriginalIdentity', $this->persistenceManager->getIdentifierByObject($currentAccount));
$this->writeSession('OriginalIdentity', $this->persistenceManager->getIdentifierByObject($currentAccount));

$this->refreshTokens($account);

$this->session->putData('Impersonate', $this->persistenceManager->getIdentifierByObject($account));
$this->writeSession('Impersonate', $this->persistenceManager->getIdentifierByObject($account));
}

/**
* @return void
* @throws SessionNotStartedException
*/
public function restoreOriginalIdentity(): void
{
$account = $this->getOriginalIdentity();
$this->refreshTokens($account);
$this->session->putData('Impersonate', null);
$this->writeSession('Impersonate', null);
}

/**
* @return Account|null
* @throws SessionNotStartedException
*/
public function getImpersonation(): ?Account
{
if ($this->session->getData('Impersonate') !== null) {
return $this->persistenceManager->getObjectByIdentifier($this->session->getData('Impersonate'), Account::class);
$impersonation = $this->getSessionData('Impersonate');
if ($impersonation !== null) {
return $this->persistenceManager->getObjectByIdentifier($impersonation, Account::class);
}
return null;
}

/**
* @return bool
* @throws SessionNotStartedException
*/
public function isActive()
{
return $this->getImpersonation() instanceof Account;
}

/**
* @return Account|null
*/
public function getCurrentUser(): ?Account
{
return $this->securityContext->getAccount();
}

/**
* @return Account|null
* @throws SessionNotStartedException
*/
public function getOriginalIdentity(): ?Account
{
if ($this->session->getData('OriginalIdentity') !== null) {
return $this->persistenceManager->getObjectByIdentifier($this->session->getData('OriginalIdentity'), Account::class);
$originalIdentity = $this->getSessionData('OriginalIdentity');
if ($originalIdentity !== null) {
return $this->persistenceManager->getObjectByIdentifier($originalIdentity, Account::class);
}
return $this->securityContext->getAccount();
}

/**
* @return array
* @throws SessionNotStartedException
*/
public function getOriginalIdentityRoles(): array
{
$roles = $this->getOriginalIdentity()->getRoles();
$originalAccount = $this->getOriginalIdentity();
$roles = $originalAccount ? $originalAccount->getRoles() : [];
foreach ($roles as $role) {
foreach ($this->policyService->getAllParentRoles($role) as $parentRole) {
if (!in_array($parentRole, $roles)) {
Expand All @@ -110,6 +136,10 @@ public function getOriginalIdentityRoles(): array
return $roles;
}

/**
* @param Account|null $account
* @return void
*/
protected function refreshTokens(Account $account = null)
{
if ($account === null) {
Expand All @@ -121,4 +151,26 @@ protected function refreshTokens(Account $account = null)
$token->setAccount($account);
}
}

/**
* @param string $key
* @param string|null $value
* @return void
* @throws SessionNotStartedException
*/
protected function writeSession(string $key, ?string $value): void
{
if ($this->session->isStarted()) {
$this->session->putData($key, $value);
}
}

/**
* @param string $key
* @throws SessionNotStartedException
*/
protected function getSessionData(string $key): mixed
{
return $this->session->isStarted() && $this->session->hasKey($key) ? $this->session->getData($key) : null;
}
}

0 comments on commit c785adc

Please sign in to comment.