. */ namespace SP\Modules\Web\Controllers; use SP\Core\Acl\Acl; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Crypt\Hash; use SP\Core\Crypt\Session as CryptSession; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Services\Config\ConfigService; use SP\Services\Crypt\MasterPassService; use SP\Services\Crypt\TemporaryMasterPassService; use SP\Services\Crypt\UpdateMasterPassRequest; use SP\Services\Task\TaskFactory; use SP\Util\Util; /** * Class ConfigEncryptionController * * @package SP\Modules\Web\Controllers */ final class ConfigEncryptionController extends SimpleControllerBase { use JsonTrait; /** * @return bool * @throws \DI\DependencyException * @throws \DI\NotFoundException * @throws \SP\Core\Exceptions\SPException * @throws \SP\Repositories\NoSuchItemException * @throws \SP\Services\ServiceException */ public function saveAction() { $this->checkSecurityToken($this->previousSk, $this->request); $mastePassService = $this->dic->get(MasterPassService::class); $currentMasterPass = $this->request->analyzeEncrypted('current_masterpass'); $newMasterPass = $this->request->analyzeEncrypted('new_masterpass'); $newMasterPassR = $this->request->analyzeEncrypted('new_masterpass_repeat'); $confirmPassChange = $this->request->analyzeBool('confirm_masterpass_change', false); $noAccountPassChange = $this->request->analyzeBool('no_account_change', false); $taskId = $this->request->analyzeString('taskId'); if (!$mastePassService->checkUserUpdateMPass($this->session->getUserData()->getLastUpdateMPass())) { return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS_STICKY, __u('Clave maestra actualizada'), [__u('Reinicie la sesión para cambiarla')]); } if (empty($newMasterPass) || empty($currentMasterPass)) { return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Clave maestra no indicada')); } if ($confirmPassChange === false) { return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Se ha de confirmar el cambio de clave')); } if ($newMasterPass === $currentMasterPass) { return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Las claves son idénticas')); } if ($newMasterPass !== $newMasterPassR) { return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Las claves maestras no coinciden')); } if (!$mastePassService->checkMasterPassword($currentMasterPass)) { return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('La clave maestra actual no coincide')); } if ($this->config->getConfigData()->isDemoEnabled()) { return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, esto es una DEMO!!')); } $configService = $this->dic->get(ConfigService::class); if (!$noAccountPassChange) { Util::lockApp($this->session->getUserData()->getId(), 'masterpass'); $task = $taskId !== null ? TaskFactory::create(__FUNCTION__, $taskId) : null; try { $request = new UpdateMasterPassRequest( $currentMasterPass, $newMasterPass, $configService->getByParam(MasterPassService::PARAM_MASTER_PASS_HASH), $task ); $this->eventDispatcher->notifyEvent('update.masterPassword.start', new Event($this)); $mastePassService->changeMasterPassword($request); $this->eventDispatcher->notifyEvent('update.masterPassword.end', new Event($this)); } catch (\Exception $e) { processException($e); $this->eventDispatcher->notifyEvent('exception', new Event($e)); return $this->returnJsonResponseException($e); } finally { Util::unlockApp(); if ($task) { TaskFactory::end($task->getTaskId()); } } } else { try { $this->eventDispatcher->notifyEvent('update.masterPassword.hash', new Event($this)); $mastePassService->updateConfig(Hash::hashKey($newMasterPass)); } catch (\Exception $e) { processException($e); $this->eventDispatcher->notifyEvent('exception', new Event($e)); return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Error al guardar el hash de la clave maestra')); } } return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS_STICKY, __u('Clave maestra actualizada'), [__u('Reinicie la sesión para cambiarla')]); } /** * Refresh master password hash */ public function refreshAction() { try { $this->checkSecurityToken($this->previousSk, $this->request); if ($this->config->getConfigData()->isDemoEnabled()) { return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, esto es una DEMO!!')); } $masterPassService = $this->dic->get(MasterPassService::class); $masterPassService->updateConfig(Hash::hashKey(CryptSession::getSessionKey($this->session))); $this->eventDispatcher->notifyEvent('refresh.masterPassword.hash', new Event($this, EventMessage::factory()->addDescription(__u('Hash de clave maestra actualizado')))); return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Hash de clave maestra actualizado')); } catch (\Exception $e) { processException($e); $this->eventDispatcher->notifyEvent('exception', new Event($e)); return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Error al actualizar el hash de la clave maestra')); } } /** * Create a temporary master pass */ public function saveTempAction() { try { $this->checkSecurityToken($this->previousSk, $this->request); $temporaryMasterPassService = $this->dic->get(TemporaryMasterPassService::class); $key = $temporaryMasterPassService->create($this->request->analyzeInt('temporary_masterpass_maxtime', 3600)); $groupId = $this->request->analyzeInt('temporary_masterpass_group', 0); $sendEmail = $this->configData->isMailEnabled() && $this->request->analyzeBool('temporary_masterpass_email') && $groupId > 0; if ($sendEmail) { try { $temporaryMasterPassService->sendByEmailForGroup($groupId, $key); return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Clave temporal generada'), [__u('Email enviado')]); } catch (\Exception $e) { processException($e); $this->eventDispatcher->notifyEvent('exception', new Event($e)); return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Clave temporal generada'), [__u('Error al enviar email')]); } } return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Clave temporal generada')); } catch (\Exception $e) { processException($e); $this->eventDispatcher->notifyEvent('exception', new Event($e)); return $this->returnJsonResponseException($e); } } /** * @return bool */ protected function initialize() { try { $this->checks(); $this->checkAccess(Acl::CONFIG_CRYPT); } catch (UnauthorizedPageException $e) { $this->eventDispatcher->notifyEvent('exception', new Event($e)); return $this->returnJsonResponseException($e); } } }