123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- <?php
- declare(strict_types=1);
- namespace OC\Session;
- use OCP\ISession;
- use OCP\Security\ICrypto;
- use OCP\Session\Exceptions\SessionNotAvailableException;
- use function json_decode;
- use function OCP\Log\logger;
- class CryptoSessionData implements \ArrayAccess, ISession {
-
- protected $session;
-
- protected $crypto;
-
- protected $passphrase;
-
- protected $sessionValues;
-
- protected $isModified = false;
- public const encryptedSessionName = 'encrypted_session_data';
-
- public function __construct(ISession $session,
- ICrypto $crypto,
- string $passphrase) {
- $this->crypto = $crypto;
- $this->session = $session;
- $this->passphrase = $passphrase;
- $this->initializeSession();
- }
-
- public function __destruct() {
- try {
- $this->close();
- } catch (SessionNotAvailableException $e) {
-
-
- }
- }
- protected function initializeSession() {
- $encryptedSessionData = $this->session->get(self::encryptedSessionName) ?: '';
- if ($encryptedSessionData === '') {
-
- $this->sessionValues = [];
- } else {
- try {
- $this->sessionValues = json_decode(
- $this->crypto->decrypt($encryptedSessionData, $this->passphrase),
- true,
- 512,
- JSON_THROW_ON_ERROR,
- );
- } catch (\Exception $e) {
- logger('core')->critical('Could not decrypt or decode encrypted session data', [
- 'exception' => $e,
- ]);
- $this->sessionValues = [];
- $this->regenerateId(true, false);
- }
- }
- }
-
- public function set(string $key, $value) {
- if ($this->get($key) === $value) {
-
- return;
- }
- $reopened = $this->reopen();
- $this->sessionValues[$key] = $value;
- $this->isModified = true;
- if ($reopened) {
- $this->close();
- }
- }
-
- public function get(string $key) {
- if (isset($this->sessionValues[$key])) {
- return $this->sessionValues[$key];
- }
- return null;
- }
-
- public function exists(string $key): bool {
- return isset($this->sessionValues[$key]);
- }
-
- public function remove(string $key) {
- $reopened = $this->reopen();
- $this->isModified = true;
- unset($this->sessionValues[$key]);
- if ($reopened) {
- $this->close();
- }
- }
-
- public function clear() {
- $reopened = $this->reopen();
- $requesttoken = $this->get('requesttoken');
- $this->sessionValues = [];
- if ($requesttoken !== null) {
- $this->set('requesttoken', $requesttoken);
- }
- $this->isModified = true;
- $this->session->clear();
- if ($reopened) {
- $this->close();
- }
- }
- public function reopen(): bool {
- $reopened = $this->session->reopen();
- if ($reopened) {
- $this->initializeSession();
- }
- return $reopened;
- }
-
- public function regenerateId(bool $deleteOldSession = true, bool $updateToken = false) {
- $this->session->regenerateId($deleteOldSession, $updateToken);
- }
-
- public function getId(): string {
- return $this->session->getId();
- }
-
- public function close() {
- if ($this->isModified) {
- $encryptedValue = $this->crypto->encrypt(json_encode($this->sessionValues), $this->passphrase);
- $this->session->set(self::encryptedSessionName, $encryptedValue);
- $this->isModified = false;
- }
- $this->session->close();
- }
-
- public function offsetExists($offset): bool {
- return $this->exists($offset);
- }
-
-
- public function offsetGet($offset) {
- return $this->get($offset);
- }
-
- public function offsetSet($offset, $value): void {
- $this->set($offset, $value);
- }
-
- public function offsetUnset($offset): void {
- $this->remove($offset);
- }
- }
|