%PDF- %PDF-
Direktori : /www/varak.net/nextcloud.varak.net/apps_old/apps/passwords/lib/Services/ |
Current File : //www/varak.net/nextcloud.varak.net/apps_old/apps/passwords/lib/Services/UserChallengeService.php |
<?php /** * This file is part of the Passwords App * created by Marius David Wieschollek * and licensed under the AGPL. */ namespace OCA\Passwords\Services; use Exception; use OCA\Passwords\Db\Challenge; use OCA\Passwords\Events\Challenge\AfterChallengeActivatedEvent; use OCA\Passwords\Events\Challenge\AfterChallengeRevertedEvent; use OCA\Passwords\Events\Challenge\BeforeChallengeActivatedEvent; use OCA\Passwords\Events\Challenge\BeforeChallengeRevertedEvent; use OCA\Passwords\Events\Challenge\ChallengeActivatedEvent; use OCA\Passwords\Events\Challenge\ChallengeRevertedEvent; use OCA\Passwords\Exception\ApiException; use OCA\Passwords\Helper\Challenge\ChallengeV1Helper; use OCA\Passwords\Services\Object\ChallengeService; use OCP\AppFramework\Http; use OCP\EventDispatcher\IEventDispatcher; use stdClass; /** * Class UserChallengeService * * @package OCA\Passwords\Services */ class UserChallengeService { const USER_CHALLENGE_ID = 'user/challenge/id'; /** * @var LoggingService */ protected LoggingService $logger; /** * @var ConfigurationService */ protected ConfigurationService $config; /** * @var SessionService */ protected SessionService $sessionService; /** * @var ChallengeService */ protected ChallengeService $challengeService; /** * @var ChallengeV1Helper */ protected ChallengeV1Helper $challengeHelper; /** * @var IEventDispatcher */ protected IEventDispatcher $eventDispatcher; /** * UserChallengeHelper constructor. * * @param LoggingService $logger * @param ConfigurationService $config * @param SessionService $sessionService * @param IEventDispatcher $eventDispatcher * @param ChallengeService $challengeService * @param ChallengeV1Helper $challengeHelper */ public function __construct( LoggingService $logger, ConfigurationService $config, SessionService $sessionService, IEventDispatcher $eventDispatcher, ChallengeService $challengeService, ChallengeV1Helper $challengeHelper ) { $this->config = $config; $this->logger = $logger; $this->sessionService = $sessionService; $this->challengeService = $challengeService; $this->challengeHelper = $challengeHelper; $this->eventDispatcher = $eventDispatcher; } /** * @return bool */ public function hasChallenge(): bool { try { return $this->config->hasUserValue(self::USER_CHALLENGE_ID); } catch(Exception $e) { $this->logger->logException($e); return false; } } /** * @return stdClass * @throws ApiException */ public function getChallengeData(): stdClass { if($this->hasChallenge()) { $challenge = $this->getDefaultChallenge(); $clientData = json_decode($challenge->getClientData()); $clientData->type = $challenge->getType(); return $clientData; } throw new ApiException('Not found', Http::STATUS_NOT_FOUND); } /** * @param string $secret * * @return bool * @throws ApiException */ public function validateChallenge(string $secret): bool { try { $challenge = $this->getDefaultChallenge(); } catch(Exception $e) { $this->logger->logException($e); return false; } $key = $this->challengeHelper->solveChallenge($challenge, $secret); $this->sessionService->set(SessionService::VALUE_USER_SECRET, $key); return true; } /** * @param array $clientData * @param string $secret * * @return bool * @throws ApiException */ public function setChallenge(array $clientData, string $secret): bool { $backup = $this->backupChallenge(); try { $this->eventDispatcher->dispatchTyped(new BeforeChallengeActivatedEvent($clientData, $secret)); /** @var $challenge Challenge */ [$key, $challenge] = $this->challengeHelper->createChallenge($secret, $clientData); $this->challengeService->save($challenge); $this->sessionService->set(SessionService::VALUE_USER_SECRET, $key); $this->config->setUserValue(self::USER_CHALLENGE_ID, $challenge->getUuid()); $this->eventDispatcher->dispatchTyped(new ChallengeActivatedEvent($challenge, $key)); $this->eventDispatcher->dispatchTyped(new AfterChallengeActivatedEvent($challenge, $key)); } catch(Exception $e) { $this->logger->logException($e); $this->revertChallenge($backup); return false; } try { if(isset($backup['challenge'])) $this->challengeService->delete($backup['challenge']); } catch(Exception $e) { $this->logger->logException($e); } return true; } /** * @return Challenge * @throws ApiException */ protected function getDefaultChallenge(): Challenge { try { $id = $this->config->getUserValue(self::USER_CHALLENGE_ID); return $this->challengeService->findByUuid($id, true); } catch(Exception $e) { $this->logger->logException($e); throw new ApiException('Loading challenge failed', $e); } } /** * @return array * @throws ApiException */ protected function backupChallenge(): array { $backup = []; if($this->hasChallenge()) { try { $backup = [ 'challenge' => $this->getDefaultChallenge(), 'secret' => $this->sessionService->get(SessionService::VALUE_USER_SECRET) ]; } catch(Exception $e) { $this->logger->logException($e); throw new ApiException('Challenge update failed', $e); } } return $backup; } /** * @param $backup */ protected function revertChallenge(array $backup): void { try { $this->eventDispatcher->dispatchTyped(new BeforeChallengeRevertedEvent($backup)); if(isset($backup['challenge'])) { $this->config->setUserValue(self::USER_CHALLENGE_ID, $backup['challenge']->getUuid()); $this->sessionService->set(SessionService::VALUE_USER_SECRET, $backup['secret']); } else { $this->config->deleteUserValue(self::USER_CHALLENGE_ID); $this->sessionService->unset(SessionService::VALUE_USER_SECRET); } $this->eventDispatcher->dispatchTyped(new ChallengeRevertedEvent($backup)); $this->eventDispatcher->dispatchTyped(new AfterChallengeRevertedEvent($backup)); } catch(Exception $e) { $this->logger->logException($e); } } }