* [ADD] Config module. Work in progress

This commit is contained in:
nuxsmin
2018-02-19 01:51:36 +01:00
parent eda5af40c7
commit faffe5495b
84 changed files with 3955 additions and 683 deletions

View File

@@ -26,6 +26,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\DataModel\ItemSearchData;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Helpers\ItemsGridHelper;
@@ -103,7 +104,7 @@ class AccessManagerController extends ControllerBase
$this->tabsGridHelper->addTab($this->getPublicLinksList());
}
$this->eventDispatcher->notifyEvent('show.itemlist.accesses', $this);
$this->eventDispatcher->notifyEvent('show.itemlist.accesses', new Event($this));
$this->tabsGridHelper->renderTabs(Acl::getActionRoute(ActionsInterface::ACCESS_MANAGE), Request::analyze('tabIndex', 0));

View File

@@ -24,9 +24,12 @@
namespace SP\Modules\Web\Controllers;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Crypt\Vault;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\Core\SessionUtil;
@@ -74,9 +77,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$accountSearchHelper->getSearchBox();
$accountSearchHelper->getAccountSearch();
$this->eventDispatcher->notifyEvent('show.account.search', $this);
$this->eventDispatcher->notifyEvent('show.account.search', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -95,7 +98,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$AccountSearchHelper = $this->dic->get(AccountSearchHelper::class);
$AccountSearchHelper->getAccountSearch();
$this->eventDispatcher->notifyEvent('show.account.search', $this);
$this->eventDispatcher->notifyEvent('show.account.search', new Event($this));
$data = [
'sk' => SessionUtil::getSessionKey(),
@@ -104,7 +107,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->returnJsonResponseData($data);
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -141,9 +144,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->accountService->incrementViewCounter($id);
$this->eventDispatcher->notifyEvent('show.account', $this);
$this->eventDispatcher->notifyEvent('show.account', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -219,12 +222,12 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->view->assign('accountData', $accountData);
$this->eventDispatcher->notifyEvent('show.account.link', $this);
$this->eventDispatcher->notifyEvent('show.account.link', new Event($this));
} else {
ErrorUtil::showErrorFull($this->view, ErrorUtil::ERR_PAGE_NO_PERMISSION, 'account-link');
}
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorFull($this->view, ErrorUtil::ERR_PAGE_NO_PERMISSION, 'account-link');
}
@@ -251,9 +254,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
);
$this->view->assign('formRoute', 'account/saveCreate');
$this->eventDispatcher->notifyEvent('show.account.create', $this);
$this->eventDispatcher->notifyEvent('show.account.create', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -290,9 +293,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
);
$this->view->assign('formRoute', 'account/saveCopy');
$this->eventDispatcher->notifyEvent('show.account.copy', $this);
$this->eventDispatcher->notifyEvent('show.account.copy', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -332,9 +335,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->accountService->incrementViewCounter($id);
$this->eventDispatcher->notifyEvent('show.account.edit', $this);
$this->eventDispatcher->notifyEvent('show.account.edit', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -370,9 +373,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
);
$this->view->assign('formRoute', 'account/saveDelete');
$this->eventDispatcher->notifyEvent('show.account.delete', $this);
$this->eventDispatcher->notifyEvent('show.account.delete', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -410,9 +413,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->view->assign('accountPassDateChange', gmdate('Y-m-d', $accountDetailsResponse->getAccountVData()->getPassDateChange()));
$this->eventDispatcher->notifyEvent('show.account.editpass', $this);
$this->eventDispatcher->notifyEvent('show.account.editpass', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -448,9 +451,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->view->assign('formRoute', 'account/saveRestore');
$this->eventDispatcher->notifyEvent('show.account.history', $this);
$this->eventDispatcher->notifyEvent('show.account.history', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -475,9 +478,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->view->addTemplate('account-request');
$this->view->assign('formRoute', 'account/saveRequest');
$this->eventDispatcher->notifyEvent('show.account.request', $this);
$this->eventDispatcher->notifyEvent('show.account.request', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}
@@ -506,11 +509,11 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
'html' => $this->render()
];
$this->eventDispatcher->notifyEvent('show.account.pass', $this);
$this->eventDispatcher->notifyEvent('show.account.pass', new Event($this));
$this->returnJsonResponseData($data);
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, $e->getMessage());
}
@@ -538,7 +541,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
'accpass' => $accountPassHelper->getPassword($account, $this->acl, AccountPasswordHelper::TYPE_NORMAL),
];
$this->eventDispatcher->notifyEvent('copy.account.pass', $this);
$this->eventDispatcher->notifyEvent('copy.account.pass', new Event($this));
$this->returnJsonResponseData($data);
}
@@ -555,8 +558,6 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
/**
* Saves create action
*
* @throws \SP\Core\Dic\ContainerException
*/
public function saveCreateAction()
{
@@ -569,7 +570,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->addCustomFieldsForItem(ActionsInterface::ACCOUNT, $accountId);
$this->eventDispatcher->notifyEvent('create.account', $this);
$this->eventDispatcher->notifyEvent('create.account', new Event($this));
$this->returnJsonResponseData(
[
@@ -581,8 +582,8 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
);
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -606,7 +607,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->updateCustomFieldsForItem(ActionsInterface::ACCOUNT, $id);
$this->eventDispatcher->notifyEvent('edit.account', $this);
$this->eventDispatcher->notifyEvent('edit.account', new Event($this));
$this->returnJsonResponseData(
[
@@ -619,7 +620,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -641,7 +642,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
$this->accountService->editPassword($form->getItemData());
$this->eventDispatcher->notifyEvent('edit.account.pass', $this);
$this->eventDispatcher->notifyEvent('edit.account.pass', new Event($this));
$this->returnJsonResponseData(
[
@@ -654,7 +655,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -673,7 +674,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
try {
$this->accountService->editRestore($historyId, $id);
$this->eventDispatcher->notifyEvent('edit.account.restore', $this);
$this->eventDispatcher->notifyEvent('edit.account.restore', new Event($this));
$this->returnJsonResponseData(
[
@@ -684,7 +685,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
__u('Cuenta restaurada')
);
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -701,7 +702,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
if ($this->accountService->delete($id)) {
$this->deleteCustomFieldsForItem(ActionsInterface::ACCOUNT, $id);
$this->eventDispatcher->notifyEvent('delete.account', $this);
$this->eventDispatcher->notifyEvent('delete.account', new Event($this));
$this->returnJsonResponseData(
['nextAction' => Acl::getActionRoute(ActionsInterface::ACCOUNT_SEARCH)],
@@ -710,7 +711,7 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
);
}
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -719,8 +720,9 @@ class AccountController extends ControllerBase implements CrudControllerInterfac
/**
* Initialize class
*
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws \SP\Services\Auth\AuthException
*/
protected function initialize()
{

View File

@@ -26,6 +26,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\DataModel\FileData;
use SP\Html\Html;
@@ -73,7 +74,7 @@ class AccountFileController extends ControllerBase implements CrudControllerInte
$this->view->assign('fileData', $fileData);
$this->view->assign('isImage', 1);
$this->eventDispatcher->notifyEvent('show.accountFile', $this);
$this->eventDispatcher->notifyEvent('show.accountFile', new Event($this));
$this->returnJsonResponseData(['html' => $this->render()]);
}
@@ -81,12 +82,12 @@ class AccountFileController extends ControllerBase implements CrudControllerInte
if (mb_strtoupper($fileData->getExtension()) === 'TXT') {
$this->view->assign('data', htmlentities($fileData->getContent()));
$this->eventDispatcher->notifyEvent('show.accountFile', $this);
$this->eventDispatcher->notifyEvent('show.accountFile', new Event($this));
$this->returnJsonResponseData(['html' => $this->render()]);
}
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -115,11 +116,11 @@ class AccountFileController extends ControllerBase implements CrudControllerInte
header('Content-Description: PHP Generated Data');
header('Content-transfer-encoding: binary');
$this->eventDispatcher->notifyEvent('download.accountFile', $this);
$this->eventDispatcher->notifyEvent('download.accountFile', new Event($this));
exit($fileData->getContent());
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
}
}
@@ -179,15 +180,15 @@ class AccountFileController extends ControllerBase implements CrudControllerInte
$this->accountFileService->create($fileData);
$this->eventDispatcher->notifyEvent('upload.accountFile', $this);
$this->eventDispatcher->notifyEvent('upload.accountFile', new Event($this));
$this->returnJsonResponse(0, __u('Archivo guardado'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(1, $e->getMessage(), [$e->getHint()]);
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -244,11 +245,11 @@ class AccountFileController extends ControllerBase implements CrudControllerInte
try {
$this->accountFileService->delete($id);
$this->eventDispatcher->notifyEvent('delete.accountFile', $this);
$this->eventDispatcher->notifyEvent('delete.accountFile', new Event($this));
$this->returnJsonResponse(0, __('Archivo Eliminado'));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -298,9 +299,9 @@ class AccountFileController extends ControllerBase implements CrudControllerInte
return;
}
$this->eventDispatcher->notifyEvent('list.accountFile', $this);
$this->eventDispatcher->notifyEvent('list.accountFile', new Event($this));
} catch (\Exception $e) {
debugLog($e->getMessage(), true);
processException($e);
ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION);
}

View File

@@ -28,6 +28,7 @@ use Defuse\Crypto\Exception\CryptoException;
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\AuthTokenData;
@@ -100,8 +101,10 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.authToken.create', $this);
$this->eventDispatcher->notifyEvent('show.authToken.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -158,8 +161,10 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.authToken.edit', $this);
$this->eventDispatcher->notifyEvent('show.authToken.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -182,11 +187,11 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa
$this->deleteCustomFieldsForItem(ActionsInterface::APITOKEN, $id);
$this->eventDispatcher->notifyEvent('delete.authToken', $this);
$this->eventDispatcher->notifyEvent('delete.authToken', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Autorización eliminada'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -213,21 +218,21 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa
$this->addCustomFieldsForItem(ActionsInterface::APITOKEN, $id);
$this->eventDispatcher->notifyEvent('create.authToken', $this);
$this->eventDispatcher->notifyEvent('create.authToken', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Autorización creada'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (EnvironmentIsBrokenException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (CryptoException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -252,11 +257,11 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa
if ($form->isRefresh()){
$this->authTokenService->refreshAndUpdate($form->getItemData());
$this->eventDispatcher->notifyEvent('refresh.authToken', $this);
$this->eventDispatcher->notifyEvent('refresh.authToken', new Event($this));
} else {
$this->authTokenService->update($form->getItemData());
$this->eventDispatcher->notifyEvent('edit.authToken', $this);
$this->eventDispatcher->notifyEvent('edit.authToken', new Event($this));
}
$this->updateCustomFieldsForItem(ActionsInterface::APITOKEN, $id);
@@ -265,11 +270,11 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (CryptoException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -293,8 +298,10 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.authToken', $this);
$this->eventDispatcher->notifyEvent('show.authToken', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -26,6 +26,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\CategoryData;
@@ -95,8 +96,10 @@ class CategoryController extends ControllerBase implements CrudControllerInterfa
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.category.create', $this);
$this->eventDispatcher->notifyEvent('show.category.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -150,8 +153,10 @@ class CategoryController extends ControllerBase implements CrudControllerInterfa
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.category.edit', $this);
$this->eventDispatcher->notifyEvent('show.category.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -175,11 +180,11 @@ class CategoryController extends ControllerBase implements CrudControllerInterfa
$this->deleteCustomFieldsForItem(ActionsInterface::CATEGORY, $id);
$this->eventDispatcher->notifyEvent('delete.category', $this);
$this->eventDispatcher->notifyEvent('delete.category', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Categoría eliminada'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -204,13 +209,13 @@ class CategoryController extends ControllerBase implements CrudControllerInterfa
$this->addCustomFieldsForItem(ActionsInterface::CATEGORY, $id);
$this->eventDispatcher->notifyEvent('create.category', $this);
$this->eventDispatcher->notifyEvent('create.category', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Categoría creada'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -236,13 +241,13 @@ class CategoryController extends ControllerBase implements CrudControllerInterfa
$this->updateCustomFieldsForItem(ActionsInterface::CATEGORY, $id);
$this->eventDispatcher->notifyEvent('edit.category', $this);
$this->eventDispatcher->notifyEvent('edit.category', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Categoría actualizada'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -266,8 +271,10 @@ class CategoryController extends ControllerBase implements CrudControllerInterfa
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.category', $this);
$this->eventDispatcher->notifyEvent('show.category', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\ClientData;
@@ -96,8 +97,10 @@ class ClientController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.client.create', $this);
$this->eventDispatcher->notifyEvent('show.client.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -151,8 +154,10 @@ class ClientController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.client.edit', $this);
$this->eventDispatcher->notifyEvent('show.client.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -175,11 +180,11 @@ class ClientController extends ControllerBase implements CrudControllerInterface
$this->deleteCustomFieldsForItem(ActionsInterface::CLIENT, $id);
$this->eventDispatcher->notifyEvent('delete.client', $this);
$this->eventDispatcher->notifyEvent('delete.client', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Cliente eliminado'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -202,13 +207,13 @@ class ClientController extends ControllerBase implements CrudControllerInterface
$this->clientService->create($form->getItemData());
$this->eventDispatcher->notifyEvent('create.client', $this);
$this->eventDispatcher->notifyEvent('create.client', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Cliente creado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -232,13 +237,13 @@ class ClientController extends ControllerBase implements CrudControllerInterface
$this->clientService->update($form->getItemData());
$this->eventDispatcher->notifyEvent('edit.client', $this);
$this->eventDispatcher->notifyEvent('edit.client', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Cliente actualizado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -262,8 +267,10 @@ class ClientController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.client', $this);
$this->eventDispatcher->notifyEvent('show.client', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -0,0 +1,105 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Traits\ConfigTrait;
/**
* Class ConfigAccountController
*
* @package SP\Modules\Web\Controllers
*/
class ConfigAccountController extends SimpleControllerBase
{
use ConfigTrait;
/**
* @throws \SP\Core\Exceptions\InvalidArgumentException
*/
public function saveAction()
{
$configData = clone $this->config->getConfigData();
// Accounts
$globalSearchEnabled = Request::analyze('globalsearch', false, false, true);
$accountPassToImageEnabled = Request::analyze('account_passtoimage', false, false, true);
$accountLinkEnabled = Request::analyze('account_link', false, false, true);
$accountFullGroupAccessEnabled = Request::analyze('account_fullgroup_access', false, false, true);
$accountCount = Request::analyze('account_count', 10);
$resultsAsCardsEnabled = Request::analyze('resultsascards', false, false, true);
$configData->setGlobalSearch($globalSearchEnabled);
$configData->setAccountPassToImage($accountPassToImageEnabled);
$configData->setAccountLink($accountLinkEnabled);
$configData->setAccountFullGroupAccess($accountFullGroupAccessEnabled);
$configData->setAccountCount($accountCount);
$configData->setResultsAsCards($resultsAsCardsEnabled);
// Files
$filesEnabled = Request::analyze('files_enabled', false, false, true);
$filesAllowedSize = Request::analyze('files_allowed_size', 1024);
$filesAllowedExts = Request::analyze('files_allowed_exts');
if ($filesEnabled && $filesAllowedSize >= 16384) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('El tamaño máximo por archivo es de 16MB'));
}
$configData->setFilesAllowedExts($filesAllowedExts);
$configData->setFilesEnabled($filesEnabled);
$configData->setFilesAllowedSize($filesAllowedSize);
// Public Links
$pubLinksEnabled = Request::analyze('publinks_enabled', false, false, true);
$pubLinksImageEnabled = Request::analyze('publinks_image_enabled', false, false, true);
$pubLinksMaxTime = Request::analyze('publinks_maxtime', 10);
$pubLinksMaxViews = Request::analyze('publinks_maxviews', 3);
$configData->setPublinksEnabled($pubLinksEnabled);
$configData->setPublinksImageEnabled($pubLinksImageEnabled);
$configData->setPublinksMaxTime($pubLinksMaxTime * 60);
$configData->setPublinksMaxViews($pubLinksMaxViews);
$this->eventDispatcher->notifyEvent('save.config.account', new Event($this));
$this->saveConfig($configData, $this->config);
}
protected function initialize()
{
try {
if (!$this->checkAccess(ActionsInterface::ACCOUNT_CONFIG)) {
throw new UnauthorizedPageException(SPException::INFO);
}
} catch (UnauthorizedPageException $e) {
$this->returnJsonResponseException($e);
}
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Exceptions\SPException;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Traits\ConfigTrait;
use SP\Services\Backup\FileBackupService;
use SP\Services\Export\XmlExportService;
/**
* Class ConfigBackupController
*
* @package SP\Modules\Web\Controllers
*/
class ConfigBackupController extends SimpleControllerBase
{
use ConfigTrait;
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function fileBackupAction()
{
if ($this->config->getConfigData()->isDemoEnabled()) {
$this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, esto es una DEMO!!'));
}
try {
$backupService = new FileBackupService();
$backupService->doBackup();
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Proceso de backup finalizado'));
} catch (\Exception $e) {
$this->returnJsonResponseException($e);
}
}
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function xmlExportAction()
{
$exportPassword = Request::analyzeEncrypted('exportPwd');
$exportPasswordR = Request::analyzeEncrypted('exportPwdR');
if (!empty($exportPassword) && $exportPassword !== $exportPasswordR) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Las claves no coinciden'));
}
try {
$exportService = $this->dic->get(XmlExportService::class);
$exportService->doExport($exportPassword);
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Proceso de exportación finalizado'));
} catch (\Exception $e) {
$this->returnJsonResponseException($e);
}
}
protected function initialize()
{
try {
if (!$this->checkAccess(ActionsInterface::BACKUP_CONFIG)) {
throw new UnauthorizedPageException(SPException::INFO);
}
} catch (UnauthorizedPageException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage(), [$e->getHint()]);
}
}
}

View File

@@ -0,0 +1,210 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Web\Controllers;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use SP\Core\Acl\ActionsInterface;
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\Exceptions\SPException;
use SP\Core\TaskFactory;
use SP\Http\JsonResponse;
use SP\Http\Request;
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\ServiceException;
use SP\Util\Util;
/**
* Class ConfigEncryptionController
*
* @package SP\Modules\Web\Controllers
*/
class ConfigEncryptionController extends SimpleControllerBase
{
use JsonTrait;
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws \SP\Services\Config\ParameterNotFoundException
*/
public function saveAction()
{
$mastePassService = $this->dic->get(MasterPassService::class);
$currentMasterPass = Request::analyzeEncrypted('curMasterPwd');
$newMasterPass = Request::analyzeEncrypted('newMasterPwd');
$newMasterPassR = Request::analyzeEncrypted('newMasterPwdR');
$confirmPassChange = Request::analyze('confirmPassChange', 0, false, 1);
$noAccountPassChange = Request::analyze('chkNoAccountChange', 0, false, 1);
if (!$mastePassService->checkUserUpdateMPass($this->session->getUserData()->getLastUpdateMPass())) {
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS_STICKY, __u('Clave maestra actualizada'), [__u('Reinicie la sesión para cambiarla')]);
}
if (empty($newMasterPass) || empty($currentMasterPass)) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Clave maestra no indicada'));
}
if ($confirmPassChange === false) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Se ha de confirmar el cambio de clave'));
}
if ($newMasterPass === $currentMasterPass) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Las claves son idénticas'));
}
if ($newMasterPass !== $newMasterPassR) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Las claves maestras no coinciden'));
}
if (!$mastePassService->checkMasterPassword($currentMasterPass)) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('La clave maestra actual no coincide'));
}
if ($this->config->getConfigData()->isDemoEnabled()) {
$this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, esto es una DEMO!!'));
}
$configService = $this->dic->get(ConfigService::class);
if (!$noAccountPassChange) {
Util::lockApp();
$request = new UpdateMasterPassRequest(
$currentMasterPass,
$newMasterPass,
$configService->getByParam('masterPwd'),
TaskFactory::create(__FUNCTION__, 'masterpass')
);
try {
$mastePassService->changeMasterPassword($request);
$configService->save('masterPwd', $request->getHash());
$configService->save('lastupdatempass', time());
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponseException($e);
} finally {
Util::unlockApp();
TaskFactory::end($request->getTask()->getTaskId());
}
} else {
try {
$configService->save('masterPwd', Hash::hashKey($newMasterPass));
$configService->save('lastupdatempass', time());
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Error al guardar el hash de la clave maestra'));
}
}
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS_STICKY, __u('Clave maestra actualizada'), [__u('Reinicie la sesión para cambiarla')]);
}
/**
* Refresh master password hash
*/
public function refreshAction()
{
if ($this->config->getConfigData()->isDemoEnabled()) {
$this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, esto es una DEMO!!'));
}
try {
$configService = $this->dic->get(ConfigService::class);
$configService->save('masterPwd', Hash::hashKey(CryptSession::getSessionKey()));
$this->eventDispatcher->notifyEvent('refresh.masterPassword', new Event($this, [__u('Hash de clave maestra actualizado')]));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Hash de clave maestra actualizado'));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Error al actualizar el hash de la clave maestra'));
}
}
/**
* Create a temporary master pass
*/
public function saveTempAction()
{
try {
$temporaryMasterPassService = $this->dic->get(TemporaryMasterPassService::class);
$temporaryMasterPassService->create(Request::analyze('tmpass_maxtime', 3600));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Clave Temporal Generada'));
} catch (ServiceException $e) {
$this->returnJsonResponseException($e);
}
// $tempMasterGroup = Request::analyze('tmpass_group', 0);
// $tempMasterEmail = Request::analyze('tmpass_chkSendEmail', 0, false, 1);
//
// $this->LogMessage->addDescription(__('Clave Temporal Generada', false));
//
// if ($tempMasterEmail) {
// $Message = new NoticeMessage();
// $Message->setTitle(sprintf(__('Clave Maestra %s'), Util::getAppInfo('appname')));
// $Message->addDescription(__('Se ha generado una nueva clave para el acceso a sysPass y se solicitará en el siguiente inicio.'));
// $Message->addDescription('');
// $Message->addDescription(sprintf(__('La nueva clave es: %s'), $tempMasterPass));
// $Message->addDescription('');
// $Message->addDescription(__('No olvide acceder lo antes posible para guardar los cambios.'));
//
// if ($tempMasterGroup !== 0) {
// Email::sendEmailBatch($Message, UserUtil::getUserGroupEmail($tempMasterGroup));
// } else {
// Email::sendEmailBatch($Message, UserUtil::getUsersEmail());
// }
// }
//
// $this->JsonResponse->setStatus(0);
}
protected function initialize()
{
try {
if (!$this->checkAccess(ActionsInterface::ENCRYPTION_CONFIG)) {
throw new UnauthorizedPageException(SPException::INFO);
}
} catch (UnauthorizedPageException $e) {
$this->returnJsonResponseException($e);
}
}
}

View File

@@ -0,0 +1,162 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Traits\ConfigTrait;
/**
* Class ConfigGeneral
*
* @package SP\Modules\Web\Controllers
*/
class ConfigGeneralController extends SimpleControllerBase
{
use ConfigTrait;
/**
* @throws \SP\Core\Exceptions\InvalidArgumentException
*/
public function saveAction()
{
$messages = [];
$configData = clone $this->config->getConfigData();
// General
$siteLang = Request::analyze('sitelang');
$siteTheme = Request::analyze('sitetheme', 'material-blue');
$sessionTimeout = Request::analyze('session_timeout', 300);
$httpsEnabled = Request::analyze('https_enabled', false, false, true);
$debugEnabled = Request::analyze('debug', false, false, true);
$maintenanceEnabled = Request::analyze('maintenance', false, false, true);
$checkUpdatesEnabled = Request::analyze('updates', false, false, true);
$checkNoticesEnabled = Request::analyze('notices', false, false, true);
$encryptSessionEnabled = Request::analyze('encryptsession', false, false, true);
$configData->setSiteLang($siteLang);
$configData->setSiteTheme($siteTheme);
$configData->setSessionTimeout($sessionTimeout);
$configData->setHttpsEnabled($httpsEnabled);
$configData->setDebug($debugEnabled);
$configData->setMaintenance($maintenanceEnabled);
$configData->setCheckUpdates($checkUpdatesEnabled);
$configData->setChecknotices($checkNoticesEnabled);
$configData->setEncryptSession($encryptSessionEnabled);
// Events
$logEnabled = Request::analyze('log_enabled', false, false, true);
$syslogEnabled = Request::analyze('syslog_enabled', false, false, true);
$remoteSyslogEnabled = Request::analyze('remotesyslog_enabled', false, false, true);
$syslogServer = Request::analyze('remotesyslog_server');
$syslogPort = Request::analyze('remotesyslog_port', 0);
$configData->setLogEnabled($logEnabled);
$configData->setSyslogEnabled($syslogEnabled);
if ($remoteSyslogEnabled && (!$syslogServer || !$syslogPort)) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de syslog remoto'));
}
if ($remoteSyslogEnabled) {
$configData->setSyslogRemoteEnabled($remoteSyslogEnabled);
$configData->setSyslogServer($syslogServer);
$configData->setSyslogPort($syslogPort);
} elseif ($configData->isSyslogEnabled()) {
$configData->setSyslogRemoteEnabled(false);
$messages[] = __u('Syslog remoto deshabilitado');
}
// Proxy
$proxyEnabled = Request::analyze('proxy_enabled', false, false, true);
$proxyServer = Request::analyze('proxy_server');
$proxyPort = Request::analyze('proxy_port', 0);
$proxyUser = Request::analyze('proxy_user');
$proxyPass = Request::analyzeEncrypted('proxy_pass');
// Valores para Proxy
if ($proxyEnabled && (!$proxyServer || !$proxyPort)) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de Proxy'));
}
if ($proxyEnabled) {
$configData->setProxyEnabled(true);
$configData->setProxyServer($proxyServer);
$configData->setProxyPort($proxyPort);
$configData->setProxyUser($proxyUser);
$configData->setProxyPass($proxyPass);
$messages[] = __u('Proxy habiltado');
} elseif ($configData->isProxyEnabled()) {
$configData->setProxyEnabled(false);
$messages[] = __u('Proxy deshabilitado');
}
// Autentificación
$authBasicEnabled = Request::analyze('authbasic_enabled', false, false, true);
$authBasicAutologinEnabled = Request::analyze('authbasic_enabled', false, false, true);
$authBasicDomain = Request::analyze('authbasic_domain');
$authSsoDefaultGroup = Request::analyze('sso_defaultgroup', false, false, true);
$authSsoDefaultProfile = Request::analyze('sso_defaultprofile', false, false, true);
// Valores para Autentificación
if ($authBasicEnabled) {
$configData->setAuthBasicEnabled(true);
$configData->setAuthBasicAutoLoginEnabled($authBasicAutologinEnabled);
$configData->setAuthBasicDomain($authBasicDomain);
$configData->setSsoDefaultGroup($authSsoDefaultGroup);
$configData->setSsoDefaultProfile($authSsoDefaultProfile);
$messages[] = __u('Auth Basic habilitada');
} elseif ($configData->isAuthBasicEnabled()) {
$configData->setAuthBasicEnabled(false);
$configData->setAuthBasicAutoLoginEnabled(false);
$messages[] = __u('Auth Basic deshabiltada');
}
$this->eventDispatcher->notifyEvent('save.config.general', new Event($this, $messages));
$this->saveConfig($configData, $this->config);
}
protected function initialize()
{
try {
if (!$this->checkAccess(ActionsInterface::CONFIG_GENERAL)) {
throw new UnauthorizedPageException(SPException::INFO);
}
} catch (UnauthorizedPageException $e) {
$this->returnJsonResponseException($e);
}
}
}

View File

@@ -0,0 +1,101 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Traits\ConfigTrait;
/**
* Class ConfigLdapController
*
* @package SP\Modules\Web\Controllers
*/
class ConfigLdapController extends SimpleControllerBase
{
use ConfigTrait;
/**
* @throws \SP\Core\Exceptions\InvalidArgumentException
*/
public function saveAction()
{
$messages = [];
$configData = clone $this->config->getConfigData();
// LDAP
$ldapEnabled = Request::analyze('ldap_enabled', false, false, true);
$ldapADSEnabled = Request::analyze('ldap_ads', false, false, true);
$ldapServer = Request::analyze('ldap_server');
$ldapBase = Request::analyze('ldap_base');
$ldapGroup = Request::analyze('ldap_group');
$ldapDefaultGroup = Request::analyze('ldap_defaultgroup', 0);
$ldapDefaultProfile = Request::analyze('ldap_defaultprofile', 0);
$ldapBindUser = Request::analyze('ldap_binduser');
$ldapBindPass = Request::analyzeEncrypted('ldap_bindpass');
// Valores para la configuración de LDAP
if ($ldapEnabled && (!$ldapServer || !$ldapBase || !$ldapBindUser)) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de LDAP'));
}
if ($ldapEnabled) {
$configData->setLdapEnabled(true);
$configData->setLdapAds($ldapADSEnabled);
$configData->setLdapServer($ldapServer);
$configData->setLdapBase($ldapBase);
$configData->setLdapGroup($ldapGroup);
$configData->setLdapDefaultGroup($ldapDefaultGroup);
$configData->setLdapDefaultProfile($ldapDefaultProfile);
$configData->setLdapBindUser($ldapBindUser);
$configData->setLdapBindPass($ldapBindPass);
$messages[] = __u('LDAP habiltado');
} elseif ($configData->isLdapEnabled()) {
$configData->setLdapEnabled(false);
$messages[] = __u('LDAP deshabilitado');
}
$this->eventDispatcher->notifyEvent('save.config.ldap', new Event($this, $messages));
$this->saveConfig($configData, $this->config);
}
protected function initialize()
{
try {
if (!$this->checkAccess(ActionsInterface::LDAP_CONFIG)) {
throw new UnauthorizedPageException(SPException::INFO);
}
} catch (UnauthorizedPageException $e) {
$this->returnJsonResponseException($e);
}
}
}

View File

@@ -0,0 +1,106 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Traits\ConfigTrait;
/**
* Class ConfigMailController
*
* @package SP\Modules\Web\Controllers
*/
class ConfigMailController extends SimpleControllerBase
{
use ConfigTrait;
/**
* @throws \SP\Core\Exceptions\InvalidArgumentException
*/
public function saveAction()
{
$messages = [];
$configData = clone $this->config->getConfigData();
// Mail
$mailEnabled = Request::analyze('mail_enabled', false, false, true);
$mailServer = Request::analyze('mail_server');
$mailPort = Request::analyze('mail_port', 25);
$mailUser = Request::analyze('mail_user');
$mailPass = Request::analyzeEncrypted('mail_pass');
$mailSecurity = Request::analyze('mail_security');
$mailFrom = Request::analyze('mail_from');
$mailRequests = Request::analyze('mail_requestsenabled', false, false, true);
$mailAuth = Request::analyze('mail_authenabled', false, false, true);
// Valores para la configuración del Correo
if ($mailEnabled && (!$mailServer || !$mailFrom)) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de Correo'));
}
if ($mailEnabled) {
$configData->setMailEnabled(true);
$configData->setMailRequestsEnabled($mailRequests);
$configData->setMailServer($mailServer);
$configData->setMailPort($mailPort);
$configData->setMailSecurity($mailSecurity);
$configData->setMailFrom($mailFrom);
if ($mailAuth) {
$configData->setMailAuthenabled($mailAuth);
$configData->setMailUser($mailUser);
$configData->setMailPass($mailPass);
}
$messages[] = __u('Correo habiltado');
} elseif ($configData->isMailEnabled()) {
$configData->setMailEnabled(false);
$configData->setMailRequestsEnabled(false);
$configData->setMailAuthenabled(false);
$messages[] = __u('Correo deshabilitado');
}
$this->eventDispatcher->notifyEvent('save.config.mail', new Event($this, $messages));
$this->saveConfig($configData, $this->config);
}
protected function initialize()
{
try {
if (!$this->checkAccess(ActionsInterface::MAIL_CONFIG)) {
throw new UnauthorizedPageException(SPException::INFO);
}
} catch (UnauthorizedPageException $e) {
$this->returnJsonResponseException($e);
}
}
}

View File

@@ -29,6 +29,7 @@ use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Crypt\CryptSessionHandler;
use SP\Core\CryptMasterPass;
use SP\Core\Events\Event;
use SP\Core\Language;
use SP\Core\Plugin\PluginUtil;
use SP\Core\Task;
@@ -63,6 +64,7 @@ class ConfigManagerController extends ControllerBase
* @throws \Psr\Container\NotFoundExceptionInterface
* @throws \SP\Core\Exceptions\InvalidArgumentException
* @throws \SP\Services\Config\ParameterNotFoundException
* @throws \SP\Core\Exceptions\SPException
*/
public function indexAction()
{
@@ -76,6 +78,7 @@ class ConfigManagerController extends ControllerBase
* @throws \Psr\Container\NotFoundExceptionInterface
* @throws \SP\Core\Exceptions\InvalidArgumentException
* @throws \SP\Services\Config\ParameterNotFoundException
* @throws \SP\Core\Exceptions\SPException
*/
protected function getTabs()
{
@@ -118,7 +121,7 @@ class ConfigManagerController extends ControllerBase
}
$this->eventDispatcher->notifyEvent('show.config', $this);
$this->eventDispatcher->notifyEvent('show.config', new Event($this));
$this->tabsHelper->renderTabs(Acl::getActionRoute(ActionsInterface::CONFIG), Request::analyze('tabIndex', 0));
@@ -261,7 +264,7 @@ class ConfigManagerController extends ControllerBase
$template->addTemplate('backup');
$template->assign('siteName', Util::getAppInfo('appname'));
$template->assign('backupDir', Bootstrap::$SERVERROOT . '/backup');
$template->assign('backupDir', BACKUP_PATH);
$template->assign('backupPath', Bootstrap::$WEBROOT . '/backup');
$backupHash = $this->configData->getBackupHash();
@@ -270,7 +273,7 @@ class ConfigManagerController extends ControllerBase
$backupFile = $template->siteName . '-' . $backupHash . '.tar.gz';
$template->assign('backupFile', [
'absolute' => $template->backupDir . DIRECTORY_SEPARATOR . $backupFile,
'absolute' => BACKUP_PATH . DIRECTORY_SEPARATOR . $backupFile,
'relative' => $template->backupPath . '/' . $backupFile,
'filename' => $backupFile
]);
@@ -278,7 +281,7 @@ class ConfigManagerController extends ControllerBase
$backupDbFile = $template->siteName . '_db-' . $backupHash . '.sql';
$template->assign('backupDbFile', [
'absolute' => $template->backupDir . DIRECTORY_SEPARATOR . $backupDbFile,
'absolute' => BACKUP_PATH . DIRECTORY_SEPARATOR . $backupDbFile,
'relative' => $template->backupPath . '/' . $backupDbFile,
'filename' => $backupDbFile
]);
@@ -291,7 +294,7 @@ class ConfigManagerController extends ControllerBase
$exportFile = $template->siteName . '-' . $exportHash . '.xml';
$template->assign('exportFile', [
'absolute' => $template->backupDir . DIRECTORY_SEPARATOR . $exportFile,
'absolute' => BACKUP_PATH . DIRECTORY_SEPARATOR . $exportFile,
'relative' => $template->backupPath . '/' . $exportFile,
'filename' => $exportFile
]);

View File

@@ -0,0 +1,119 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Traits\ConfigTrait;
/**
* Class ConfigWikiController
*
* @package SP\Modules\Web\Controllers
*/
class ConfigWikiController extends SimpleControllerBase
{
use ConfigTrait;
/**
* @throws \SP\Core\Exceptions\InvalidArgumentException
*/
public function saveAction()
{
$messages = [];
$configData = clone $this->config->getConfigData();
// Wiki
$wikiEnabled = Request::analyze('wiki_enabled', false, false, true);
$wikiSearchUrl = Request::analyze('wiki_searchurl');
$wikiPageUrl = Request::analyze('wiki_pageurl');
$wikiFilter = Request::analyze('wiki_filter');
// Valores para la conexión a la Wiki
if ($wikiEnabled && (!$wikiSearchUrl || !$wikiPageUrl || !$wikiFilter)) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de Wiki'));
}
if ($wikiEnabled) {
$configData->setWikiEnabled(true);
$configData->setWikiSearchurl($wikiSearchUrl);
$configData->setWikiPageurl($wikiPageUrl);
$configData->setWikiFilter(explode(',', $wikiFilter));
$messages[] = __u('Wiki habiltada');
} elseif ($configData->isWikiEnabled()) {
$configData->setWikiEnabled(false);
$messages[] = __u('Wiki deshabilitada');
}
// DokuWiki
$dokuWikiEnabled = Request::analyze('dokuwiki_enabled', false, false, true);
$dokuWikiUrl = Request::analyze('dokuwiki_url');
$dokuWikiUrlBase = Request::analyze('dokuwiki_urlbase');
$dokuWikiUser = Request::analyze('dokuwiki_user');
$dokuWikiPass = Request::analyzeEncrypted('dokuwiki_pass');
$dokuWikiNamespace = Request::analyze('dokuwiki_namespace');
// Valores para la conexión a la API de DokuWiki
if ($dokuWikiEnabled && (!$dokuWikiUrl || !$dokuWikiUrlBase)) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de DokuWiki'));
}
if ($dokuWikiEnabled) {
$configData->setDokuwikiEnabled(true);
$configData->setDokuwikiUrl($dokuWikiUrl);
$configData->setDokuwikiUrlBase(trim($dokuWikiUrlBase, '/'));
$configData->setDokuwikiUser($dokuWikiUser);
$configData->setDokuwikiPass($dokuWikiPass);
$configData->setDokuwikiNamespace($dokuWikiNamespace);
$messages[] = __u('DokuWiki habilitada');
} elseif ($configData->isDokuwikiEnabled()) {
$configData->setDokuwikiEnabled(false);
$messages[] = __u('DokuWiki deshabilitada');
}
$this->eventDispatcher->notifyEvent('save.config.wiki', new Event($this, $messages));
$this->saveConfig($configData, $this->config);
}
protected function initialize()
{
try {
if (!$this->checkAccess(ActionsInterface::WIKI_CONFIG)) {
throw new UnauthorizedPageException(SPException::INFO);
}
} catch (UnauthorizedPageException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage(), [$e->getHint()]);
}
}
}

View File

@@ -189,7 +189,7 @@ abstract class ControllerBase
try {
echo $this->view->render();
} catch (FileNotFoundException $e) {
debugLog($e->getMessage(), true);
processException($e);
echo $e->getMessage();
}
@@ -205,7 +205,7 @@ abstract class ControllerBase
try {
return $this->view->render();
} catch (FileNotFoundException $e) {
debugLog($e->getMessage(), true);
processException($e);
return $e->getMessage();
}

View File

@@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\CustomFieldDefinitionData;
@@ -98,8 +99,10 @@ class CustomFieldController extends ControllerBase implements CrudControllerInte
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.customField.create', $this);
$this->eventDispatcher->notifyEvent('show.customField.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -156,8 +159,10 @@ class CustomFieldController extends ControllerBase implements CrudControllerInte
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.customField.edit', $this);
$this->eventDispatcher->notifyEvent('show.customField.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -180,11 +185,11 @@ class CustomFieldController extends ControllerBase implements CrudControllerInte
$this->deleteCustomFieldsForItem(ActionsInterface::CUSTOMFIELD, $id);
$this->eventDispatcher->notifyEvent('delete.customField', $this);
$this->eventDispatcher->notifyEvent('delete.customField', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Campo eliminado'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -205,13 +210,13 @@ class CustomFieldController extends ControllerBase implements CrudControllerInte
$this->customFieldService->create($form->getItemData());
$this->eventDispatcher->notifyEvent('create.customField', $this);
$this->eventDispatcher->notifyEvent('create.customField', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Campo creado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -235,13 +240,13 @@ class CustomFieldController extends ControllerBase implements CrudControllerInte
$this->customFieldService->update($form->getItemData());
$this->eventDispatcher->notifyEvent('edit.customField', $this);
$this->eventDispatcher->notifyEvent('edit.customField', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Campo actualizado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -265,8 +270,10 @@ class CustomFieldController extends ControllerBase implements CrudControllerInte
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.customField', $this);
$this->eventDispatcher->notifyEvent('show.customField', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -124,7 +124,7 @@ class LayoutHelper extends HelperBase
// Cargar la clave pública en la sesión
SessionUtil::loadPublicKey();
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
}
$this->getResourcesLinks();

View File

@@ -26,6 +26,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\DataModel\ItemSearchData;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Helpers\ItemsGridHelper;
@@ -118,7 +119,7 @@ class ItemManagerController extends ControllerBase
$this->tabsGridHelper->addTab($this->getPluginsList());
}
$this->eventDispatcher->notifyEvent('show.itemlist.items', $this);
$this->eventDispatcher->notifyEvent('show.itemlist.items', new Event($this));
$this->tabsGridHelper->renderTabs(Acl::getActionRoute(ActionsInterface::ITEMS_MANAGE), Request::analyze('tabIndex', 0));

View File

@@ -117,7 +117,7 @@ class MainController extends ControllerBase implements ActionsInterface
// Cargar la clave pública en la sesión
SessionUtil::loadPublicKey();
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
}
$this->getResourcesLinks();

View File

@@ -24,9 +24,9 @@
namespace SP\Modules\Web\Controllers;
use Defuse\Crypto\Exception\CryptoException;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\PublicLinkListData;
@@ -98,8 +98,10 @@ class PublicLinkController extends ControllerBase implements CrudControllerInter
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.publicLink.create', $this);
$this->eventDispatcher->notifyEvent('show.publicLink.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -150,15 +152,11 @@ class PublicLinkController extends ControllerBase implements CrudControllerInter
try {
$this->publicLinkService->refresh($id);
$this->eventDispatcher->notifyEvent('edit.publicLink.refresh', $this);
$this->eventDispatcher->notifyEvent('edit.publicLink.refresh', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Enlace actualizado'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (CryptoException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -183,8 +181,10 @@ class PublicLinkController extends ControllerBase implements CrudControllerInter
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.publicLink.edit', $this);
$this->eventDispatcher->notifyEvent('show.publicLink.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -208,11 +208,11 @@ class PublicLinkController extends ControllerBase implements CrudControllerInter
$this->deleteCustomFieldsForItem(ActionsInterface::PUBLICLINK, $id);
$this->eventDispatcher->notifyEvent('delete.publicLink', $this);
$this->eventDispatcher->notifyEvent('delete.publicLink', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Enlace eliminado'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -223,7 +223,6 @@ class PublicLinkController extends ControllerBase implements CrudControllerInter
*
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
* @throws \SP\Core\Dic\ContainerException
*/
public function saveCreateAction()
{
@@ -238,17 +237,13 @@ class PublicLinkController extends ControllerBase implements CrudControllerInter
$this->publicLinkService->create($form->getItemData());
// $this->publicLinkService->logAction($id, ActionsInterface::PUBLICLINK_CREATE);
$this->eventDispatcher->notifyEvent('create.publicLink', $this);
$this->eventDispatcher->notifyEvent('create.publicLink', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Enlace creado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (CryptoException $e) {
debugLog($e->getMessage(), true);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -282,8 +277,10 @@ class PublicLinkController extends ControllerBase implements CrudControllerInter
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.publicLink', $this);
$this->eventDispatcher->notifyEvent('show.publicLink', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -28,6 +28,7 @@ use DI\Container;
use Interop\Container\ContainerInterface;
use Klein\Klein;
use SP\Config\Config;
use SP\Core\Acl\Acl;
use SP\Core\Events\EventDispatcher;
use SP\Core\Session\Session;
use SP\Core\UI\Theme;
@@ -74,6 +75,10 @@ abstract class SimpleControllerBase
* @var ContainerInterface
*/
protected $dic;
/**
* @var Acl
*/
protected $acl;
/**
* SimpleControllerBase constructor.
@@ -95,6 +100,7 @@ abstract class SimpleControllerBase
$this->theme = $this->dic->get(Theme::class);
$this->eventDispatcher = $this->dic->get(EventDispatcher::class);
$this->router = $this->dic->get(Klein::class);
$this->acl = $this->dic->get(Acl::class);
if (method_exists($this, 'initialize')) {
$this->initialize();
@@ -109,4 +115,15 @@ abstract class SimpleControllerBase
$this->checkLoggedInSession($this->session);
$this->checkSecurityToken($this->session);
}
/**
* Comprobar si está permitido el acceso al módulo/página.
*
* @param null $action La acción a comprobar
* @return bool
*/
protected function checkAccess($action)
{
return $this->session->getUserData()->getIsAdminApp() || $this->acl->checkUserAccess($action);
}
}

View File

@@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\TagData;
@@ -96,8 +97,10 @@ class TagController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.tag.create', $this);
$this->eventDispatcher->notifyEvent('show.tag.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -149,8 +152,10 @@ class TagController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.tag.edit', $this);
$this->eventDispatcher->notifyEvent('show.tag.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -173,11 +178,11 @@ class TagController extends ControllerBase implements CrudControllerInterface
$this->deleteCustomFieldsForItem(ActionsInterface::TAG, $id);
$this->eventDispatcher->notifyEvent('delete.tag', $this);
$this->eventDispatcher->notifyEvent('delete.tag', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Etiqueta eliminada'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -200,13 +205,13 @@ class TagController extends ControllerBase implements CrudControllerInterface
$this->tagService->create($form->getItemData());
$this->eventDispatcher->notifyEvent('create.tag', $this);
$this->eventDispatcher->notifyEvent('create.tag', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Etiqueta creada'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -230,13 +235,13 @@ class TagController extends ControllerBase implements CrudControllerInterface
$this->tagService->update($form->getItemData());
$this->eventDispatcher->notifyEvent('edit.tag', $this);
$this->eventDispatcher->notifyEvent('edit.tag', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Etiqueta actualizada'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -260,8 +265,10 @@ class TagController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.tag', $this);
$this->eventDispatcher->notifyEvent('show.tag', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Modules\Web\Controllers\Traits;
use SP\Bootstrap;
use SP\Config\Config;
use SP\Config\ConfigData;
use SP\Http\JsonResponse;
use SP\Util\Util;
/**
* Trait ConfigTrait
*
* @package SP\Modules\Web\Controllers\Traits
*/
trait ConfigTrait
{
use JsonTrait;
/**
* Guardar la configuración
*
* @param ConfigData $configData
* @param Config $config
*/
protected function saveConfig(ConfigData $configData, Config $config)
{
try {
if ($configData->isDemoEnabled()) {
$this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, esto es una DEMO!!'));
}
$config->saveConfig($configData);
if ($configData->isMaintenance()) {
Util::lockApp(false);
} elseif (Bootstrap::$LOCK > 0) {
Util::unlockApp(false);
}
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Configuración actualizada'));
} catch (\Exception $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Error al guardar la configuración'));
}
}
}

View File

@@ -24,6 +24,7 @@
namespace SP\Modules\Web\Controllers\Traits;
use SP\Core\Exceptions\SPException;
use SP\Http\JsonResponse;
use SP\Util\Json;
@@ -72,6 +73,25 @@ trait JsonTrait
}
Json::returnJson($jsonResponse);
}
/**
* Returns JSON response
*
* @param \Exception $exception
* @param int $status Status code
*/
protected function returnJsonResponseException(\Exception $exception, $status = JsonResponse::JSON_ERROR)
{
$jsonResponse = new JsonResponse();
$jsonResponse->setStatus($status);
$jsonResponse->setDescription($exception->getMessage());
if ($exception instanceof SPException && $exception->getHint() !== null ) {
$jsonResponse->setMessages([$exception->getHint()]);
}
Json::returnJson($jsonResponse);
}
}

View File

@@ -26,6 +26,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\Core\SessionUtil;
@@ -100,8 +101,10 @@ class UserController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.user.create', $this);
$this->eventDispatcher->notifyEvent('show.user.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -159,8 +162,10 @@ class UserController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.user.edit', $this);
$this->eventDispatcher->notifyEvent('show.user.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -193,8 +198,10 @@ class UserController extends ControllerBase implements CrudControllerInterface
$this->view->assign('user', $user);
$this->eventDispatcher->notifyEvent('show.user.editPass', $this);
$this->eventDispatcher->notifyEvent('show.user.editPass', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -220,11 +227,11 @@ class UserController extends ControllerBase implements CrudControllerInterface
$this->deleteCustomFieldsForItem(ActionsInterface::USER, $id);
$this->eventDispatcher->notifyEvent('delete.user', $this);
$this->eventDispatcher->notifyEvent('delete.user', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Usuario eliminado'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -248,7 +255,7 @@ class UserController extends ControllerBase implements CrudControllerInterface
$this->addCustomFieldsForItem(ActionsInterface::USER, $id);
$this->eventDispatcher->notifyEvent('create.user', $this);
$this->eventDispatcher->notifyEvent('create.user', new Event($this));
if ($form->getItemData()->isIsChangePass()
&& !AuthUtil::mailPassRecover($form->getItemData())
@@ -263,8 +270,8 @@ class UserController extends ControllerBase implements CrudControllerInterface
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Usuario creado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -291,7 +298,7 @@ class UserController extends ControllerBase implements CrudControllerInterface
$this->updateCustomFieldsForItem(ActionsInterface::USER, $id);
$this->eventDispatcher->notifyEvent('edit.user', $this);
$this->eventDispatcher->notifyEvent('edit.user', new Event($this));
if ($form->getItemData()->isIsChangePass()
&& !AuthUtil::mailPassRecover($form->getItemData())
@@ -306,8 +313,8 @@ class UserController extends ControllerBase implements CrudControllerInterface
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Usuario actualizado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -331,13 +338,13 @@ class UserController extends ControllerBase implements CrudControllerInterface
$this->userService->updatePass($form->getItemData());
// $this->userService->logAction($id, ActionsInterface::USER_EDIT_PASS);
$this->eventDispatcher->notifyEvent('edit.user.pass', $this);
$this->eventDispatcher->notifyEvent('edit.user.pass', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Clave actualizada'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -362,8 +369,10 @@ class UserController extends ControllerBase implements CrudControllerInterface
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.user', $this);
$this->eventDispatcher->notifyEvent('show.user', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -26,6 +26,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\UserGroupData;
@@ -102,8 +103,10 @@ class UserGroupController extends ControllerBase implements CrudControllerInterf
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.userGroup.create', $this);
$this->eventDispatcher->notifyEvent('show.userGroup.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -159,8 +162,10 @@ class UserGroupController extends ControllerBase implements CrudControllerInterf
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.userGroup.edit', $this);
$this->eventDispatcher->notifyEvent('show.userGroup.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -184,11 +189,11 @@ class UserGroupController extends ControllerBase implements CrudControllerInterf
$this->deleteCustomFieldsForItem(ActionsInterface::GROUP, $id);
$this->eventDispatcher->notifyEvent('delete.userGroup', $this);
$this->eventDispatcher->notifyEvent('delete.userGroup', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Grupo eliminado'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -215,13 +220,13 @@ class UserGroupController extends ControllerBase implements CrudControllerInterf
$this->addCustomFieldsForItem(ActionsInterface::GROUP, $id);
$this->eventDispatcher->notifyEvent('create.userGroup', $this);
$this->eventDispatcher->notifyEvent('create.userGroup', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Grupo creado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -250,13 +255,13 @@ class UserGroupController extends ControllerBase implements CrudControllerInterf
$this->updateCustomFieldsForItem(ActionsInterface::GROUP, $id);
$this->eventDispatcher->notifyEvent('edit.useGroup', $this);
$this->eventDispatcher->notifyEvent('edit.useGroup', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Grupo actualizado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -280,8 +285,10 @@ class UserGroupController extends ControllerBase implements CrudControllerInterf
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.userGroup', $this);
$this->eventDispatcher->notifyEvent('show.userGroup', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -26,7 +26,7 @@ namespace SP\Modules\Web\Controllers;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Exceptions\SPException;
use SP\Core\Events\Event;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\ProfileData;
use SP\Forms\UserProfileForm;
@@ -95,8 +95,10 @@ class UserProfileController extends ControllerBase implements CrudControllerInte
try {
$this->setViewData();
$this->eventDispatcher->notifyEvent('show.userProfile.create', $this);
$this->eventDispatcher->notifyEvent('show.userProfile.create', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(1, $e->getMessage());
}
@@ -152,8 +154,10 @@ class UserProfileController extends ControllerBase implements CrudControllerInte
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.userProfile.edit', $this);
$this->eventDispatcher->notifyEvent('show.userProfile.edit', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -177,11 +181,11 @@ class UserProfileController extends ControllerBase implements CrudControllerInte
$this->deleteCustomFieldsForItem(ActionsInterface::PROFILE, $id);
$this->eventDispatcher->notifyEvent('delete.userProfile', $this);
$this->eventDispatcher->notifyEvent('delete.userProfile', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Perfil eliminado'));
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -207,13 +211,13 @@ class UserProfileController extends ControllerBase implements CrudControllerInte
$this->addCustomFieldsForItem(ActionsInterface::PROFILE, $id);
$this->eventDispatcher->notifyEvent('create.userProfile', $this);
$this->eventDispatcher->notifyEvent('create.userProfile', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Perfil creado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -241,13 +245,13 @@ class UserProfileController extends ControllerBase implements CrudControllerInte
$this->updateCustomFieldsForItem(ActionsInterface::PROFILE, $id);
$this->eventDispatcher->notifyEvent('edit.userProfile', $this);
$this->eventDispatcher->notifyEvent('edit.userProfile', new Event($this));
$this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Perfil actualizado'));
} catch (ValidationException $e) {
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
} catch (SPException $e) {
debugLog($e->getMessage(), true);
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
@@ -271,8 +275,10 @@ class UserProfileController extends ControllerBase implements CrudControllerInte
try {
$this->setViewData($id);
$this->eventDispatcher->notifyEvent('show.userProfile', $this);
$this->eventDispatcher->notifyEvent('show.userProfile', new Event($this));
} catch (\Exception $e) {
processException($e);
$this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}

View File

@@ -2,7 +2,7 @@
<form method="post" name="frmAccounts" id="frmAccounts" class="form-action"
data-onsubmit="config/save"
data-type="general"
data-action-route="configAccount/save"
data-reload="1"
data-hash="">

View File

@@ -44,10 +44,6 @@
<?php endif; ?>
</table>
<form method="post" name="frmBackup" id="frmBackup" class="form-action"
data-onsubmit="config/backup">
</form>
<div class="tab-actions">
<ul>
<li>
@@ -66,8 +62,10 @@
</li>
<li>
<button form="frmBackup"
class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored <?php echo $icons->getIconPlay()->getClassButton(); ?>"
<button type="button"
class="btn-action mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored <?php echo $icons->getIconPlay()->getClassButton(); ?>"
data-onclick="config/backup"
data-action-route="configBackup/fileBackup"
title="<?php echo $icons->getIconPlay()->getTitle(); ?>">
<i class="material-icons"><?php echo $icons->getIconPlay()->getIcon(); ?></i>
</button>
@@ -79,8 +77,8 @@
<?php echo __('Exportar Cuentas'); ?>
</div>
<form method="post" name="frmExport" id="frmExport" class="form-action"
data-onsubmit="config/export">
<form method="post" name="frmExport" id="frmExport" class="form-action" data-onsubmit="config/export"
data-action-route="configBackup/xmlExport">
<table class="data round">
<tr>
<td class="descField">

View File

@@ -1,7 +1,8 @@
<?php /** @var $icons \Theme\Icons */ ?>
<form method="post" name="frmCrypt" id="frmCrypt" class="form-action" data-onsubmit="config/masterpass"
data-type="masterpass"
<form method="post" name="frmCrypt" id="frmCrypt" class="form-action"
data-onsubmit="config/save"
data-action-route="configEncryption/save"
data-hash="">
<div id="title" class="midroundup titleNormal">
@@ -138,7 +139,7 @@
<button type="button"
class="btn-action mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored <?php echo $icons->getIconCheck()->getClassButton(); ?>"
data-onclick="config/refreshMpass"
data-action-id="<?php echo \SP\Core\Acl\ActionsInterface::ENCRYPTION_REFRESH; ?>"
data-action-route="configEncryption/refresh"
title="<?php echo __('Actualizar hash de clave maestra'); ?>">
<i class="material-icons"><?php echo $icons->getIconRefresh()->getIcon(); ?></i>
</button>
@@ -163,8 +164,7 @@
<form method="post" name="frmTempMasterPass" id="frmTempMasterPass" class="form-action"
data-onsubmit="config/save"
data-type="temppass"
data-nextaction-id="<?php echo \SP\Core\Acl\ActionsInterface::ENCRYPTION_TEMPPASS; ?>">
data-action-route="configEncryption/saveTemp">
<table class="data tblConfig round">
<tr>
<td class="descField">
@@ -266,8 +266,6 @@
</tr>
<?php endif; ?>
</table>
<input type="hidden" name="sk" value="">
<input type="hidden" name="isAjax" value="1"/>
</form>
<div class="tab-actions">

View File

@@ -4,7 +4,7 @@
?>
<form method="post" name="frmConfig" id="frmConfig" class="form-action"
data-onsubmit="config/save"
data-type="general"
data-action-route="configGeneral/save"
data-reload="1"
data-hash="">
@@ -12,9 +12,6 @@
<?php include $this->includeTemplate('general-events'); ?>
<?php include $this->includeTemplate('general-proxy'); ?>
<?php include $this->includeTemplate('general-auth'); ?>
<input type="hidden" name="sk" value="">
<input type="hidden" name="isAjax" value="1"/>
</form>
<div class="tab-actions">

View File

@@ -6,7 +6,7 @@
<form method="post" name="frmLdap" id="frmLdap" class="form-action"
data-onsubmit="config/save"
data-type="ldap"
data-action-route="configLdap/save"
data-hash="">
<table id="tblLdap" class="data tblConfig round">
<?php if ($ldapIsAvailable || $isDemoMode): ?>
@@ -312,10 +312,6 @@
</tr>
<?php endif; ?>
</table>
<input type="hidden" name="type" value="ldap"/>
<input type="hidden" name="sk" value="">
<input type="hidden" name="isAjax" value="1"/>
</form>
<div class="tab-actions">
@@ -331,7 +327,7 @@
<button type="button"
class="btn-action mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored"
data-onclick="appMgmt/ldapSync"
data-action-id="<?php echo \SP\Core\Acl\ActionsInterface::LDAP_SYNC; ?>"
data-action-route="configLdap/sync"
title="<?php echo __('Importar usuarios de LDAP'); ?>">
<i class="material-icons">get_app</i>
</button>
@@ -340,6 +336,7 @@
<button type="button"
class="btn-action mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored <?php echo $icons->getIconCheck()->getClassButton(); ?>"
data-onclick="checks/ldap"
data-action-route="configLdap/check"
data-src="#frmLdap"
title="<?php echo $icons->getIconCheck()->getTitle(); ?>">
<i class="material-icons"><?php echo $icons->getIconCheck()->getIcon(); ?></i>

View File

@@ -1,6 +1,8 @@
<?php /** @var $icons \Theme\Icons */ ?>
<form method="post" name="frmWiki" id="frmWiki" class="form-action" data-onsubmit="config/save" data-type="wiki"
<form method="post" name="frmWiki" id="frmWiki" class="form-action"
data-onsubmit="config/save"
data-action-route="configWiki/save"
data-hash="">
<div id="title" class="midroundup titleNormal">
@@ -258,10 +260,6 @@
</td>
</tr>
</table>
<input type="hidden" name="type" value="dokuwiki"/>
<input type="hidden" name="sk" value="">
<input type="hidden" name="isAjax" value="1"/>
</form>
<div class="tab-actions">
@@ -277,6 +275,7 @@
<button type="button"
class="btn-action mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored <?php echo $icons->getIconCheck()->getClassButton(); ?>"
data-onclick="checks/wiki"
data-action-route="configWiki/checkDokuwiki"
data-src="#frmWiki"
title="<?php echo $icons->getIconCheck()->getTitle(); ?>">
<i class="material-icons"><?php echo $icons->getIconCheck()->getIcon(); ?></i>

View File

@@ -26,7 +26,7 @@
* Función para enviar mensajes al log de errores
*
* @param mixed $data
* @param bool $printLastCaller
* @param bool $printLastCaller
*/
function debugLog($data, $printLastCaller = false)
{
@@ -48,6 +48,20 @@ function debugLog($data, $printLastCaller = false)
}
}
/**
* Procesar una excepción y registrarla en el log
*
* @param \Exception $exception
*/
function processException(\Exception $exception)
{
debugLog(__($exception->getMessage()), true);
if ($exception->getPrevious() !== null) {
debugLog(__($exception->getPrevious()->getMessage()));
}
}
/**
* @param $trace
* @return string
@@ -73,7 +87,7 @@ function formatTrace($trace)
* Alias gettext function
*
* @param string $message
* @param bool $translate Si es necesario traducir
* @param bool $translate Si es necesario traducir
* @return string
*/
function __($message, $translate = true)
@@ -97,7 +111,7 @@ function __u($message)
*
* @param string $domain
* @param string $message
* @param bool $translate
* @param bool $translate
* @return string
*/
function _t($domain, $message, $translate = true)

View File

@@ -128,7 +128,7 @@ class AccountCrypt
$AccountDataBase = new AccountData();
TaskFactory::$Message->setTask(__('Actualizar Clave Maestra'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
$counter = 0;
$startTime = time();
@@ -150,7 +150,7 @@ class AccountCrypt
TaskFactory::$Message->setMessage(__('Cuentas actualizadas') . ': ' . $counter . '/' . $numAccounts);
TaskFactory::$Message->setProgress(round(($counter * 100) / $numAccounts, 2));
TaskFactory::$Message->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
TaskFactory::sendTaskMessage();
TaskFactory::update();
debugLog(TaskFactory::$Message->composeText());
}
@@ -249,7 +249,7 @@ class AccountCrypt
$AccountDataBase = new AccountData();
TaskFactory::$Message->setTask(__('Actualizar Clave Maestra'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
$counter = 0;
$startTime = time();
@@ -271,7 +271,7 @@ class AccountCrypt
TaskFactory::$Message->setMessage(__('Cuentas actualizadas') . ': ' . $counter . '/' . $numAccounts);
TaskFactory::$Message->setProgress(round(($counter * 100) / $numAccounts, 2));
TaskFactory::$Message->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
TaskFactory::sendTaskMessage();
TaskFactory::update();
debugLog(TaskFactory::$Message->composeText());
}

View File

@@ -135,7 +135,7 @@ class AccountHistoryCrypt
$AccountDataBase->hash = Hash::hashKey($currentMasterPass);
TaskFactory::$Message->setTask(__('Actualizar Clave Maestra (H)'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
$counter = 0;
$startTime = time();
@@ -158,7 +158,7 @@ class AccountHistoryCrypt
TaskFactory::$Message->setProgress(round(($counter * 100) / $numAccounts, 2));
TaskFactory::$Message->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
TaskFactory::sendTaskMessage();
TaskFactory::update();
debugLog(TaskFactory::$Message->composeText());
}
@@ -263,7 +263,7 @@ class AccountHistoryCrypt
$AccountDataBase->hash = Hash::hashKey($newMasterPass);
TaskFactory::$Message->setTask(__('Actualizar Clave Maestra (H)'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
$counter = 0;
$startTime = time();
@@ -286,7 +286,7 @@ class AccountHistoryCrypt
TaskFactory::$Message->setProgress(round(($counter * 100) / $numAccounts, 2));
TaskFactory::$Message->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
TaskFactory::sendTaskMessage();
TaskFactory::update();
debugLog(TaskFactory::$Message->composeText());
}

View File

@@ -29,6 +29,7 @@ use SP\Core\Exceptions\ConfigException;
use SP\Core\Session\Session;
use SP\Core\Traits\InjectableTrait;
use SP\Storage\XmlFileStorageInterface;
use SP\Storage\XmlHandler;
defined('APP_ROOT') || die();
@@ -48,7 +49,7 @@ class Config
*/
private $configData;
/**
* @var XmlFileStorageInterface
* @var XmlHandler
*/
private $fileStorage;
/**
@@ -153,22 +154,22 @@ class Config
/**
* Guardar la configuración
*
* @param ConfigData $Config
* @param ConfigData $configData
* @param bool $backup
*/
public function saveConfig(ConfigData $Config = null, $backup = true)
public function saveConfig(ConfigData $configData = null, $backup = true)
{
$ConfigData = null === $Config ? $this->configData : $Config;
$ConfigData->setConfigDate(time());
$ConfigData->setConfigSaver($this->session->getUserData()->getLogin());
$ConfigData->setConfigHash();
$configData = null === $configData ? $this->configData : $configData;
$configData->setConfigDate(time());
$configData->setConfigSaver($this->session->getUserData()->getLogin());
$configData->setConfigHash();
$this->fileStorage->setItems($ConfigData);
$this->fileStorage->setItems($configData);
$this->fileStorage->save('config');
if ($backup) {
$this->backupToDB();
}
// if ($backup) {
// $this->backupToDB();
// }
}
/**

View File

@@ -97,7 +97,7 @@ class MainActionController
throw new ValidationException(__('Es necesario confirmar la actualización', false));
}
TaskFactory::createTask('upgrade', $taskId);
TaskFactory::create('upgrade', $taskId);
$this->upgrade($version, $type);
@@ -105,7 +105,7 @@ class MainActionController
$JsonResponse->addMessage(__('En 5 segundos será redirigido al login', false));
$JsonResponse->setStatus(0);
} catch (\Exception $e) {
TaskFactory::endTask();
TaskFactory::end();
$JsonResponse->setDescription($e->getMessage());
}
@@ -131,7 +131,7 @@ class MainActionController
$Upgrade = new Upgrade();
$Upgrade->doUpgrade($version);
TaskFactory::endTask();
TaskFactory::end();
$this->ConfigData->setMaintenance(false);
$this->ConfigData->setUpgradeKey('');

View File

@@ -99,14 +99,12 @@ class Crypt
{
try {
if ($securedKey instanceof Key) {
$key = $securedKey;
return Crypto::decrypt($data, $securedKey);
} elseif (null !== $password && $securedKey instanceof KeyProtectedByPassword) {
$key = self::unlockSecuredKey($securedKey, $password);
} else {
$key = Key::loadFromAsciiSafeString($securedKey);
return Crypto::decrypt($data, self::unlockSecuredKey($securedKey, $password));
}
return Crypto::decrypt($data, $key);
return Crypto::decrypt($data, Key::loadFromAsciiSafeString($securedKey));
} catch (CryptoException $e) {
debugLog($e->getMessage());

View File

@@ -0,0 +1,72 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Core\Events;
/**
* Class Event
*
* @package SP\Core\Events
*/
class Event
{
/**
* @var object
*/
private $source;
/**
* @var array
*/
private $data;
/**
* Event constructor.
*
* @param object $source
* @param array $data
*/
public function __construct($source, array $data = [])
{
$this->source = $source;
$this->data = $data;
}
/**
* @return object
*/
public function getSource()
{
return $this->source;
}
/**
* @return array
*/
public function getData()
{
return $this->data;
}
}

View File

@@ -77,7 +77,7 @@ abstract class EventDispatcherBase implements EventDispatcherInterface
$observerClass = get_class($observer);
if (!array_key_exists($observerClass, $this->observers)) {
throw new InvalidClassException(SPException::ERROR, __('Observador no inicializado'));
throw new InvalidClassException(__u('Observador no inicializado'), SPException::ERROR);
}
unset($this->observers[$observerClass]);
@@ -100,19 +100,20 @@ abstract class EventDispatcherBase implements EventDispatcherInterface
/**
* Notificar un evento
*
* @param string $event
* @param mixed $object
* @param string $eventType
* @param Event $event
* @throws \SP\Core\Exceptions\InvalidArgumentException
*/
public function notifyEvent($event, $object)
public function notifyEvent($eventType, Event $event)
{
if (!is_object($object)) {
throw new InvalidArgumentException(SPException::ERROR, __('Es necesario un objeto'));
if (!is_object($event->getSource())) {
throw new InvalidArgumentException(__u('Es necesario un objeto'), SPException::ERROR);
}
foreach ($this->observers as $observer) {
if (in_array($event, $observer->getEvents(), true)) {
$observer->updateEvent($event, $object);
if (in_array($eventType, $observer->getEvents(), true)) {
// FIXME: update receivers Event
$observer->updateEvent($eventType, $event);
}
}
}

View File

@@ -2,8 +2,8 @@
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2017, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -34,9 +34,8 @@ interface EventDispatcherInterface extends \SplSubject
/**
* Notificar a los observadores y establecer el estado
*
* @param string $event Nombre del evento
* @param mixed $object Objeto del evento
* @return
* @param string $event Nombre del evento
* @param Event $object Objeto del evento
*/
public function notifyEvent($event, $object);
public function notifyEvent($event, Event $object);
}

View File

@@ -41,11 +41,10 @@ interface EventReceiver extends SplObserver
/**
* Evento de actualización
*
* @param string $event Nombre del evento
* @param object $object Objeto del evento
* @return
* @param string $eventType Nombre del evento
* @param Event $event Objeto del evento
*/
public function updateEvent($event, $object);
public function updateEvent($eventType, Event $event);
/**
* Devuelve los eventos que implementa el observador

View File

@@ -58,6 +58,18 @@ class TaskMessage implements MessageInterface, JsonSerializable
*/
protected $end = 0;
/**
* TaskMessage constructor.
*
* @param string $taskId
* @param string $task
*/
public function __construct($taskId, $task)
{
$this->taskId = $taskId;
$this->task = $task;
}
/**
* @return string
*/
@@ -68,10 +80,13 @@ class TaskMessage implements MessageInterface, JsonSerializable
/**
* @param string $task
* @return TaskMessage
*/
public function setTask($task)
{
$this->task = $task;
return $this;
}
/**
@@ -84,10 +99,13 @@ class TaskMessage implements MessageInterface, JsonSerializable
/**
* @param string $message
* @return TaskMessage
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
@@ -100,10 +118,13 @@ class TaskMessage implements MessageInterface, JsonSerializable
/**
* @param int $time
* @return TaskMessage
*/
public function setTime($time)
{
$this->time = $time;
return $this;
}
/**
@@ -116,10 +137,13 @@ class TaskMessage implements MessageInterface, JsonSerializable
/**
* @param int $progress
* @return TaskMessage
*/
public function setProgress($progress)
{
$this->progress = $progress;
return $this;
}
/**
@@ -132,10 +156,13 @@ class TaskMessage implements MessageInterface, JsonSerializable
/**
* @param int $end
* @return TaskMessage
*/
public function setEnd($end)
{
$this->end = $end;
return $this;
}
/**
@@ -203,9 +230,12 @@ class TaskMessage implements MessageInterface, JsonSerializable
/**
* @param string $taskId
* @return TaskMessage
*/
public function setTaskId($taskId)
{
$this->taskId = $taskId;
return $this;
}
}

View File

@@ -62,6 +62,10 @@ class Task
* @var bool Si se ha inicializado para escribir en el archivo
*/
protected $initialized = false;
/**
* @var string
*/
protected $uid;
/**
* Task constructor.
@@ -74,6 +78,7 @@ class Task
$this->name = $name;
$this->taskId = $id;
$this->initialized = $this->checkFile();
$this->uid = $this->genUid();
}
/**
@@ -109,6 +114,14 @@ class Task
array_map('unlink', glob($filesTask));
}
/**
* @return string
*/
public function genUid()
{
return md5($this->name . $this->taskId);
}
/**
* Generar un ID de tarea
*
@@ -215,7 +228,7 @@ class Task
{
debugLog('Deregister Task: ' . $this->name);
unlink($this->fileTask);
return unlink($this->fileTask);
}
/**
@@ -242,10 +255,13 @@ class Task
/**
* @param int $interval
* @return Task
*/
public function setInterval($interval)
{
$this->interval = $interval;
return $this;
}
/**
@@ -270,6 +286,7 @@ class Task
* Es necesario bloquear la sesión para permitir la ejecución de otros scripts
*
* @param bool $lockSession Bloquear la sesión
* @return Task
*/
public function register($lockSession = true)
{
@@ -280,6 +297,8 @@ class Task
if ($lockSession === true) {
session_write_close();
}
return $this;
}
/**
@@ -289,4 +308,12 @@ class Task
{
return $this->fileTask;
}
/**
* @return string
*/
public function getUid()
{
return $this->uid;
}
}

View File

@@ -34,49 +34,92 @@ use SP\Core\Messages\TaskMessage;
class TaskFactory
{
/**
* @var TaskMessage
* @var Task[]
*/
public static $Message;
/**
* @var Task
*/
private static $Task;
private static $tasks = [];
/**
* Crear una tarea para la actualización de estado de la actualización
*
* @param $name
* @param $id
* @return Task
*/
public static function createTask($name, $id)
public static function create($name, $id)
{
if (self::$Task === null) {
self::$Task = new Task($name, $id);
self::$Task->register(false);
return self::add((new Task($name, $id))->register(false));
}
/**
* @param Task $task
* @return Task
*/
private static function add(Task $task)
{
if (isset(self::$tasks[$task->getTaskId()])) {
throw new \RuntimeException('Task already registered');
}
self::$Message = new TaskMessage();
self::$Message->setTaskId($id);
self::$tasks[$task->getTaskId()] = $task;
return $task;
}
/**
* Finalizar la tarea
*
* @param $id
*/
public static function endTask()
public static function end($id)
{
if (self::$Task !== null) {
self::$Task->end(false);
self::$Task = null;
self::get($id)->end(false);
self::delete($id);
}
/**
* @param $id
* @return Task
*/
private static function get($id)
{
if (isset(self::$tasks[$id])) {
return self::$tasks[$id];
} else {
throw new \RuntimeException('Task not registered');
}
}
/**
* Enviar un mensaje de actualización a la tarea
* @param $id
*/
public static function sendTaskMessage()
private static function delete($id)
{
if (self::$Task !== null) {
self::$Task->writeJsonStatusAndFlush(self::$Message);
if (!isset(self::$tasks[$id])) {
throw new \RuntimeException('Task not registered');
}
unset(self::$tasks[$id]);
}
/**
* @param string $taskId
* @param string $task
* @return TaskMessage
*/
public static function createMessage($taskId, $task)
{
return new TaskMessage($taskId, $task);
}
/**
* Enviar un mensaje de actualización a la tarea
*
* @param string $id
* @param TaskMessage $taskMessage
*/
public static function update($id, TaskMessage $taskMessage)
{
self::get($id)->writeJsonStatusAndFlush($taskMessage);
}
}

View File

@@ -45,7 +45,7 @@ class Account
{
TaskFactory::$Message->setTask(__FUNCTION__);
TaskFactory::$Message->setMessage(__('Actualizando IDs de cuentas'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
try {
DbWrapper::beginTransaction();
@@ -58,7 +58,7 @@ class Account
DbWrapper::getQuery($Data);
$query = /** @lang SQL */
'DELETE FROM AccountToGroup WHERE accountId NOT IN (SELECT account_id FROM Account) OR accountId IS NULL';
'DELETE FROM AccountToUserGroup WHERE accountId NOT IN (SELECT account_id FROM Account) OR accountId IS NULL';
$Data->setQuery($query);
DbWrapper::getQuery($Data);

View File

@@ -46,7 +46,7 @@ class Category
{
TaskFactory::$Message->setTask(__FUNCTION__);
TaskFactory::$Message->setMessage(__('Actualizando IDs de categorías'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
try {
DbWrapper::beginTransaction();

View File

@@ -46,7 +46,7 @@ class Customer
{
TaskFactory::$Message->setTask(__FUNCTION__);
TaskFactory::$Message->setMessage(__('Actualizando IDs de clientes'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
try {
DbWrapper::beginTransaction();

View File

@@ -49,7 +49,7 @@ class Group
{
TaskFactory::$Message->setTask(__FUNCTION__);
TaskFactory::$Message->setMessage(__('Actualizando IDs de grupos'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
try {
DbWrapper::beginTransaction();
@@ -80,7 +80,7 @@ class Group
DbWrapper::getQuery($Data);
$query = /** @lang SQL */
'DELETE FROM UserToGroup WHERE usertogroup_groupId NOT IN (SELECT usergroup_id FROM usrGroups ORDER BY usergroup_id) OR usertogroup_groupId IS NULL';
'DELETE FROM UserToUserGroup WHERE usertogroup_groupId NOT IN (SELECT usergroup_id FROM usrGroups ORDER BY usergroup_id) OR usertogroup_groupId IS NULL';
$Data->setQuery($query);
$Data->setParams([]);

View File

@@ -52,7 +52,7 @@ class Profile
try {
TaskFactory::$Message->setTask(__FUNCTION__);
TaskFactory::$Message->setMessage(__('Actualizando IDs de perfil'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
DbWrapper::beginTransaction();

View File

@@ -203,7 +203,7 @@ class Upgrade
TaskFactory::$Message->setTask(__('Actualizar BBDD'));
TaskFactory::$Message->setMessage(sprintf('%s : %s', __('Versión'), $version));
TaskFactory::sendTaskMessage();
TaskFactory::update();
debugLog(__FUNCTION__ . ': ' . $version);

View File

@@ -50,7 +50,7 @@ class User
{
TaskFactory::$Message->setTask(__FUNCTION__);
TaskFactory::$Message->setMessage(__('Actualizando IDs de usuarios'));
TaskFactory::sendTaskMessage();
TaskFactory::update();
try {
DbWrapper::beginTransaction();
@@ -105,7 +105,7 @@ class User
DbWrapper::getQuery($Data);
$query = /** @lang SQL */
'DELETE FROM UserToGroup WHERE usertogroup_userId <> ? AND usertogroup_userId NOT IN (' . $paramsIn . ') OR usertogroup_userId IS NULL';
'DELETE FROM UserToUserGroup WHERE usertogroup_userId <> ? AND usertogroup_userId NOT IN (' . $paramsIn . ') OR usertogroup_userId IS NULL';
$Data->setQuery($query);
DbWrapper::getQuery($Data);

View File

@@ -27,6 +27,7 @@ namespace SP\Crypt;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Hash;
use SP\Core\Crypt\Session as CryptSession;
use SP\Core\Events\Event;
use SP\Core\Events\EventDispatcher;
use SP\Core\Session\Session;
use SP\Core\Traits\InjectableTrait;
@@ -130,7 +131,7 @@ class TemporaryMasterPass
// Guardar la configuración
$this->configService->saveBatch($configRequest);
$this->eventDispatcher->notifyEvent('temporaryMasterPass.expired', $this);
$this->eventDispatcher->notifyEvent('temporaryMasterPass.expired', new Event($this));
// Log::writeNewLog(__FUNCTION__, __u('Clave temporal caducada'), Log::INFO);
}

View File

@@ -143,10 +143,10 @@ class Group extends GroupBase implements ItemInterface, ItemSelectInterface
FROM usrData WHERE user_groupId = ?
UNION ALL
SELECT userGroupId as groupId
FROM UserToGroup WHERE userGroupId = ?
FROM UserToUserGroup WHERE userGroupId = ?
UNION ALL
SELECT userGroupId as groupId
FROM AccountToGroup WHERE userGroupId = ?
FROM AccountToUserGroup WHERE userGroupId = ?
UNION ALL
SELECT account_userGroupId as groupId
FROM Account WHERE account_userGroupId = ?';

View File

@@ -62,7 +62,7 @@ class GroupAccounts extends GroupAccountsBase implements ItemInterface
public function delete($id)
{
$query = /** @lang SQL */
'DELETE FROM AccountToGroup WHERE accountId = ?';
'DELETE FROM AccountToUserGroup WHERE accountId = ?';
$Data = new QueryData();
$Data->setQuery($query);
@@ -87,7 +87,7 @@ class GroupAccounts extends GroupAccountsBase implements ItemInterface
}
$query = /** @lang SQL */
'INSERT INTO AccountToGroup (accountId, userGroupId) VALUES ' . $this->getParamsFromArray($this->itemData->getGroups(), '(?,?)');
'INSERT INTO AccountToUserGroup (accountId, userGroupId) VALUES ' . $this->getParamsFromArray($this->itemData->getGroups(), '(?,?)');
$Data = new QueryData();
$Data->setQuery($query);
@@ -111,7 +111,7 @@ class GroupAccounts extends GroupAccountsBase implements ItemInterface
public function getById($id)
{
$query = /** @lang SQL */
'SELECT userGroupId, accountId FROM AccountToGroup WHERE userGroupId = ?';
'SELECT userGroupId, accountId FROM AccountToUserGroup WHERE userGroupId = ?';
$Data = new QueryData();
$Data->setMapClassName($this->getDataModel());
@@ -136,7 +136,7 @@ class GroupAccounts extends GroupAccountsBase implements ItemInterface
public function checkInUse($id)
{
$query = /** @lang SQL */
'SELECT userGroupId FROM AccountToGroup WHERE userGroupId = ?';
'SELECT userGroupId FROM AccountToUserGroup WHERE userGroupId = ?';
$Data = new QueryData();
$Data->setQuery($query);
@@ -170,7 +170,7 @@ class GroupAccounts extends GroupAccountsBase implements ItemInterface
public function getByAccountId($id)
{
$query = /** @lang SQL */
'SELECT userGroupId, accountId FROM AccountToGroup WHERE accountId = ?';
'SELECT userGroupId, accountId FROM AccountToUserGroup WHERE accountId = ?';
$Data = new QueryData();
$Data->setMapClassName($this->getDataModel());

View File

@@ -64,7 +64,7 @@ class GroupUsers extends GroupUsersBase implements ItemInterface, ItemSelectInte
public function delete($id)
{
$query = /** @lang SQL */
'DELETE FROM UserToGroup WHERE userGroupId = ?';
'DELETE FROM UserToUserGroup WHERE userGroupId = ?';
$Data = new QueryData();
$Data->setQuery($query);
@@ -89,7 +89,7 @@ class GroupUsers extends GroupUsersBase implements ItemInterface, ItemSelectInte
}
$query = /** @lang SQL */
'INSERT INTO UserToGroup (userId, userGroupId) VALUES ' . $this->getParamsFromArray($this->itemData->getUsers(), '(?,?)');
'INSERT INTO UserToUserGroup (userId, userGroupId) VALUES ' . $this->getParamsFromArray($this->itemData->getUsers(), '(?,?)');
$Data = new QueryData();
$Data->setQuery($query);
@@ -113,7 +113,7 @@ class GroupUsers extends GroupUsersBase implements ItemInterface, ItemSelectInte
public function getById($id)
{
$query = /** @lang SQL */
'SELECT userGroupId, userId FROM UserToGroup WHERE userGroupId = ?';
'SELECT userGroupId, userId FROM UserToUserGroup WHERE userGroupId = ?';
$Data = new QueryData();
$Data->setMapClassName($this->getDataModel());
@@ -140,7 +140,7 @@ class GroupUsers extends GroupUsersBase implements ItemInterface, ItemSelectInte
public function checkInUse($id)
{
$query = /** @lang SQL */
'SELECT userGroupId FROM UserToGroup WHERE userGroupId = ?';
'SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = ?';
$Data = new QueryData();
$Data->setQuery($query);
@@ -188,7 +188,7 @@ class GroupUsers extends GroupUsersBase implements ItemInterface, ItemSelectInte
public function checkUserInGroup($groupId, $userId)
{
$query = /** @lang SQL */
'SELECT userGroupId FROM UserToGroup WHERE userGroupId = ? AND userId = ?';
'SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = ? AND userId = ?';
$Data = new QueryData();
$Data->setQuery($query);
@@ -209,7 +209,7 @@ class GroupUsers extends GroupUsersBase implements ItemInterface, ItemSelectInte
public function getGroupsForUser($userId)
{
$query = /** @lang SQL */
'SELECT userGroupId AS groupId FROM UserToGroup WHERE userId = ?';
'SELECT userGroupId AS groupId FROM UserToUserGroup WHERE userId = ?';
$Data = new QueryData();
$Data->setQuery($query);

View File

@@ -161,7 +161,7 @@ class UserUtil
$query = /** @lang SQL */
'SELECT user_id, user_login, user_name, user_email
FROM usrData
LEFT JOIN UserToGroup ON usertogroup_userId = user_id
LEFT JOIN UserToUserGroup ON usertogroup_userId = user_id
WHERE user_email IS NOT NULL
AND user_groupId = ? OR usertogroup_groupId = ?
AND user_isDisabled = 0

View File

@@ -33,6 +33,7 @@ use SP\DataModel\ItemSearchData;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemInterface;
use SP\Repositories\RepositoryItemTrait;
use SP\Services\Account\AccountPasswordRequest;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
@@ -416,4 +417,49 @@ class AccountHistoryRepository extends Repository implements RepositoryItemInter
return $queryRes;
}
/**
* Obtener los datos relativos a la clave de todas las cuentas.
*
* @return array Con los datos de la clave
*/
public function getAccountsPassData()
{
$query = /** @lang SQL */
'SELECT id, name, pass, `key`, mPassHash
FROM AccountHistory WHERE BIT_LENGTH(pass) > 0';
$queryData = new QueryData();
$queryData->setQuery($query);
return DbWrapper::getResultsArray($queryData);
}
/**
* Actualiza la clave de una cuenta en la BBDD.
*
* @param AccountPasswordRequest $request
* @return bool
* @throws QueryException
* @throws \SP\Core\Exceptions\ConstraintException
*/
public function updatePassword(AccountPasswordRequest $request)
{
$query = /** @lang SQL */
'UPDATE AccountHistory SET
pass = ?,
`key` = ?,
mPassHash = ?
WHERE id = ?';
$Data = new QueryData();
$Data->setQuery($query);
$Data->addParam($request->pass);
$Data->addParam($request->key);
$Data->addParam($request->hash);
$Data->addParam($request->id);
$Data->setOnErrorMessage(__u('Error al actualizar la clave'));
return DbWrapper::getQuery($Data, $this->db);
}
}

View File

@@ -29,6 +29,7 @@ use SP\Account\AccountSearchFilter;
use SP\Account\AccountUtil;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\AccountData;
use SP\DataModel\AccountExtData;
use SP\DataModel\AccountPassData;
use SP\DataModel\AccountSearchVData;
@@ -41,6 +42,7 @@ use SP\Mvc\Model\QueryCondition;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemInterface;
use SP\Repositories\RepositoryItemTrait;
use SP\Services\Account\AccountPasswordRequest;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
@@ -195,7 +197,6 @@ class AccountRepository extends Repository implements RepositoryItemInterface
*
* @param AccountRequest $accountRequest
* @return bool
* @throws QueryException
* @throws SPException
* @throws \SP\Core\Exceptions\ConstraintException
*/
@@ -203,24 +204,50 @@ class AccountRepository extends Repository implements RepositoryItemInterface
{
$query = /** @lang SQL */
'UPDATE Account SET
pass = :pass,
`key` = :key,
userEditId = :userEditId,
pass = ?,
`key` = ?,
userEditId = ?,
dateEdit = NOW(),
passDate = UNIX_TIMESTAMP(),
passDateChange = :passDateChange
WHERE id = :id';
passDateChange = ?
WHERE id = ?';
$Data = new QueryData();
$Data->setQuery($query);
$Data->addParam($accountRequest->pass, 'pass');
$Data->addParam($accountRequest->key, 'key');
$Data->addParam($accountRequest->userEditId, 'userEditId');
$Data->addParam($accountRequest->passDateChange, 'passDateChange');
$Data->addParam($accountRequest->id, 'id');
$Data->setOnErrorMessage(__u('Error al actualizar la clave'));
$queryData = new QueryData();
$queryData->setQuery($query);
$queryData->addParam($accountRequest->pass);
$queryData->addParam($accountRequest->key);
$queryData->addParam($accountRequest->userEditId);
$queryData->addParam($accountRequest->passDateChange);
$queryData->addParam($accountRequest->id);
$queryData->setOnErrorMessage(__u('Error al actualizar la clave'));
return DbWrapper::getQuery($Data, $this->db);
return DbWrapper::getQuery($queryData, $this->db);
}
/**
* Actualiza la clave de una cuenta en la BBDD.
*
* @param AccountPasswordRequest $request
* @return bool
* @throws QueryException
* @throws \SP\Core\Exceptions\ConstraintException
*/
public function updatePassword(AccountPasswordRequest $request)
{
$query = /** @lang SQL */
'UPDATE Account SET
pass = ?,
`key` = ?
WHERE id = ?';
$queryData = new QueryData();
$queryData->setQuery($query);
$queryData->addParam($request->pass);
$queryData->addParam($request->key);
$queryData->addParam($request->id);
$queryData->setOnErrorMessage(__u('Error al actualizar la clave'));
return DbWrapper::getQuery($queryData, $this->db);
}
/**
@@ -383,10 +410,18 @@ class AccountRepository extends Repository implements RepositoryItemInterface
/**
* Returns all the items
*
* @return AccountData[]
*/
public function getAll()
{
throw new \RuntimeException('Not implemented');
$query = /** @lang SQL */
'SELECT * FROM Account A ORDER BY id';
$queryData = new QueryData();
$queryData->setMapClassName(AccountData::class);
$queryData->setQuery($query);
return DbWrapper::getResultsArray($queryData, $this->db);
}
/**
@@ -664,4 +699,20 @@ class AccountRepository extends Repository implements RepositoryItemInterface
return DbWrapper::getResultsArray($queryData, $this->db);
}
/**
* Obtener los datos relativos a la clave de todas las cuentas.
*
* @return array Con los datos de la clave
*/
public function getAccountsPassData()
{
$query = /** @lang SQL */
'SELECT id, name, pass, `key` FROM Account WHERE BIT_LENGTH(pass) > 0';
$queryData = new QueryData();
$queryData->setQuery($query);
return DbWrapper::getResultsArray($queryData);
}
}

View File

@@ -176,7 +176,7 @@ class CategoryRepository extends Repository implements RepositoryItemInterface
/**
* Returns all the items
*
* @return array
* @return CategoryData[]
*/
public function getAll()
{

View File

@@ -181,7 +181,7 @@ class ClientRepository extends Repository implements RepositoryItemInterface
/**
* Returns all the items
*
* @return array
* @return ClientData[]
*/
public function getAll()
{

View File

@@ -168,11 +168,18 @@ class CustomFieldRepository extends Repository implements RepositoryItemInterfac
/**
* Returns all the items
*
* @return mixed
* @return CustomFieldData[]
*/
public function getAll()
{
throw new \RuntimeException('Unimplemented');
$query = /** @lang SQL */
'SELECT * FROM CustomFieldData';
$queryData = new QueryData();
$queryData->setMapClassName(CustomFieldData::class);
$queryData->setQuery($query);
return DbWrapper::getResultsArray($queryData, $this->db);
}
/**

View File

@@ -0,0 +1,308 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\Account;
use Defuse\Crypto\Exception\CryptoException;
use SP\Core\Crypt\Crypt;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\OldCrypt;
use SP\Core\TaskFactory;
use SP\Services\Crypt\UpdateMasterPassRequest;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Util\Util;
/**
* Class AccountCryptService
*
* @package SP\Services\Account
*/
class AccountCryptService extends Service
{
/**
* @var AccountService
*/
protected $accountService;
/**
* @var AccountHistoryService
*/
protected $accountHistoryService;
/**
* @var UpdateMasterPassRequest
*/
protected $request;
/**
* Actualiza las claves de todas las cuentas con la clave maestra actual
* usando nueva encriptación.
*
* @param UpdateMasterPassRequest $updateMasterPassRequest
* @throws ServiceException
* @throws \SP\Core\Exceptions\InvalidArgumentException
*/
public function updateOldPass(UpdateMasterPassRequest $updateMasterPassRequest)
{
set_time_limit(0);
$this->request = $updateMasterPassRequest;
$accountsOk = [];
$errorCount = 0;
$messages = [];
$this->eventDispatcher->notifyEvent('update.masterPassword.accounts.start', new Event($this, [__u('Actualizar Clave Maestra')]));
if (!OldCrypt::checkCryptModule()) {
throw new ServiceException(__u('Error en el módulo de encriptación'), SPException::ERROR);
}
$accountsPass = $this->accountService->getAccountsPassData();
$numAccounts = count($accountsPass);
if ($numAccounts === 0) {
throw new ServiceException(__u('Error al obtener las claves de las cuentas'), SPException::ERROR);
}
$taskId = $this->request->getTask()->getTaskId();
TaskFactory::update($taskId, TaskFactory::createMessage($taskId, __('Actualizar Clave Maestra')));
$counter = 0;
$startTime = time();
$configData = $this->config->getConfigData();
$accountRequestBase = new AccountPasswordRequest();
foreach ($accountsPass as $account) {
// No realizar cambios si está en modo demo
if ($configData->isDemoEnabled()) {
$accountsOk[] = $account->id;
continue;
}
if ($counter % 100 === 0) {
$eta = Util::getETA($startTime, $counter, $numAccounts);
$taskMessage = TaskFactory::createMessage($taskId, __('Actualizar Clave Maestra'))
->setMessage(sprintf(__('Cuentas actualizadas: %d /%d'), $counter, $numAccounts))
->setProgress(round(($counter * 100) / $numAccounts, 2))
->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
TaskFactory::update($taskId, $taskMessage);
debugLog($taskMessage->composeText());
}
$accountRequest = clone $accountRequestBase;
$accountRequest->id = $account->id;
try {
$passData = $this->accountService->getPasswordEncrypted(
OldCrypt::getDecrypt($account->pass, $account->key, $this->request->getCurrentMasterPass()),
$this->request->getNewMasterPass()
);
$accountRequest->key = $passData['key'];
$accountRequest->pass = $passData['pass'];
$this->accountService->updatePasswordMasterPass($accountRequest);
$accountsOk[] = $account->id;
$counter++;
} catch (SPException $e) {
$errorCount++;
$messages[] = __u('Fallo al actualizar la clave de la cuenta');
$messages[] = sprintf('%s (%d)', $account->name, $account->id);
}
}
$messages[] = __u('Cuentas actualizadas');
$messages[] = implode(',', $accountsOk);
$messages[] = __u('Errores');
$messages[] = $errorCount;
$this->eventDispatcher->notifyEvent('update.masterPassword.accounts.end', new Event($this, $messages));
}
/**
* Actualiza las claves de todas las cuentas con la nueva clave maestra.
*
* @param UpdateMasterPassRequest $updateMasterPassRequest
* @throws ServiceException
*/
public function updateMasterPassword(UpdateMasterPassRequest $updateMasterPassRequest)
{
$this->request = $updateMasterPassRequest;
try {
$this->eventDispatcher->notifyEvent('update.masterPassword.accounts.start', new Event($this, [__u('Actualizar Clave Maestra')]));
$taskId = $this->request->getTask();
TaskFactory::update($taskId, TaskFactory::createMessage($taskId, __u('Actualizar Clave Maestra')));
$process = $this->processAccounts($this->accountService->getAccountsPassData(), function ($request) {
$this->accountService->updatePasswordMasterPass($request);
});
$this->eventDispatcher->notifyEvent('update.masterPassword.accounts.end', new Event($this, $process));
} catch (\Exception $e) {
throw new ServiceException(__u('Errores al actualizar las claves de las cuentas'), SPException::ERROR, null, $e->getCode(), $e);
}
}
/**
* @param array $accounts
* @param callable $passUpdater
* @return array
* @throws ServiceException
*/
protected function processAccounts(array $accounts, callable $passUpdater)
{
set_time_limit(0);
$accountsOk = [];
$messages = [];
$errorCount = 0;
$counter = 0;
$startTime = time();
$numAccounts = count($accounts);
if ($numAccounts === 0) {
throw new ServiceException(__u('Error al obtener las claves de las cuentas'), SPException::ERROR);
}
$configData = $this->config->getConfigData();
$currentMasterPassHash = $this->request->getCurrentHash();
$accountPasswordRequest = new AccountPasswordRequest();
$taskId = $this->request->getTask()->getTaskId();
foreach ($accounts as $account) {
// No realizar cambios si está en modo demo
if ($configData->isDemoEnabled()) {
$accountsOk[] = $account->id;
continue;
}
if ($counter % 100 === 0) {
$eta = Util::getETA($startTime, $counter, $numAccounts);
$taskMessage = TaskFactory::createMessage($taskId, __('Actualizar Clave Maestra'))
->setMessage(sprintf(__('Cuentas actualizadas: %d /%d'), $counter, $numAccounts))
->setProgress(round(($counter * 100) / $numAccounts, 2))
->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
TaskFactory::update($taskId, $taskMessage);
debugLog($taskMessage->composeText());
}
if (isset($account->mPassHash) && $account->mPassHash !== $currentMasterPassHash) {
$messages[] = __u('La clave maestra del registro no coincide');
$messages[] = sprintf('%s (%d)', $account->name, $account->id);
continue;
}
$request = clone $accountPasswordRequest;
$request->id = $account->id;
try {
$passData = $this->accountService->getPasswordEncrypted(
Crypt::decrypt($account->pass, Crypt::unlockSecuredKey($account->key, $this->request->getCurrentMasterPass())),
$this->request->getNewMasterPass()
);
$request->key = $passData['key'];
$request->pass = $passData['pass'];
// Call the specific updater
$passUpdater($request);
$accountsOk[] = $account->id;
$counter++;
} catch (SPException $e) {
$errorCount++;
$messages[] = __u('Fallo al actualizar la clave de la cuenta');
$messages[] = sprintf('%s (%d)', $account->name, $account->id);
} catch (CryptoException $e) {
$errorCount++;
$messages[] = __u('Fallo al actualizar la clave de la cuenta');
$messages[] = sprintf('%s (%d)', $account->name, $account->id);
}
}
$messages[] = __u('Cuentas actualizadas');
$messages[] = implode(',', $accountsOk);
$messages[] = __u('Errores');
$messages[] = $errorCount;
return $messages;
}
/**
* Actualiza las claves de todas las cuentas con la nueva clave maestra.
*
* @param UpdateMasterPassRequest $updateMasterPassRequest
* @throws ServiceException
*/
public function updateHistoryMasterPassword(UpdateMasterPassRequest $updateMasterPassRequest)
{
$this->request = $updateMasterPassRequest;
try {
$this->eventDispatcher->notifyEvent('update.masterPassword.accountsHistory.start', new Event($this, [__u('Actualizar Clave Maestra (H)')]));
$taskId = $this->request->getTask();
TaskFactory::update($taskId, TaskFactory::createMessage($taskId, __u('Actualizar Clave Maestra (H)')));
$process = $this->processAccounts($this->accountHistoryService->getAccountsPassData(), function ($request) {
/** @var AccountPasswordRequest $request */
$request->hash = $this->request->getHash();
$this->accountHistoryService->updatePasswordMasterPass($request);
});
$this->eventDispatcher->notifyEvent('update.masterPassword.accountsHistory.end', new Event($this, $process));
} catch (\Exception $e) {
throw new ServiceException(__u('Errores al actualizar las claves de las cuentas del histórico'), SPException::ERROR, null, $e->getCode(), $e);
}
}
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
protected function initialize()
{
$this->accountService = $this->dic->get(AccountService::class);
$this->accountHistoryService = $this->dic->get(AccountHistoryService::class);
}
}

View File

@@ -129,4 +129,23 @@ class AccountHistoryService extends Service
return $this->accountHistoryRepository->create($itemData);
}
/**
* @return array
*/
public function getAccountsPassData()
{
return $this->accountHistoryRepository->getAccountsPassData();
}
/**
* @param AccountPasswordRequest $accountRequest
* @return bool
* @throws SPException
* @throws \SP\Core\Exceptions\ConstraintException
*/
public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest)
{
return $this->accountHistoryRepository->updatePassword($accountRequest);
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\Account;
/**
* Class AccountPasswordRequest
*
* @package SP\Services\Account
*/
class AccountPasswordRequest
{
/**
* @var int
*/
public $id;
/**
* @var string
*/
public $pass;
/**
* @var string
*/
public $key;
/**
* @var string
*/
public $hash;
}

View File

@@ -35,6 +35,7 @@ use SP\Core\Crypt\Session as CryptSession;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\Core\Session\Session;
use SP\DataModel\AccountData;
use SP\DataModel\Dto\AccountDetailsResponse;
use SP\DataModel\ItemSearchData;
use SP\Log\Log;
@@ -44,6 +45,7 @@ use SP\Repositories\Account\AccountToUserGroupRepository;
use SP\Repositories\Account\AccountToUserRepository;
use SP\Services\Config\ConfigService;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Services\ServiceItemTrait;
/**
@@ -83,9 +85,9 @@ class AccountService extends Service implements AccountServiceInterface
public function initialize()
{
$this->accountRepository = $this->dic->get(AccountRepository::class);
$this->accountToUserGroupRepository = $this->dic->get(AccountToUserGroupRepository::class);
$this->accountToUserRepository = $this->dic->get(AccountToUserRepository::class);
$this->accountToTagRepository = $this->dic->get(AccountToUserRepository::class);
$this->accountToUserGroupRepository = $this->dic->get(AccountToUserGroupRepository::class);
$this->accountToTagRepository = $this->dic->get(AccountToTagRepository::class);
}
/**
@@ -194,8 +196,7 @@ class AccountService extends Service implements AccountServiceInterface
* @param string $pass
* @param string $masterPass Clave maestra a utilizar
* @return array
* @throws QueryException
* @throws SPException
* @throws ServiceException
*/
public function getPasswordEncrypted($pass, $masterPass = null)
{
@@ -206,12 +207,12 @@ class AccountService extends Service implements AccountServiceInterface
$out['pass'] = Crypt::encrypt($pass, $out['key'], $masterPass);
if (strlen($pass) > 1000 || strlen($out['key']) > 1000) {
throw new QueryException(__u('Error interno'), SPException::ERROR);
throw new ServiceException(__u('Error interno'), SPException::ERROR);
}
return $out;
} catch (CryptoException $e) {
throw new SPException(__u('Error interno'), SPException::ERROR);
throw new ServiceException(__u('Error interno'), SPException::ERROR);
}
}
@@ -326,16 +327,18 @@ class AccountService extends Service implements AccountServiceInterface
/**
* @param AccountRequest $accountRequest
* @throws QueryException
* @param bool $addHistory
* @throws SPException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Services\Config\ParameterNotFoundException
*/
public function editPassword(AccountRequest $accountRequest)
public function editPassword(AccountRequest $accountRequest, $addHistory = true)
{
$this->addHistory($accountRequest->id);
if ($addHistory) {
$this->addHistory($accountRequest->id);
}
$pass = $this->getPasswordEncrypted($accountRequest->pass);
@@ -345,6 +348,17 @@ class AccountService extends Service implements AccountServiceInterface
$this->accountRepository->editPassword($accountRequest);
}
/**
* @param AccountPasswordRequest $accountRequest
* @throws SPException
* @throws \SP\Core\Exceptions\ConstraintException
*/
public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest)
{
$this->accountRepository->updatePassword($accountRequest);
}
/**
* @param $historyId
* @param $accountId
@@ -434,7 +448,7 @@ class AccountService extends Service implements AccountServiceInterface
}
/**
* @return array
* @return AccountData[]
*/
public function getAllBasic()
{
@@ -471,4 +485,14 @@ class AccountService extends Service implements AccountServiceInterface
{
return $this->accountRepository->getDataForLink($id);
}
/**
* Obtener los datos relativos a la clave de todas las cuentas.
*
* @return array Con los datos de la clave
*/
public function getAccountsPassData()
{
return $this->accountRepository->getAccountsPassData();
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\Account;
use SP\Repositories\Account\AccountToTagRepository;
use SP\Services\Service;
/**
* Class AccountToTagService
*
* @package SP\Services\Account
*/
class AccountToTagService extends Service
{
/**
* @var AccountToTagRepository
*/
protected $accountToTagRepository;
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
protected function initialize()
{
$this->accountToTagRepository = $this->dic->get(AccountToTagRepository::class);
}
/**
* @param $id
* @return array
*/
public function getTagsByAccountId($id)
{
return $this->accountToTagRepository->getTagsByAccountId($id);
}
}

View File

@@ -30,6 +30,7 @@ use Defuse\Crypto\Exception\BadFormatException;
use Defuse\Crypto\Exception\CryptoException;
use SP\Bootstrap;
use SP\Config\ConfigData;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\Language;
use SP\Core\Messages\LogMessage;
@@ -385,7 +386,7 @@ class LoginService extends Service
$this->session->setAuthCompleted(true);
$this->eventDispatcher->notifyEvent('login.preferences', $this);
$this->eventDispatcher->notifyEvent('login.preferences', new Event($this));
}
/**

View File

@@ -0,0 +1,307 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\Backup;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use SP\Bootstrap;
use SP\Config\ConfigData;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Storage\Database;
use SP\Storage\DBUtil;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
use SP\Util\Checks;
use SP\Util\Util;
defined('APP_ROOT') || die();
/**
* Esta clase es la encargada de realizar la copia de sysPass.
*/
class FileBackupService extends Service
{
/**
* @var ConfigData
*/
protected $configData;
/**
* Realizar backup de la BBDD y aplicación.
*
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ServiceException
*/
public function doBackup()
{
$siteName = Util::getAppInfo('appname');
// Generar hash unico para evitar descargas no permitidas
$backupUniqueHash = sha1(uniqid('sysPassBackup', true));
$this->configData->setBackupHash($backupUniqueHash);
$this->config->saveConfig();
$bakFileApp = BACKUP_PATH . DIRECTORY_SEPARATOR . $siteName . '-' . $backupUniqueHash . '.tar';
$bakFileDB = BACKUP_PATH . DIRECTORY_SEPARATOR . $siteName . '_db-' . $backupUniqueHash . '.sql';
try {
$this->eventDispatcher->notifyEvent('run.backup.start', new Event($this, [__u('Realizar Backup')]));
$this->checkBackupDir();
$this->deleteOldBackups();
$this->backupTables('*', $bakFileDB);
$this->backupApp($bakFileApp);
$this->eventDispatcher->notifyEvent('run.backup.end', new Event($this, [__u('Copia de la aplicación y base de datos realizada correctamente')]));
} catch (ServiceException $e) {
throw $e;
} catch (\Exception $e) {
throw new ServiceException(__u('Error al realizar el backup'), SPException::ERROR, __u('Revise el registro de eventos para más detalles'));
}
return true;
}
/**
* Comprobar y crear el directorio de backups.
*
* @throws ServiceException
* @return bool
*/
private function checkBackupDir()
{
if (@mkdir(BACKUP_PATH, 0750) === false && is_dir(BACKUP_PATH) === false) {
throw new ServiceException(
sprintf(__('No es posible crear el directorio de backups ("%s")'), BACKUP_PATH), SPException::ERROR);
}
if (!is_writable(BACKUP_PATH)) {
throw new ServiceException(
__u('Compruebe los permisos del directorio de backups'), SPException::ERROR);
}
return true;
}
/**
* Eliminar las copias de seguridad anteriores
*/
private function deleteOldBackups()
{
array_map('unlink', glob(BACKUP_PATH . DIRECTORY_SEPARATOR . '*.tar.gz'));
array_map('unlink', glob(BACKUP_PATH . DIRECTORY_SEPARATOR . '*.sql'));
}
/**
* Backup de las tablas de la BBDD.
* Utilizar '*' para toda la BBDD o 'table1 table2 table3...'
*
* @param string|array $tables
* @param string $backupFile
* @throws ServiceException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
private function backupTables($tables = '*', $backupFile)
{
$db = $this->dic->get(Database::class);
$dbname = $this->configData->getDbName();
try {
$handle = fopen($backupFile, 'w');
$Data = new QueryData();
if ($tables === '*') {
$resTables = DBUtil::$tables;
} else {
$resTables = is_array($tables) ? $tables : explode(',', $tables);
}
$sqlOut = '--' . PHP_EOL;
$sqlOut .= '-- sysPass DB dump generated on ' . time() . ' (START)' . PHP_EOL;
$sqlOut .= '--' . PHP_EOL;
$sqlOut .= '-- Please, do not alter this file, it could break your DB' . PHP_EOL;
$sqlOut .= '--' . PHP_EOL . PHP_EOL;
$sqlOut .= 'CREATE DATABASE IF NOT EXISTS `' . $dbname . '`;' . PHP_EOL . PHP_EOL;
$sqlOut .= 'USE `' . $dbname . '`;' . PHP_EOL . PHP_EOL;
fwrite($handle, $sqlOut);
$sqlOutViews = '';
// Recorrer las tablas y almacenar los datos
foreach ($resTables as $table) {
$tableName = is_object($table) ? $table->{'Tables_in_' . $dbname} : $table;
$Data->setQuery('SHOW CREATE TABLE ' . $tableName);
// Consulta para crear la tabla
$txtCreate = DbWrapper::getResults($Data, $db);
if (isset($txtCreate->{'Create Table'})) {
$sqlOut = '-- ' . PHP_EOL;
$sqlOut .= '-- Table ' . strtoupper($tableName) . PHP_EOL;
$sqlOut .= '-- ' . PHP_EOL;
$sqlOut .= 'DROP TABLE IF EXISTS `' . $tableName . '`;' . PHP_EOL . PHP_EOL;
$sqlOut .= $txtCreate->{'Create Table'} . ';' . PHP_EOL . PHP_EOL;
fwrite($handle, $sqlOut);
} elseif ($txtCreate->{'Create View'}) {
$sqlOutViews .= '-- ' . PHP_EOL;
$sqlOutViews .= '-- View ' . strtoupper($tableName) . PHP_EOL;
$sqlOutViews .= '-- ' . PHP_EOL;
$sqlOutViews .= 'DROP TABLE IF EXISTS `' . $tableName . '`;' . PHP_EOL . PHP_EOL;
$sqlOutViews .= $txtCreate->{'Create View'} . ';' . PHP_EOL . PHP_EOL;
}
fwrite($handle, PHP_EOL . PHP_EOL);
}
// Guardar las vistas
fwrite($handle, $sqlOutViews);
// Guardar los datos
foreach ($resTables as $tableName) {
// No guardar las vistas!
if (strrpos($tableName, '_v') !== false) {
continue;
}
$Data->setQuery('SELECT * FROM `' . $tableName . '`');
// Consulta para obtener los registros de la tabla
$queryRes = DbWrapper::getResultsRaw($Data);
$numColumns = $queryRes->columnCount();
while ($row = $queryRes->fetch(\PDO::FETCH_NUM)) {
fwrite($handle, 'INSERT INTO `' . $tableName . '` VALUES(');
$field = 1;
foreach ($row as $value) {
if (is_numeric($value)) {
fwrite($handle, $value);
} else {
fwrite($handle, DBUtil::escape($value, $db->getDbHandler()));
}
if ($field < $numColumns) {
fwrite($handle, ',');
}
$field++;
}
fwrite($handle, ');' . PHP_EOL);
}
}
$sqlOut = '--' . PHP_EOL;
$sqlOut .= '-- sysPass DB dump generated on ' . time() . ' (END)' . PHP_EOL;
$sqlOut .= '--' . PHP_EOL;
$sqlOut .= '-- Please, do not alter this file, it could break your DB' . PHP_EOL;
$sqlOut .= '--' . PHP_EOL . PHP_EOL;
fwrite($handle, $sqlOut);
fclose($handle);
} catch (\Exception $e) {
processException($e);
throw new ServiceException($e->getMessage(), SPException::CRITICAL);
}
}
/**
* Realizar un backup de la aplicación y comprimirlo.
*
* @param string $backupFile nombre del archivo de backup
* @return bool
* @throws ServiceException
*/
private function backupApp($backupFile)
{
if (!class_exists(\PharData::class)) {
if (Checks::checkIsWindows()) {
throw new ServiceException(
__u('Esta operación sólo es posible en entornos Linux'), SPException::INFO);
}
if (!$this->backupAppLegacyLinux($backupFile)) {
throw new ServiceException(
__u('Error al realizar backup en modo compatibilidad'), SPException::ERROR);
}
}
$compressedFile = $backupFile . '.gz';
try {
if (file_exists($compressedFile)) {
unlink($compressedFile);
}
$archive = new \PharData($backupFile);
$archive->buildFromDirectory(Bootstrap::$SERVERROOT, '/^(?!backup).*$/');
$archive->compress(\Phar::GZ);
unlink($backupFile);
return file_exists($backupFile);
} catch (\Exception $e) {
processException($e);
throw new ServiceException($e->getMessage(), SPException::CRITICAL);
}
}
/**
* Realizar un backup de la aplicación y comprimirlo usando aplicaciones del SO Linux.
*
* @param string $backupFile nombre del archivo de backup
* @return int Con el código de salida del comando ejecutado
*/
private function backupAppLegacyLinux($backupFile)
{
$compressedFile = $backupFile . '.gz';
$command = 'tar czf ' . $compressedFile . ' ' . BASE_PATH . ' --exclude "' . BACKUP_PATH . '" 2>&1';
exec($command, $resOut, $resBakApp);
return $resBakApp;
}
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
protected function initialize()
{
$this->configData = $this->config->getConfigData();
}
}

View File

@@ -25,6 +25,7 @@
namespace SP\Services\Category;
use SP\Core\Exceptions\SPException;
use SP\DataModel\CategoryData;
use SP\DataModel\ItemSearchData;
use SP\Repositories\Category\CategoryRepository;
use SP\Services\Service;
@@ -115,7 +116,7 @@ class CategoryService extends Service
/**
* Get all items from the service's repository
*
* @return array
* @return CategoryData[]
*/
public function getAllBasic()
{

View File

@@ -27,6 +27,7 @@ namespace SP\Services\Client;
use SP\Account\AccountUtil;
use SP\Core\Exceptions\SPException;
use SP\Core\Session\Session;
use SP\DataModel\ClientData;
use SP\DataModel\ItemSearchData;
use SP\Repositories\Client\ClientRepository;
use SP\Services\Service;
@@ -116,7 +117,7 @@ class ClientService extends Service
/**
* Get all items from the service's repository
*
* @return array
* @return ClientData[]
*/
public function getAllBasic()
{

View File

@@ -0,0 +1,121 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\Crypt;
use SP\Core\Crypt\Hash;
use SP\Core\Exceptions\SPException;
use SP\Services\Account\AccountCryptService;
use SP\Services\Config\ConfigService;
use SP\Services\CustomField\CustomFieldCryptService;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Storage\Database;
use SP\Storage\DbWrapper;
/**
* Class MasterPassService
*
* @package SP\Services\Crypt
*/
class MasterPassService extends Service
{
/**
* @var ConfigService
*/
protected $configService;
/**
* @var AccountCryptService
*/
protected $accountCryptService;
/**
* @var CustomFieldCryptService
*/
protected $customFieldCryptService;
/**
* @param int $userMPassTime
* @return bool
* @throws \SP\Services\Config\ParameterNotFoundException
*/
public function checkUserUpdateMPass($userMPassTime)
{
$lastUpdateMPass = $this->configService->getByParam('lastupdatempass');
return $userMPassTime >= $lastUpdateMPass;
}
/**
* @param string $masterPassword
* @return bool
* @throws \SP\Services\Config\ParameterNotFoundException
*/
public function checkMasterPassword($masterPassword)
{
return Hash::checkHashKey($masterPassword, $this->configService->getByParam('masterPwd'));
}
/**
* @param UpdateMasterPassRequest $request
* @throws ServiceException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function changeMasterPassword(UpdateMasterPassRequest $request)
{
$db = $this->dic->get(Database::class);
if (!DbWrapper::beginTransaction($db)) {
throw new ServiceException(__u('No es posible iniciar una transacción'), SPException::ERROR);
}
try {
$this->accountCryptService->updateMasterPassword($request);
$this->accountCryptService->updateHistoryMasterPassword($request);
$this->customFieldCryptService->updateMasterPassword($request);
} catch (ServiceException $e) {
DbWrapper::rollbackTransaction($db);
throw $e;
}
if (!DbWrapper::endTransaction($db)) {
throw new ServiceException(__u('No es posible finalizar una transacción'), SPException::ERROR);
}
}
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
protected function initialize()
{
$this->configService = $this->dic->get(ConfigService::class);
$this->accountCryptService = $this->dic->get(AccountCryptService::class);
$this->customFieldCryptService = $this->dic->get(CustomFieldCryptService::class);
}
}

View File

@@ -0,0 +1,158 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\Crypt;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Hash;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Services\Config\ConfigService;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Util\Util;
/**
* Class TemporaryMasterPassService
*
* @package SP\Services\Crypt
*/
class TemporaryMasterPassService extends Service
{
/**
* Número máximo de intentos
*/
const MAX_ATTEMPTS = 50;
/**
* @var ConfigService
*/
protected $configService;
/**
* Devuelve la clave maestra que ha sido encriptada con la clave temporal
*
* @param $randomKey string con la clave utilizada para encriptar
* @return string con la clave maestra desencriptada
* @throws \Defuse\Crypto\Exception\CryptoException
* @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
* @throws \Defuse\Crypto\Exception\BadFormatException
*/
public static function getTempMasterPass($randomKey)
{
$securedKey = Crypt::unlockSecuredKey(ConfigDB::getValue('tempmaster_passkey'), $randomKey);
return Crypt::decrypt(ConfigDB::getValue('tempmaster_pass'), $securedKey, $randomKey);
}
/**
* Crea una clave temporal para encriptar la clave maestra y guardarla.
*
* @param int $maxTime El tiempo máximo de validez de la clave
* @return string
* @throws ServiceException
*/
public function create($maxTime = 14400)
{
try {
// Encriptar la clave maestra con hash aleatorio generado
$randomKey = Util::generateRandomBytes(32);
$securedKey = Crypt::makeSecuredKey($randomKey);
$this->configService->save('tempmaster_passkey', $securedKey);
$this->configService->save('tempmaster_passhash', Hash::hashKey($randomKey));
$this->configService->save('tempmaster_passtime', time());
$this->configService->save('tempmaster_maxtime', time() + $maxTime);
$this->configService->save('tempmaster_attempts', 0);
// Guardar la clave temporal hasta que finalice la sesión
$this->session->setTemporaryMasterPass($randomKey);
$this->eventDispatcher->notifyEvent('create.tempMasterPass', new Event($this, [__u('Generar Clave Temporal')]));
return $randomKey;
} catch (\Exception $e) {
processException($e);
throw new ServiceException(__u('Error al generar clave temporal'), SPException::ERROR);
}
}
/**
* Comprueba si la clave temporal es válida
*
* @param string $pass clave a comprobar
* @return bool
* @throws ServiceException
*/
public function checkTempMasterPass($pass)
{
try {
$isValid = false;
$passTime = (int)$this->configService->getByParam('tempmaster_passtime');
$passMaxTime = (int)$this->configService->getByParam('tempmaster_maxtime');
$attempts = (int)$this->configService->getByParam('tempmaster_attempts');
// Comprobar si el tiempo de validez o los intentos se han superado
if ($passMaxTime === 0) {
$this->eventDispatcher->notifyEvent('check.tempMasterPass', new Event($this, [__u('Clave temporal caducada')]));
return $isValid;
}
if ((!empty($passTime) && time() > $passMaxTime)
|| $attempts >= self::MAX_ATTEMPTS
) {
$this->configService->save('tempmaster_passkey', '');
$this->configService->save('tempmaster_passhash', '');
$this->configService->save('tempmaster_maxtime', '');
$this->configService->save('tempmaster_attempts', 0);
$this->eventDispatcher->notifyEvent('check.tempMasterPass', new Event($this, [__u('Clave temporal caducada')]));
return $isValid;
}
$isValid = Hash::checkHashKey($pass, $this->configService->getByParam('tempmaster_passhash'));
if (!$isValid) {
$this->configService->save('tempmaster_attempts', $attempts + 1);
}
return $isValid;
} catch (\Exception $e) {
processException($e);
throw new ServiceException(__('Error al comprobar clave temporal'), SPException::ERROR);
}
}
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
protected function initialize()
{
$this->configService = $this->dic->get(ConfigService::class);
}
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\Crypt;
use SP\Core\Crypt\Hash;
use SP\Core\Task;
/**
* Class UpdateMasterPassRequest
*
* @package SP\Services\Crypt
*/
class UpdateMasterPassRequest
{
/**
* @var string
*/
private $currentMasterPass;
/**
* @var string
*/
private $newMasterPass;
/**
* @var Task
*/
private $task;
/**
* @var string
*/
private $hash;
/**
* @var string
*/
private $currentHash;
/**
* UpdateMasterPassRequest constructor.
*
* @param string $currentMasterPass
* @param string $newMasterPass
* @param string $currentHash
* @param Task $task
*/
public function __construct($currentMasterPass, $newMasterPass, $currentHash, Task $task)
{
$this->currentMasterPass = $currentMasterPass;
$this->newMasterPass = $newMasterPass;
$this->task = $task;
$this->hash = Hash::hashKey($newMasterPass);
$this->currentHash = $currentHash;
}
/**
* @return string
*/
public function getCurrentMasterPass()
{
return $this->currentMasterPass;
}
/**
* @return string
*/
public function getNewMasterPass()
{
return $this->newMasterPass;
}
/**
* @return Task
*/
public function getTask()
{
return $this->task;
}
/**
* @return string
*/
public function getHash()
{
return $this->hash;
}
/**
* @return string
*/
public function getCurrentHash()
{
return $this->currentHash;
}
}

View File

@@ -0,0 +1,159 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\CustomField;
defined('APP_ROOT') || die();
use SP\Core\Crypt\Crypt;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\Core\OldCrypt;
use SP\Core\TaskFactory;
use SP\DataModel\CustomFieldData;
use SP\Services\Crypt\UpdateMasterPassRequest;
use SP\Services\Service;
use SP\Services\ServiceException;
/**
* Class CustomFieldCryptService
*
* @package SP\Mgmt\CustomFields
*/
class CustomFieldCryptService extends Service
{
/**
* @var CustomFieldService
*/
protected $customFieldService;
/**
* @var UpdateMasterPassRequest
*/
protected $request;
/**
* Actualizar los datos encriptados con una nueva clave
*
* @param UpdateMasterPassRequest $request
* @return array
* @throws ServiceException
*/
public function updateMasterPasswordOld(UpdateMasterPassRequest $request)
{
$this->request = $request;
try {
return $this->processUpdateMasterPassword(function (CustomFieldData $customFieldData) {
return OldCrypt::getDecrypt($customFieldData->getData(), $customFieldData->getKey(), $this->request->getCurrentMasterPass());
});
} catch (ServiceException $e) {
throw $e;
} catch (\Exception $e) {
throw new ServiceException(__u('Errores al actualizar datos de campos personalizados'), SPException::ERROR, null, $e->getCode(), $e);
}
}
/**
* @param callable $decryptor
* @return array
* @throws ServiceException
* @throws \SP\Core\Exceptions\InvalidArgumentException
*/
protected function processUpdateMasterPassword(callable $decryptor)
{
$messages = [];
$customFields = $this->customFieldService->getAll();
if (count($customFields) === 0) {
throw new ServiceException(__u('No hay datos de campos personalizados'), SPException::INFO);
}
$this->eventDispatcher->notifyEvent('update.masterPassword.customFields.start', new Event($this, [__u('Actualizar Clave Maestra')]));
$taskId = $this->request->getTask()->getTaskId();
TaskFactory::update($taskId, TaskFactory::createMessage($taskId, __('Actualizar Clave Maestra'))->setMessage(__u('Actualizando datos encriptados')));
$errors = [];
$success = [];
foreach ($customFields as $customField) {
try {
$customField->setData($decryptor($customField));
$this->customFieldService->updateMasterPass($customField, $this->request->getNewMasterPass());
$success[] = $customField->getId();
} catch (\Exception $e) {
processException($e);
$errors[] = $customField->getId();
}
}
$messages[] = __u('Registros no actualizados');
$messages[] = implode(',', $errors);
$messages[] = __u('Registros actualizados');
$messages[] = implode(',', $success);
$this->eventDispatcher->notifyEvent('update.masterPassword.customFields.end', new Event($this, [__u('Actualizar Clave Maestra')]));
return $messages;
}
/**
* Actualizar los datos encriptados con una nueva clave
*
* @param UpdateMasterPassRequest $request
* @return array
* @throws ServiceException
*/
public function updateMasterPassword(UpdateMasterPassRequest $request)
{
try {
$this->request = $request;
return $this->processUpdateMasterPassword(function (CustomFieldData $customFieldData) {
return Crypt::decrypt(
$customFieldData->getData(),
Crypt::unlockSecuredKey($customFieldData->getKey(), $this->request->getCurrentMasterPass()),
$this->request->getCurrentMasterPass());
});
} catch (ServiceException $e) {
throw $e;
} catch (\Exception $e) {
throw new ServiceException(__u('Errores al actualizar datos de campos personalizados'), SPException::ERROR, null, $e->getCode(), $e);
}
}
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
protected function initialize()
{
$this->customFieldService = $this->dic->get(CustomFieldService::class);
}
}

View File

@@ -32,6 +32,7 @@ use SP\Core\Exceptions\SPException;
use SP\DataModel\CustomFieldData;
use SP\Repositories\CustomField\CustomFieldRepository;
use SP\Services\Service;
use SP\Services\ServiceException;
/**
* Class CustomFieldService
@@ -150,6 +151,7 @@ class CustomFieldService extends Service
* @return bool
* @throws CryptoException
* @throws QueryException
* @throws ServiceException
* @throws \SP\Core\Exceptions\ConstraintException
*/
public function create(CustomFieldData $customFieldData)
@@ -165,22 +167,49 @@ class CustomFieldService extends Service
/**
* @param CustomFieldData $customFieldData
* @param null $key
* @throws CryptoException
* @throws QueryException
* @throws ServiceException
*/
protected function setSecureData(CustomFieldData $customFieldData)
protected function setSecureData(CustomFieldData $customFieldData, $key = null)
{
$sessionKey = CryptSession::getSessionKey();
$securedKey = Crypt::makeSecuredKey($sessionKey);
$key = $key ?: CryptSession::getSessionKey();
$securedKey = Crypt::makeSecuredKey($key);
if (strlen($securedKey) > 1000) {
throw new QueryException(__u('Error interno'), SPException::ERROR);
throw new ServiceException(__u('Error interno'), SPException::ERROR);
}
$customFieldData->setData(Crypt::encrypt($customFieldData->getData(), $securedKey, $sessionKey));
$customFieldData->setData(Crypt::encrypt($customFieldData->getData(), $securedKey, $key));
$customFieldData->setKey($securedKey);
}
/**
* Updates an item
*
* @param CustomFieldData $customFieldData
* @param string $masterPass
* @return bool
* @throws CryptoException
* @throws QueryException
* @throws ServiceException
* @throws \SP\Core\Exceptions\ConstraintException
*/
public function updateMasterPass(CustomFieldData $customFieldData, $masterPass)
{
$this->setSecureData($customFieldData, $masterPass);
return $this->customFieldRepository->update($customFieldData);
}
/**
* @return CustomFieldData[]
*/
public function getAll()
{
return $this->customFieldRepository->getAll();
}
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface

View File

@@ -0,0 +1,566 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link http://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Services\Export;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use SP\Config\ConfigData;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Hash;
use SP\Core\Events\Event;
use SP\Core\Exceptions\SPException;
use SP\DataModel\CategoryData;
use SP\Services\Account\AccountService;
use SP\Services\Account\AccountToTagService;
use SP\Services\Category\CategoryService;
use SP\Services\Client\ClientService;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Services\Tag\TagService;
use SP\Util\Util;
defined('APP_ROOT') || die();
/**
* Clase XmlExport para realizar la exportación de las cuentas de sysPass a formato XML
*
* @package SP
*/
class XmlExportService extends Service
{
/**
* @var ConfigData
*/
protected $configData;
/**
* @var \DOMDocument
*/
private $xml;
/**
* @var \DOMElement
*/
private $root;
/**
* @var string
*/
private $exportPass;
/**
* @var bool
*/
private $encrypted = false;
/**
* @var string
*/
private $exportDir = '';
/**
* @var string
*/
private $exportFile = '';
/**
* Realiza la exportación de las cuentas a XML
*
* @param null $pass string La clave de exportación
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ServiceException
*/
public function doExport($pass = null)
{
if (!empty($pass)) {
$this->setExportPass($pass);
$this->setEncrypted(true);
}
$this->setExportDir(BACKUP_PATH);
$this->setExportFile();
$this->deleteOldExports();
$this->makeXML();
}
/**
* Establecer la clave de exportación
*
* @param string $exportPass
*/
public function setExportPass($exportPass)
{
$this->exportPass = $exportPass;
}
/**
* @param boolean $encrypted
*/
public function setEncrypted($encrypted)
{
$this->encrypted = $encrypted;
}
/**
* @param string $exportDir
*/
public function setExportDir($exportDir)
{
$this->exportDir = $exportDir;
}
/**
* Genera el nombre del archivo usado para la exportación.
*/
private function setExportFile()
{
// Generar hash unico para evitar descargas no permitidas
$exportUniqueHash = sha1(uniqid('sysPassExport', true));
$this->configData->setExportHash($exportUniqueHash);
$this->config->saveConfig();
$this->exportFile = $this->exportDir . DIRECTORY_SEPARATOR . Util::getAppInfo('appname') . '-' . $exportUniqueHash . '.xml';
}
/**
* Eliminar los archivos de exportación anteriores
*/
private function deleteOldExports()
{
array_map('unlink', glob($this->exportDir . DIRECTORY_SEPARATOR . '*.xml'));
}
/**
* Crear el documento XML y guardarlo
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ServiceException
*/
public function makeXML()
{
try {
$this->eventDispatcher->notifyEvent('export.xml.start', new Event($this, [__u('Exportar XML')]));
$this->checkExportDir();
$this->createRoot();
$this->createMeta();
$this->createCategories();
$this->createClients();
$this->createTags();
$this->createAccounts();
$this->createHash();
$this->writeXML();
$this->eventDispatcher->notifyEvent('export.xml.end', new Event($this, [__u('Exportación realizada correctamente')]));
} catch (ServiceException $e) {
throw $e;
} catch (\Exception $e) {
processException($e);
throw new ServiceException(__u('Error al realizar la exportación'), SPException::ERROR, __u('Revise el registro de eventos para más detalles'));
}
}
/**
* Comprobar y crear el directorio de exportación.
*
* @throws ServiceException
* @return bool
*/
private function checkExportDir()
{
if (@mkdir($this->exportDir, 0750) === false && is_dir($this->exportDir) === false) {
throw new ServiceException(sprintf(__('No es posible crear el directorio de backups ("%s")'), $this->exportDir), SPException::ERROR);
}
clearstatcache(true, $this->exportDir);
if (!is_writable($this->exportDir)) {
throw new ServiceException(__u('Compruebe los permisos del directorio de backups'), SPException::ERROR);
}
return true;
}
/**
* Crear el nodo raíz
*
* @throws ServiceException
*/
private function createRoot()
{
try {
$root = $this->xml->createElement('Root');
$this->root = $this->xml->appendChild($root);
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Crear el nodo con metainformación del archivo XML
*
* @throws ServiceException
*/
private function createMeta()
{
try {
$userData = $this->session->getUserData();
$nodeMeta = $this->xml->createElement('Meta');
$metaGenerator = $this->xml->createElement('Generator', 'sysPass');
$metaVersion = $this->xml->createElement('Version', Util::getVersionStringNormalized());
$metaTime = $this->xml->createElement('Time', time());
$metaUser = $this->xml->createElement('User', $userData->getLogin());
$metaUser->setAttribute('id', $userData->getId());
// FIXME: get user group name
$metaGroup = $this->xml->createElement('Group', '');
$metaGroup->setAttribute('id', $userData->getUserGroupId());
$nodeMeta->appendChild($metaGenerator);
$nodeMeta->appendChild($metaVersion);
$nodeMeta->appendChild($metaTime);
$nodeMeta->appendChild($metaUser);
$nodeMeta->appendChild($metaGroup);
$this->root->appendChild($nodeMeta);
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Crear el nodo con los datos de las categorías
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ServiceException
*/
private function createCategories()
{
try {
$categoryService = $this->dic->get(CategoryService::class);
$categories = $categoryService->getAllBasic();
// Crear el nodo de categorías
$nodeCategories = $this->xml->createElement('Categories');
if (count($categories) === 0) {
$this->appendNode($nodeCategories);
return;
}
foreach ($categories as $category) {
/** @var $category CategoryData */
$categoryName = $this->xml->createElement('name', $this->escapeChars($category->getName()));
$categoryDescription = $this->xml->createElement('description', $this->escapeChars($category->getDescription()));
// Crear el nodo de categoría
$nodeCategory = $this->xml->createElement('Category');
$nodeCategory->setAttribute('id', $category->getId());
$nodeCategory->appendChild($categoryName);
$nodeCategory->appendChild($categoryDescription);
// Añadir categoría al nodo de categorías
$nodeCategories->appendChild($nodeCategory);
}
$this->appendNode($nodeCategories);
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Escapar carácteres no válidos en XML
*
* @param $data string Los datos a escapar
* @return mixed
*/
private function escapeChars($data)
{
$arrStrFrom = ['&', '<', '>', '"', '\''];
$arrStrTo = ['&#38;', '&#60;', '&#62;', '&#34;', '&#39;'];
return str_replace($arrStrFrom, $arrStrTo, $data);
}
/**
* Añadir un nuevo nodo al árbol raíz
*
* @param \DOMElement $node El nodo a añadir
* @throws ServiceException
*/
private function appendNode(\DOMElement $node)
{
try {
// Si se utiliza clave de encriptación los datos se encriptan en un nuevo nodo:
// Encrypted -> Data
if ($this->encrypted === true) {
// Obtener el nodo en formato XML
$nodeXML = $this->xml->saveXML($node);
// Crear los datos encriptados con la información del nodo
$securedKey = Crypt::makeSecuredKey($this->exportPass);
$encrypted = Crypt::encrypt($nodeXML, $securedKey, $this->exportPass);
// Buscar si existe ya un nodo para el conjunto de datos encriptados
$encryptedNode = $this->root->getElementsByTagName('Encrypted')->item(0);
if (!$encryptedNode instanceof \DOMElement) {
$encryptedNode = $this->xml->createElement('Encrypted');
$encryptedNode->setAttribute('hash', Hash::hashKey($this->exportPass));
}
// Crear el nodo hijo con los datos encriptados
$encryptedData = $this->xml->createElement('Data', base64_encode($encrypted));
$encryptedDataIV = $this->xml->createAttribute('key');
$encryptedDataIV->value = $securedKey;
// Añadir nodos de datos
$encryptedData->appendChild($encryptedDataIV);
$encryptedNode->appendChild($encryptedData);
// Añadir el nodo encriptado
$this->root->appendChild($encryptedNode);
} else {
$this->root->appendChild($node);
}
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Crear el nodo con los datos de los clientes
*
* @throws ServiceException
* @throws ServiceException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
private function createClients()
{
try {
$clientService = $this->dic->get(ClientService::class);
$clients = $clientService->getAllBasic();
// Crear el nodo de clientes
$nodeClients = $this->xml->createElement('Clients');
if (count($clients) === 0) {
$this->appendNode($nodeClients);
return;
}
foreach ($clients as $client) {
$clientName = $this->xml->createElement('name', $this->escapeChars($client->getName()));
$clientDescription = $this->xml->createElement('description', $this->escapeChars($client->getDescription()));
// Crear el nodo de clientes
$nodeClient = $this->xml->createElement('Client');
$nodeClient->setAttribute('id', $client->getId());
$nodeClient->appendChild($clientName);
$nodeClient->appendChild($clientDescription);
// Añadir cliente al nodo de clientes
$nodeClients->appendChild($nodeClient);
}
$this->appendNode($nodeClients);
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Crear el nodo con los datos de las etiquetas
*
* @throws ServiceException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
private function createTags()
{
try {
$tagService = $this->dic->get(TagService::class);
$tags = $tagService->getAllBasic();
// Crear el nodo de etiquetas
$nodeTags = $this->xml->createElement('Tags');
if (count($tags) === 0) {
$this->appendNode($nodeTags);
return;
}
foreach ($tags as $tag) {
$tagName = $this->xml->createElement('name', $this->escapeChars($tag->getName()));
// Crear el nodo de etiquetas
$nodeTag = $this->xml->createElement('Tag');
$nodeTag->setAttribute('id', $tag->getId());
$nodeTag->appendChild($tagName);
// Añadir etiqueta al nodo de etiquetas
$nodeTags->appendChild($nodeTag);
}
$this->appendNode($nodeTags);
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Crear el nodo con los datos de las cuentas
*
* @throws ServiceException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
private function createAccounts()
{
try {
$accountService = $this->dic->get(AccountService::class);
$accountToTagService = $this->dic->get(AccountToTagService::class);
$accounts = $accountService->getAllBasic();
// Crear el nodo de cuentas
$nodeAccounts = $this->xml->createElement('Accounts');
if (count($accounts) === 0) {
$this->appendNode($nodeAccounts);
return;
}
foreach ($accounts as $account) {
$accountName = $this->xml->createElement('name', $this->escapeChars($account->getName()));
$accountCustomerId = $this->xml->createElement('clientId', $account->getClientId());
$accountCategoryId = $this->xml->createElement('categoryId', $account->getCategoryId());
$accountLogin = $this->xml->createElement('login', $this->escapeChars($account->getLogin()));
$accountUrl = $this->xml->createElement('url', $this->escapeChars($account->getUrl()));
$accountNotes = $this->xml->createElement('notes', $this->escapeChars($account->getNotes()));
$accountPass = $this->xml->createElement('pass', $this->escapeChars($account->getPass()));
$accountIV = $this->xml->createElement('key', $this->escapeChars($account->getKey()));
$tags = $this->xml->createElement('tags');
foreach ($accountToTagService->getTagsByAccountId($account->getId()) as $id => $name) {
$tag = $this->xml->createElement('tag');
$tag->setAttribute('id', $id);
$tags->appendChild($tag);
}
// Crear el nodo de cuenta
$nodeAccount = $this->xml->createElement('Account');
$nodeAccount->setAttribute('id', $account->getId());
$nodeAccount->appendChild($accountName);
$nodeAccount->appendChild($accountCustomerId);
$nodeAccount->appendChild($accountCategoryId);
$nodeAccount->appendChild($accountLogin);
$nodeAccount->appendChild($accountUrl);
$nodeAccount->appendChild($accountNotes);
$nodeAccount->appendChild($accountPass);
$nodeAccount->appendChild($accountIV);
$nodeAccount->appendChild($tags);
// Añadir cuenta al nodo de cuentas
$nodeAccounts->appendChild($nodeAccount);
}
$this->appendNode($nodeAccounts);
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Crear el hash del archivo XML e insertarlo en el árbol DOM
*
* @throws ServiceException
*/
private function createHash()
{
try {
if ($this->encrypted === true) {
$hash = sha1($this->getNodeXML('Encrypted'));
} else {
$hash = sha1($this->getNodeXML('Categories') . $this->getNodeXML('Customers') . $this->getNodeXML('Accounts'));
}
$metaHash = $this->xml->createElement('Hash', $hash);
$nodeMeta = $this->root->getElementsByTagName('Meta')->item(0);
$nodeMeta->appendChild($metaHash);
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Devuelve el código XML de un nodo
*
* @param $node string El nodo a devolver
* @return string
* @throws ServiceException
*/
private function getNodeXML($node)
{
try {
$nodeXML = $this->xml->saveXML($this->root->getElementsByTagName($node)->item(0));
return $nodeXML;
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::WARNING, __FUNCTION__);
}
}
/**
* Generar el archivo XML
*
* @throws ServiceException
*/
private function writeXML()
{
try {
$this->xml->formatOutput = true;
$this->xml->preserveWhiteSpace = false;
if (!$this->xml->save($this->exportFile)) {
throw new ServiceException(__u('Error al crear el archivo XML'), SPException::ERROR);
}
} catch (\Exception $e) {
throw new ServiceException($e->getMessage(), SPException::ERROR, __FUNCTION__);
}
}
/**
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function initialize()
{
$this->configData = $this->config->getConfigData();
$this->xml = new \DOMDocument('1.0', 'UTF-8');
}
}

View File

@@ -26,6 +26,7 @@ namespace SP\Services\Tag;
use SP\Core\Exceptions\SPException;
use SP\DataModel\ItemSearchData;
use SP\DataModel\TagData;
use SP\Repositories\Tag\TagRepository;
use SP\Services\Service;
use SP\Services\ServiceItemTrait;
@@ -110,7 +111,7 @@ class TagService extends Service
/**
* Get all items from the service's repository
*
* @return array
* @return TagData[]
*/
public function getAllBasic()
{

View File

@@ -39,7 +39,7 @@ class DBUtil
* @var array Tablas de la BBDD
*/
public static $tables = [
'Customer',
'Client',
'Category',
'Tag',
'UserGroup',
@@ -51,13 +51,13 @@ class DBUtil
'AccountToUserGroup',
'AccountHistory',
'AccountToTag',
'AccountTouser',
'AccountToUser',
'AuthToken',
'Config',
'Action',
'CustomFieldType',
'CustomFieldDefinition',
'customFieldData',
'CustomFieldData',
'EventLog',
'PublicLink',
'UserPassRecover',

View File

@@ -77,7 +77,7 @@ class XmlHandler implements XmlFileStorageInterface
public function load($node = 'root')
{
if (!$this->checkSourceFile()) {
throw new FileNotFoundException(SPException::SP_ERROR, sprintf(__('No es posible leer/escribir el archivo: %s', false), $this->file));
throw new FileNotFoundException(sprintf(__('No es posible leer/escribir el archivo: %s'), $this->file), SPException::ERROR);
}
$this->setDOM();
@@ -163,7 +163,7 @@ class XmlHandler implements XmlFileStorageInterface
public function save($node = 'root')
{
if (null === $this->items) {
throw new RuntimeException(__('No hay elementos para guardar', false));
throw new RuntimeException(__u('No hay elementos para guardar'));
}
$this->setDOM();

View File

@@ -22,6 +22,225 @@
*/
sysPass.Actions = function (Common) {
"use strict";
const log = Common.log;
// Variable para almacenar la llamada a setTimeout()
let timeout = 0;
// Atributos de la ordenación de búsquedas
const order = {key: 0, dir: 0};
// Objeto con las URLs de las acciones
const ajaxUrl = {
entrypoint: "/index.php",
doAction: "/index.php",
updateItems: "/index.php",
user: {
savePreferences: "/ajax/ajax_userPrefsSave.php",
password: "/ajax/ajax_usrpass.php",
passreset: "/ajax/ajax_passReset.php"
},
main: {
login: "/index.php?r=login/login",
install: "/ajax/ajax_install.php",
upgrade: "/ajax/ajax_upgrade.php",
getUpdates: "/index.php?r=index/checkUpdates",
task: "/ajax/ajax_task.php"
},
checks: "/ajax/ajax_checkConnection.php",
config: {
save: "/ajax/ajax_configSave.php",
export: "/ajax/ajax_configSave.php",
import: "/ajax/ajax_configSave.php"
},
file: "/ajax/ajax_filesMgmt.php",
link: "/index.php",
plugin: "/ajax/ajax_itemSave.php",
account: {
save: "/index.php",
saveFavorite: "/ajax/ajax_itemSave.php",
request: "/ajax/ajax_itemSave.php",
getFiles: "/index.php",
search: "/index.php?r=account/search"
},
appMgmt: {
show: "/index.php",
save: "/index.php",
search: "/index.php"
},
eventlog: "/ajax/ajax_eventlog.php",
wiki: {
show: "/ajax/ajax_wiki.php"
},
notice: {
show: "/ajax/ajax_noticeShow.php",
search: "/ajax/ajax_noticeSearch.php"
}
};
Object.freeze(ajaxUrl);
// Función para cargar el contenido de la acción del menú seleccionada
const doAction = function (obj, view) {
var itemId = obj.itemId !== undefined ? "/" + obj.itemId : "";
var data = {
r: obj.r + itemId,
isAjax: 1
};
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.doAction;
opts.method = "get";
opts.type = "html";
opts.addHistory = true;
opts.data = data;
Common.appRequests().getActionCall(opts, function (response) {
var $content = $("#content");
$content.empty().html(response);
var views = Common.triggers().views;
views.common($content);
if (view !== undefined && typeof views[view] === "function") {
views[view]();
}
var $mdlContent = $(".mdl-layout__content");
if ($mdlContent.scrollTop() > 0) {
$mdlContent.animate({scrollTop: 0}, 1000);
}
});
};
// Función para cargar el contenido de la acción del menú seleccionada
const getContent = function (data, view) {
log.info("getContent");
data.isAjax = 1;
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.doAction;
opts.method = "get";
opts.type = "html";
opts.addHistory = true;
opts.data = data;
Common.appRequests().getActionCall(opts, function (response) {
const $content = $("#content");
$content.empty().html(response);
const views = Common.triggers().views;
views.common($content);
if (view !== undefined && typeof views[view] === "function") {
views[view]();
}
const $mdlContent = $(".mdl-layout__content");
if ($mdlContent.scrollTop() > 0) {
$mdlContent.animate({scrollTop: 0}, 1000);
}
});
};
/**
* Mostrar el contenido en una caja flotante
*
* @param response
* @param {Object} callback
* @param {function} callback.open
* @param {function} callback.close
*/
const showFloatingBox = function (response, callback) {
response = response || "";
$.magnificPopup.open({
items: {
src: response,
type: "inline"
},
callbacks: {
open: function () {
var $boxPopup = $("#box-popup");
Common.appTriggers().views.common($boxPopup);
$boxPopup.find(":input:text:visible:first").focus();
if (callback !== undefined && typeof callback.open === "function") {
callback.open();
}
},
close: function () {
if (callback !== undefined && typeof callback.close === "function") {
callback.close();
}
}
},
showCloseBtn: false
});
};
/**
* Mostrar una imagen
*
* @param $obj
* @param response
*/
const showImageBox = function ($obj, response) {
const $content = $("<div id=\"box-popup\" class=\"image\">" + response + "</div>");
const $image = $content.find("img");
if ($image.length === 0) {
return showFloatingBox(response);
}
$image.hide();
$.magnificPopup.open({
items: {
src: $content,
type: "inline"
},
callbacks: {
open: function () {
const $popup = this;
$image.on("click", function () {
$popup.close();
});
setTimeout(function () {
const image = Common.resizeImage($image);
$content.css({
backgroundColor: "#fff",
width: image.width,
height: "auto"
});
$image.show("slow");
}, 500);
}
}
});
};
/**
* Cerrar los diálogos
*/
var closeFloatingBox = function () {
$.magnificPopup.close();
};
/**
* Objeto con acciones para las cuentas
*/
@@ -44,7 +263,7 @@ sysPass.Actions = function (Common) {
delete: function ($obj) {
log.info("account:delete");
var atext = "<div id=\"alert\"><p id=\"alert-text\">" + Common.config().LANG[3] + "</p></div>";
const atext = "<div id=\"alert\"><p id=\"alert-text\">" + Common.config().LANG[3] + "</p></div>";
mdlDialog().show({
text: atext,
@@ -59,7 +278,7 @@ sysPass.Actions = function (Common) {
positive: {
title: Common.config().LANG[43],
onClick: function (e) {
var opts = Common.appRequests().getRequestOpts();
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.account.save;
opts.data = {
r: "account/saveDelete/" + $obj.data("item-id"),
@@ -281,224 +500,6 @@ sysPass.Actions = function (Common) {
});
}
};
"use strict";
const log = Common.log;
// Variable para almacenar la llamada a setTimeout()
let timeout = 0;
// Atributos de la ordenación de búsquedas
const order = {key: 0, dir: 0};
// Objeto con las URLs de las acciones
const ajaxUrl = {
entrypoint: "/index.php",
doAction: "/index.php",
updateItems: "/index.php",
user: {
savePreferences: "/ajax/ajax_userPrefsSave.php",
password: "/ajax/ajax_usrpass.php",
passreset: "/ajax/ajax_passReset.php"
},
main: {
login: "/index.php?r=login/login",
install: "/ajax/ajax_install.php",
upgrade: "/ajax/ajax_upgrade.php",
getUpdates: "/index.php?r=index/checkUpdates",
task: "/ajax/ajax_task.php"
},
checks: "/ajax/ajax_checkConnection.php",
config: {
save: "/ajax/ajax_configSave.php",
export: "/ajax/ajax_configSave.php",
import: "/ajax/ajax_configSave.php"
},
file: "/ajax/ajax_filesMgmt.php",
link: "/index.php",
plugin: "/ajax/ajax_itemSave.php",
account: {
save: "/index.php",
saveFavorite: "/ajax/ajax_itemSave.php",
request: "/ajax/ajax_itemSave.php",
getFiles: "/index.php",
search: "/index.php?r=account/search"
},
appMgmt: {
show: "/index.php",
save: "/index.php",
search: "/index.php"
},
eventlog: "/ajax/ajax_eventlog.php",
wiki: {
show: "/ajax/ajax_wiki.php"
},
notice: {
show: "/ajax/ajax_noticeShow.php",
search: "/ajax/ajax_noticeSearch.php"
}
};
Object.freeze(ajaxUrl);
// Función para cargar el contenido de la acción del menú seleccionada
const doAction = function (obj, view) {
var itemId = obj.itemId !== undefined ? "/" + obj.itemId : "";
var data = {
r: obj.r + itemId,
isAjax: 1
};
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.doAction;
opts.method = "get";
opts.type = "html";
opts.addHistory = true;
opts.data = data;
Common.appRequests().getActionCall(opts, function (response) {
var $content = $("#content");
$content.empty().html(response);
var views = Common.triggers().views;
views.common($content);
if (view !== undefined && typeof views[view] === "function") {
views[view]();
}
var $mdlContent = $(".mdl-layout__content");
if ($mdlContent.scrollTop() > 0) {
$mdlContent.animate({scrollTop: 0}, 1000);
}
});
};
// Función para cargar el contenido de la acción del menú seleccionada
const getContent = function (data, view) {
log.info("getContent");
data.isAjax = 1;
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.doAction;
opts.method = "get";
opts.type = "html";
opts.addHistory = true;
opts.data = data;
Common.appRequests().getActionCall(opts, function (response) {
var $content = $("#content");
$content.empty().html(response);
var views = Common.triggers().views;
views.common($content);
if (view !== undefined && typeof views[view] === "function") {
views[view]();
}
var $mdlContent = $(".mdl-layout__content");
if ($mdlContent.scrollTop() > 0) {
$mdlContent.animate({scrollTop: 0}, 1000);
}
});
};
/**
* Mostrar el contenido en una caja flotante
*
* @param response
* @param {Object} callback
* @param {function} callback.open
* @param {function} callback.close
*/
const showFloatingBox = function (response, callback) {
response = response || "";
$.magnificPopup.open({
items: {
src: response,
type: "inline"
},
callbacks: {
open: function () {
var $boxPopup = $("#box-popup");
Common.appTriggers().views.common($boxPopup);
$boxPopup.find(":input:text:visible:first").focus();
if (callback !== undefined && typeof callback.open === "function") {
callback.open();
}
},
close: function () {
if (callback !== undefined && typeof callback.close === "function") {
callback.close();
}
}
},
showCloseBtn: false
});
};
/**
* Mostrar una imagen
*
* @param $obj
* @param response
*/
const showImageBox = function ($obj, response) {
const $content = $("<div id=\"box-popup\" class=\"image\">" + response + "</div>");
const $image = $content.find("img");
if ($image.length === 0) {
return showFloatingBox(response);
}
$image.hide();
$.magnificPopup.open({
items: {
src: $content,
type: "inline"
},
callbacks: {
open: function () {
const $popup = this;
$image.on("click", function () {
$popup.close();
});
setTimeout(function () {
const image = Common.resizeImage($image);
$content.css({
backgroundColor: "#fff",
width: image.width,
height: "auto"
});
$image.show("slow");
}, 500);
}
}
});
};
/**
* Cerrar los diálogos
*/
var closeFloatingBox = function () {
$.magnificPopup.close();
};
/**
* Actualizar los elemento de un select
@@ -837,24 +838,25 @@ sysPass.Actions = function (Common) {
*
* @type {{save: config.save, backup: config.backup, export: config.export, import: config.import}}
*/
var config = {
const config = {
save: function ($obj) {
log.info("config:save");
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.config.save;
opts.data = $obj.serialize();
tabs.state.update($obj);
if ($obj.data("type") === "masterpass") {
opts.useFullLoading = true;
}
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route");
opts.data = $obj.serialize();
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
if (json.status === 0) {
if ($obj.data("nextaction-id") !== undefined) {
doAction({actionId: $obj.data("nextaction-id"), itemId: $obj.data("activetab")});
if (tabs.state.tab.refresh === true) {
getContent({
r: tabs.state.tab.route,
tabIndex: tabs.state.tab.index
});
} else if ($obj.data("reload") !== undefined) {
setTimeout(function () {
Common.redirect("index.php");
@@ -864,7 +866,7 @@ sysPass.Actions = function (Common) {
});
},
masterpass: function ($obj) {
var atext = "<div id=\"alert\"><p id=\"alert-text\">" + Common.config().LANG[59] + "</p></div>";
const atext = "<div id=\"alert\"><p id=\"alert-text\">" + Common.config().LANG[59] + "</p></div>";
mdlDialog().show({
text: atext,
@@ -881,28 +883,28 @@ sysPass.Actions = function (Common) {
positive: {
title: Common.config().LANG[43],
onClick: function (e) {
var $useTask = $obj.find("input[name='useTask']");
var $taskStatus = $("#taskStatus");
const $useTask = $obj.find("input[name='useTask']");
const $taskStatus = $("#taskStatus");
$taskStatus.empty().html(Common.config().LANG[62]);
if ($useTask.length > 0 && $useTask.val() == 1) {
var optsTask = Common.appRequests().getRequestOpts();
const optsTask = Common.appRequests().getRequestOpts();
optsTask.url = ajaxUrl.main.task;
optsTask.data = {
source: $obj.find("input[name='lock']").val(),
taskId: $obj.find("input[name='taskId']").val()
};
var task = Common.appRequests().getActionEvent(optsTask, function (result) {
var text = result.task + " - " + result.message + " - " + result.time + " - " + result.progress + "%";
const task = Common.appRequests().getActionEvent(optsTask, function (result) {
let text = result.task + " - " + result.message + " - " + result.time + " - " + result.progress + "%";
text += "<br>" + Common.config().LANG[62];
$taskStatus.empty().html(text);
});
}
var opts = Common.appRequests().getRequestOpts();
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.config.save;
opts.useFullLoading = true;
opts.data = $obj.serialize();
@@ -923,58 +925,61 @@ sysPass.Actions = function (Common) {
backup: function ($obj) {
log.info("config:backup");
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.config.export;
opts.method = "post";
tabs.state.update($obj);
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route");
opts.useFullLoading = true;
opts.data = $obj.serialize();
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
if (json.status === 0 && $obj.data("nextaction-id") !== undefined) {
doAction({actionId: $obj.data("nextaction-id"), itemId: $obj.data("activetab")});
if (json.status === 0) {
getContent({
r: tabs.state.tab.route,
tabIndex: tabs.state.tab.index
});
}
});
},
export: function ($obj) {
log.info("config:export");
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.config.export;
tabs.state.update($obj);
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route");
opts.data = $obj.serialize();
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
if (json.status === 0 && $obj.data("nextaction-id") !== undefined) {
doAction({actionId: $obj.data("nextaction-id"), itemId: $obj.data("activetab")});
if (json.status === 0) {
getContent({
r: tabs.state.tab.route,
tabIndex: tabs.state.tab.index
});
}
});
},
import: function ($obj) {
log.info("config:import");
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.config.import;
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route");
opts.data = $obj.serialize();
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
if (json.status === 0 && $obj.data("nextaction-id") !== undefined) {
doAction({actionId: $obj.data("nextaction-id"), itemId: $obj.data("activetab")});
}
});
},
refreshMpass: function ($obj) {
log.info("config:import");
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.config.save;
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route");
opts.data = {
actionId: $obj.data("action-id"),
itemId: $obj.data("item-id"),
sk: $obj.data("sk"),
isAjax: 1
};
@@ -987,8 +992,6 @@ sysPass.Actions = function (Common) {
/**
* Objeto con las acciones de los archivos
*
* @type {{view: file.view, download: file.download, delete: file.delete}}
*/
const file = {
view: function ($obj) {
@@ -1122,19 +1125,15 @@ sysPass.Actions = function (Common) {
Common.msg.out(json);
getContent({
r: appMgmt.state.tab.route,
tabIndex: appMgmt.state.tab.index
r: tabs.state.tab.route,
tabIndex: tabs.state.tab.index
});
});
}
};
/**
* Objeto con acciones sobre elementos de la aplicación
*/
var appMgmt = {
refreshTab: true,
const tabs = {
state: {
tab: {
index: 0,
@@ -1143,22 +1142,28 @@ sysPass.Actions = function (Common) {
},
itemId: 0,
update: function ($obj) {
var $currentTab = $("#content").find("[id^='tabs-'].is-active");
const $currentTab = $("#content").find("[id^='tabs-'].is-active");
if ($currentTab.length > 0) {
appMgmt.state.tab.refresh = !$obj.data("item-dst");
appMgmt.state.tab.index = $currentTab.data("tab-index");
appMgmt.state.tab.route = $currentTab.data("tab-route");
appMgmt.state.itemId = $obj.data("item-id");
tabs.state.tab.refresh = !$obj.data("item-dst");
tabs.state.tab.index = $currentTab.data("tab-index");
tabs.state.tab.route = $currentTab.data("tab-route");
tabs.state.itemId = $obj.data("item-id");
}
}
},
}
};
/**
* Objeto con acciones sobre elementos de la aplicación
*/
const appMgmt = {
show: function ($obj) {
log.info("appMgmt:show");
appMgmt.state.update($obj);
tabs.state.update($obj);
var opts = Common.appRequests().getRequestOpts();
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.appMgmt.show;
opts.method = "get";
opts.data = {
@@ -1176,7 +1181,7 @@ sysPass.Actions = function (Common) {
showFloatingBox(json.data.html, {
open: function () {
if ($itemDst) {
appMgmt.state.tab.refresh = false;
tabs.state.tab.refresh = false;
}
},
close: function () {
@@ -1191,16 +1196,16 @@ sysPass.Actions = function (Common) {
delete: function ($obj) {
log.info("appMgmt:delete");
appMgmt.state.update($obj);
tabs.state.update($obj);
var atext = "<div id=\"alert\"><p id=\"alert-text\">" + Common.config().LANG[12] + "</p></div>";
var selection = $obj.data("selection");
var items = [];
const atext = "<div id=\"alert\"><p id=\"alert-text\">" + Common.config().LANG[12] + "</p></div>";
const selection = $obj.data("selection");
const items = [];
// FIXME
if (selection) {
$(selection).find(".is-selected").each(function () {
var $this = $(this);
const $this = $(this);
items.push($this.data("item-id"));
});
@@ -1225,8 +1230,8 @@ sysPass.Actions = function (Common) {
onClick: function (e) {
e.preventDefault();
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.appMgmt.save;
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint;
opts.method = "get";
opts.data = {
r: $obj.data("action-route") + "/" + $obj.data("item-id"),
@@ -1238,8 +1243,8 @@ sysPass.Actions = function (Common) {
Common.msg.out(json);
getContent({
r: appMgmt.state.tab.route,
tabIndex: appMgmt.state.tab.index
r: tabs.state.tab.route,
tabIndex: tabs.state.tab.index
});
});
}
@@ -1249,18 +1254,18 @@ sysPass.Actions = function (Common) {
save: function ($obj) {
log.info("appMgmt:save");
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.appMgmt.save + "?r=" + $obj.data("route");
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("route");
opts.data = $obj.serialize();
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
if (json.status === 0) {
if (appMgmt.state.tab.refresh === true) {
if (tabs.state.tab.refresh === true) {
getContent({
r: appMgmt.state.tab.route,
tabIndex: appMgmt.state.tab.index
r: tabs.state.tab.route,
tabIndex: tabs.state.tab.index
});
}
@@ -1271,9 +1276,9 @@ sysPass.Actions = function (Common) {
search: function ($obj) {
log.info("appMgmt:search");
var $target = $($obj.data("target"));
var opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.appMgmt.search + "?r=" + $obj.data("action-route");
const $target = $($obj.data("target"));
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route");
opts.method = "get";
opts.data = $obj.serialize();
@@ -1290,7 +1295,7 @@ sysPass.Actions = function (Common) {
nav: function ($obj) {
log.info("appMgmt:nav");
var $form = $("#" + $obj.data("action-form"));
const $form = $("#" + $obj.data("action-form"));
$form.find("[name='start']").val($obj.data("start"));
$form.find("[name='count']").val($obj.data("count"));

View File

@@ -1,47 +1,47 @@
var $jscomp={scope:{},findInternal:function(c,k,e){c instanceof String&&(c=String(c));for(var l=c.length,f=0;f<l;f++){var m=c[f];if(k.call(e,m,f,c))return{i:f,v:m}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(c,k,e){if(e.get||e.set)throw new TypeError("ES3 does not support getters and setters.");c!=Array.prototype&&c!=Object.prototype&&(c[k]=e.value)};
$jscomp.getGlobal=function(c){return"undefined"!=typeof window&&window===c?c:"undefined"!=typeof global&&null!=global?global:c};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(c,k,e,l){if(k){e=$jscomp.global;c=c.split(".");for(l=0;l<c.length-1;l++){var f=c[l];f in e||(e[f]={});e=e[f]}c=c[c.length-1];l=e[c];k=k(l);k!=l&&null!=k&&$jscomp.defineProperty(e,c,{configurable:!0,writable:!0,value:k})}};
$jscomp.polyfill("Array.prototype.find",function(c){return c?c:function(c,e){return $jscomp.findInternal(this,c,e).v}},"es6-impl","es3");
sysPass.Actions=function(c){var k={view:function(a){e.info("account:show");n(c.appRequests().getRouteForQuery(a.data("action-route"),a.data("item-id")),"account")},viewHistory:function(a){e.info("account:showHistory");n(c.appRequests().getRouteForQuery(a.data("action-route"),a.val()),"account")},edit:function(a){e.info("account:edit");n(c.appRequests().getRouteForQuery(a.data("action-route"),a.data("item-id")),"account")},"delete":function(a){e.info("account:delete");var b='<div id="alert"><p id="alert-text">'+
c.config().LANG[3]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b=c.appRequests().getRequestOpts();b.url=f.account.save;b.data={r:"account/saveDelete/"+a.data("item-id"),sk:c.sk.get()};c.appRequests().getActionCall(b,function(a){c.msg.out(a);k.search()})}}})},viewPass:function(a){e.info("account:showpass");var b=a.data("parent-id")||0,b=0===
b?a.data("item-id"):b,d=a.data("history")||0,g=c.appRequests().getRequestOpts();g.url=f.entrypoint;g.method="get";g.data={r:a.data("action-route")+"/"+b+"/"+d,sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(g,function(a){0!==a.status?c.msg.out(a):(a=$(a.data.html),p(a),l=setTimeout(function(){$.magnificPopup.close()},3E4),a.on("mouseleave",function(){clearTimeout(l);l=setTimeout(function(){$.magnificPopup.close()},3E4)}).on("mouseenter",function(){0!==l&&clearTimeout(l)}))})},copyPass:function(a){e.info("account:copypass");
var b=a.data("parent-id"),b=0===b?a.data("item-id"):b,d=c.appRequests().getRequestOpts();d.url=f.entrypoint;d.method="get";d.async=!1;d.data={r:a.data("action-route")+"/"+b+"/"+a.data("history"),sk:c.sk.get(),isAjax:1};return c.appRequests().getActionCall(d)},copy:function(a){e.info("account:copy");n(c.appRequests().getRouteForQuery(a.data("action-route"),a.data("item-id")),"account")},saveFavorite:function(a,b){e.info("account:saveFavorite");var d="on"===a.data("status"),g={r:(d?a.data("action-id-off"):
a.data("action-id-on"))+"/"+a.data("item-id"),sk:c.sk.get(),isAjax:1},q=c.appRequests().getRequestOpts();q.url=f.account.saveFavorite;q.data=g;c.appRequests().getActionCall(q,function(g){c.msg.out(g);0===g.status&&(a.data("status",d?"off":"on"),"function"===typeof b&&b())})},request:function(a){e.info("account:request");var b=c.appRequests().getRequestOpts();b.url=f.account.request;b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a)})},menu:function(c){c.hide();c.parent().children(".actions-optional").show(250)},
sort:function(c){e.info("account:sort");var a=$("#frmSearch");a.find('input[name="skey"]').val(c.data("key"));a.find('input[name="sorder"]').val(c.data("dir"));a.find('input[name="start"]').val(c.data("start"));k.search()},editPass:function(a){e.info("account:editpass");var b=a.data("parent-id"),b=void 0===b?a.data("item-id"):b;n(c.appRequests().getRouteForQuery(a.data("action-route"),b),"account")},saveEditRestore:function(a){e.info("account:restore");var b=c.appRequests().getRequestOpts();b.url=
f.entrypoint+"?r="+a.data("action-route")+"/"+a.data("history-id")+"/"+a.data("item-id");b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);void 0!==a.data.itemId&&void 0!==a.data.nextAction&&n(c.appRequests().getRouteForQuery(a.data.nextAction,a.data.itemId),"account")})},listFiles:function(a){e.info("account:getfiles");var b=c.appRequests().getRequestOpts();b.method="get";b.type="html";b.url=f.entrypoint;b.data={r:a.data("action-route")+"/"+a.data("item-id"),del:a.data("delete"),
var $jscomp={scope:{},findInternal:function(c,e,k){c instanceof String&&(c=String(c));for(var f=c.length,m=0;m<f;m++){var l=c[m];if(e.call(k,l,m,c))return{i:m,v:l}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(c,e,k){if(k.get||k.set)throw new TypeError("ES3 does not support getters and setters.");c!=Array.prototype&&c!=Object.prototype&&(c[e]=k.value)};
$jscomp.getGlobal=function(c){return"undefined"!=typeof window&&window===c?c:"undefined"!=typeof global?global:c};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(c,e,k,f){if(e){k=$jscomp.global;c=c.split(".");for(f=0;f<c.length-1;f++){var m=c[f];m in k||(k[m]={});k=k[m]}c=c[c.length-1];f=k[c];e=e(f);e!=f&&null!=e&&$jscomp.defineProperty(k,c,{configurable:!0,writable:!0,value:e})}};
$jscomp.polyfill("Array.prototype.find",function(c){return c?c:function(c,k){return $jscomp.findInternal(this,c,k).v}},"es6-impl","es3");
sysPass.Actions=function(c){var e=c.log,k=0,f={entrypoint:"/index.php",doAction:"/index.php",updateItems:"/index.php",user:{savePreferences:"/ajax/ajax_userPrefsSave.php",password:"/ajax/ajax_usrpass.php",passreset:"/ajax/ajax_passReset.php"},main:{login:"/index.php?r=login/login",install:"/ajax/ajax_install.php",upgrade:"/ajax/ajax_upgrade.php",getUpdates:"/index.php?r=index/checkUpdates",task:"/ajax/ajax_task.php"},checks:"/ajax/ajax_checkConnection.php",config:{save:"/ajax/ajax_configSave.php",
"export":"/ajax/ajax_configSave.php","import":"/ajax/ajax_configSave.php"},file:"/ajax/ajax_filesMgmt.php",link:"/index.php",plugin:"/ajax/ajax_itemSave.php",account:{save:"/index.php",saveFavorite:"/ajax/ajax_itemSave.php",request:"/ajax/ajax_itemSave.php",getFiles:"/index.php",search:"/index.php?r=account/search"},appMgmt:{show:"/index.php",save:"/index.php",search:"/index.php"},eventlog:"/ajax/ajax_eventlog.php",wiki:{show:"/ajax/ajax_wiki.php"},notice:{show:"/ajax/ajax_noticeShow.php",search:"/ajax/ajax_noticeSearch.php"}};
Object.freeze(f);var m=function(a,b){var d={r:a.r+(void 0!==a.itemId?"/"+a.itemId:""),isAjax:1},g=c.appRequests().getRequestOpts();g.url=f.doAction;g.method="get";g.type="html";g.addHistory=!0;g.data=d;c.appRequests().getActionCall(g,function(a){var d=$("#content");d.empty().html(a);a=c.triggers().views;a.common(d);if(void 0!==b&&"function"===typeof a[b])a[b]();d=$(".mdl-layout__content");0<d.scrollTop()&&d.animate({scrollTop:0},1E3)})},l=function(a,b){e.info("getContent");a.isAjax=1;var d=c.appRequests().getRequestOpts();
d.url=f.doAction;d.method="get";d.type="html";d.addHistory=!0;d.data=a;c.appRequests().getActionCall(d,function(a){var d=$("#content");d.empty().html(a);a=c.triggers().views;a.common(d);if(void 0!==b&&"function"===typeof a[b])a[b]();d=$(".mdl-layout__content");0<d.scrollTop()&&d.animate({scrollTop:0},1E3)})},n=function(a,b){$.magnificPopup.open({items:{src:a||"",type:"inline"},callbacks:{open:function(){var a=$("#box-popup");c.appTriggers().views.common(a);a.find(":input:text:visible:first").focus();
void 0!==b&&"function"===typeof b.open&&b.open()},close:function(){void 0!==b&&"function"===typeof b.close&&b.close()}},showCloseBtn:!1})},v=function(a,b){var d=$('<div id="box-popup" class="image">'+b+"</div>"),g=d.find("img");if(0===g.length)return n(b);g.hide();$.magnificPopup.open({items:{src:d,type:"inline"},callbacks:{open:function(){var a=this;g.on("click",function(){a.close()});setTimeout(function(){var a=c.resizeImage(g);d.css({backgroundColor:"#fff",width:a.width,height:"auto"});g.show("slow")},
500)}}})},p={view:function(a){e.info("account:show");l(c.appRequests().getRouteForQuery(a.data("action-route"),a.data("item-id")),"account")},viewHistory:function(a){e.info("account:showHistory");l(c.appRequests().getRouteForQuery(a.data("action-route"),a.val()),"account")},edit:function(a){e.info("account:edit");l(c.appRequests().getRouteForQuery(a.data("action-route"),a.data("item-id")),"account")},"delete":function(a){e.info("account:delete");var b='<div id="alert"><p id="alert-text">'+c.config().LANG[3]+
"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(d){d=c.appRequests().getRequestOpts();d.url=f.account.save;d.data={r:"account/saveDelete/"+a.data("item-id"),sk:c.sk.get()};c.appRequests().getActionCall(d,function(a){c.msg.out(a);p.search()})}}})},viewPass:function(a){e.info("account:showpass");var b=a.data("parent-id")||0,b=0===b?a.data("item-id"):
b,d=a.data("history")||0,g=c.appRequests().getRequestOpts();g.url=f.entrypoint;g.method="get";g.data={r:a.data("action-route")+"/"+b+"/"+d,sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(g,function(a){0!==a.status?c.msg.out(a):(a=$(a.data.html),n(a),k=setTimeout(function(){$.magnificPopup.close()},3E4),a.on("mouseleave",function(){clearTimeout(k);k=setTimeout(function(){$.magnificPopup.close()},3E4)}).on("mouseenter",function(){0!==k&&clearTimeout(k)}))})},copyPass:function(a){e.info("account:copypass");
var b=a.data("parent-id"),b=0===b?a.data("item-id"):b,d=c.appRequests().getRequestOpts();d.url=f.entrypoint;d.method="get";d.async=!1;d.data={r:a.data("action-route")+"/"+b+"/"+a.data("history"),sk:c.sk.get(),isAjax:1};return c.appRequests().getActionCall(d)},copy:function(a){e.info("account:copy");l(c.appRequests().getRouteForQuery(a.data("action-route"),a.data("item-id")),"account")},saveFavorite:function(a,b){e.info("account:saveFavorite");var d="on"===a.data("status"),g={r:(d?a.data("action-id-off"):
a.data("action-id-on"))+"/"+a.data("item-id"),sk:c.sk.get(),isAjax:1},q=c.appRequests().getRequestOpts();q.url=f.account.saveFavorite;q.data=g;c.appRequests().getActionCall(q,function(g){c.msg.out(g);0===g.status&&(a.data("status",d?"off":"on"),"function"===typeof b&&b())})},request:function(a){e.info("account:request");var b=c.appRequests().getRequestOpts();b.url=f.account.request;b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a)})},menu:function(a){a.hide();a.parent().children(".actions-optional").show(250)},
sort:function(a){e.info("account:sort");var c=$("#frmSearch");c.find('input[name="skey"]').val(a.data("key"));c.find('input[name="sorder"]').val(a.data("dir"));c.find('input[name="start"]').val(a.data("start"));p.search()},editPass:function(a){e.info("account:editpass");var b=a.data("parent-id"),b=void 0===b?a.data("item-id"):b;l(c.appRequests().getRouteForQuery(a.data("action-route"),b),"account")},saveEditRestore:function(a){e.info("account:restore");var b=c.appRequests().getRequestOpts();b.url=
f.entrypoint+"?r="+a.data("action-route")+"/"+a.data("history-id")+"/"+a.data("item-id");b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);void 0!==a.data.itemId&&void 0!==a.data.nextAction&&l(c.appRequests().getRouteForQuery(a.data.nextAction,a.data.itemId),"account")})},listFiles:function(a){e.info("account:getfiles");var b=c.appRequests().getRequestOpts();b.method="get";b.type="html";b.url=f.entrypoint;b.data={r:a.data("action-route")+"/"+a.data("item-id"),del:a.data("delete"),
sk:c.sk.get()};c.appRequests().getActionCall(b,function(c){a.html(c)})},search:function(a){e.info("account:search");var b=$("#frmSearch");b.find("input[name='sk']").val(c.sk.get());b.find("input[name='skey']").val();b.find("input[name='sorder']").val();void 0!==a&&b.find("input[name='start']").val(0);a=c.appRequests().getRequestOpts();a.url=f.account.search;a.method="get";a.data=b.serialize();c.appRequests().getActionCall(a,function(a){10===a.status&&c.msg.out(a);c.sk.set(a.data.sk);$("#res-content").empty().html(a.data.html)})},
save:function(a){e.info("account:save");var b=c.appRequests().getRequestOpts();b.url=f.account.save+"?r="+a.data("action-route")+"/"+a.data("item-id");b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);void 0!==a.data.itemId&&void 0!==a.data.nextAction&&n(c.appRequests().getRouteForQuery(a.data.nextAction,a.data.itemId),"account")})}};"use strict";var e=c.log,l=0,f={entrypoint:"/index.php",doAction:"/index.php",updateItems:"/index.php",user:{savePreferences:"/ajax/ajax_userPrefsSave.php",
password:"/ajax/ajax_usrpass.php",passreset:"/ajax/ajax_passReset.php"},main:{login:"/index.php?r=login/login",install:"/ajax/ajax_install.php",upgrade:"/ajax/ajax_upgrade.php",getUpdates:"/index.php?r=index/checkUpdates",task:"/ajax/ajax_task.php"},checks:"/ajax/ajax_checkConnection.php",config:{save:"/ajax/ajax_configSave.php","export":"/ajax/ajax_configSave.php","import":"/ajax/ajax_configSave.php"},file:"/ajax/ajax_filesMgmt.php",link:"/index.php",plugin:"/ajax/ajax_itemSave.php",account:{save:"/index.php",
saveFavorite:"/ajax/ajax_itemSave.php",request:"/ajax/ajax_itemSave.php",getFiles:"/index.php",search:"/index.php?r=account/search"},appMgmt:{show:"/index.php",save:"/index.php",search:"/index.php"},eventlog:"/ajax/ajax_eventlog.php",wiki:{show:"/ajax/ajax_wiki.php"},notice:{show:"/ajax/ajax_noticeShow.php",search:"/ajax/ajax_noticeSearch.php"}};Object.freeze(f);var m=function(a,b){var d={r:a.r+(void 0!==a.itemId?"/"+a.itemId:""),isAjax:1},g=c.appRequests().getRequestOpts();g.url=f.doAction;g.method=
"get";g.type="html";g.addHistory=!0;g.data=d;c.appRequests().getActionCall(g,function(a){var d=$("#content");d.empty().html(a);a=c.triggers().views;a.common(d);if(void 0!==b&&"function"===typeof a[b])a[b]();d=$(".mdl-layout__content");0<d.scrollTop()&&d.animate({scrollTop:0},1E3)})},n=function(a,b){e.info("getContent");a.isAjax=1;var d=c.appRequests().getRequestOpts();d.url=f.doAction;d.method="get";d.type="html";d.addHistory=!0;d.data=a;c.appRequests().getActionCall(d,function(a){var d=$("#content");
d.empty().html(a);a=c.triggers().views;a.common(d);if(void 0!==b&&"function"===typeof a[b])a[b]();d=$(".mdl-layout__content");0<d.scrollTop()&&d.animate({scrollTop:0},1E3)})},p=function(a,b){$.magnificPopup.open({items:{src:a||"",type:"inline"},callbacks:{open:function(){var a=$("#box-popup");c.appTriggers().views.common(a);a.find(":input:text:visible:first").focus();void 0!==b&&"function"===typeof b.open&&b.open()},close:function(){void 0!==b&&"function"===typeof b.close&&b.close()}},showCloseBtn:!1})},
u=function(a,b){var d=$('<div id="box-popup" class="image">'+b+"</div>"),g=d.find("img");if(0===g.length)return p(b);g.hide();$.magnificPopup.open({items:{src:d,type:"inline"},callbacks:{open:function(){var a=this;g.on("click",function(){a.close()});setTimeout(function(){var a=c.resizeImage(g);d.css({backgroundColor:"#fff",width:a.width,height:"auto"});g.show("slow")},500)}}})},r={get:function(a){e.info("items:get");var b=a[0].selectize;b.clearOptions();b.load(function(d){var g=c.appRequests().getRequestOpts();
g.url=f.updateItems;g.method="get";g.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:a.data("sk")};c.appRequests().getActionCall(g,function(g){d(g.data);b.setValue(a.data("selected-id"),!0);c.appTriggers().updateFormHash()})})},update:function(a){e.info("items:update");var b=$("#"+a.data("item-dst"))[0].selectize;b.clearOptions();b.load(function(b){var d=c.appRequests().getRequestOpts();d.url=f.updateItems;d.method="get";d.data={r:a.data("item-route"),sk:c.sk.get()};c.appRequests().getActionCall(d,
function(a){b(a)})})}},t={logout:function(){c.redirect("index.php?r=login/logout")},login:function(a){e.info("main:login");var b=c.appRequests().getRequestOpts();b.url=f.entrypoint+"?r="+a.data("route");b.method="get";b.data=a.serialize();c.appRequests().getActionCall(b,function(b){var d=$(".extra-hidden");switch(b.status){case 0:c.redirect(b.data.url);break;case 2:c.msg.out(b);a.find("input[type='text'],input[type='password']").val("");a.find("input:first").focus();0<d.length&&d.hide();$("#mpass").prop("disabled",
save:function(a){e.info("account:save");var b=c.appRequests().getRequestOpts();b.url=f.account.save+"?r="+a.data("action-route")+"/"+a.data("item-id");b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);void 0!==a.data.itemId&&void 0!==a.data.nextAction&&l(c.appRequests().getRouteForQuery(a.data.nextAction,a.data.itemId),"account")})}},t={get:function(a){e.info("items:get");var b=a[0].selectize;b.clearOptions();b.load(function(d){var g=c.appRequests().getRequestOpts();g.url=
f.updateItems;g.method="get";g.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:a.data("sk")};c.appRequests().getActionCall(g,function(g){d(g.data);b.setValue(a.data("selected-id"),!0);c.appTriggers().updateFormHash()})})},update:function(a){e.info("items:update");var b=$("#"+a.data("item-dst"))[0].selectize;b.clearOptions();b.load(function(b){var d=c.appRequests().getRequestOpts();d.url=f.updateItems;d.method="get";d.data={r:a.data("item-route"),sk:c.sk.get()};c.appRequests().getActionCall(d,
function(a){b(a)})})}},u={logout:function(){c.redirect("index.php?r=login/logout")},login:function(a){e.info("main:login");var b=c.appRequests().getRequestOpts();b.url=f.entrypoint+"?r="+a.data("route");b.method="get";b.data=a.serialize();c.appRequests().getActionCall(b,function(b){var d=$(".extra-hidden");switch(b.status){case 0:c.redirect(b.data.url);break;case 2:c.msg.out(b);a.find("input[type='text'],input[type='password']").val("");a.find("input:first").focus();0<d.length&&d.hide();$("#mpass").prop("disabled",
!1).val("");$("#smpass").show();break;case 5:c.msg.out(b);a.find("input[type='text'],input[type='password']").val("");a.find("input:first").focus();0<d.length&&d.hide();$("#oldpass").prop("disabled",!1).val("");$("#soldpass").show();break;default:c.msg.out(b),a.find("input[type='text'],input[type='password']").val(""),a.find("input:first").focus()}})},install:function(a){e.info("main:install");var b=c.appRequests().getRequestOpts();b.url=f.entrypoint+"?r="+a.data("route");b.data=a.serialize();c.appRequests().getActionCall(b,
function(a){c.msg.out(a);0===a.status&&setTimeout(function(){c.redirect("index.php?r=login/index")},1E3)})},upgrade:function(a){e.info("main:upgrade");var b='<div id="alert"><p id="alert-text">'+c.config().LANG[59]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b=a.find("input[name='useTask']");var d=$("#taskStatus");d.empty().html(c.config().LANG[62]);
if(0<b.length&&1==b.val()){b=c.appRequests().getRequestOpts();b.url=f.main.task;b.data={source:a.find("input[name='lock']").val(),taskId:a.find("input[name='taskId']").val()};var e=c.appRequests().getActionEvent(b,function(a){a=a.task+" - "+a.message+" - "+a.time+" - "+a.progress+"%";a+="<br>"+c.config().LANG[62];d.empty().html(a)})}b=c.appRequests().getRequestOpts();b.url=f.main.upgrade;b.method="get";b.useFullLoading=!0;b.data=a.serialize();c.appRequests().getActionCall(b,function(b){c.msg.out(b);
0!==b.status?a.find(":input[name=h]").val(""):(void 0!==e&&e.close(),setTimeout(function(){c.redirect("index.php")},5E3))})}}})},getUpdates:function(){e.info("main:getUpdates");var a=c.appRequests().getRequestOpts();a.url=f.main.getUpdates;a.type="html";a.method="get";a.timeout=1E4;a.useLoading=!1;a.data={isAjax:1};c.appRequests().getActionCall(a,function(a){$("#updates").html(a);void 0!==componentHandler&&componentHandler.upgradeDom()},function(){$("#updates").html("!")})}},h={refreshTab:!0,state:{tab:{index:0,
refresh:!0,route:""},itemId:0,update:function(a){var c=$("#content").find("[id^='tabs-'].is-active");0<c.length&&(h.state.tab.refresh=!a.data("item-dst"),h.state.tab.index=c.data("tab-index"),h.state.tab.route=c.data("tab-route"),h.state.itemId=a.data("item-id"))}},show:function(a){e.info("appMgmt:show");h.state.update(a);var b=c.appRequests().getRequestOpts();b.url=f.appMgmt.show;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,
function(b){if(0!==b.status)c.msg.out(b);else{var d=a.data("item-dst");p(b.data.html,{open:function(){d&&(h.state.tab.refresh=!1)},close:function(){d&&r.update(a)}})}})},"delete":function(a){e.info("appMgmt:delete");h.state.update(a);var b='<div id="alert"><p id="alert-text">'+c.config().LANG[12]+"</p></div>",d=a.data("selection"),g=[];if(d&&($(d).find(".is-selected").each(function(){var a=$(this);g.push(a.data("item-id"))}),0===g.length))return;mdlDialog().show({text:b,negative:{title:c.config().LANG[44],
onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b.preventDefault();b=c.appRequests().getRequestOpts();b.url=f.appMgmt.save;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){c.msg.out(a);n({r:h.state.tab.route,tabIndex:h.state.tab.index})})}}})},save:function(a){e.info("appMgmt:save");var b=c.appRequests().getRequestOpts();b.url=f.appMgmt.save+
"?r="+a.data("route");b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&(!0===h.state.tab.refresh&&n({r:h.state.tab.route,tabIndex:h.state.tab.index}),$.magnificPopup.close())})},search:function(a){e.info("appMgmt:search");var b=$(a.data("target")),d=c.appRequests().getRequestOpts();d.url=f.appMgmt.search+"?r="+a.data("action-route");d.method="get";d.data=a.serialize();c.appRequests().getActionCall(d,function(a){0===a.status?b.html(a.data.html):b.html(c.msg.html.error(a.description));
c.sk.set(a.csrf)})},nav:function(a){e.info("appMgmt:nav");var b=$("#"+a.data("action-form"));b.find("[name='start']").val(a.data("start"));b.find("[name='count']").val(a.data("count"));b.find("[name='sk']").val(c.sk.get());h.search(b)},ldapSync:function(a){e.info("appMgmt:ldapSync");var b='<div id="alert"><p id="alert-text">'+c.config().LANG[57]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],
onClick:function(b){b=c.appRequests().getRequestOpts();b.url=f.appMgmt.save;b.data={actionId:a.data("action-id"),sk:c.sk.get(),isAjax:1,ldap_loginattribute:$("#ldap_loginattribute").val(),ldap_nameattribute:$("#ldap_nameattribute").val(),ldap_ads:$("#ldap_ads").prop("checked")};c.appRequests().getActionCall(b,function(a){c.msg.out(a)})}}})}};return{doAction:m,appMgmt:h,account:k,file:{view:function(a){e.info("file:view");var b=c.appRequests().getRequestOpts();b.url=f.entrypoint;b.method="get";b.data=
{r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get()};c.appRequests().getActionCall(b,function(b){if(1===b.status)return c.msg.out(b);u(a,b.data.html)})},download:function(a){e.info("file:download");a={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get()};$.fileDownload(f.entrypoint,{httpMethod:"GET",data:a})},"delete":function(a){e.info("file:delete");var b='<div id="alert"><p id="alert-text">'+c.config().LANG[15]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],
onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b=c.appRequests().getRequestOpts();b.url=f.entrypoint;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get()};c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&k.listFiles($("#list-account-files"))})}}})}},checks:{ldap:function(a){e.info("checks:ldap");a=$(a.data("src"));a.find("[name='sk']").val(c.sk.get());var b=c.appRequests().getRequestOpts();
0!==b.status?a.find(":input[name=h]").val(""):(void 0!==e&&e.close(),setTimeout(function(){c.redirect("index.php")},5E3))})}}})},getUpdates:function(){e.info("main:getUpdates");var a=c.appRequests().getRequestOpts();a.url=f.main.getUpdates;a.type="html";a.method="get";a.timeout=1E4;a.useLoading=!1;a.data={isAjax:1};c.appRequests().getActionCall(a,function(a){$("#updates").html(a);void 0!==componentHandler&&componentHandler.upgradeDom()},function(){$("#updates").html("!")})}},h={state:{tab:{index:0,
refresh:!0,route:""},itemId:0,update:function(a){var c=$("#content").find("[id^='tabs-'].is-active");0<c.length&&(h.state.tab.refresh=!a.data("item-dst"),h.state.tab.index=c.data("tab-index"),h.state.tab.route=c.data("tab-route"),h.state.itemId=a.data("item-id"))}}},r={show:function(a){e.info("appMgmt:show");h.state.update(a);var b=c.appRequests().getRequestOpts();b.url=f.appMgmt.show;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,
function(b){if(0!==b.status)c.msg.out(b);else{var d=a.data("item-dst");n(b.data.html,{open:function(){d&&(h.state.tab.refresh=!1)},close:function(){d&&t.update(a)}})}})},"delete":function(a){e.info("appMgmt:delete");h.state.update(a);var b='<div id="alert"><p id="alert-text">'+c.config().LANG[12]+"</p></div>",d=a.data("selection"),g=[];if(d&&($(d).find(".is-selected").each(function(){var a=$(this);g.push(a.data("item-id"))}),0===g.length))return;mdlDialog().show({text:b,negative:{title:c.config().LANG[44],
onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b.preventDefault();b=c.appRequests().getRequestOpts();b.url=f.entrypoint;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){c.msg.out(a);l({r:h.state.tab.route,tabIndex:h.state.tab.index})})}}})},save:function(a){e.info("appMgmt:save");var b=c.appRequests().getRequestOpts();b.url=f.entrypoint+
"?r="+a.data("route");b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&(!0===h.state.tab.refresh&&l({r:h.state.tab.route,tabIndex:h.state.tab.index}),$.magnificPopup.close())})},search:function(a){e.info("appMgmt:search");var b=$(a.data("target")),d=c.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");d.method="get";d.data=a.serialize();c.appRequests().getActionCall(d,function(a){0===a.status?b.html(a.data.html):b.html(c.msg.html.error(a.description));
c.sk.set(a.csrf)})},nav:function(a){e.info("appMgmt:nav");var b=$("#"+a.data("action-form"));b.find("[name='start']").val(a.data("start"));b.find("[name='count']").val(a.data("count"));b.find("[name='sk']").val(c.sk.get());r.search(b)},ldapSync:function(a){e.info("appMgmt:ldapSync");var b='<div id="alert"><p id="alert-text">'+c.config().LANG[57]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],
onClick:function(b){b=c.appRequests().getRequestOpts();b.url=f.appMgmt.save;b.data={actionId:a.data("action-id"),sk:c.sk.get(),isAjax:1,ldap_loginattribute:$("#ldap_loginattribute").val(),ldap_nameattribute:$("#ldap_nameattribute").val(),ldap_ads:$("#ldap_ads").prop("checked")};c.appRequests().getActionCall(b,function(a){c.msg.out(a)})}}})}};return{doAction:m,appMgmt:r,account:p,file:{view:function(a){e.info("file:view");var b=c.appRequests().getRequestOpts();b.url=f.entrypoint;b.method="get";b.data=
{r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get()};c.appRequests().getActionCall(b,function(b){if(1===b.status)return c.msg.out(b);v(a,b.data.html)})},download:function(a){e.info("file:download");a={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get()};$.fileDownload(f.entrypoint,{httpMethod:"GET",data:a})},"delete":function(a){e.info("file:delete");var b='<div id="alert"><p id="alert-text">'+c.config().LANG[15]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],
onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b=c.appRequests().getRequestOpts();b.url=f.entrypoint;b.method="get";b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get()};c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&p.listFiles($("#list-account-files"))})}}})}},checks:{ldap:function(a){e.info("checks:ldap");a=$(a.data("src"));a.find("[name='sk']").val(c.sk.get());var b=c.appRequests().getRequestOpts();
b.url=f.checks;b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);var b=$("#ldap-results");b.find(".list-wrap").html(c.appTheme().html.getList(a.data));b.show("slow")})},wiki:function(a){e.info("checks:wiki");a=$(a.data("src"));a.find("[name='sk']").val(c.sk.get());var b=c.appRequests().getRequestOpts();b.url=f.checks;b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&$("#dokuWikiResCheck").html(a.data)})}},config:{save:function(a){e.info("config:save");
var b=c.appRequests().getRequestOpts();b.url=f.config.save;b.data=a.serialize();"masterpass"===a.data("type")&&(b.useFullLoading=!0);c.appRequests().getActionCall(b,function(b){c.msg.out(b);0===b.status&&(void 0!==a.data("nextaction-id")?m({actionId:a.data("nextaction-id"),itemId:a.data("activetab")}):void 0!==a.data("reload")&&setTimeout(function(){c.redirect("index.php")},2E3))})},masterpass:function(a){var b='<div id="alert"><p id="alert-text">'+c.config().LANG[59]+"</p></div>";mdlDialog().show({text:b,
negative:{title:c.config().LANG[44],onClick:function(b){b.preventDefault();c.msg.error(c.config().LANG[44]);a.find(":input[type=password]").val("")}},positive:{title:c.config().LANG[43],onClick:function(b){b=a.find("input[name='useTask']");var d=$("#taskStatus");d.empty().html(c.config().LANG[62]);if(0<b.length&&1==b.val()){b=c.appRequests().getRequestOpts();b.url=f.main.task;b.data={source:a.find("input[name='lock']").val(),taskId:a.find("input[name='taskId']").val()};var e=c.appRequests().getActionEvent(b,
function(a){a=a.task+" - "+a.message+" - "+a.time+" - "+a.progress+"%";a+="<br>"+c.config().LANG[62];d.empty().html(a)})}b=c.appRequests().getRequestOpts();b.url=f.config.save;b.useFullLoading=!0;b.data=a.serialize();c.appRequests().getActionCall(b,function(b){c.msg.out(b);a.find(":input[type=password]").val("");void 0!==e&&e.close()})}}})},backup:function(a){e.info("config:backup");var b=c.appRequests().getRequestOpts();b.url=f.config["export"];b.method="post";b.useFullLoading=!0;b.data=a.serialize();
c.appRequests().getActionCall(b,function(b){c.msg.out(b);0===b.status&&void 0!==a.data("nextaction-id")&&m({actionId:a.data("nextaction-id"),itemId:a.data("activetab")})})},"export":function(a){e.info("config:export");var b=c.appRequests().getRequestOpts();b.url=f.config["export"];b.data=a.serialize();c.appRequests().getActionCall(b,function(b){c.msg.out(b);0===b.status&&void 0!==a.data("nextaction-id")&&m({actionId:a.data("nextaction-id"),itemId:a.data("activetab")})})},"import":function(a){e.info("config:import");
var b=c.appRequests().getRequestOpts();b.url=f.config["import"];b.data=a.serialize();c.appRequests().getActionCall(b,function(b){c.msg.out(b);0===b.status&&void 0!==a.data("nextaction-id")&&m({actionId:a.data("nextaction-id"),itemId:a.data("activetab")})})},refreshMpass:function(a){e.info("config:import");var b=c.appRequests().getRequestOpts();b.url=f.config.save;b.data={actionId:a.data("action-id"),itemId:a.data("item-id"),sk:a.data("sk"),isAjax:1};c.appRequests().getActionCall(b,function(a){c.msg.out(a)})}},
main:t,user:{savePreferences:function(a){e.info("user:savePreferences");var b=c.appRequests().getRequestOpts();b.url=f.user.savePreferences;b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);setTimeout(function(){c.redirect("index.php")},2E3)})},saveSecurity:function(a){e.info("user:saveSecurity");var b=c.appRequests().getRequestOpts();b.url=f.user.savePreferences;b.data=a.serialize();c.appRequests().getActionCall(b,function(b){c.msg.out(b);m({actionId:a.data("nextaction-id"),
itemId:a.data("activetab")})})},password:function(a){e.info("user:password");var b=c.appRequests().getRequestOpts();b.type="html";b.method="get";b.url=f.user.password;b.data={actionId:a.data("action-id"),itemId:a.data("item-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){0===a.length?t.logout():p(a)})},passreset:function(a){e.info("user:passreset");var b=c.appRequests().getRequestOpts();b.url=f.user.passreset;b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);
0==a.status&&setTimeout(function(){c.redirect("index.php")},2E3)})}},link:{save:function(a){e.info("link:save");var b=c.appRequests().getRequestOpts();b.url=f.link;b.data={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get(),isAjax:1};var d='<div id="alert"><p id="alert-text">'+c.config().LANG[48]+"</p></div>";mdlDialog().show({text:d,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.appRequests().getActionCall(b,function(a){c.msg.out(a)})}},positive:{title:c.config().LANG[43],
onClick:function(d){d.preventDefault();b.data.notify=1;c.appRequests().getActionCall(b,function(b){c.msg.out(b);m({actionId:a.data("nextaction-id"),itemId:a.data("item-id")})})}}})},refresh:function(a){e.info("link:refresh");h.state.update(a);var b=c.appRequests().getRequestOpts();b.url=f.link;b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){c.msg.out(a);n({r:h.state.tab.route,tabIndex:h.state.tab.index})})}},eventlog:{nav:function(a){if(void 0===
a.data("start"))return!1;var b=c.appRequests().getRequestOpts();b.url=f.eventlog;b.method="get";b.type="html";b.data={actionId:a.data("action-id"),sk:c.sk.get(),isAjax:1,start:a.data("start"),count:a.data("count"),current:a.data("current")};c.appRequests().getActionCall(b,function(a){$("#content").html(a);c.scrollUp()})},clear:function(a){var b='<div id="alert"><p id="alert-text">'+c.config().LANG[20]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();
c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b.preventDefault();b=c.appRequests().getRequestOpts();b.url=f.eventlog;b.method="get";b.data={clear:1,sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(b){c.msg.out(b);0==b.status&&m({actionId:a.data("nextaction-id")})})}}})}},ajaxUrl:f,plugin:{toggle:function(a){e.info("plugin:enable");a={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get(),activeTab:a.data("activetab")};var b=
c.appRequests().getRequestOpts();b.url=f.appMgmt.save;b.data=a;c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&setTimeout(function(){c.redirect("index.php")},2E3)})},reset:function(a){e.info("plugin:reset");var b='<div id="alert"><p id="alert-text">'+c.config().LANG[58]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b.preventDefault();
b={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get(),activeTab:a.data("activetab")};var d=c.appRequests().getRequestOpts();d.url=f.appMgmt.save;d.data=b;c.appRequests().getActionCall(d,function(a){c.msg.out(a)})}}})}},notice:{check:function(a){e.info("notice:check");var b={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get()},d=c.appRequests().getRequestOpts();d.url=f.appMgmt.save;d.data=b;c.appRequests().getActionCall(d,function(b){c.msg.out(b);0===b.status&&m({actionId:a.data("nextaction-id"),
itemId:a.data("activetab")})})},search:function(a){e.info("notice:search");var b=$(a.data("target")),d=c.appRequests().getRequestOpts();d.url=f.notice.search;d.method="get";d.data=a.serialize();c.appRequests().getActionCall(d,function(a){0===a.status?b.html(a.data.html):b.html(c.msg.html.error(a.description));c.sk.set(a.csrf)})},show:function(a){e.info("notice:show");var b=c.appRequests().getRequestOpts();b.url=f.notice.show;b.method="get";b.data={itemId:a.data("item-id"),actionId:a.data("action-id"),
activeTab:a.data("activetab"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){0!==a.status?c.msg.out(a):p(a.data.html)})}},wiki:{show:function(a){e.info("wiki:show");var b=c.appRequests().getRequestOpts();b.url=f.wiki.show;b.method="get";b.data={pageName:a.data("pagename"),actionId:a.data("action-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){0!==a.status?c.msg.out(a):p(a.data.html)})}},items:r}};
h.state.update(a);var b=c.appRequests().getRequestOpts();b.url=f.entrypoint+"?r="+a.data("action-route");b.data=a.serialize();c.appRequests().getActionCall(b,function(b){c.msg.out(b);0===b.status&&(!0===h.state.tab.refresh?l({r:h.state.tab.route,tabIndex:h.state.tab.index}):void 0!==a.data("reload")&&setTimeout(function(){c.redirect("index.php")},2E3))})},masterpass:function(a){var b='<div id="alert"><p id="alert-text">'+c.config().LANG[59]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],
onClick:function(b){b.preventDefault();c.msg.error(c.config().LANG[44]);a.find(":input[type=password]").val("")}},positive:{title:c.config().LANG[43],onClick:function(b){b=a.find("input[name='useTask']");var d=$("#taskStatus");d.empty().html(c.config().LANG[62]);0<b.length&&1==b.val()&&(b=c.appRequests().getRequestOpts(),b.url=f.main.task,b.data={source:a.find("input[name='lock']").val(),taskId:a.find("input[name='taskId']").val()},c.appRequests().getActionEvent(b,function(a){a=a.task+" - "+a.message+
" - "+a.time+" - "+a.progress+"%";a+="<br>"+c.config().LANG[62];d.empty().html(a)}));b=c.appRequests().getRequestOpts();b.url=f.config.save;b.useFullLoading=!0;b.data=a.serialize();c.appRequests().getActionCall(b,function(b){c.msg.out(b);a.find(":input[type=password]").val("");void 0!==task&&task.close()})}}})},backup:function(a){e.info("config:backup");h.state.update(a);var b=c.appRequests().getRequestOpts();b.url=f.entrypoint+"?r="+a.data("action-route");b.useFullLoading=!0;b.data=a.serialize();
c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&l({r:h.state.tab.route,tabIndex:h.state.tab.index})})},"export":function(a){e.info("config:export");h.state.update(a);var b=c.appRequests().getRequestOpts();b.url=f.entrypoint+"?r="+a.data("action-route");b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&l({r:h.state.tab.route,tabIndex:h.state.tab.index})})},"import":function(a){e.info("config:import");var b=c.appRequests().getRequestOpts();
b.url=f.entrypoint+"?r="+a.data("action-route");b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a)})},refreshMpass:function(a){e.info("config:import");var b=c.appRequests().getRequestOpts();b.url=f.entrypoint+"?r="+a.data("action-route");b.data={sk:a.data("sk"),isAjax:1};c.appRequests().getActionCall(b,function(a){c.msg.out(a)})}},main:u,user:{savePreferences:function(a){e.info("user:savePreferences");var b=c.appRequests().getRequestOpts();b.url=f.user.savePreferences;b.data=
a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);setTimeout(function(){c.redirect("index.php")},2E3)})},saveSecurity:function(a){e.info("user:saveSecurity");var b=c.appRequests().getRequestOpts();b.url=f.user.savePreferences;b.data=a.serialize();c.appRequests().getActionCall(b,function(b){c.msg.out(b);m({actionId:a.data("nextaction-id"),itemId:a.data("activetab")})})},password:function(a){e.info("user:password");var b=c.appRequests().getRequestOpts();b.type="html";b.method="get";
b.url=f.user.password;b.data={actionId:a.data("action-id"),itemId:a.data("item-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){0===a.length?u.logout():n(a)})},passreset:function(a){e.info("user:passreset");var b=c.appRequests().getRequestOpts();b.url=f.user.passreset;b.data=a.serialize();c.appRequests().getActionCall(b,function(a){c.msg.out(a);0==a.status&&setTimeout(function(){c.redirect("index.php")},2E3)})}},link:{save:function(a){e.info("link:save");var b=c.appRequests().getRequestOpts();
b.url=f.link;b.data={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get(),isAjax:1};var d='<div id="alert"><p id="alert-text">'+c.config().LANG[48]+"</p></div>";mdlDialog().show({text:d,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.appRequests().getActionCall(b,function(a){c.msg.out(a)})}},positive:{title:c.config().LANG[43],onClick:function(d){d.preventDefault();b.data.notify=1;c.appRequests().getActionCall(b,function(b){c.msg.out(b);m({actionId:a.data("nextaction-id"),
itemId:a.data("item-id")})})}}})},refresh:function(a){e.info("link:refresh");r.state.update(a);var b=c.appRequests().getRequestOpts();b.url=f.link;b.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){c.msg.out(a);l({r:h.state.tab.route,tabIndex:h.state.tab.index})})}},eventlog:{nav:function(a){if(void 0===a.data("start"))return!1;var b=c.appRequests().getRequestOpts();b.url=f.eventlog;b.method="get";b.type="html";b.data={actionId:a.data("action-id"),
sk:c.sk.get(),isAjax:1,start:a.data("start"),count:a.data("count"),current:a.data("current")};c.appRequests().getActionCall(b,function(a){$("#content").html(a);c.scrollUp()})},clear:function(a){var b='<div id="alert"><p id="alert-text">'+c.config().LANG[20]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b.preventDefault();b=c.appRequests().getRequestOpts();
b.url=f.eventlog;b.method="get";b.data={clear:1,sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(b){c.msg.out(b);0==b.status&&m({actionId:a.data("nextaction-id")})})}}})}},ajaxUrl:f,plugin:{toggle:function(a){e.info("plugin:enable");a={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get(),activeTab:a.data("activetab")};var b=c.appRequests().getRequestOpts();b.url=f.appMgmt.save;b.data=a;c.appRequests().getActionCall(b,function(a){c.msg.out(a);0===a.status&&setTimeout(function(){c.redirect("index.php")},
2E3)})},reset:function(a){e.info("plugin:reset");var b='<div id="alert"><p id="alert-text">'+c.config().LANG[58]+"</p></div>";mdlDialog().show({text:b,negative:{title:c.config().LANG[44],onClick:function(a){a.preventDefault();c.msg.error(c.config().LANG[44])}},positive:{title:c.config().LANG[43],onClick:function(b){b.preventDefault();b={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get(),activeTab:a.data("activetab")};var d=c.appRequests().getRequestOpts();d.url=f.appMgmt.save;d.data=
b;c.appRequests().getActionCall(d,function(a){c.msg.out(a)})}}})}},notice:{check:function(a){e.info("notice:check");var b={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:c.sk.get()},d=c.appRequests().getRequestOpts();d.url=f.appMgmt.save;d.data=b;c.appRequests().getActionCall(d,function(b){c.msg.out(b);0===b.status&&m({actionId:a.data("nextaction-id"),itemId:a.data("activetab")})})},search:function(a){e.info("notice:search");var b=$(a.data("target")),d=c.appRequests().getRequestOpts();d.url=
f.notice.search;d.method="get";d.data=a.serialize();c.appRequests().getActionCall(d,function(a){0===a.status?b.html(a.data.html):b.html(c.msg.html.error(a.description));c.sk.set(a.csrf)})},show:function(a){e.info("notice:show");var b=c.appRequests().getRequestOpts();b.url=f.notice.show;b.method="get";b.data={itemId:a.data("item-id"),actionId:a.data("action-id"),activeTab:a.data("activetab"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){0!==a.status?c.msg.out(a):n(a.data.html)})}},
wiki:{show:function(a){e.info("wiki:show");var b=c.appRequests().getRequestOpts();b.url=f.wiki.show;b.method="get";b.data={pageName:a.data("pagename"),actionId:a.data("action-id"),sk:c.sk.get(),isAjax:1};c.appRequests().getActionCall(b,function(a){0!==a.status?c.msg.out(a):n(a.data.html)})}},items:t}};

View File

@@ -127,16 +127,16 @@ CREATE TABLE `AccountToFavorite` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `AccountToGroup`;
DROP TABLE IF EXISTS AccountToUserGroup;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `AccountToGroup` (
CREATE TABLE `AccountToUserGroup` (
`accountId` mediumint(8) unsigned NOT NULL,
`userGroupId` smallint(5) unsigned NOT NULL,
KEY `IDX_accountId` (`accountId`),
KEY `fk_AccountToGroup_userGroupId` (`userGroupId`),
CONSTRAINT `fk_AccountToGroup_accountId` FOREIGN KEY (`accountId`) REFERENCES `Account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_AccountToGroup_userGroupId` FOREIGN KEY (`userGroupId`) REFERENCES `UserGroup` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
CONSTRAINT `fk_AccountToUserGroup_accountId` FOREIGN KEY (`accountId`) REFERENCES `Account` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_AccountToUserGroup_userGroupId` FOREIGN KEY (`userGroupId`) REFERENCES `UserGroup` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -465,16 +465,16 @@ CREATE TABLE `UserProfile` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `UserToGroup`;
DROP TABLE IF EXISTS UserToUserGroup;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `UserToGroup` (
CREATE TABLE `UserToUserGroup` (
`userId` smallint(5) unsigned NOT NULL,
`userGroupId` smallint(5) unsigned NOT NULL,
KEY `IDX_usertogroup_userId` (`userId`),
KEY `fk_UserToGroup_userGroupId` (`userGroupId`),
CONSTRAINT `fk_UserToGroup_userGroupId` FOREIGN KEY (`userGroupId`) REFERENCES `UserGroup` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_UserToGroup_userId` FOREIGN KEY (`userId`) REFERENCES `User` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
CONSTRAINT `fk_UserToUserGroup_userGroupId` FOREIGN KEY (`userGroupId`) REFERENCES `UserGroup` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_UserToUserGroup_userId` FOREIGN KEY (`userId`) REFERENCES `User` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;