diff --git a/app/modules/web/themes/material-blue/views/account/account-permissions.inc b/app/modules/web/themes/material-blue/views/account/account-permissions.inc
index 0c57fbd3..df05668d 100644
--- a/app/modules/web/themes/material-blue/views/account/account-permissions.inc
+++ b/app/modules/web/themes/material-blue/views/account/account-permissions.inc
@@ -67,6 +67,7 @@
+
|
diff --git a/app/modules/web/themes/material-blue/views/account/account.inc b/app/modules/web/themes/material-blue/views/account/account.inc
index bbe26aca..4538d488 100644
--- a/app/modules/web/themes/material-blue/views/account/account.inc
+++ b/app/modules/web/themes/material-blue/views/account/account.inc
@@ -1,6 +1,9 @@
@@ -238,7 +241,7 @@
- isShowPermission()): ?>
+ isShowPermission() || $allowPrivate || $allowPrivateGroup)): ?>
includeTemplate('account-permissions'); ?>
@@ -264,7 +267,7 @@
isShowFiles()) {
+ if ($gotData && $configData->isFilesEnabled() && $accountAcl->isShowFiles()) {
include $this->includeTemplate('files');
}
diff --git a/app/modules/web/themes/material-blue/views/account/actions.inc b/app/modules/web/themes/material-blue/views/account/actions.inc
index fd2282a6..ca0ff377 100644
--- a/app/modules/web/themes/material-blue/views/account/actions.inc
+++ b/app/modules/web/themes/material-blue/views/account/actions.inc
@@ -4,7 +4,7 @@
+ foreach ($accountActions as $action): ?>
-
diff --git a/lib/Definitions.php b/lib/Definitions.php
index 2f8f33b4..db6949c8 100644
--- a/lib/Definitions.php
+++ b/lib/Definitions.php
@@ -44,12 +44,11 @@ return [
\SP\Core\Acl\Actions::class => object(\SP\Core\Acl\Actions::class)
->constructor(object(\SP\Storage\FileCache::class), object(\SP\Storage\XmlHandler::class)
->constructor(ACTIONS_FILE)),
- \SP\Core\Acl\Acl::class => object(\SP\Core\Acl\Acl::class)
- ->constructor(get(\SP\Core\Session\Session::class), get(\SP\Core\Acl\Actions::class)),
- \SP\Core\UI\Theme::class => object(\SP\Core\UI\Theme::class)
- ->constructor(APP_MODULE),
\SP\Core\Events\EventDispatcher::class => object(\SP\Core\Events\EventDispatcher::class),
- \SP\Log\Log::class => object(\SP\Log\Log::class)->scope(\DI\Scope::PROTOTYPE),
+ \SP\Core\Acl\Acl::class => object(\SP\Core\Acl\Acl::class)
+ ->constructor(get(\SP\Core\Session\Session::class), get(\SP\Core\Events\EventDispatcher::class), get(\SP\Core\Acl\Actions::class)),
+ \SP\Core\UI\Theme::class => object(\SP\Core\UI\Theme::class)
+ ->constructor(APP_MODULE, get(\SP\Config\Config::class), get(\SP\Core\Session\Session::class)),
\PHPMailer\PHPMailer\PHPMailer::class => object(\PHPMailer\PHPMailer\PHPMailer::class)
->constructor(true)
];
\ No newline at end of file
diff --git a/lib/SP/Account/AccountAcl.php b/lib/SP/Account/AccountAcl.php
index 35ecdd44..4e601dc4 100644
--- a/lib/SP/Account/AccountAcl.php
+++ b/lib/SP/Account/AccountAcl.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -24,15 +24,8 @@
namespace SP\Account;
-use SP\Config\ConfigData;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
-use SP\Core\Session\Session;
-use SP\Core\Traits\InjectableTrait;
-use SP\DataModel\Dto\AccountAclDto;
-use SP\Repositories\UserGroup\UserToUserGroupRepository;
-use SP\Services\User\UserLoginResponse;
-use SP\Util\ArrayUtil;
/**
* Class AccountAcl
@@ -42,158 +35,116 @@ use SP\Util\ArrayUtil;
class AccountAcl
{
/**
- * @var AccountAclDto
+ * @var bool
*/
- protected $accountAclDto;
+ public $userInGroups = false;
+ /**
+ * @var bool
+ */
+ public $userInUsers = false;
+ /**
+ * @var bool
+ */
+ public $resultView = false;
+ /**
+ * @var bool
+ */
+ public $resultEdit = false;
+ /**
+ * @var bool
+ */
+ public $modified = false;
+ /**
+ * @var bool
+ */
+ public $showView = false;
+ /**
+ * @var bool
+ */
+ public $showHistory = false;
+ /**
+ * @var bool
+ */
+ public $showDetails = false;
+ /**
+ * @var bool
+ */
+ public $showPass = false;
+ /**
+ * @var bool
+ */
+ public $showFiles = false;
+ /**
+ * @var bool
+ */
+ public $showViewPass = false;
+ /**
+ * @var bool
+ */
+ public $showSave = false;
+ /**
+ * @var bool
+ */
+ public $showEdit = false;
+ /**
+ * @var bool
+ */
+ public $showEditPass = false;
+ /**
+ * @var bool
+ */
+ public $showDelete = false;
+ /**
+ * @var bool
+ */
+ public $showRestore = false;
+ /**
+ * @var bool
+ */
+ public $showLink = false;
+ /**
+ * @var bool
+ */
+ public $showCopy = false;
+ /**
+ * @var bool
+ */
+ public $showPermission = false;
+ /**
+ * @var bool
+ */
+ private $compiledAccountAccess = false;
+ /**
+ * @var bool
+ */
+ private $compiledShowAccess = false;
/**
* @var int
*/
- protected $accountId;
+ private $accountId;
/**
* @var int
*/
- protected $action;
+ private $actionId;
/**
* @var int
*/
- protected $time = 0;
+ private $time = 0;
/**
* @var bool
*/
- protected $userInGroups = false;
- /**
- * @var bool
- */
- protected $userInUsers = false;
- /**
- * @var bool
- */
- protected $resultView = false;
- /**
- * @var bool
- */
- protected $resultEdit = false;
- /**
- * @var bool
- */
- protected $modified = false;
- /**
- * @var bool
- */
- protected $showView = false;
- /**
- * @var bool
- */
- protected $showHistory = false;
- /**
- * @var bool
- */
- protected $showDetails = false;
- /**
- * @var bool
- */
- protected $showPass = false;
- /**
- * @var bool
- */
- protected $showFiles = false;
- /**
- * @var bool
- */
- protected $showViewPass = false;
- /**
- * @var bool
- */
- protected $showSave = false;
- /**
- * @var bool
- */
- protected $showEdit = false;
- /**
- * @var bool
- */
- protected $showEditPass = false;
- /**
- * @var bool
- */
- protected $showDelete = false;
- /**
- * @var bool
- */
- protected $showRestore = false;
- /**
- * @var bool
- */
- protected $showLink = false;
- /**
- * @var bool
- */
- protected $showCopy = false;
- /**
- * @var bool
- */
- protected $showPermission = false;
- /**
- * @var UserLoginResponse
- */
- protected $userData;
- /**
- * @var bool
- */
- protected $compiled = false;
- /**
- * @var ConfigData;
- */
- protected $configData;
- /**
- * @var Session
- */
- protected $session;
- /**
- * @var \SP\Core\Acl\Acl
- */
- protected $acl;
- /**
- * @var bool
- */
- protected $isHistory;
-
- use InjectableTrait;
+ private $isHistory;
/**
* AccountAcl constructor.
*
- * @param int $action
+ * @param int $actionId
* @param bool $isHistory
- * @throws \SP\Core\Dic\ContainerException
*/
- public function __construct($action, $isHistory = false)
+ public function __construct($actionId, $isHistory = false)
{
- $this->injectDependencies();
-
- $this->action = $action;
+ $this->actionId = (int)$actionId;
$this->isHistory = $isHistory;
- $this->userData = $this->session->getUserData();
- }
-
- /**
- * Resetaear los datos de ACL en la sesión
- */
- public static function resetData()
- {
- unset($_SESSION['accountAcl']);
- }
-
- /**
- * @param ConfigData $configData
- * @param Session $session
- * @param \SP\Core\Acl\Acl $acl
- */
- public function inject(ConfigData $configData, Session $session, Acl $acl)
- {
- $this->configData = $configData;
- $this->session = $session;
- $this->acl = $acl;
}
/**
@@ -201,9 +152,9 @@ class AccountAcl
*/
public function isShowDetails()
{
- return $this->action === Acl::ACCOUNT_VIEW
- || $this->action === Acl::ACCOUNT_VIEW_HISTORY
- || $this->action === Acl::ACCOUNT_DELETE;
+ return $this->actionId === Acl::ACCOUNT_VIEW
+ || $this->actionId === Acl::ACCOUNT_VIEW_HISTORY
+ || $this->actionId === Acl::ACCOUNT_DELETE;
}
/**
@@ -211,8 +162,8 @@ class AccountAcl
*/
public function isShowPass()
{
- return ($this->action === Acl::ACCOUNT_CREATE
- || $this->action === Acl::ACCOUNT_COPY);
+ return ($this->actionId === Acl::ACCOUNT_CREATE
+ || $this->actionId === Acl::ACCOUNT_COPY);
}
/**
@@ -220,10 +171,9 @@ class AccountAcl
*/
public function isShowFiles()
{
- return $this->configData->isFilesEnabled() &&
- ($this->action === Acl::ACCOUNT_EDIT
- || $this->action === Acl::ACCOUNT_VIEW
- || $this->action === Acl::ACCOUNT_VIEW_HISTORY)
+ return ($this->actionId === Acl::ACCOUNT_EDIT
+ || $this->actionId === Acl::ACCOUNT_VIEW
+ || $this->actionId === Acl::ACCOUNT_VIEW_HISTORY)
&& $this->showFiles;
}
@@ -232,11 +182,11 @@ class AccountAcl
*/
public function isShowViewPass()
{
- return ($this->action === Acl::ACCOUNT_SEARCH
- || $this->action === Acl::ACCOUNT_VIEW
- || $this->action === Acl::ACCOUNT_VIEW_PASS
- || $this->action === Acl::ACCOUNT_VIEW_HISTORY
- || $this->action === Acl::ACCOUNT_EDIT)
+ return ($this->actionId === Acl::ACCOUNT_SEARCH
+ || $this->actionId === Acl::ACCOUNT_VIEW
+ || $this->actionId === Acl::ACCOUNT_VIEW_PASS
+ || $this->actionId === Acl::ACCOUNT_VIEW_HISTORY
+ || $this->actionId === Acl::ACCOUNT_EDIT)
&& $this->showViewPass;
}
@@ -245,9 +195,9 @@ class AccountAcl
*/
public function isShowSave()
{
- return $this->action === Acl::ACCOUNT_EDIT
- || $this->action === Acl::ACCOUNT_CREATE
- || $this->action === Acl::ACCOUNT_COPY;
+ return $this->actionId === Acl::ACCOUNT_EDIT
+ || $this->actionId === Acl::ACCOUNT_CREATE
+ || $this->actionId === Acl::ACCOUNT_COPY;
}
/**
@@ -255,8 +205,8 @@ class AccountAcl
*/
public function isShowEdit()
{
- return ($this->action === Acl::ACCOUNT_SEARCH
- || $this->action === Acl::ACCOUNT_VIEW)
+ return ($this->actionId === Acl::ACCOUNT_SEARCH
+ || $this->actionId === Acl::ACCOUNT_VIEW)
&& $this->showEdit;
}
@@ -265,8 +215,8 @@ class AccountAcl
*/
public function isShowEditPass()
{
- return ($this->action === Acl::ACCOUNT_EDIT
- || $this->action === Acl::ACCOUNT_VIEW)
+ return ($this->actionId === Acl::ACCOUNT_EDIT
+ || $this->actionId === Acl::ACCOUNT_VIEW)
&& $this->showEditPass;
}
@@ -275,9 +225,9 @@ class AccountAcl
*/
public function isShowDelete()
{
- return ($this->action === Acl::ACCOUNT_SEARCH
- || $this->action === Acl::ACCOUNT_DELETE
- || $this->action === Acl::ACCOUNT_EDIT)
+ return ($this->actionId === Acl::ACCOUNT_SEARCH
+ || $this->actionId === Acl::ACCOUNT_DELETE
+ || $this->actionId === Acl::ACCOUNT_EDIT)
&& $this->showDelete;
}
@@ -286,7 +236,7 @@ class AccountAcl
*/
public function isShowRestore()
{
- return $this->action === Acl::ACCOUNT_VIEW_HISTORY && $this->showRestore;
+ return $this->actionId === Acl::ACCOUNT_VIEW_HISTORY && $this->showRestore;
}
/**
@@ -294,7 +244,7 @@ class AccountAcl
*/
public function isShowLink()
{
- return $this->configData->isPublinksEnabled() && $this->showLink;
+ return $this->showLink;
}
/**
@@ -302,8 +252,8 @@ class AccountAcl
*/
public function isShowHistory()
{
- return ($this->action === Acl::ACCOUNT_VIEW
- || $this->action === Acl::ACCOUNT_VIEW_HISTORY)
+ return ($this->actionId === Acl::ACCOUNT_VIEW
+ || $this->actionId === Acl::ACCOUNT_VIEW_HISTORY)
&& $this->showHistory;
}
@@ -315,57 +265,20 @@ class AccountAcl
return ($this->showView || $this->showEdit || $this->showViewPass || $this->showCopy || $this->showDelete);
}
- /**
- * Obtener la ACL de una cuenta
- *
- * @param AccountAclDto $accountAclDto
- * @return $this
- */
- public function getAcl(AccountAclDto $accountAclDto)
- {
- $this->accountAclDto = $accountAclDto;
- $this->accountId = $accountAclDto->getAccountId();
- $sessionAcl = $this->getStoredAcl();
-
- if (null !== $sessionAcl
- && !($this->modified = (int)strtotime($this->accountAclDto->getDateEdit()) > $sessionAcl->getTime())
- ) {
- return $sessionAcl;
- }
-
- return $this->updateAcl();
- }
-
- /**
- * Devolver una ACL almacenada
- *
- * @return AccountAcl
- */
- public function getStoredAcl()
- {
- $sessionAcl = $this->session->getAccountAcl($this->accountId);
-
- if (null !== $sessionAcl && $sessionAcl->getAction() !== $this->action) {
- $sessionAcl->setAction($this->action);
- }
-
- return $sessionAcl;
- }
-
/**
* @return int
*/
- public function getAction()
+ public function getActionId()
{
- return (int)$this->action;
+ return $this->actionId;
}
/**
- * @param int $action
+ * @param int $actionId
*/
- public function setAction($action)
+ public function setActionId($actionId)
{
- $this->action = (int)$action;
+ $this->actionId = (int)$actionId;
}
/**
@@ -377,132 +290,11 @@ class AccountAcl
}
/**
- * Actualizar la ACL
- *
- * @return $this
+ * @param int $time
*/
- public function updateAcl()
+ public function setTime($time)
{
- if ($this->checkComponents()) {
- $this->makeAcl();
- }
-
- return $this;
- }
-
- /**
- * @return bool
- */
- protected function checkComponents()
- {
- return null !== $this->accountId && null !== $this->accountAclDto;
- }
-
- /**
- * Crear la ACL de una cuenta
- */
- protected function makeAcl()
- {
- $this->compileAccountAccess();
-
- // Mostrar historial
- $this->showHistory = $this->acl->checkUserAccess(Acl::ACCOUNT_VIEW_HISTORY);
-
- // Mostrar lista archivos
- $this->showFiles = $this->acl->checkUserAccess(Acl::ACCOUNT_FILE);
-
- // Mostrar acción de ver clave
- $this->showViewPass = $this->checkAccountAccess(Acl::ACCOUNT_VIEW_PASS)
- && $this->acl->checkUserAccess(Acl::ACCOUNT_VIEW_PASS);
-
- // Mostrar acción de editar
- $this->showEdit = $this->checkAccountAccess(Acl::ACCOUNT_EDIT)
- && $this->acl->checkUserAccess(Acl::ACCOUNT_EDIT)
- && !$this->isHistory;
-
- // Mostrar acción de editar clave
- $this->showEditPass = $this->checkAccountAccess(Acl::ACCOUNT_EDIT_PASS)
- && $this->acl->checkUserAccess(Acl::ACCOUNT_EDIT_PASS)
- && !$this->isHistory;
-
- // Mostrar acción de eliminar
- $this->showDelete = $this->checkAccountAccess(Acl::ACCOUNT_DELETE)
- && $this->acl->checkUserAccess(Acl::ACCOUNT_DELETE);
-
- // Mostrar acción de restaurar
- $this->showRestore = $this->checkAccountAccess(Acl::ACCOUNT_EDIT)
- && $this->acl->checkUserAccess(Acl::ACCOUNT_EDIT);
-
- // Mostrar acción de enlace público
- $this->showLink = $this->acl->checkUserAccess(Acl::PUBLICLINK_CREATE);
-
- // Mostrar acción de ver cuenta
- $this->showView = $this->checkAccountAccess(Acl::ACCOUNT_VIEW)
- && $this->acl->checkUserAccess(Acl::ACCOUNT_VIEW);
-
- // Mostrar acción de copiar cuenta
- $this->showCopy = $this->checkAccountAccess(Acl::ACCOUNT_COPY)
- && $this->acl->checkUserAccess(Acl::ACCOUNT_COPY);
- }
-
- /**
- * Evaluar la ACL
- */
- protected function compileAccountAccess()
- {
- if ($this->userData->getIsAdminApp()
- || $this->userData->getIsAdminAcc()
- ) {
- $this->resultView = true;
- $this->resultEdit = true;
-
- return;
- }
-
- $this->userInGroups = $this->getIsUserInGroups();
- $this->userInUsers = in_array($this->userData->getId(), $this->accountAclDto->getUsersId());
-
- $this->resultView = ($this->userData->getId() === $this->accountAclDto->getUserId()
- || $this->userData->getUserGroupId() === $this->accountAclDto->getUserGroupId()
- || $this->userInUsers
- || $this->userInGroups);
-
- $this->resultEdit = ($this->userData->getId() === $this->accountAclDto->getUserId()
- || $this->userData->getUserGroupId() === $this->accountAclDto->getUserGroupId()
- || ($this->userInUsers && $this->accountAclDto->getOtherUserEdit())
- || ($this->userInGroups && $this->accountAclDto->getOtherUserGroupEdit()));
- }
-
- /**
- * Comprobar si el usuario o el grupo del usuario se encuentran los grupos asociados a la
- * cuenta.
- *
- * @return bool
- */
- protected function getIsUserInGroups()
- {
- // Comprobar si el usuario está vinculado desde el grupo principal de la cuenta
- if (UserToUserGroupRepository::checkUserInGroup($this->accountAclDto->getUserGroupId(), $this->userData->getId())) {
- return true;
- }
-
- // Grupos en los que se encuentra el usuario
- $groupsId = UserToUserGroupRepository::getGroupsForUser($this->userData->getId());
-
- // Comprobar si el grupo del usuario está vinculado desde los grupos secundarios de la cuenta
- foreach ($this->accountAclDto->getUserGroupsId() as $groupId) {
- // Consultar el grupo principal del usuario
- if ($groupId === $this->userData->getUserGroupId()
- // o... permitir los grupos que no sean el principal del usuario?
- || ($this->configData->isAccountFullGroupAccess()
- // Comprobar si el usuario está vinculado desde los grupos secundarios de la cuenta
- && ArrayUtil::checkInObjectArray($groupsId, 'groupId', $groupId))
- ) {
- return true;
- }
- }
-
- return false;
+ $this->time = (int)$time;
}
/**
@@ -511,11 +303,13 @@ class AccountAcl
* @param null $actionId
* @return bool
*/
- public function checkAccountAccess($actionId = null)
+ public function checkAccountAccess($actionId)
{
- $action = null === $actionId ? $this->getAction() : $actionId;
+ if ($this->compiledAccountAccess === false) {
+ return false;
+ }
- switch ($action) {
+ switch ($actionId) {
case ActionsInterface::ACCOUNT_VIEW:
case ActionsInterface::ACCOUNT_SEARCH:
case ActionsInterface::ACCOUNT_VIEW_PASS:
@@ -560,9 +354,9 @@ class AccountAcl
*/
public function isShowCopy()
{
- return ($this->action === Acl::ACCOUNT_SEARCH
- || $this->action === Acl::ACCOUNT_VIEW
- || $this->action === Acl::ACCOUNT_EDIT)
+ return ($this->actionId === Acl::ACCOUNT_SEARCH
+ || $this->actionId === Acl::ACCOUNT_VIEW
+ || $this->actionId === Acl::ACCOUNT_EDIT)
&& $this->showCopy;
}
@@ -571,22 +365,7 @@ class AccountAcl
*/
public function isShowPermission()
{
- $userProfile = $this->session->getUserProfile();
- $userData = $this->session->getUserData();
-
- return $userData->getIsAdminApp()
- || $userData->getIsAdminAcc()
- || $userProfile->isAccPermission()
- || $userProfile->isAccPrivateGroup()
- || $userProfile->isAccPrivate();
- }
-
- /**
- * @param boolean $showPermission
- */
- public function setShowPermission($showPermission)
- {
- $this->showPermission = $showPermission;
+ return $this->showPermission;
}
/**
@@ -598,50 +377,50 @@ class AccountAcl
}
/**
- * unserialize() checks for the presence of a function with the magic name __wakeup.
- * If present, this function can reconstruct any resources that the object may have.
- * The intended use of __wakeup is to reestablish any database connections that may have been lost during
- * serialization and perform other reinitialization tasks.
- *
- * @return void
- * @link http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep
- * @throws \SP\Core\Dic\ContainerException
- * @throws \ReflectionException
+ * @param int $accountId
*/
- public function __wakeup()
+ public function setAccountId($accountId)
{
- $this->injectDependencies();
+ $this->accountId = (int)$accountId;
}
/**
- * serialize() checks if your class has a function with the magic name __sleep.
- * If so, that function is executed prior to any serialization.
- * It can clean up the object and is supposed to return an array with the names of all variables of that object that should be serialized.
- * If the method doesn't return anything then NULL is serialized and E_NOTICE is issued.
- * The intended use of __sleep is to commit pending data or perform similar cleanup tasks.
- * Also, the function is useful if you have very large objects which do not need to be saved completely.
- *
- * @return string[]
- * @link http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep
+ * @return bool
*/
- public function __sleep()
+ public function isHistory()
{
- $this->time = time();
+ return $this->isHistory;
+ }
- unset($this->accountAclDto, $this->userData, $this->session, $this->acl, $this->configData);
+ /**
+ * @return bool
+ */
+ public function isCompiledShowAccess()
+ {
+ return $this->compiledShowAccess;
+ }
- $props = [];
+ /**
+ * @param bool $compiledShowAccess
+ */
+ public function setCompiledShowAccess($compiledShowAccess)
+ {
+ $this->compiledShowAccess = (bool)$compiledShowAccess;
+ }
- foreach ((array)$this as $prop => $value) {
- if ($prop !== "\0*\0configData"
- && $prop !== "\0*\0accountAclDto"
- && $prop !== "\0*\0userData"
- && $prop !== "\0*\0acl"
- && $prop !== "\0*\0session") {
- $props[] = $prop;
- }
- }
+ /**
+ * @return bool
+ */
+ public function isCompiledAccountAccess()
+ {
+ return $this->compiledAccountAccess;
+ }
- return $props;
+ /**
+ * @param bool $compiledAccountAccess
+ */
+ public function setCompiledAccountAccess($compiledAccountAccess)
+ {
+ $this->compiledAccountAccess = (bool)$compiledAccountAccess;
}
}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountSearchItem.php b/lib/SP/Account/AccountSearchItem.php
index 8067b58d..e1659b04 100644
--- a/lib/SP/Account/AccountSearchItem.php
+++ b/lib/SP/Account/AccountSearchItem.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -27,8 +27,8 @@ namespace SP\Account;
defined('APP_ROOT') || die();
use SP\Config\ConfigData;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\AccountSearchVData;
+use SP\DataModel\ItemData;
use SP\Html\Html;
/**
@@ -38,19 +38,33 @@ use SP\Html\Html;
*/
class AccountSearchItem
{
- /** @var bool */
+ /**
+ * @var bool
+ */
public static $accountLink = false;
- /** @var bool */
+ /**
+ * @var bool
+ */
public static $topNavbar = false;
- /** @var bool */
+ /**
+ * @var bool
+ */
public static $optionalActions = false;
- /** @var bool */
+ /**
+ * @var bool
+ */
public static $requestEnabled = true;
- /** @var bool */
+ /**
+ * @var bool
+ */
public static $wikiEnabled = false;
- /** @var bool */
+ /**
+ * @var bool
+ */
public static $dokuWikiEnabled = false;
- /** @var bool */
+ /**
+ * @var bool
+ */
public static $isDemoMode = false;
/**
@@ -82,15 +96,15 @@ class AccountSearchItem
*/
protected $textMaxLength = 60;
/**
- * @var array
+ * @var ItemData[]
*/
protected $users;
/**
- * @var array
+ * @var ItemData[]
*/
protected $tags;
/**
- * @var array
+ * @var ItemData[]
*/
protected $userGroups;
/**
@@ -102,28 +116,17 @@ class AccountSearchItem
*/
private $accountAcl;
- use InjectableTrait;
-
/**
* AccountsSearchItem constructor.
*
* @param AccountSearchVData $accountSearchVData
* @param AccountAcl $accountAcl
- * @throws \SP\Core\Dic\ContainerException
+ * @param ConfigData $configData
*/
- public function __construct(AccountSearchVData $accountSearchVData, AccountAcl $accountAcl)
+ public function __construct(AccountSearchVData $accountSearchVData, AccountAcl $accountAcl, ConfigData $configData)
{
- $this->injectDependencies();
-
$this->accountSearchVData = $accountSearchVData;
$this->accountAcl = $accountAcl;
- }
-
- /**
- * @param ConfigData $configData
- */
- public function inject(ConfigData $configData)
- {
$this->configData = $configData;
}
@@ -257,18 +260,24 @@ class AccountSearchItem
}
/**
- * @return string
+ * @return array
*/
public function getAccesses()
{
- $accesses = sprintf(' (G) %s*', $this->accountSearchVData->getUserGroupName());
+ $accesses = [
+ '(G*) ' . $this->accountSearchVData->getUserGroupName() . '',
+ '(U*) ' . $this->accountSearchVData->getUserLogin() . ''
+ ];
+
+ $userLabel = $this->accountSearchVData->getOtherUserEdit() === 1 ? 'U+' : 'U';
+ $userGroupLabel = $this->accountSearchVData->getOtherUserGroupEdit() === 1 ? 'G+' : 'G';
foreach ($this->userGroups as $group) {
- $accesses .= sprintf(' (G) %s', $group->name);
+ $accesses[] = sprintf('(%s) %s', $userGroupLabel, $group->getName());
}
foreach ($this->users as $user) {
- $accesses .= sprintf(' (U) %s', $user->login);
+ $accesses[] = sprintf('(%s) %s', $userLabel, $user->login);
}
return $accesses;
@@ -364,7 +373,7 @@ class AccountSearchItem
}
/**
- * @param array $userGroups
+ * @param ItemData[] $userGroups
*/
public function setUserGroups(array $userGroups)
{
@@ -372,7 +381,7 @@ class AccountSearchItem
}
/**
- * @param array $users
+ * @param ItemData[] $users
*/
public function setUsers(array $users)
{
@@ -380,7 +389,7 @@ class AccountSearchItem
}
/**
- * @return array
+ * @return ItemData[]
*/
public function getTags()
{
@@ -388,7 +397,7 @@ class AccountSearchItem
}
/**
- * @param array $tags
+ * @param ItemData[] $tags
*/
public function setTags(array $tags)
{
diff --git a/lib/SP/Account/AccountUtil.php b/lib/SP/Account/AccountUtil.php
index 9a1f5e37..0169e629 100644
--- a/lib/SP/Account/AccountUtil.php
+++ b/lib/SP/Account/AccountUtil.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -256,10 +256,10 @@ class AccountUtil
// Filtro usuario y grupo
$filter =
/** @lang SQL */
- 'A.userId = ?
+ '(A.userId = ?
OR A.userGroupId = ?
OR A.id IN (SELECT accountId AS accountId FROM AccountToUser WHERE accountId = A.id AND userId = ? UNION ALL SELECT accountId FROM AccountToUserGroup WHERE accountId = A.id AND userGroupId = ?)
- OR A.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = Account.userGroupId AND userId = ?)';
+ OR A.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = A.userGroupId AND userId = ?))';
$params = [$userData->getId(), $userData->getUserGroupId(), $userData->getId(), $userData->getUserGroupId(), $userData->getId()];
@@ -300,10 +300,10 @@ class AccountUtil
// Filtro usuario y grupo
$filter =
/** @lang SQL */
- 'AH.userId = ?
+ '(AH.userId = ?
OR AH.userGroupId = ?
OR AH.accountId IN (SELECT accountId AS accountId FROM AccountToUser WHERE accountId = AH.accountId AND userId = ? UNION ALL SELECT accountId FROM AccountToUserGroup WHERE accountId = AH.accountId AND userGroupId = ?)
- OR AH.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = Account.userGroupId AND userId = ?)';
+ OR AH.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = AH.userGroupId AND userId = ?))';
$params = [$userData->getId(), $userData->getUserGroupId(), $userData->getId(), $userData->getUserGroupId(), $userData->getId()];
diff --git a/lib/SP/Bootstrap.php b/lib/SP/Bootstrap.php
index eeb8a2d8..935fc4f1 100644
--- a/lib/SP/Bootstrap.php
+++ b/lib/SP/Bootstrap.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -48,6 +48,8 @@ use SP\Core\Upgrade\Upgrade;
use SP\Http\Request;
use SP\Log\Log;
use SP\Providers\Log\LogHandler;
+use SP\Providers\Notification\NotificationHandler;
+use SP\Services\UserProfile\UserProfileService;
use SP\Storage\Database;
use SP\Storage\DBUtil;
use SP\Util\Checks;
@@ -143,7 +145,9 @@ class Bootstrap
$this->language = $container->get(Language::class);
$this->upgrade = $container->get(Upgrade::class);
- $container->get(EventDispatcher::class)->attach($container->get(LogHandler::class));
+ $eventDispatcher = $container->get(EventDispatcher::class);
+ $eventDispatcher->attach($container->get(LogHandler::class));
+ $eventDispatcher->attach($container->get(NotificationHandler::class));
$this->initRouter();
}
@@ -272,26 +276,23 @@ class Bootstrap
$this->initSession($this->configData->isEncryptSession());
// Volver a cargar la configuración si se recarga la página
- if (!Request::checkReload()) {
+ if (Request::checkReload($this->router) === false) {
// Cargar la configuración
$this->config->loadConfig();
// Cargar el lenguaje
$this->language->setLanguage();
} else {
+ debugLog('Browser reload');
+
+ $this->session->setAppStatus(Session::APP_STATUS_RELOADED);
+
// Cargar la configuración
$this->config->loadConfig(true);
// Restablecer el idioma y el tema visual
$this->language->setLanguage(true);
$this->theme->initTheme(true);
-
- if ($this->session->isLoggedIn()) {
- // Recargar los permisos del perfil de usuario
-// $this->session->setUserProfile(Profile::getItem()->getById($this->session->getUserData()->getUserProfileId()));
- // Reset de los datos de ACL de cuentas
- $this->session->resetAccountAcl();
- }
}
// Comprobar si es necesario cambiar a HTTPS
@@ -495,6 +496,12 @@ class Bootstrap
// Comprobar acciones en URL
// $this->checkPreLoginActions();
+
+ if ($this->session->isLoggedIn() && $this->session->getAppStatus() === Session::APP_STATUS_RELOADED) {
+ debugLog('Reload user profile');
+ // Recargar los permisos del perfil de usuario
+ $this->session->setUserProfile(self::$container->get(UserProfileService::class)->getById($this->session->getUserData()->getUserProfileId())->getProfile());
+ }
}
/**
@@ -625,7 +632,7 @@ class Bootstrap
/**
* @param Container $container
- * @param string $module
+ * @param string $module
* @throws InitializationException
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
diff --git a/lib/SP/Controller/AccountController.php b/lib/SP/Controller/AccountController.php
index c5613215..76f3dc53 100644
--- a/lib/SP/Controller/AccountController.php
+++ b/lib/SP/Controller/AccountController.php
@@ -62,7 +62,7 @@ use SP\Util\Json;
class AccountController extends ControllerBase implements ActionsInterface
{
/**
- * @var AccountAcl
+ * @var \SP\Account\AccountAcl
*/
protected $AccountAcl;
/**
diff --git a/lib/SP/Controller/ItemListController.php b/lib/SP/Controller/ItemListController.php
index 28f9a8ed..c8f8d2a1 100644
--- a/lib/SP/Controller/ItemListController.php
+++ b/lib/SP/Controller/ItemListController.php
@@ -89,7 +89,7 @@ class ItemListController extends GridTabControllerBase implements ActionsInterfa
$this->view->assign('deleteEnabled', Request::analyze('del', 0));
$this->view->assign('files', FileUtil::getAccountFiles($this->view->accountId));
- if (!is_array($this->view->files) || count($this->view->files) === 0) {
+ if (!is_array($this->view->templates) || count($this->view->templates) === 0) {
return;
}
}
diff --git a/lib/SP/Controller/ItemShowController.php b/lib/SP/Controller/ItemShowController.php
index 0327dad8..e6d6a316 100644
--- a/lib/SP/Controller/ItemShowController.php
+++ b/lib/SP/Controller/ItemShowController.php
@@ -600,7 +600,7 @@ class ItemShowController extends ControllerBase implements ActionsInterface, Ite
$this->view->assign('deleteEnabled', Request::analyze('del', 0));
$this->view->assign('files', FileUtil::getAccountFiles($this->view->accountId));
- if (!is_array($this->view->files) || count($this->view->files) === 0) {
+ if (!is_array($this->view->templates) || count($this->view->templates) === 0) {
return;
}
diff --git a/lib/SP/Core/Acl/Acl.php b/lib/SP/Core/Acl/Acl.php
index 6f05795f..14517cae 100644
--- a/lib/SP/Core/Acl/Acl.php
+++ b/lib/SP/Core/Acl/Acl.php
@@ -3,8 +3,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -25,6 +25,9 @@
namespace SP\Core\Acl;
+use SP\Core\Events\Event;
+use SP\Core\Events\EventDispatcher;
+use SP\Core\Events\EventMessage;
use SP\Core\Session\Session;
defined('APP_ROOT') || die();
@@ -42,16 +45,22 @@ class Acl implements ActionsInterface
* @var Session
*/
private $session;
+ /**
+ * @var EventDispatcher
+ */
+ private $eventDispatcher;
/**
* Acl constructor.
*
- * @param Session $session
- * @param Actions|null $action
+ * @param Session $session
+ * @param EventDispatcher $eventDispatcher
+ * @param Actions|null $action
*/
- public function __construct(Session $session, Actions $action = null)
+ public function __construct(Session $session, EventDispatcher $eventDispatcher, Actions $action = null)
{
$this->session = $session;
+ $this->eventDispatcher = $eventDispatcher;
self::$action = $action;
}
@@ -105,11 +114,7 @@ class Acl implements ActionsInterface
*/
public function checkUserAccess($action, $userId = 0)
{
- $userProfile = $this->session->getUserProfile();
-
- // Comprobamos si la cache de permisos está inicializada
- if (!is_object($userProfile)) {
-// error_log('ACL_CACHE_MISS');
+ if (!($userProfile = $this->session->getUserProfile())) {
return false;
}
@@ -161,6 +166,7 @@ class Acl implements ActionsInterface
case self::PUBLICLINK_SEARCH:
return $userProfile->isMgmPublicLinks();
case self::PUBLICLINK_CREATE:
+ case self::PUBLICLINK_REFRESH:
return ($userProfile->isMgmPublicLinks() || $userProfile->isAccPublicLinks());
case self::ACCOUNTMGR:
case self::ACCOUNTMGR_SEARCH:
@@ -199,18 +205,26 @@ class Acl implements ActionsInterface
case self::EVENTLOG:
case self::EVENTLOG_SEARCH:
return $userProfile->isEvl();
+ case self::ACCOUNT_REQUEST:
case self::NOTIFICATION:
+ case self::NOTIFICATION_VIEW:
case self::NOTIFICATION_SEARCH:
case self::NOTIFICATION_CHECK:
return true;
}
-// $Log = new Log();
-// $Log->getLogMessage()
-// ->setAction(__FUNCTION__)
-// ->addDetails(__('Acceso denegado', false), self::getActionInfo($action, false));
-// $Log->setLogLevel(Log::NOTICE);
-// $Log->writeLog();
+ try {
+ $actionName = self::$action->getActionById($action)->getName();
+ } catch (ActionNotFoundException $e) {
+ $actionName = __u('N/D');
+ }
+
+ $this->eventDispatcher->notifyEvent('acl.deny',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Acceso denegado'))
+ ->addDetail(__u('Acción'), $actionName)
+ ->addDetail(__u('Usuario'), $userData->getLogin()))
+ );
return false;
}
diff --git a/lib/SP/Core/DiFactory.php b/lib/SP/Core/DiFactory.php
deleted file mode 100644
index 77002ce8..00000000
--- a/lib/SP/Core/DiFactory.php
+++ /dev/null
@@ -1,132 +0,0 @@
-.
- */
-
-namespace SP\Core;
-
-use SP\Core\Events\EventDispatcher;
-use SP\Core\Events\EventDispatcherInterface;
-use SP\Core\Exceptions\InvalidClassException;
-use SP\Core\UI\ThemeInterface;
-use SP\Mgmt\ItemBaseInterface;
-use SP\Storage\DBStorageInterface;
-use SP\Storage\MySQLHandler;
-use SP\Storage\XmlFileStorageInterface;
-use SP\Storage\XmlHandler;
-
-/**
- * Class SingleFactory
- *
- * @package SP\Core
- */
-class DiFactory
-{
- /**
- * @var XmlFileStorageInterface
- */
- private static $ConfigFactory;
- /**
- * @var DBStorageInterface
- */
- private static $DBFactory;
- /**
- * @var ItemBaseInterface[]
- */
- private static $ItemFactory = [];
- /**
- * @var ThemeInterface
- */
- private static $ThemeFactory;
- /**
- * @var EventDispatcherInterface
- */
- private static $EventDispatcher;
-
- /**
- * Devuelve el almacenamiento para la configuración
- *
- * @return XmlFileStorageInterface
- */
- final public static function getConfigStorage()
- {
- if (!self::$ConfigFactory instanceof XmlFileStorageInterface) {
- self::$ConfigFactory = new XmlHandler(CONFIG_FILE);
- }
-
- return self::$ConfigFactory;
- }
-
- /**
- * Devuelve el manejador para la BD
- *
- * @return DBStorageInterface
- */
- final public static function getDBStorage()
- {
- if (!self::$DBFactory instanceof DBStorageInterface) {
- self::$DBFactory = new MySQLHandler();
- }
-
- return self::$DBFactory;
- }
-
- /**
- * Devuelve la instancia de la clase del elemento solicitado
- *
- * @param string $caller La clase del objeto
- * @param mixed $itemData Los datos del elemento
- * @return ItemBaseInterface
- */
- final public static function getItem($caller, $itemData = null)
- {
-// error_log(count(self::$ItemFactory) . '-' . (memory_get_usage() / 1000));
-
- try {
- if (!isset(self::$ItemFactory[$caller])) {
- self::$ItemFactory[$caller] = new $caller($itemData);
-
- return self::$ItemFactory[$caller];
- }
-
- return (null !== $itemData) ? self::$ItemFactory[$caller]->setItemData($itemData) : self::$ItemFactory[$caller];
- } catch (InvalidClassException $e) {
- debugLog('Invalid class for item data: ' . $e->getMessage(), true);
- }
-
- return self::$ItemFactory[$caller];
- }
-
- /**
- * Devuelve el manejador de eventos
- *
- * @return EventDispatcherInterface
- */
- final public static function getEventDispatcher()
- {
- if (!self::$EventDispatcher instanceof EventDispatcher) {
- self::$EventDispatcher = new EventDispatcher();
- }
-
- return self::$EventDispatcher;
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Core/Events/EventMessage.php b/lib/SP/Core/Events/EventMessage.php
index 31ee95a9..814a9604 100644
--- a/lib/SP/Core/Events/EventMessage.php
+++ b/lib/SP/Core/Events/EventMessage.php
@@ -24,6 +24,7 @@
namespace SP\Core\Events;
+use SP\Core\Messages\MessageInterface;
use SP\Html\Html;
/**
@@ -31,7 +32,7 @@ use SP\Html\Html;
*
* @package SP\Core\Events
*/
-class EventMessage
+class EventMessage implements MessageInterface
{
/**
* @var array Detalles de la acción en formato "detalle : descripción"
@@ -49,6 +50,10 @@ class EventMessage
* @var array
*/
protected $description = [];
+ /**
+ * @var array
+ */
+ protected $data = [];
/**
* @return static
@@ -255,4 +260,28 @@ class EventMessage
{
return $this->detailsCounter;
}
+
+ /**
+ * @return array
+ */
+ public function getData()
+ {
+ return $this->data;
+ }
+
+ /**
+ * @param string $type
+ * @param mixed $data
+ * @return EventMessage
+ */
+ public function addData($type, $data)
+ {
+ if (isset($this->data[$type]) && in_array($data, $this->data[$type])) {
+ return $this;
+ }
+
+ $this->data[$type][] = $data;
+
+ return $this;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Core/Init.php b/lib/SP/Core/Init.php
deleted file mode 100644
index 70eb0c40..00000000
--- a/lib/SP/Core/Init.php
+++ /dev/null
@@ -1,758 +0,0 @@
-.
- */
-
-namespace SP\Core;
-
-use Defuse\Crypto\Exception\CryptoException;
-use SP\Account\AccountAcl;
-use SP\Config\Config;
-use SP\Core\Crypt\CryptSessionHandler;
-use SP\Core\Crypt\SecureKeyCookie;
-use SP\Core\Crypt\Session as CryptSession;
-use SP\Core\Exceptions\SPException;
-use SP\Core\Upgrade\Upgrade;
-use SP\Http\JsonResponse;
-use SP\Http\Request;
-use SP\Log\Email;
-use SP\Log\Log;
-use SP\Mgmt\Profiles\Profile;
-use SP\Modules\Web\Controllers\MainController;
-use SP\Providers\Auth\Browser\Browser;
-use SP\Storage\DBUtil;
-use SP\Util\Checks;
-use SP\Util\HttpUtil;
-use SP\Util\Json;
-use SP\Util\Util;
-
-defined('APP_ROOT') || die();
-
-/**
- * Clase Init para la inicialización del entorno de sysPass
- *
- * @package SP
- */
-class Init
-{
- /**
- * @var string The installation path on the server (e.g. /srv/www/syspass)
- */
- public static $SERVERROOT = '';
-
- /**
- * @var string The current request path relative to the sysPass root (e.g. files/index.php)
- */
- public static $WEBROOT = '';
-
- /**
- * @var string The full URL to reach sysPass (e.g. https://sub.example.com/syspass/)
- */
- public static $WEBURI = '';
-
- /**
- * @var bool True if sysPass has been updated. Only for notices.
- */
- public static $UPDATED = false;
- /**
- * @var int
- */
- public static $LOCK = 0;
- /**
- * @var string
- */
- private static $SUBURI = '';
- /**
- * @var bool Indica si la versión de PHP es correcta
- */
- private static $checkPhpVersion;
- /**
- * @var bool Indica si el script requiere inicialización
- */
- private static $checkInitSourceInclude;
- /**
- * @var string
- */
- private static $sourceScript;
-
- /**
- * Inicializar la aplicación.
- * Esta función inicializa las variables de la aplicación y muestra la página
- * según el estado en el que se encuentre.
- *
- * @throws \SP\Core\Exceptions\SPException
- * @throws \phpmailer\phpmailerException
- * @throws \Defuse\Crypto\Exception\BadFormatException
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
- */
- public static function start()
- {
- self::$checkPhpVersion = Checks::checkPhpVersion();
- self::$checkInitSourceInclude = self::checkInitSourceInclude();
-
- if (date_default_timezone_get() === 'UTC') {
- date_default_timezone_set('UTC');
- }
-
- // Variables de autentificación
- self::setAuth();
-
- // Establecer el nivel de logging
- self::setLogging();
-
- // Cargar las extensiones
-// self::loadExtensions();
-
- // Establecer el lenguaje por defecto
- Language::setLocales('en_US');
-
- // Establecer las rutas de la aplicación
- self::setPaths();
-
- if (!self::$checkPhpVersion && !self::$checkInitSourceInclude) {
- self::initError(
- __('Versión de PHP requerida >= ') . ' 5.6.0 <= 7.0',
- __('Actualice la versión de PHP para que la aplicación funcione correctamente'));
- }
-
- // Comprobar la configuración
- self::checkConfig();
-
- // Iniciar la sesión de PHP
- self::startSession(Config::getConfig()->isEncryptSession());
-
- // Volver a cargar la configuración si se recarga la página
- if (!Request::checkReload()) {
- // Cargar la configuración
- Config::loadConfig();
-
- // Cargar el lenguaje
- Language::setLanguage();
-
- // Establecer el tema de sysPass
- DiFactory::getTheme();
- } else {
- // Cargar la configuración
- Config::loadConfig(true);
-
- // Restablecer el idioma y el tema visual
- Language::setLanguage(true);
- DiFactory::getTheme()->initTheme(true);
-
- if (CryptSession::isLoggedIn() === true) {
- // Recargar los permisos del perfil de usuario
- SessionFactory::setUserProfile(Profile::getItem()->getById(SessionFactory::getUserData()->getUserProfileId()));
- // Reset de los datos de ACL de cuentas
- AccountAcl::resetData();
- }
- }
-
- // Comprobar si es necesario cambiar a HTTPS
- HttpUtil::checkHttps();
-
- // Comprobar si es necesario inicialización
- if (self::$checkInitSourceInclude ||
- ((defined('IS_INSTALLER') || defined('IS_UPGRADE')) && Checks::isAjax())
- ) {
- return;
- }
-
- // Comprobar si está instalado
- self::checkInstalled();
-
- // Comprobar si el modo mantenimiento está activado
- self::checkMaintenanceMode();
-
- // Comprobar si la Base de datos existe
- if (!DBUtil::checkDatabaseExist()) {
- self::initError(__('Error en la verificación de la base de datos'));
- }
-
- // Comprobar si es cierre de sesión
- self::checkLogout();
-
- // Comprobar si es necesario actualizar componentes
- self::checkUpgrade();
-
- // Inicializar la sesión
- self::initSession();
-
- // Cargar los plugins
- CryptSession::loadPlugins();
-
- // Comprobar acciones en URL
- self::checkPreLoginActions();
-
- // Si es una petición AJAX
- if (Checks::isAjax()) {
- return;
- }
-
- if (CryptSession::isLoggedIn() === true && SessionFactory::getAuthCompleted() === true) {
- $AuthBrowser = new Browser();
-
- // Comprobar si se ha identificado mediante el servidor web y el usuario coincide
- if ($AuthBrowser->checkServerAuthUser(SessionFactory::getUserData()->getLogin()) === false
- && $AuthBrowser->checkServerAuthUser(SessionFactory::getUserData()->getSsoLogin()) === false
- ) {
- self::goLogout();
- }
-
- return;
- }
-
- // El usuario no está logado y no es una petición, redirigir al login
- self::goLogin();
- }
-
- /**
- * Comprobar el archivo que realiza el include necesita inicialización.
- *
- * @returns bool
- */
- private static function checkInitSourceInclude()
- {
- self::$sourceScript = pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_BASENAME);
- $skipInit = ['js.php', 'css.php', 'api.php', 'ajax_getEnvironment.php', 'ajax_task.php'];
-
- return in_array(self::$sourceScript, $skipInit, true);
- }
-
- /**
- * Establecer variables de autentificación
- */
- private static function setAuth()
- {
- // Copiar la cabecera http de autentificación para apache+php-fcgid
- if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) {
- $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION'];
- }
-
- // Establecer las cabeceras de autentificación para apache+php-cgi
- if (isset($_SERVER['HTTP_AUTHORIZATION'])
- && preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches)
- ) {
- list($name, $password) = explode(':', base64_decode($matches[1]), 2);
- $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
- $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
- }
-
- // Establecer las cabeceras de autentificación para que apache+php-cgi funcione si la variable es renombrada por apache
- if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])
- && preg_match('/Basic\s+(.*)$/i', $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches)
- ) {
- list($name, $password) = explode(':', base64_decode($matches[1]), 2);
- $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
- $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
- }
- }
-
- /**
- * Establecer el nivel de logging
- */
- public static function setLogging()
- {
- // Establecer el modo debug si una sesión de xdebug está activa
- if (isset($_COOKIE['XDEBUG_SESSION']) && !defined('DEBUG')) {
- define('DEBUG', true);
- }
-
- if (defined('DEBUG') && DEBUG) {
- error_reporting(E_ALL);
- ini_set('display_errors', 'On');
- } else {
- error_reporting(E_ALL & ~(E_DEPRECATED | E_STRICT | E_NOTICE));
- ini_set('display_errors', 'Off');
- }
-
- if (!file_exists(LOG_FILE) && touch(LOG_FILE) && chmod(LOG_FILE, 0600)) {
- debugLog('Setup log file: ' . LOG_FILE);
- }
- }
-
- /**
- * Cargar las clases de las extensiones de sysPass
- */
- private static function loadExtensions()
- {
- $CryptoLoader = new \SplClassLoader('Defuse\Crypto', EXTENSIONS_PATH);
- $CryptoLoader->setPrepend(false);
- $CryptoLoader->register();
-
- $PhpSecLoader = new \SplClassLoader('phpseclib', EXTENSIONS_PATH);
- $PhpSecLoader->setPrepend(false);
- $PhpSecLoader->register();
-
- $PhpMailerLoader = new \SplClassLoader('phpmailer', EXTENSIONS_PATH);
- $PhpMailerLoader->setPrepend(false);
- $PhpMailerLoader->register();
-
- $ExtsLoader = new \SplClassLoader('Exts', BASE_PATH);
- $ExtsLoader->setFileExtension('.class.php');
- $ExtsLoader->setPrepend(false);
- $ExtsLoader->register();
-
- $PluginsLoader = new \SplClassLoader('Plugins', BASE_PATH);
- $PluginsLoader->setFileExtension('.class.php');
- $PluginsLoader->setPrepend(false);
- $PluginsLoader->register();
- }
-
- /**
- * Establecer las rutas de la aplicación.
- * Esta función establece las rutas del sistema de archivos y web de la aplicación.
- * La variables de clase definidas son $SERVERROOT, $WEBROOT y $SUBURI
- */
- private static function setPaths()
- {
- // Calcular los directorios raíz
-// $dir = substr(__DIR__, 0, strpos(__DIR__, str_replace('\\', '/', __NAMESPACE__)) - 1);
-// self::$SERVERROOT = substr($dir, 0, strripos($dir, DIRECTORY_SEPARATOR));
-
- self::$SERVERROOT = dirname(BASE_PATH);
-
- self::$SUBURI = str_replace("\\", '/', substr(realpath($_SERVER['SCRIPT_FILENAME']), strlen(self::$SERVERROOT)));
-
- $scriptName = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
-
- if (substr($scriptName, -1) === '/') {
- $scriptName .= 'index.php';
- // Asegurar que suburi sigue las mismas reglas que scriptName
- if (substr(self::$SUBURI, -9) !== 'index.php') {
- if (substr(self::$SUBURI, -1) !== '/') {
- self::$SUBURI .= '/';
- }
- self::$SUBURI .= 'index.php';
- }
- }
-
- $pos = strpos($scriptName, self::$SUBURI);
-
- if ($pos === false) {
- $pos = strpos($scriptName, '?');
- }
-
- self::$WEBROOT = substr($scriptName, 0, $pos);
-
- if (self::$WEBROOT !== '' && self::$WEBROOT[0] !== '/') {
- self::$WEBROOT = '/' . self::$WEBROOT;
- }
-
- self::$WEBURI = HttpUtil::getHttpHost() . self::$WEBROOT;
- }
-
-
- /**
- * Devuelve un error utilizando la plantilla de error o en formato JSON
- *
- * @param string $message con la descripción del error
- * @param string $hint opcional, con una ayuda sobre el error
- * @param bool $headers
- */
- public static function initError($message, $hint = '', $headers = false)
- {
- debugLog(__FUNCTION__);
- debugLog(__($message));
- debugLog(__($hint));
-
- if (Checks::isJson()) {
- $JsonResponse = new JsonResponse();
- $JsonResponse->setDescription($message);
- $JsonResponse->addMessage($hint);
- Json::returnJson($JsonResponse);
- } elseif ($headers === true) {
- header('HTTP/1.1 503 Service Temporarily Unavailable');
- header('Status: 503 Service Temporarily Unavailable');
- header('Retry-After: 120');
- }
-
- SessionUtil::cleanSession();
-
- $Tpl = new Template();
- $Tpl->append('errors', ['type' => SPException::CRITICAL, 'description' => __($message), 'hint' => __($hint)]);
-
- $Controller = new MainController($Tpl, 'error', !Checks::isAjax());
- $Controller->getError();
- }
-
- /**
- * Cargar la configuración
- *
- * @throws \SP\Core\Exceptions\SPException
- */
- private static function checkConfig()
- {
- // Comprobar si es una versión antigua
- self::checkConfigVersion();
-
- // Comprobar la configuración y cargar
- self::checkConfigDir();
- }
-
- /**
- * Comprobar la versión de configuración y actualizarla
- */
- private static function checkConfigVersion()
- {
- $appVersion = Util::getVersionStringNormalized();
-
- if (file_exists(OLD_CONFIG_FILE) && Upgrade::upgradeOldConfigFile($appVersion)) {
- self::logConfigUpgrade($appVersion);
-
- self::$UPDATED = true;
-
- return;
- }
-
- $configVersion = Upgrade::fixVersionNumber(Config::getConfig()->getConfigVersion());
-
- if (Config::getConfig()->isInstalled()
- && Util::checkVersion($configVersion, Util::getVersionArrayNormalized())
- && Upgrade::needConfigUpgrade($configVersion)
- && Upgrade::upgradeConfig($configVersion)
- ) {
- self::logConfigUpgrade($appVersion);
-
- self::$UPDATED = true;
- }
- }
-
- /**
- * Registrar la actualización de la configuración
- *
- * @param $version
- */
- private static function logConfigUpgrade($version)
- {
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(__('Actualización', false));
- $LogMessage->addDescription(__('Actualización de versión realizada.', false));
- $LogMessage->addDetails(__('Versión', false), $version);
- $LogMessage->addDetails(__('Tipo', false), 'config');
- $Log->writeLog();
-
- Email::sendEmail($LogMessage);
- }
-
- /**
- * Comprobar el archivo de configuración.
- * Esta función comprueba que el archivo de configuración exista y los permisos sean correctos.
- *
- * @throws \SP\Core\Exceptions\SPException
- */
- private static function checkConfigDir()
- {
- if (self::$checkInitSourceInclude) {
- return;
- }
-
- if (!is_dir(self::$SERVERROOT . DIRECTORY_SEPARATOR . 'config')) {
- clearstatcache();
- self::initError(__('El directorio "/config" no existe'));
- }
-
- if (!is_writable(self::$SERVERROOT . DIRECTORY_SEPARATOR . 'config')) {
- clearstatcache();
- self::initError(__('No es posible escribir en el directorio "config"'));
- }
-
- $configPerms = decoct(fileperms(self::$SERVERROOT . DIRECTORY_SEPARATOR . 'config') & 0777);
-
- if ($configPerms !== '750' && !Checks::checkIsWindows()) {
- clearstatcache();
- self::initError(__('Los permisos del directorio "/config" son incorrectos'), __('Actual:') . ' ' . $configPerms . ' - ' . __('Necesario: 750'));
- }
- }
-
- /**
- * Iniciar la sesión PHP
- *
- * @param bool $encrypt Encriptar la sesión de PHP
- */
- private static function startSession($encrypt = false)
- {
- // Evita que javascript acceda a las cookies de sesion de PHP
- ini_set('session.cookie_httponly', '1');
- ini_set('session.save_handler', 'files');
-
- if ($encrypt === true) {
- $Key = SecureKeyCookie::getKey();
-
- if ($Key !== false && self::$checkPhpVersion) {
- session_set_save_handler(new CryptSessionHandler($Key), true);
- }
- }
-
- // Si la sesión no puede ser iniciada, devolver un error 500
- if (session_start() === false) {
- Log::writeNewLog(__('Sesión', false), __('La sesión no puede ser inicializada', false));
-
- header('HTTP/1.1 500 Internal Server Error');
-
- self::initError(__('La sesión no puede ser inicializada'), __('Consulte con el administrador'));
- }
- }
-
- /**
- * Comprueba que la aplicación esté instalada
- * Esta función comprueba si la aplicación está instalada. Si no lo está, redirige al instalador.
- *
- * @throws \SP\Core\Exceptions\SPException
- * @throws \Defuse\Crypto\Exception\BadFormatException
- */
- private static function checkInstalled()
- {
- // Redirigir al instalador si no está instalada
- if (!Config::getConfig()->isInstalled()) {
- if (self::$SUBURI !== '/index.php') {
- $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
-
- $url = $protocol . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . self::$WEBROOT . '/index.php';
- header("Location: $url");
- exit();
- }
-
- if (SessionFactory::getAuthCompleted()) {
- session_destroy();
-
- self::start();
- return;
- }
-
- // Comprobar si sysPass está instalada o en modo mantenimiento
- $Controller = new MainController();
- $Controller->getInstaller();
- $Controller->view();
- exit();
- }
- }
-
- /**
- * Comprobar si el modo mantenimiento está activado
- * Esta función comprueba si el modo mantenimiento está activado.
- * Devuelve un error 503 y un reintento de 120s al cliente.
- *
- * @param bool $check sólo comprobar si está activado el modo
- * @return bool
- */
- public static function checkMaintenanceMode($check = false)
- {
- if (Config::getConfig()->isMaintenance()) {
- self::$LOCK = Util::getAppLock();
-
- if ($check === true
- || Checks::isAjax()
- || Request::analyze('nodbupgrade', 0) === 1
- || (Request::analyze('a') === 'upgrade' && Request::analyze('type') !== '')
- || (self::$LOCK > 0 && Util::isLoggedIn() && self::$LOCK === SessionFactory::getUserData()->getId())
- ) {
- return true;
- }
-
- self::initError(__('Aplicación en mantenimiento'), __('En breve estará operativa'));
- }
-
- return false;
- }
-
- /**
- * Comprobar si es necesario cerrar la sesión
- */
- private static function checkLogout()
- {
- if (Request::analyze('logout', false, true)) {
- self::goLogout();
- }
- }
-
- /**
- * Deslogar el usuario actual y eliminar la información de sesión.
- */
- private static function goLogout()
- {
- self::wrLogoutInfo();
-
- SessionUtil::cleanSession();
-
- SessionFactory::setLoggedOut(true);
-
- $Controller = new MainController();
- $Controller->getLogout();
- }
-
- /**
- * Escribir la información de logout en el registro de eventos.
- */
- private static function wrLogoutInfo()
- {
- $inactiveTime = abs(round((time() - SessionFactory::getLastActivity()) / 60, 2));
- $totalTime = abs(round((time() - SessionFactory::getStartActivity()) / 60, 2));
-
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(__('Finalizar sesión', false));
- $LogMessage->addDetails(__('Usuario', false), SessionFactory::getUserData()->getLogin());
- $LogMessage->addDetails(__('Tiempo inactivo', false), $inactiveTime . ' min.');
- $LogMessage->addDetails(__('Tiempo total', false), $totalTime . ' min.');
- $Log->writeLog();
- }
-
- /**
- * Mostrar la página de login
- */
- private static function goLogin()
- {
- SessionUtil::cleanSession();
-
- $Controller = new MainController();
- $Controller->getLogin();
- }
-
- /**
- * Comprobar si es necesario actualizar componentes
- */
- private static function checkUpgrade()
- {
- return self::$SUBURI === '/index.php' && (Upgrade::checkDbVersion() || Upgrade::checkAppVersion());
- }
-
- /**
- * Inicializar la sesión de usuario
- *
- */
- private static function initSession()
- {
- $lastActivity = SessionFactory::getLastActivity();
- $inMaintenance = Config::getConfig()->isMaintenance();
-
- // Timeout de sesión
- if ($lastActivity > 0
- && !$inMaintenance
- && (time() - $lastActivity) > self::getSessionLifeTime()
- ) {
- if (isset($_COOKIE[session_name()])) {
- setcookie(session_name(), '', time() - 42000, '/');
- }
-
- self::wrLogoutInfo();
-
- SessionUtil::restart();
- return;
- }
-
- $sidStartTime = SessionFactory::getSidStartTime();
-
- // Regenerar el Id de sesión periódicamente para evitar fijación
- if ($sidStartTime === 0) {
- // Intentar establecer el tiempo de vida de la sesión en PHP
- @ini_set('session.gc_maxlifetime', self::getSessionLifeTime());
-
- SessionFactory::setSidStartTime(time());
- SessionFactory::setStartActivity(time());
- } else if (!$inMaintenance
- && time() - $sidStartTime > 120
- && SessionFactory::getUserData()->getId() > 0
- ) {
- try {
- CryptSession::reKey();
-
- // Recargar los permisos del perfil de usuario
- SessionFactory::setUserProfile(Profile::getItem()->getById(SessionFactory::getUserData()->getUserProfileId()));
- } catch (CryptoException $e) {
- debugLog($e->getMessage());
-
- SessionUtil::restart();
- return;
- }
- }
-
- SessionFactory::setLastActivity(time());
- }
-
- /**
- * Obtener el timeout de sesión desde la configuración.
- *
- * @return int con el tiempo en segundos
- */
- private static function getSessionLifeTime()
- {
- $timeout = SessionFactory::getSessionTimeout();
-
- if (null === $timeout) {
- $configTimeout = Config::getConfig()->getSessionTimeout();
- SessionFactory::setSessionTimeout($configTimeout);
-
- return $configTimeout;
- }
-
- return $timeout;
- }
-
- /**
- * Comprobar si hay que ejecutar acciones de URL antes de presentar la pantalla de login.
- *
- * @return bool
- * @throws phpmailerException
- */
- public static function checkPreLoginActions()
- {
- $action = Request::analyze('a');
-
- if ($action === '') {
- return false;
- }
-
- $Controller = new MainController();
- $Controller->doAction('prelogin.' . $action);
-
- return true;
- }
-
- /**
- * Establecer las rutas de sysPass en el PATH de PHP
- */
- public static function setIncludes()
- {
- set_include_path(MODEL_PATH . PATH_SEPARATOR . CONTROLLER_PATH . PATH_SEPARATOR . EXTENSIONS_PATH . PATH_SEPARATOR . PLUGINS_PATH . PATH_SEPARATOR . get_include_path());
- }
-
- /**
- * Comprobar si hay que ejecutar acciones de URL después de realizar login.
- *
- * @return bool
- * @throws \phpmailer\phpmailerException
- */
- public static function checkPostLoginActions()
- {
- $action = Request::analyze('a');
-
- if ($action === '') {
- return false;
- }
-
- $Controller = new MainController();
- $Controller->doAction('postlogin.' . $action);
-
- return false;
- }
-}
diff --git a/lib/SP/Core/Session/Session.php b/lib/SP/Core/Session/Session.php
index 66da52a7..f7eee7d7 100644
--- a/lib/SP/Core/Session/Session.php
+++ b/lib/SP/Core/Session/Session.php
@@ -24,7 +24,6 @@
namespace SP\Core\Session;
-use SP\Account\AccountAcl;
use SP\Account\AccountSearchFilter;
use SP\Config\ConfigData;
use SP\DataModel\ProfileData;
@@ -37,6 +36,11 @@ use SP\Services\User\UserLoginResponse;
*/
class Session
{
+ const APP_STATUS_UPDATED = 'updated';
+ const APP_STATUS_RELOADED = 'reloaded';
+ const APP_STATUS_INSTALLED = 'installed';
+ const APP_STATUS_LOGGEDOUT = 'loggedout';
+
private static $isReset = false;
private static $isLocked = false;
@@ -202,32 +206,6 @@ class Session
$this->setSessionKey('searchFilters', $searchFilters);
}
- /**
- * Establecer la ACL de una cuenta
- *
- * @param AccountAcl $AccountAcl
- */
- public function setAccountAcl(AccountAcl $AccountAcl)
- {
- $_SESSION['accountAcl'][$AccountAcl->getAccountId()] = $AccountAcl;
- }
-
- /**
- * Devolver la ACL de una cuenta
- *
- * @param $accountId
- *
- * @return null|AccountAcl
- */
- public function getAccountAcl($accountId)
- {
- if (isset($_SESSION['accountAcl'][$accountId])) {
- return $_SESSION['accountAcl'][$accountId];
- }
-
- return null;
- }
-
public function resetAccountAcl()
{
$this->setSessionKey('accountAcl', null);
@@ -477,22 +455,32 @@ class Session
}
/**
- * Devuelve si se ha realizado un cierre de sesión
+ * Devuelve el estado de la aplicación
*
* @return bool
*/
- public function getLoggedOut()
+ public function getAppStatus()
{
- return $this->getSessionKey('loggedout', false);
+ return $this->getSessionKey('status');
}
/**
- * Establecer si se ha realizado un cierre de sesión
+ * Establecer el estado de la aplicación
*
- * @param bool $loggedout
+ * @param string $status
*/
- public function setLoggedOut($loggedout = false)
+ public function setAppStatus($status)
{
- $this->setSessionKey('loggedout', $loggedout);
+ $this->setSessionKey('status', $status);
+ }
+
+ /**
+ * Reset del estado de la aplicación
+ *
+ * @return bool
+ */
+ public function resetAppStatus()
+ {
+ return $this->setSessionKey('status', null);
}
}
diff --git a/lib/SP/Core/UI/Theme.php b/lib/SP/Core/UI/Theme.php
index 917d1818..a4b9248e 100644
--- a/lib/SP/Core/UI/Theme.php
+++ b/lib/SP/Core/UI/Theme.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -24,12 +24,10 @@
namespace SP\Core\UI;
-use Pimple\Container;
+use SP\Bootstrap;
use SP\Config\Config;
use SP\Config\ConfigData;
-use SP\Core\Init;
use SP\Core\Session\Session;
-use SP\Core\Traits\InjectableTrait;
use Theme\Icons;
defined('APP_ROOT') || die();
@@ -41,8 +39,6 @@ defined('APP_ROOT') || die();
*/
class Theme implements ThemeInterface
{
- use InjectableTrait;
-
/**
* @var string
*/
@@ -83,12 +79,14 @@ class Theme implements ThemeInterface
/**
* Theme constructor.
*
- * @param $module
- * @throws \SP\Core\Dic\ContainerException
+ * @param $module
+ * @param Config $config
+ * @param Session $session
*/
- public function __construct($module)
+ public function __construct($module, Config $config, Session $session)
{
- $this->injectDependencies();
+ $this->configData = $config->getConfigData();
+ $this->session = $session;
if (is_dir(VIEW_PATH)) {
$this->initTheme();
@@ -111,7 +109,7 @@ class Theme implements ThemeInterface
$this->session->setTheme($this->themeName);
}
- $this->themeUri = Init::$WEBURI . '/app/modules/' . $this->module . 'themes' . $this->themeName;
+ $this->themeUri = Bootstrap::$WEBURI . '/app/modules/' . $this->module . 'themes' . $this->themeName;
$this->themePath = str_replace(APP_ROOT, '', VIEW_PATH) . DIRECTORY_SEPARATOR . $this->themeName;
$this->themePathFull = VIEW_PATH . DIRECTORY_SEPARATOR . $this->themeName;
$this->viewsPath = $this->themePathFull . DIRECTORY_SEPARATOR . 'views';
@@ -155,16 +153,6 @@ class Theme implements ThemeInterface
return $this->icons;
}
- /**
- * @param Config $config
- * @param Session $session
- */
- public function inject(Config $config, Session $session)
- {
- $this->configData = $config->getConfigData();
- $this->session = $session;
- }
-
/**
* Obtener los temas disponibles desde el directorio de temas
*
@@ -172,7 +160,7 @@ class Theme implements ThemeInterface
*/
public function getThemesAvailable()
{
- $themesAvailable = array();
+ $themesAvailable = [];
$themesDirs = dir(VIEW_PATH);
diff --git a/lib/SP/DataModel/Dto/AccountAclDto.php b/lib/SP/DataModel/Dto/AccountAclDto.php
index d3d2f51c..d877120c 100644
--- a/lib/SP/DataModel/Dto/AccountAclDto.php
+++ b/lib/SP/DataModel/Dto/AccountAclDto.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -24,6 +24,8 @@
namespace SP\DataModel\Dto;
+use SP\DataModel\ItemData;
+
/**
* Class AccountAclDto
*
@@ -40,7 +42,7 @@ class AccountAclDto
*/
private $userId;
/**
- * @var int[]
+ * @var ItemData[]
*/
private $usersId;
/**
@@ -48,7 +50,7 @@ class AccountAclDto
*/
private $userGroupId;
/**
- * @var int[]
+ * @var ItemData[]
*/
private $userGroupsId;
/**
@@ -81,7 +83,7 @@ class AccountAclDto
}
/**
- * @return int[]
+ * @return ItemData[]
*/
public function getUsersId()
{
@@ -89,7 +91,7 @@ class AccountAclDto
}
/**
- * @param int[] $usersId
+ * @param ItemData[] $usersId
*/
public function setUsersId(array $usersId)
{
@@ -113,7 +115,7 @@ class AccountAclDto
}
/**
- * @return int[]
+ * @return ItemData[]
*/
public function getUserGroupsId()
{
@@ -121,7 +123,7 @@ class AccountAclDto
}
/**
- * @param int[] $userGroupsId
+ * @param ItemData[] $userGroupsId
*/
public function setUserGroupsId(array $userGroupsId)
{
@@ -141,7 +143,7 @@ class AccountAclDto
*/
public function setDateEdit($dateEdit)
{
- $this->dateEdit = (int)$dateEdit;
+ $this->dateEdit = $dateEdit;
}
/**
diff --git a/lib/SP/DataModel/Dto/AccountCache.php b/lib/SP/DataModel/Dto/AccountCache.php
index 5dcc0995..1b5299d4 100644
--- a/lib/SP/DataModel/Dto/AccountCache.php
+++ b/lib/SP/DataModel/Dto/AccountCache.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -24,6 +24,8 @@
namespace SP\DataModel\Dto;
+use SP\DataModel\ItemData;
+
/**
* Class AccountCacheDto
*
@@ -40,20 +42,20 @@ class AccountCache
*/
private $accountId;
/**
- * @var array
+ * @var ItemData[]
*/
private $users;
/**
- * @var array
+ * @var ItemData[]
*/
private $userGroups;
/**
* AccountCacheDto constructor.
*
- * @param int $accountId
- * @param array $users
- * @param array $userGroups
+ * @param int $accountId
+ * @param ItemData[] $users
+ * @param ItemData[] $userGroups
*/
public function __construct($accountId, array $users, array $userGroups)
{
@@ -72,7 +74,7 @@ class AccountCache
}
/**
- * @return array
+ * @return ItemData[]
*/
public function getUsers()
{
@@ -80,7 +82,7 @@ class AccountCache
}
/**
- * @return array
+ * @return ItemData[]
*/
public function getUserGroups()
{
diff --git a/lib/SP/DataModel/Dto/AccountDetailsResponse.php b/lib/SP/DataModel/Dto/AccountDetailsResponse.php
index 331f2b37..a3fc5a13 100644
--- a/lib/SP/DataModel/Dto/AccountDetailsResponse.php
+++ b/lib/SP/DataModel/Dto/AccountDetailsResponse.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -25,6 +25,7 @@
namespace SP\DataModel\Dto;
use SP\DataModel\AccountVData;
+use SP\DataModel\ItemData;
/**
* Class AccountDto
@@ -42,15 +43,15 @@ class AccountDetailsResponse
*/
private $accountVData;
/**
- * @var array Los Ids de los usuarios secundarios de la cuenta.
+ * @var ItemData[] Los usuarios secundarios de la cuenta.
*/
private $users = [];
/**
- * @var array Los Ids de los grupos secundarios de la cuenta.
+ * @var ItemData[] Los grupos secundarios de la cuenta.
*/
private $userGroups = [];
/**
- * @var array
+ * @var ItemData[] Las etiquetas de la cuenta.
*/
private $tags = [];
@@ -67,7 +68,7 @@ class AccountDetailsResponse
}
/**
- * @return array
+ * @return ItemData[]
*/
public function getUsers()
{
@@ -75,7 +76,7 @@ class AccountDetailsResponse
}
/**
- * @param array $users
+ * @param ItemData[] $users
*/
public function setUsers(array $users)
{
@@ -83,7 +84,7 @@ class AccountDetailsResponse
}
/**
- * @return array
+ * @return ItemData[]
*/
public function getUserGroups()
{
@@ -91,7 +92,7 @@ class AccountDetailsResponse
}
/**
- * @param array $userGroups
+ * @param ItemData[] $userGroups
*/
public function setUserGroups(array $userGroups)
{
@@ -99,7 +100,7 @@ class AccountDetailsResponse
}
/**
- * @return array
+ * @return ItemData[]
*/
public function getTags()
{
@@ -107,7 +108,7 @@ class AccountDetailsResponse
}
/**
- * @param array $tags
+ * @param ItemData[] $tags
*/
public function setTags(array $tags)
{
diff --git a/lib/SP/Http/Request.php b/lib/SP/Http/Request.php
index a710302a..83573851 100644
--- a/lib/SP/Http/Request.php
+++ b/lib/SP/Http/Request.php
@@ -24,6 +24,7 @@
namespace SP\Http;
+use Klein\Klein;
use SP\Core\CryptPKI;
use SP\Core\Init;
use SP\Html\Html;
@@ -285,11 +286,12 @@ class Request
/**
* Comprobar si se realiza una recarga de la página
*
+ * @param Klein $router
* @return bool
*/
- public static function checkReload()
+ public static function checkReload(Klein $router)
{
- return (self::getRequestHeaders('Cache-Control') === 'max-age=0');
+ return $router->request()->headers()->get('Cache-Control') === 'max-age=0';
}
/**
diff --git a/lib/SP/Mvc/View/Template.php b/lib/SP/Mvc/View/Template.php
index a0774adc..e80210bd 100644
--- a/lib/SP/Mvc/View/Template.php
+++ b/lib/SP/Mvc/View/Template.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -28,7 +28,6 @@ defined('APP_ROOT') || die();
use SP\Core\Exceptions\FileNotFoundException;
use SP\Core\Exceptions\InvalidArgumentException;
-use SP\Core\Traits\InjectableTrait;
use SP\Core\UI\Theme;
use SP\Core\UI\ThemeInterface;
@@ -43,8 +42,6 @@ use SP\Core\UI\ThemeInterface;
*/
class Template
{
- use InjectableTrait;
-
const TEMPLATE_EXTENSION = '.inc';
const PARTIALS_DIR = '_partials';
const LAYOUTS_DIR = '_layouts';
@@ -56,7 +53,7 @@ class Template
/**
* @var array Variable con los archivos de plantilla a cargar
*/
- private $files = [];
+ private $templates = [];
/**
* @var array Variable con las variables a incluir en la plantilla
*/
@@ -69,23 +66,17 @@ class Template
* @var array
*/
private $contentTemplates = [];
+ /**
+ * @var bool
+ */
+ private $upgraded = false;
/**
- * @param null $file Archivo de plantilla a añadir
- * @param array $vars Variables a inicializar
- * @throws \SP\Core\Dic\ContainerException
+ * @param Theme $theme
*/
- public function __construct($file = null, array $vars = [])
+ public function __construct(Theme $theme)
{
- $this->injectDependencies();
-
- if (null !== $file) {
- $this->addTemplate($file);
- }
-
- if (!empty($vars)) {
- $this->setVars($vars);
- }
+ $this->theme = $theme;
}
/**
@@ -95,11 +86,11 @@ class Template
* @param string $base Directorio base para la plantilla
* @return bool
*/
- public function addTemplate($name, $base = null)
+ public function addContentTemplate($name, $base = null)
{
try {
$template = $this->checkTemplate($name, $base);
- $this->setTemplate($template, $name);
+ $this->setContentTemplate($template, $name);
} catch (FileNotFoundException $e) {
return '';
}
@@ -134,48 +125,6 @@ class Template
return $templateFile;
}
- /**
- * Añadir un nuevo archivo de plantilla al array de plantillas
- *
- * @param string $file Con el nombre del archivo
- * @param string $name Nombre de la plantilla
- */
- private function setTemplate($file, $name)
- {
- $this->files[$name] = $file;
- }
-
- /**
- * Establecer los atributos de la clase a partir de un array.
- *
- * @param array $vars Con los atributos de la clase
- */
- private function setVars(&$vars)
- {
- foreach ($vars as $name => $value) {
- $this->{$name} = $value;
- }
- }
-
- /**
- * Añadir una nueva plantilla al array de plantillas de la clase
- *
- * @param string $name Con el nombre del archivo de plantilla
- * @param string $base Directorio base para la plantilla
- * @return bool
- */
- public function addContentTemplate($name, $base = null)
- {
- try {
- $template = $this->checkTemplate($name, $base);
- $this->setContentTemplate($template, $name);
- } catch (FileNotFoundException $e) {
- return '';
- }
-
- return $template;
- }
-
/**
* Añadir un nuevo archivo de plantilla al array de plantillas de contenido
*
@@ -195,7 +144,7 @@ class Template
*/
public function removeTemplate($name)
{
- unset($this->files[$name]);
+ unset($this->templates[$name]);
return $this;
}
@@ -234,14 +183,6 @@ class Template
return $this->contentTemplates[$dst];
}
- /**
- * @param Theme $theme
- */
- public function inject(Theme $theme)
- {
- $this->theme = $theme;
- }
-
/**
* Add partial template
*
@@ -252,6 +193,36 @@ class Template
$this->addTemplate($partial, self::PARTIALS_DIR);
}
+ /**
+ * Añadir una nueva plantilla al array de plantillas de la clase
+ *
+ * @param string $name Con el nombre del archivo de plantilla
+ * @param string $base Directorio base para la plantilla
+ * @return bool
+ */
+ public function addTemplate($name, $base = null)
+ {
+ try {
+ $template = $this->checkTemplate($name, $base);
+ $this->setTemplate($template, $name);
+ } catch (FileNotFoundException $e) {
+ return '';
+ }
+
+ return $template;
+ }
+
+ /**
+ * Añadir un nuevo archivo de plantilla al array de plantillas
+ *
+ * @param string $file Con el nombre del archivo
+ * @param string $name Nombre de la plantilla
+ */
+ private function setTemplate($file, $name)
+ {
+ $this->templates[$name] = $file;
+ }
+
/**
* Añadir una nueva plantilla dentro de una plantilla
*
@@ -352,7 +323,7 @@ class Template
*/
public function render()
{
- if (count($this->files) === 0) {
+ if (count($this->templates) === 0) {
throw new FileNotFoundException(__u('La plantilla no contiene archivos'));
}
@@ -361,29 +332,13 @@ class Template
ob_start();
// Añadimos las plantillas
- foreach ($this->files as $template) {
+ foreach ($this->templates as $template) {
include_once $template;
}
return ob_get_clean();
}
- /**
- * Crear la variable y asignarle un valor en el array de variables
- *
- * @param $name string nombre de la variable
- * @param $value mixed valor de la variable
- * @param null $scope string ámbito de la variable
- */
- public function assign($name, $value = '', $scope = null)
- {
- if (null !== $scope) {
- $name = $scope . '_' . $name;
- }
-
- $this->vars[$name] = $value;
- }
-
/**
* Anexar el valor de la variable al array de la misma en el array de variables
*
@@ -410,7 +365,7 @@ class Template
*/
public function resetTemplates()
{
- $this->files = [];
+ $this->templates = [];
return $this;
}
@@ -480,4 +435,66 @@ class Template
{
return count($this->contentTemplates) > 0;
}
+
+ /**
+ * @return array
+ */
+ public function getTemplates()
+ {
+ return $this->templates;
+ }
+
+ /**
+ * Assigns the current templates to contentTemplates
+ *
+ * @return $this
+ */
+ public function upgrade()
+ {
+ if (count($this->templates) > 0) {
+ $this->contentTemplates = $this->templates;
+
+ $this->templates = [];
+
+ $this->upgraded = true;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Crear la variable y asignarle un valor en el array de variables
+ *
+ * @param $name string nombre de la variable
+ * @param $value mixed valor de la variable
+ * @param null $scope string ámbito de la variable
+ */
+ public function assign($name, $value = '', $scope = null)
+ {
+ if (null !== $scope) {
+ $name = $scope . '_' . $name;
+ }
+
+ $this->vars[$name] = $value;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isUpgraded()
+ {
+ return $this->upgraded;
+ }
+
+ /**
+ * Establecer los atributos de la clase a partir de un array.
+ *
+ * @param array $vars Con los atributos de la clase
+ */
+ private function setVars(&$vars)
+ {
+ foreach ($vars as $name => $value) {
+ $this->{$name} = $value;
+ }
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Providers/Log/LogHandler.php b/lib/SP/Providers/Log/LogHandler.php
index 25f158ac..cc9e0004 100644
--- a/lib/SP/Providers/Log/LogHandler.php
+++ b/lib/SP/Providers/Log/LogHandler.php
@@ -49,7 +49,8 @@ class LogHandler extends Provider implements EventReceiver
'clear.eventlog',
'login.',
'logout',
- 'track.'
+ 'track.',
+ 'acl.deny'
];
/**
diff --git a/lib/SP/Providers/Mail/Mailer.php b/lib/SP/Providers/Mail/MailHandler.php
similarity index 92%
rename from lib/SP/Providers/Mail/Mailer.php
rename to lib/SP/Providers/Mail/MailHandler.php
index 4f18456e..b2245f33 100644
--- a/lib/SP/Providers/Mail/Mailer.php
+++ b/lib/SP/Providers/Mail/MailHandler.php
@@ -41,7 +41,7 @@ use SP\Util\Util;
*
* @package SP\Providers\Mail
*/
-class Mailer extends Provider
+class MailHandler extends Provider
{
/**
* @var PHPMailer
@@ -56,7 +56,7 @@ class Mailer extends Provider
* @param string $subject
* @param string $to
* @param MailMessage $mailMessage
- * @throws MailerException
+ * @throws MailHandlerException
*/
public function send($subject, $to, MailMessage $mailMessage)
{
@@ -84,7 +84,7 @@ class Mailer extends Provider
}
/**
- * @throws MailerException
+ * @throws MailHandlerException
*/
private function sendMail()
{
@@ -101,14 +101,14 @@ class Mailer extends Provider
$this->eventDispatcher->notifyEvent('exception', new Event($e));
- throw new MailerException(__u('Error al enviar correo'));
+ throw new MailHandlerException(__u('Error al enviar correo'));
}
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
- * @throws MailerException
+ * @throws MailHandlerException
*/
protected function initialize()
{
@@ -122,7 +122,7 @@ class Mailer extends Provider
* @return PHPMailer
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
- * @throws MailerException
+ * @throws MailHandlerException
*/
private function getMailer()
{
@@ -154,9 +154,9 @@ class Mailer extends Provider
} catch (\Exception $e) {
processException($e);
- throw new MailerException(
+ throw new MailHandlerException(
__u('No es posible inicializar'),
- MailerException::ERROR,
+ MailHandlerException::ERROR,
$e->getMessage(),
$e->getCode(),
$e
diff --git a/lib/SP/Providers/Mail/MailerException.php b/lib/SP/Providers/Mail/MailHandlerException.php
similarity index 95%
rename from lib/SP/Providers/Mail/MailerException.php
rename to lib/SP/Providers/Mail/MailHandlerException.php
index 508f66ab..0733359b 100644
--- a/lib/SP/Providers/Mail/MailerException.php
+++ b/lib/SP/Providers/Mail/MailHandlerException.php
@@ -31,7 +31,7 @@ use SP\Core\Exceptions\SPException;
*
* @package SP\Providers\Mail
*/
-class MailerException extends SPException
+class MailHandlerException extends SPException
{
}
\ No newline at end of file
diff --git a/lib/SP/Providers/Notification/NotificationHandler.php b/lib/SP/Providers/Notification/NotificationHandler.php
new file mode 100644
index 00000000..1d9c665f
--- /dev/null
+++ b/lib/SP/Providers/Notification/NotificationHandler.php
@@ -0,0 +1,128 @@
+.
+ */
+
+namespace SP\Providers\Notification;
+
+
+use SP\Core\Events\Event;
+use SP\Core\Events\EventReceiver;
+use SP\DataModel\NotificationData;
+use SP\Providers\Provider;
+use SP\Services\Notification\NotificationService;
+use SplSubject;
+
+/**
+ * Class NotificationHandler
+ *
+ * @package SP\Providers\Notification
+ */
+class NotificationHandler extends Provider implements EventReceiver
+{
+ const EVENTS = ['request.account'];
+
+ /**
+ * @var NotificationService
+ */
+ protected $notificationService;
+ /**
+ * @var string
+ */
+ protected $events;
+
+ /**
+ * Inicialización del observador
+ */
+ public function init()
+ {
+ // TODO: Implement init() method.
+ }
+
+ /**
+ * Evento de actualización
+ *
+ * @param string $eventType Nombre del evento
+ * @param Event $event Objeto del evento
+ */
+ public function updateEvent($eventType, Event $event)
+ {
+ $eventMessage = $event->getEventMessage();
+ $data = $eventMessage->getData();
+
+ foreach ($data['userId'] as $userId) {
+ $notificationData = new NotificationData();
+ $notificationData->setType(__('Solicitud'));
+ $notificationData->setComponent(__('Cuentas'));
+ $notificationData->setUserId($userId);
+ $notificationData->setDescription($eventMessage);
+
+ try {
+ $this->notificationService->create($notificationData);
+ } catch (\Exception $e) {
+ processException($e);
+ }
+ }
+ }
+
+ /**
+ * Devuelve los eventos que implementa el observador
+ *
+ * @return array
+ */
+ public function getEvents()
+ {
+ return self::EVENTS;
+ }
+
+ /**
+ * Devuelve los eventos que implementa el observador en formato cadena
+ *
+ * @return string
+ */
+ public function getEventsString()
+ {
+ return $this->events;
+ }
+
+ /**
+ * Receive update from subject
+ *
+ * @link http://php.net/manual/en/splobserver.update.php
+ * @param SplSubject $subject
+ * The SplSubject notifying the observer of an update.
+ *
+ * @return void
+ * @since 5.1.0
+ */
+ public function update(SplSubject $subject)
+ {
+ // TODO: Implement update() method.
+ }
+
+ protected function initialize()
+ {
+ $this->notificationService = $this->dic->get(NotificationService::class);
+
+ $this->events = str_replace('.', '\\.', implode('|', self::EVENTS));
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Repositories/Account/AccountToTagRepository.php b/lib/SP/Repositories/Account/AccountToTagRepository.php
index d42d067c..74f9aa38 100644
--- a/lib/SP/Repositories/Account/AccountToTagRepository.php
+++ b/lib/SP/Repositories/Account/AccountToTagRepository.php
@@ -25,6 +25,7 @@
namespace SP\Repositories\Account;
use SP\Account\AccountRequest;
+use SP\DataModel\ItemData;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemTrait;
use SP\Storage\DbWrapper;
@@ -43,7 +44,7 @@ class AccountToTagRepository extends Repository
* Devolver las etiquetas de una cuenta
*
* @param int $id
- * @return array
+ * @return ItemData[]
*/
public function getTagsByAccountId($id)
{
@@ -57,6 +58,7 @@ class AccountToTagRepository extends Repository
$queryData = new QueryData();
$queryData->setQuery($query);
$queryData->addParam($id);
+ $queryData->setMapClassName(ItemData::class);
return DbWrapper::getResultsArray($queryData, $this->db);
}
diff --git a/lib/SP/Repositories/Account/AccountToUserGroupRepository.php b/lib/SP/Repositories/Account/AccountToUserGroupRepository.php
index a1db64cf..f71ca34a 100644
--- a/lib/SP/Repositories/Account/AccountToUserGroupRepository.php
+++ b/lib/SP/Repositories/Account/AccountToUserGroupRepository.php
@@ -25,7 +25,7 @@
namespace SP\Repositories\Account;
use SP\Account\AccountRequest;
-use SP\DataModel\UserGroupData;
+use SP\DataModel\ItemData;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemTrait;
use SP\Storage\DbWrapper;
@@ -44,7 +44,7 @@ class AccountToUserGroupRepository extends Repository
* Obtiene el listado con el nombre de los grupos de una cuenta.
*
* @param int $id con el Id de la cuenta
- * @return array
+ * @return ItemData[]
*/
public function getUserGroupsByAccountId($id)
{
@@ -58,6 +58,7 @@ class AccountToUserGroupRepository extends Repository
$queryData = new QueryData();
$queryData->setQuery($query);
$queryData->addParam($id);
+ $queryData->setMapClassName(ItemData::class);
return DbWrapper::getResultsArray($queryData, $this->db);
}
@@ -66,7 +67,7 @@ class AccountToUserGroupRepository extends Repository
* Obtiene el listado con el nombre de los grupos de una cuenta.
*
* @param $id
- * @return UserGroupData[]
+ * @return ItemData[]
*/
public function getUserGroupsByUserGroupId($id)
{
@@ -80,6 +81,7 @@ class AccountToUserGroupRepository extends Repository
$queryData = new QueryData();
$queryData->setQuery($query);
$queryData->addParam($id);
+ $queryData->setMapClassName(ItemData::class);
return DbWrapper::getResultsArray($queryData, $this->db);
}
diff --git a/lib/SP/Repositories/Account/AccountToUserRepository.php b/lib/SP/Repositories/Account/AccountToUserRepository.php
index a117c75a..56ff02f3 100644
--- a/lib/SP/Repositories/Account/AccountToUserRepository.php
+++ b/lib/SP/Repositories/Account/AccountToUserRepository.php
@@ -25,6 +25,7 @@
namespace SP\Repositories\Account;
use SP\Account\AccountRequest;
+use SP\DataModel\ItemData;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemTrait;
use SP\Storage\DbWrapper;
@@ -104,7 +105,7 @@ class AccountToUserRepository extends Repository
* Obtiene el listado de usuarios de una cuenta.
*
* @param int $id con el id de la cuenta
- * @return array con los id de usuarios de la cuenta
+ * @return ItemData[] con los id de usuarios de la cuenta
*/
public function getUsersByAccountId($id)
{
@@ -118,6 +119,7 @@ class AccountToUserRepository extends Repository
$queryData = new QueryData();
$queryData->setQuery($query);
$queryData->addParam($id);
+ $queryData->setMapClassName(ItemData::class);
return DbWrapper::getResultsArray($queryData, $this->db);
}
diff --git a/lib/SP/Repositories/EventLog/EventlogRepository.php b/lib/SP/Repositories/EventLog/EventlogRepository.php
index 8679968e..f7e0e125 100644
--- a/lib/SP/Repositories/EventLog/EventlogRepository.php
+++ b/lib/SP/Repositories/EventLog/EventlogRepository.php
@@ -68,12 +68,10 @@ class EventlogRepository extends Repository
$queryData->setOrder('id DESC');
if ($itemSearchData->getSeachString() !== '') {
- $queryData->setWhere('action LIKE ? OR ipAddress LIKE ? OR description LIKE ?');
+ $queryData->setWhere('action LIKE ? OR login LIKE ? OR ipAddress LIKE ? OR description LIKE ?');
$search = '%' . $itemSearchData->getSeachString() . '%';
- $queryData->addParam($search);
- $queryData->addParam($search);
- $queryData->addParam($search);
+ $queryData->setParams(array_fill(0, 4, $search));
}
$queryData->setLimit('?,?');
diff --git a/lib/SP/Repositories/PublicLink/PublicLinkRepository.php b/lib/SP/Repositories/PublicLink/PublicLinkRepository.php
index 4317dd50..68c3b3be 100644
--- a/lib/SP/Repositories/PublicLink/PublicLinkRepository.php
+++ b/lib/SP/Repositories/PublicLink/PublicLinkRepository.php
@@ -472,14 +472,11 @@ class PublicLinkRepository extends Repository implements RepositoryItemInterface
$queryData->setMapClassName(PublicLinkData::class);
$queryData->setQuery($query);
$queryData->addParam($hash);
+ $queryData->setOnErrorMessage(__u('Error al obtener enlace'));
/** @var PublicLinkData $queryRes */
$queryRes = DbWrapper::getResults($queryData, $this->db);
- if ($queryRes === false) {
- throw new SPException(__u('Error al obtener enlace'), SPException::ERROR);
- }
-
if ($queryData->getQueryNumRows() === 0) {
throw new SPException(__u('El enlace no existe'), SPException::ERROR);
}
diff --git a/lib/SP/Repositories/UserGroup/UserToUserGroupRepository.php b/lib/SP/Repositories/UserGroup/UserToUserGroupRepository.php
index 0aa2f0fe..e722ea8b 100644
--- a/lib/SP/Repositories/UserGroup/UserToUserGroupRepository.php
+++ b/lib/SP/Repositories/UserGroup/UserToUserGroupRepository.php
@@ -46,19 +46,16 @@ class UserToUserGroupRepository extends Repository
* @param $groupId
* @return bool
*/
- public static function checkUserInGroup($groupId, $userId)
+ public function checkUserInGroup($groupId, $userId)
{
- $query = /** @lang SQL */
- 'SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = ? AND userId = ?';
+ $queryData = new QueryData();
+ $queryData->setQuery('SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = ? AND userId = ?');
+ $queryData->addParam($groupId);
+ $queryData->addParam($userId);
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($groupId);
- $Data->addParam($userId);
+ DbWrapper::getResults($queryData, $this->db);
- DbWrapper::getResults($Data);
-
- return ($Data->getQueryNumRows() === 1);
+ return ($queryData->getQueryNumRows() === 1);
}
/**
@@ -67,16 +64,13 @@ class UserToUserGroupRepository extends Repository
* @param $userId
* @return array
*/
- public static function getGroupsForUser($userId)
+ public function getGroupsForUser($userId)
{
- $query = /** @lang SQL */
- 'SELECT userGroupId AS groupId FROM UserToUserGroup WHERE userId = ?';
+ $queryData = new QueryData();
+ $queryData->setQuery('SELECT userGroupId AS groupId FROM UserToUserGroup WHERE userId = ?');
+ $queryData->addParam($userId);
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($userId);
-
- return DbWrapper::getResultsArray($Data);
+ return DbWrapper::getResultsArray($queryData, $this->db);
}
/**
@@ -104,15 +98,12 @@ class UserToUserGroupRepository extends Repository
*/
public function delete($id)
{
- $query = /** @lang SQL */
- 'DELETE FROM UserToUserGroup WHERE userGroupId = ?';
+ $queryData = new QueryData();
+ $queryData->setQuery('DELETE FROM UserToUserGroup WHERE userGroupId = ?');
+ $queryData->addParam($id);
+ $queryData->setOnErrorMessage(__u('Error al eliminar los usuarios del grupo'));
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($id);
- $Data->setOnErrorMessage(__u('Error al eliminar los usuarios del grupo'));
-
- DbWrapper::getQuery($Data, $this->db);
+ DbWrapper::getQuery($queryData, $this->db);
return $this;
}
@@ -131,17 +122,17 @@ class UserToUserGroupRepository extends Repository
$query = /** @lang SQL */
'INSERT INTO UserToUserGroup (userId, userGroupId) VALUES ' . $this->getParamsFromArray($users, '(?,?)');
- $Data = new QueryData();
- $Data->setQuery($query);
+ $queryData = new QueryData();
+ $queryData->setQuery($query);
foreach ($users as $user) {
- $Data->addParam($user);
- $Data->addParam($groupId);
+ $queryData->addParam($user);
+ $queryData->addParam($groupId);
}
- $Data->setOnErrorMessage(__u('Error al asignar los usuarios al grupo'));
+ $queryData->setOnErrorMessage(__u('Error al asignar los usuarios al grupo'));
- DbWrapper::getQuery($Data, $this->db);
+ DbWrapper::getQuery($queryData, $this->db);
return $this;
}
@@ -154,14 +145,11 @@ class UserToUserGroupRepository extends Repository
*/
public function getById($id)
{
- $query = /** @lang SQL */
- 'SELECT userGroupId, userId FROM UserToUserGroup WHERE userGroupId = ?';
+ $queryData = new QueryData();
+ $queryData->setQuery('SELECT userGroupId, userId FROM UserToUserGroup WHERE userGroupId = ?');
+ $queryData->addParam($id);
+ $queryData->setMapClassName(UserToUserGroupData::class);
- $Data = new QueryData();
- $Data->setMapClassName(UserToUserGroupData::class);
- $Data->setQuery($query);
- $Data->addParam($id);
-
- return DbWrapper::getResultsArray($Data, $this->db);
+ return DbWrapper::getResultsArray($queryData, $this->db);
}
}
\ No newline at end of file
diff --git a/lib/SP/Services/Account/AccountAclService.php b/lib/SP/Services/Account/AccountAclService.php
new file mode 100644
index 00000000..7ac1f780
--- /dev/null
+++ b/lib/SP/Services/Account/AccountAclService.php
@@ -0,0 +1,324 @@
+.
+ */
+
+namespace SP\Services\Account;
+
+use SP\Account\AccountAcl;
+use SP\Core\Acl\Acl;
+use SP\DataModel\Dto\AccountAclDto;
+use SP\DataModel\ProfileData;
+use SP\Services\Service;
+use SP\Services\User\UserLoginResponse;
+use SP\Services\UserGroup\UserToUserGroupService;
+use SP\Storage\FileCache;
+use SP\Util\ArrayUtil;
+use SP\Util\FileUtil;
+
+/**
+ * Class AccountAclService
+ *
+ * @package SP\Services\Account
+ */
+class AccountAclService extends Service
+{
+ /**
+ * ACL's file base path
+ */
+ const ACL_PATH = CACHE_PATH . DIRECTORY_SEPARATOR . 'accountAcl' . DIRECTORY_SEPARATOR;
+ /**
+ * @var AccountAclDto
+ */
+ protected $accountAclDto;
+ /**
+ * @var AccountAcl
+ */
+ protected $accountAcl;
+ /**
+ * @var Acl
+ */
+ protected $acl;
+ /**
+ * @var FileCache
+ */
+ protected $fileCache;
+
+ /**
+ * @param $userId
+ */
+ public static function clearAcl($userId)
+ {
+ if (FileUtil::rmdir_recursive(self::ACL_PATH . $userId) === false) {
+ debugLog(sprintf('Unable to delete %s directory', self::ACL_PATH . $userId));
+ }
+
+ debugLog(__FUNCTION__);
+ }
+
+ /**
+ * Obtener la ACL de una cuenta
+ *
+ * @param int $actionId
+ * @param AccountAclDto $accountAclDto
+ * @param bool $isHistory
+ * @return AccountAcl
+ */
+ public function getAcl($actionId, AccountAclDto $accountAclDto = null, $isHistory = false)
+ {
+ $this->accountAcl = new AccountAcl($actionId, $isHistory);
+
+ $this->accountAcl->showPermission = self::getShowPermission($this->session->getUserData(), $this->session->getUserProfile());
+
+ if ($accountAclDto !== null) {
+ $this->accountAclDto = $accountAclDto;
+ $accountAcl = $this->getAclFromCache($accountAclDto->getAccountId(), $actionId);
+
+ if (null !== $accountAcl
+ && !($this->accountAcl->modified = (int)strtotime($accountAclDto->getDateEdit()) > $accountAcl->getTime())
+ ) {
+ debugLog('Account ACL HIT');
+
+ return $accountAcl;
+ }
+
+ debugLog('Account ACL MISS');
+
+ $this->accountAcl->setAccountId($accountAclDto->getAccountId());
+
+ return $this->updateAcl();
+ }
+
+ return $this->accountAcl;
+ }
+
+ /**
+ * Sets grants which don't need the account's data
+ *
+ * @param UserLoginResponse $userData
+ * @param ProfileData $profileData
+ * @return bool
+ */
+ public static function getShowPermission(UserLoginResponse $userData, ProfileData $profileData)
+ {
+ return $userData->getIsAdminApp()
+ || $userData->getIsAdminAcc()
+ || $profileData->isAccPermission();
+ }
+
+ /**
+ * Resturns an stored ACL
+ *
+ * @param int $accountId
+ * @param int $actionId
+ * @return AccountAcl
+ */
+ public function getAclFromCache($accountId, $actionId)
+ {
+ try {
+ return $this->fileCache->load($this->getCacheFileForAcl($accountId, $actionId));
+ } catch (\RuntimeException $e) {
+ return null;
+ }
+ }
+
+ /**
+ * @param int $accountId
+ * @param int $actionId
+ * @return string
+ */
+ public function getCacheFileForAcl($accountId, $actionId)
+ {
+ $userId = $this->session->getUserData()->getId();
+ return self::ACL_PATH . $userId . DIRECTORY_SEPARATOR . $accountId . DIRECTORY_SEPARATOR . md5($userId . $accountId . $actionId) . '.cache';
+ }
+
+ /**
+ * Actualizar la ACL
+ *
+ * @return AccountAcl
+ */
+ public function updateAcl()
+ {
+ if ($this->checkComponents()) {
+ $this->makeAcl();
+ }
+
+ $this->saveAclInCache($this->accountAcl);
+
+ return $this->accountAcl;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function checkComponents()
+ {
+ return null !== $this->accountAclDto;
+ }
+
+ /**
+ * Crear la ACL de una cuenta
+ */
+ protected function makeAcl()
+ {
+ $this->compileAccountAccess();
+ $this->accountAcl->setCompiledAccountAccess(true);
+
+ $this->compileShowAccess();
+ $this->accountAcl->setCompiledShowAccess(true);
+
+ $this->accountAcl->setTime(time());
+ }
+
+ /**
+ * compileAccountAccess
+ */
+ protected function compileAccountAccess()
+ {
+ $userData = $this->session->getUserData();
+
+ if ($userData->getIsAdminApp()
+ || $userData->getIsAdminAcc()
+ ) {
+ $this->accountAcl->resultView = true;
+ $this->accountAcl->resultEdit = true;
+
+ return;
+ }
+
+ $this->accountAcl->userInGroups = $this->getIsUserInGroups();
+ $this->accountAcl->userInUsers = ArrayUtil::checkInObjectArray($this->accountAclDto->getUsersId(), 'id', $userData->getId());
+
+ $this->accountAcl->resultView = ($userData->getId() === $this->accountAclDto->getUserId()
+ || $userData->getUserGroupId() === $this->accountAclDto->getUserGroupId()
+ || $this->accountAcl->userInUsers
+ || $this->accountAcl->userInGroups);
+
+ $this->accountAcl->resultEdit = ($userData->getId() === $this->accountAclDto->getUserId()
+ || $userData->getUserGroupId() === $this->accountAclDto->getUserGroupId()
+ || ($this->accountAcl->userInUsers && $this->accountAclDto->getOtherUserEdit() === 1)
+ || ($this->accountAcl->userInGroups && $this->accountAclDto->getOtherUserGroupEdit() === 1));
+ }
+
+ /**
+ * Comprobar si el usuario o el grupo del usuario se encuentran los grupos asociados a la
+ * cuenta.
+ *
+ * @return bool
+ */
+ protected function getIsUserInGroups()
+ {
+ $userData = $this->session->getUserData();
+ $userToUserGroupService = $this->dic->get(UserToUserGroupService::class);
+
+ // Comprobar si el usuario está vinculado desde el grupo principal de la cuenta
+ if ($userToUserGroupService->checkUserInGroup($this->accountAclDto->getUserGroupId(), $userData->getId())) {
+ return true;
+ }
+
+ // Grupos en los que se encuentra el usuario
+ $userGroupIds = $userToUserGroupService->getGroupsForUser($userData->getId());
+ $isAccountFullGroupAccess = $this->config->getConfigData()->isAccountFullGroupAccess();
+
+ // Comprobar si el grupo del usuario está vinculado desde los grupos secundarios de la cuenta
+ foreach ($this->accountAclDto->getUserGroupsId() as $userGroup) {
+ // Consultar el grupo principal del usuario
+ if ((int)$userGroup->id === $userData->getUserGroupId()
+ // o... permitir los grupos que no sean el principal del usuario?
+ || ($isAccountFullGroupAccess
+ // Comprobar si el usuario está vinculado desde los grupos secundarios de la cuenta
+ && ArrayUtil::checkInObjectArray($userGroupIds, 'userGroupId', $userGroup->id))
+ ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * compileShowAccess
+ */
+ protected function compileShowAccess()
+ {
+ // Mostrar historial
+ $this->accountAcl->showHistory = $this->acl->checkUserAccess(Acl::ACCOUNT_VIEW_HISTORY);
+
+ // Mostrar lista archivos
+ $this->accountAcl->showFiles = $this->acl->checkUserAccess(Acl::ACCOUNT_FILE);
+
+ // Mostrar acción de ver clave
+ $this->accountAcl->showViewPass = $this->accountAcl->checkAccountAccess(Acl::ACCOUNT_VIEW_PASS)
+ && $this->acl->checkUserAccess(Acl::ACCOUNT_VIEW_PASS);
+
+ // Mostrar acción de editar
+ $this->accountAcl->showEdit = $this->accountAcl->checkAccountAccess(Acl::ACCOUNT_EDIT)
+ && $this->acl->checkUserAccess(Acl::ACCOUNT_EDIT)
+ && !$this->accountAcl->isHistory();
+
+ // Mostrar acción de editar clave
+ $this->accountAcl->showEditPass = $this->accountAcl->checkAccountAccess(Acl::ACCOUNT_EDIT_PASS)
+ && $this->acl->checkUserAccess(Acl::ACCOUNT_EDIT_PASS)
+ && !$this->accountAcl->isHistory();
+
+ // Mostrar acción de eliminar
+ $this->accountAcl->showDelete = $this->accountAcl->checkAccountAccess(Acl::ACCOUNT_DELETE)
+ && $this->acl->checkUserAccess(Acl::ACCOUNT_DELETE);
+
+ // Mostrar acción de restaurar
+ $this->accountAcl->showRestore = $this->accountAcl->checkAccountAccess(Acl::ACCOUNT_EDIT)
+ && $this->acl->checkUserAccess(Acl::ACCOUNT_EDIT);
+
+ // Mostrar acción de enlace público
+ $this->accountAcl->showLink = $this->acl->checkUserAccess(Acl::PUBLICLINK_CREATE);
+
+ // Mostrar acción de ver cuenta
+ $this->accountAcl->showView = $this->accountAcl->checkAccountAccess(Acl::ACCOUNT_VIEW)
+ && $this->acl->checkUserAccess(Acl::ACCOUNT_VIEW);
+
+ // Mostrar acción de copiar cuenta
+ $this->accountAcl->showCopy = $this->accountAcl->checkAccountAccess(Acl::ACCOUNT_COPY)
+ && $this->acl->checkUserAccess(Acl::ACCOUNT_COPY);
+ }
+
+ /**
+ * Saves the ACL
+ *
+ * @param AccountAcl $accountAcl
+ * @return null|\SP\Storage\FileStorageInterface
+ */
+ public function saveAclInCache(AccountAcl $accountAcl)
+ {
+ try {
+ return $this->fileCache->save($this->getCacheFileForAcl($accountAcl->getAccountId(), $accountAcl->getActionId()), $accountAcl);
+ } catch (\RuntimeException $e) {
+ return null;
+ }
+ }
+
+ public function initialize()
+ {
+ $this->acl = $this->dic->get(Acl::class);
+ $this->fileCache = $this->dic->get(FileCache::class);
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Account/AccountCryptService.php b/lib/SP/Services/Account/AccountCryptService.php
index 327e8fd5..e0a2bc3b 100644
--- a/lib/SP/Services/Account/AccountCryptService.php
+++ b/lib/SP/Services/Account/AccountCryptService.php
@@ -62,7 +62,6 @@ class AccountCryptService extends Service
*
* @param UpdateMasterPassRequest $updateMasterPassRequest
* @throws ServiceException
- * @throws \SP\Core\Exceptions\InvalidArgumentException
*/
public function updateOldPass(UpdateMasterPassRequest $updateMasterPassRequest)
{
@@ -77,14 +76,14 @@ class AccountCryptService extends Service
$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);
+ throw new ServiceException(__u('Error en el módulo de encriptación'), ServiceException::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);
+ throw new ServiceException(__u('Error al obtener las claves de las cuentas'), ServiceException::ERROR);
}
$taskId = $this->request->getTask()->getTaskId();
@@ -171,7 +170,7 @@ class AccountCryptService extends Service
$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);
+ throw new ServiceException(__u('Errores al actualizar las claves de las cuentas'), ServiceException::ERROR, null, $e->getCode(), $e);
}
}
@@ -193,7 +192,7 @@ class AccountCryptService extends Service
$numAccounts = count($accounts);
if ($numAccounts === 0) {
- throw new ServiceException(__u('Error al obtener las claves de las cuentas'), SPException::ERROR);
+ throw new ServiceException(__u('Error al obtener las claves de las cuentas'), ServiceException::ERROR);
}
$configData = $this->config->getConfigData();
@@ -292,7 +291,7 @@ class AccountCryptService extends Service
$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);
+ throw new ServiceException(__u('Errores al actualizar las claves de las cuentas del histórico'), ServiceException::ERROR, null, $e->getCode(), $e);
}
}
diff --git a/lib/SP/Services/Account/AccountHistoryService.php b/lib/SP/Services/Account/AccountHistoryService.php
index 5ee9f629..fa40431a 100644
--- a/lib/SP/Services/Account/AccountHistoryService.php
+++ b/lib/SP/Services/Account/AccountHistoryService.php
@@ -27,6 +27,7 @@ namespace SP\Services\Account;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\AccountHistoryData;
+use SP\DataModel\ItemData;
use SP\DataModel\ItemSearchData;
use SP\Repositories\Account\AccountHistoryRepository;
use SP\Repositories\Account\AccountToUserGroupRepository;
@@ -90,7 +91,7 @@ class AccountHistoryService extends Service
/**
* @param $id
- * @return array
+ * @return ItemData[]
*/
public function getUsersByAccountId($id)
{
@@ -99,7 +100,7 @@ class AccountHistoryService extends Service
/**
* @param $id
- * @return array
+ * @return ItemData[]
*/
public function getUserGroupsByAccountId($id)
{
diff --git a/lib/SP/Services/Account/AccountSearchService.php b/lib/SP/Services/Account/AccountSearchService.php
index 84dff3ec..9f24bfe6 100644
--- a/lib/SP/Services/Account/AccountSearchService.php
+++ b/lib/SP/Services/Account/AccountSearchService.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -24,12 +24,10 @@
namespace SP\Services\Account;
-use SP\Account\AccountAcl;
use SP\Account\AccountSearchFilter;
use SP\Account\AccountSearchItem;
use SP\Config\ConfigData;
use SP\Core\Acl\Acl;
-use SP\Core\Session\Session;
use SP\DataModel\AccountSearchVData;
use SP\DataModel\Dto\AccountAclDto;
use SP\DataModel\Dto\AccountCache;
@@ -49,11 +47,14 @@ defined('APP_ROOT') || die();
class AccountSearchService extends Service
{
/**
- * Colores para resaltar las cuentas
- *
- * @var array
+ * Regex filter for special searching
*/
- private static $colors = [
+ const FILTERS_REGEX = '^(?:(?P user|group|file|owner|maingroup|expired|private):(?:"(?P[\w\.]+)")?)$';
+
+ /**
+ * Colores para resaltar las cuentas
+ */
+ const COLORS = [
'2196F3',
'03A9F4',
'00BCD4',
@@ -72,10 +73,6 @@ class AccountSearchService extends Service
'673AB7',
'3F51B5',
];
- /**
- * @var Session
- */
- protected $session;
/**
* @var ConfigData
*/
@@ -97,19 +94,6 @@ class AccountSearchService extends Service
*/
private $accountRepository;
- /**
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
- */
- protected function initialize()
- {
- $this->accountRepository = $this->dic->get(AccountRepository::class);
- $this->accountToTagRepository = $this->dic->get(AccountToTagRepository::class);
- $this->accountToUserRepository = $this->dic->get(AccountToUserRepository::class);
- $this->accountToUserGroupRepository = $this->dic->get(AccountToUserGroupRepository::class);
- $this->configData = $this->config->getConfigData();
- }
-
/**
* Procesar los resultados de la búsqueda y crear la variable que contiene los datos de cada cuenta
* a mostrar.
@@ -118,7 +102,6 @@ class AccountSearchService extends Service
* @return array
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
- * @throws \SP\Core\Dic\ContainerException
* @throws \SP\Core\Exceptions\SPException
*/
public function processSearchResults(AccountSearchFilter $accountSearchFilter)
@@ -133,25 +116,26 @@ class AccountSearchService extends Service
$accountLinkEnabled = $this->session->getUserData()->getPreferences()->isAccountLink() || $this->configData->isAccountLink();
$favorites = $this->dic->get(AccountFavoriteService::class)->getForUserId($this->session->getUserData()->getId());
+ $accountAclService = $this->dic->get(AccountAclService::class);
+
foreach ($accountSearchResponse->getData() as $accountSearchData) {
$cache = $this->getCacheForAccount($accountSearchData);
- $acccountAclDto = new AccountAclDto();
- $acccountAclDto->setAccountId($accountSearchData->getId());
- $acccountAclDto->setDateEdit($accountSearchData->getDateEdit());
- $acccountAclDto->setUserId($accountSearchData->getUserId());
- $acccountAclDto->setUserGroupId($accountSearchData->getUserGroupId());
- $acccountAclDto->setUsersId($cache->getUsers());
- $acccountAclDto->setUserGroupsId($cache->getUserGroups());
+ $accountAclDto = new AccountAclDto();
+ $accountAclDto->setAccountId($accountSearchData->getId());
+ $accountAclDto->setDateEdit($accountSearchData->getDateEdit());
+ $accountAclDto->setUserId($accountSearchData->getUserId());
+ $accountAclDto->setUserGroupId($accountSearchData->getUserGroupId());
+ $accountAclDto->setUsersId($cache->getUsers());
+ $accountAclDto->setUserGroupsId($cache->getUserGroups());
+ $accountAclDto->setOtherUserEdit($accountSearchData->getOtherUserEdit());
+ $accountAclDto->setOtherUserGroupEdit($accountSearchData->getOtherUserGroupEdit());
// Obtener la ACL de la cuenta
- $accountAcl = (new AccountAcl(Acl::ACCOUNT_SEARCH))->getAcl($acccountAclDto);
-
- // Guardar la ACL
- $this->session->setAccountAcl($accountAcl);
+ $accountAcl = $accountAclService->getAcl(Acl::ACCOUNT_SEARCH, $accountAclDto);
// Propiedades de búsqueda de cada cuenta
- $accountsSearchItem = new AccountSearchItem($accountSearchData, $accountAcl);
+ $accountsSearchItem = new AccountSearchItem($accountSearchData, $accountAcl, $this->configData);
if (!$accountSearchData->getIsPrivate()) {
$accountsSearchItem->setUsers($cache->getUsers());
@@ -184,17 +168,16 @@ class AccountSearchService extends Service
*/
private function analyzeQueryString($txt)
{
- if (!preg_match('/^(?Puser|group|file|owner|maingroup):"(?P[\w\.]+)"$/i', $txt, $filters)
- && !preg_match('/^(?Pexpired|private):$/i', $txt, $filters)
- ) {
+ if (!preg_match('/' . self::FILTERS_REGEX . '/i', $txt, $filters)) {
return [];
}
+ $text = isset($filters['text']) && empty($filters['text']) === false ? $filters['text'] : false;
+
switch ($filters['filter']) {
case 'user':
- $userData = $this->dic->get(UserService::class)->getByLogin($filters['text']);
-
- if (!is_object($userData)) {
+ if ($text === false
+ || is_object(($userData = $this->dic->get(UserService::class)->getByLogin($text))) === false) {
return [];
}
@@ -205,22 +188,19 @@ class AccountSearchService extends Service
];
break;
case 'owner':
- $userData = $this->dic->get(UserService::class)->getByLogin($filters['text']);
-
- if (!is_object($userData)) {
+ if ($text === false) {
return [];
}
return [
'type' => 'user',
- 'query' => 'A.userId = ?',
- 'values' => [$userData->getId()]
+ 'query' => 'A.userLogin LIKE ?',
+ 'values' => ['%' . $text . '%']
];
break;
case 'group':
- $userGroupData = $this->dic->get(UserGroupService::class)->getByName($filters['text']);
-
- if (!is_object($userGroupData)) {
+ if ($text === false
+ || is_object(($userGroupData = $this->dic->get(UserGroupService::class)->getByName($text))) === false) {
return [];
}
@@ -231,23 +211,21 @@ class AccountSearchService extends Service
];
break;
case 'maingroup':
- $userGroupData = $this->dic->get(UserGroupService::class)->getByName($filters['text']);
-
- if (!is_object($userGroupData)) {
+ if ($text === false) {
return [];
}
return [
'type' => 'group',
- 'query' => 'A.userGroupId = ?',
- 'values' => [$userGroupData->getId()]
+ 'query' => 'A.userGroupName = ?',
+ 'values' => ['%' . $text . '%']
];
break;
case 'file':
return [
'type' => 'file',
'query' => 'A.id IN (SELECT AF.accountId FROM AccountFile AF WHERE AF.name LIKE ?)',
- 'values' => ['%' . $filters[2] . '%']
+ 'values' => ['%' . $text . '%']
];
break;
case 'expired':
@@ -308,12 +286,25 @@ class AccountSearchService extends Service
|| !isset($accountColor[$id])
) {
// Se asigna el color de forma aleatoria a cada id
- $color = array_rand(self::$colors);
+ $color = array_rand(self::COLORS);
- $accountColor[$id] = '#' . self::$colors[$color];
+ $accountColor[$id] = '#' . self::COLORS[$color];
$this->session->setAccountColor($accountColor);
}
return $accountColor[$id];
}
+
+ /**
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
+ */
+ protected function initialize()
+ {
+ $this->accountRepository = $this->dic->get(AccountRepository::class);
+ $this->accountToTagRepository = $this->dic->get(AccountToTagRepository::class);
+ $this->accountToUserRepository = $this->dic->get(AccountToUserRepository::class);
+ $this->accountToUserGroupRepository = $this->dic->get(AccountToUserGroupRepository::class);
+ $this->configData = $this->config->getConfigData();
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Services/Account/AccountService.php b/lib/SP/Services/Account/AccountService.php
index 99c097dd..8c5294bc 100644
--- a/lib/SP/Services/Account/AccountService.php
+++ b/lib/SP/Services/Account/AccountService.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -25,11 +25,8 @@
namespace SP\Services\Account;
use Defuse\Crypto\Exception\CryptoException;
-use SP\Account\AccountAcl;
use SP\Account\AccountRequest;
use SP\Account\AccountUtil;
-use SP\Core\Acl\Acl;
-use SP\Core\Acl\ActionsInterface;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Session as CryptSession;
use SP\Core\Exceptions\QueryException;
@@ -38,7 +35,6 @@ use SP\Core\Session\Session;
use SP\DataModel\AccountData;
use SP\DataModel\Dto\AccountDetailsResponse;
use SP\DataModel\ItemSearchData;
-use SP\Log\Log;
use SP\Repositories\Account\AccountRepository;
use SP\Repositories\Account\AccountToTagRepository;
use SP\Repositories\Account\AccountToUserGroupRepository;
@@ -171,13 +167,12 @@ class AccountService extends Service implements AccountServiceInterface
* @return int
* @throws QueryException
* @throws SPException
- * @throws \SP\Core\Dic\ContainerException
* @throws \SP\Core\Exceptions\ConstraintException
*/
public function create(AccountRequest $accountRequest)
{
- $accountRequest->changePermissions = (new AccountAcl(ActionsInterface::ACCOUNT_EDIT))->isShowPermission();
- $accountRequest->userGroupId ?: $this->session->getUserData()->getUserGroupId();
+ $accountRequest->changePermissions = AccountAclService::getShowPermission($this->session->getUserData(), $this->session->getUserProfile());
+ $accountRequest->userGroupId = $accountRequest->userGroupId ?: $this->session->getUserData()->getUserGroupId();
$pass = $this->getPasswordEncrypted($accountRequest->pass);
@@ -250,13 +245,12 @@ class AccountService extends Service implements AccountServiceInterface
* @throws SPException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
- * @throws \SP\Core\Dic\ContainerException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Services\Config\ParameterNotFoundException
*/
public function update(AccountRequest $accountRequest)
{
- $accountRequest->changePermissions = (new AccountAcl(ActionsInterface::ACCOUNT_EDIT))->isShowPermission();
+ $accountRequest->changePermissions = AccountAclService::getShowPermission($this->session->getUserData(), $this->session->getUserProfile());
// Cambiar el grupo principal si el usuario es Admin
$accountRequest->changeUserGroup = ($accountRequest->userGroupId !== 0
@@ -405,29 +399,6 @@ class AccountService extends Service implements AccountServiceInterface
return $this;
}
- /**
- * Logs account action
- *
- * @param int $id
- * @param int $actionId
- * @return \SP\Core\Messages\LogMessage
- * @throws SPException
- * @throws \SP\Core\Dic\ContainerException
- */
- public function logAction($id, $actionId)
- {
- $account = $this->accountRepository->getById($id);
-
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(Acl::getActionInfo($actionId));
- $LogMessage->addDetails(__u('ID'), $id);
- $LogMessage->addDetails(__u('Cuenta'), $account->getClientName() . ' / ' . $account->getName());
- $Log->writeLog();
-
- return $LogMessage;
- }
-
/**
* @param $accountId
* @return array
diff --git a/lib/SP/Services/Account/AccountToTagService.php b/lib/SP/Services/Account/AccountToTagService.php
index 248027d6..3ea9a4ea 100644
--- a/lib/SP/Services/Account/AccountToTagService.php
+++ b/lib/SP/Services/Account/AccountToTagService.php
@@ -24,6 +24,7 @@
namespace SP\Services\Account;
+use SP\DataModel\ItemData;
use SP\Repositories\Account\AccountToTagRepository;
use SP\Services\Service;
@@ -50,7 +51,7 @@ class AccountToTagService extends Service
/**
* @param $id
- * @return array
+ * @return ItemData[]
*/
public function getTagsByAccountId($id)
{
diff --git a/lib/SP/Services/Export/XmlExportService.php b/lib/SP/Services/Export/XmlExportService.php
index b3312f64..6d0cbb47 100644
--- a/lib/SP/Services/Export/XmlExportService.php
+++ b/lib/SP/Services/Export/XmlExportService.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -485,9 +485,9 @@ class XmlExportService extends Service
$accountIV = $this->xml->createElement('key', $this->escapeChars($account->getKey()));
$tags = $this->xml->createElement('tags');
- foreach ($accountToTagService->getTagsByAccountId($account->getId()) as $id => $name) {
+ foreach ($accountToTagService->getTagsByAccountId($account->getId()) as $itemData) {
$tag = $this->xml->createElement('tag');
- $tag->setAttribute('id', $id);
+ $tag->setAttribute('id', $itemData->getId());
$tags->appendChild($tag);
}
diff --git a/lib/SP/Services/UserGroup/UserToUserGroupService.php b/lib/SP/Services/UserGroup/UserToUserGroupService.php
index cd7b4c3d..cbbf828d 100644
--- a/lib/SP/Services/UserGroup/UserToUserGroupService.php
+++ b/lib/SP/Services/UserGroup/UserToUserGroupService.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -39,15 +39,6 @@ class UserToUserGroupService extends Service
*/
protected $userToUserGroupRepository;
- /**
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
- */
- protected function initialize()
- {
- $this->userToUserGroupRepository = $this->dic->get(UserToUserGroupRepository::class);
- }
-
/**
* @param $id
* @return \SP\DataModel\UserToUserGroupData[]
@@ -95,4 +86,36 @@ class UserToUserGroupService extends Service
return $usersId;
}
+
+ /**
+ * Checks whether the user is included in the group
+ *
+ * @param $userId
+ * @param $groupId
+ * @return bool
+ */
+ public function checkUserInGroup($groupId, $userId)
+ {
+ return $this->userToUserGroupRepository->checkUserInGroup($groupId, $userId);
+ }
+
+ /**
+ * Returns the groups which the user belongs to
+ *
+ * @param $userId
+ * @return array
+ */
+ public function getGroupsForUser($userId)
+ {
+ return $this->userToUserGroupRepository->getGroupsForUser($userId);
+ }
+
+ /**
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
+ */
+ protected function initialize()
+ {
+ $this->userToUserGroupRepository = $this->dic->get(UserToUserGroupRepository::class);
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Storage/FileCache.php b/lib/SP/Storage/FileCache.php
index 3d06a129..b699a334 100644
--- a/lib/SP/Storage/FileCache.php
+++ b/lib/SP/Storage/FileCache.php
@@ -58,6 +58,12 @@ class FileCache implements FileStorageInterface
*/
public function save($path, $data)
{
+ $dir = dirname($path);
+
+ if (!is_dir($dir) && mkdir($dir, 0700, true) === false) {
+ throw new RuntimeException(sprintf(__('No es posible crear el directorio: %s'), $dir));
+ }
+
if (file_exists($path) && !is_writable($path)) {
throw new RuntimeException(sprintf(__('No es posible leer/escribir el archivo: %s'), $path));
}
@@ -68,4 +74,22 @@ class FileCache implements FileStorageInterface
return $this;
}
+
+ /**
+ * @param string $path
+ *
+ * @return FileStorageInterface
+ */
+ public function delete($path)
+ {
+ if (file_exists($path) && !is_writable($path)) {
+ throw new RuntimeException(sprintf(__('No es posible leer/escribir el archivo: %s'), $path));
+ }
+
+ if (!unlink($path)) {
+ throw new RuntimeException(sprintf(__('Error al eliminar el archivo: %s'), $path));
+ }
+
+ return $this;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Storage/FileStorageInterface.php b/lib/SP/Storage/FileStorageInterface.php
index 67e893dc..7d17521f 100644
--- a/lib/SP/Storage/FileStorageInterface.php
+++ b/lib/SP/Storage/FileStorageInterface.php
@@ -44,4 +44,11 @@ interface FileStorageInterface
* @return FileStorageInterface
*/
public function save($path, $data);
+
+ /**
+ * @param string $path
+ *
+ * @return mixed
+ */
+ public function delete($path);
}
\ No newline at end of file
diff --git a/lib/SP/Util/ArrayUtil.php b/lib/SP/Util/ArrayUtil.php
index e70c2f91..e56346d9 100644
--- a/lib/SP/Util/ArrayUtil.php
+++ b/lib/SP/Util/ArrayUtil.php
@@ -83,6 +83,10 @@ class ArrayUtil
*/
public static function checkInObjectArray(array $objectArray, $property, $value)
{
+ if (empty($objectArray)) {
+ return false;
+ }
+
foreach ($objectArray as $object) {
if (is_object($object)
&& isset($object->$property)
diff --git a/lib/SP/Util/ErrorUtil.php b/lib/SP/Util/ErrorUtil.php
index 5801c924..2543cd99 100644
--- a/lib/SP/Util/ErrorUtil.php
+++ b/lib/SP/Util/ErrorUtil.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -24,9 +24,12 @@
namespace SP\Util;
+use SP\Core\Acl\AccountPermissionException;
+use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Exceptions\FileNotFoundException;
use SP\Core\Exceptions\SPException;
use SP\Mvc\View\Template;
+use SP\Services\User\UpdatedMasterPassException;
/**
* Class ErrorUtil
@@ -45,6 +48,72 @@ class ErrorUtil
const ERR_OPERATION_NO_PERMISSION = 4;
const ERR_EXCEPTION = 5;
+ /**
+ * Establecer la plantilla de error con el código indicado.
+ *
+ * @param \SP\Mvc\View\Template $view
+ * @param \Exception $e
+ * @param string $replace Template replacement
+ */
+ public static function showExceptionInView(Template $view, \Exception $e, $replace = null)
+ {
+ switch (get_class($e)) {
+ case UpdatedMasterPassException::class:
+ self::showErrorInView($view, self::ERR_UPDATE_MPASS, $replace);
+ break;
+ case UnauthorizedPageException::class:
+ self::showErrorInView($view, self::ERR_PAGE_NO_PERMISSION, $replace);
+ break;
+ case AccountPermissionException::class:
+ self::showErrorInView($view, self::ERR_ACCOUNT_NO_PERMISSION, $replace);
+ break;
+ default;
+ self::showErrorInView($view, self::ERR_EXCEPTION, $replace);
+ }
+ }
+
+ /**
+ * Establecer la plantilla de error con el código indicado.
+ *
+ * @param \SP\Mvc\View\Template $view
+ * @param int $type int con el tipo de error
+ * @param string $replace Template replacement
+ */
+ public static function showErrorInView(Template $view, $type, $replace = null)
+ {
+ if ($replace === null) {
+ $view->resetTemplates();
+ $view->resetContentTemplates();
+ } else {
+ if ($view->hashContentTemplates()) {
+ $view->removeContentTemplate($replace);
+ $view->addContentTemplate('error', Template::PARTIALS_DIR);
+ } else {
+ $view->removeTemplate($replace);
+ $view->addTemplate('error', Template::PARTIALS_DIR);
+ }
+ }
+
+ $error = self::getErrorTypes($type);
+
+ $view->append('errors',
+ [
+ 'type' => SPException::WARNING,
+ 'description' => $error['txt'],
+ 'hint' => $error['hint']
+ ]);
+
+ try {
+ echo $view->render();
+ } catch (FileNotFoundException $e) {
+ processException($e);
+
+ echo $e->getMessage();
+ }
+
+ die();
+ }
+
/**
* Return error message by type
*
@@ -80,43 +149,13 @@ class ErrorUtil
]
];
+ if (!isset($errorTypes[$type])) {
+ return [
+ 'txt' => __('Se ha producido una excepción'),
+ 'hint' => __('Consulte con el administrador')
+ ];
+ }
+
return $errorTypes[$type];
}
-
- /**
- * Establecer la plantilla de error con el código indicado.
- *
- * @param \SP\Mvc\View\Template $view
- * @param int $type int con el tipo de error
- * @param string $replace Template replacement
- */
- public static function showErrorInView(Template $view, $type, $replace = null)
- {
- if ($replace === null) {
- $view->resetContentTemplates();
- } else {
- $view->removeContentTemplate($replace);
- }
-
- $view->addContentTemplate('error', Template::PARTIALS_DIR);
-
- $error = self::getErrorTypes($type);
-
- $view->append('errors',
- [
- 'type' => SPException::WARNING,
- 'description' => $error['txt'],
- 'hint' => $error['hint']
- ]);
-
- try {
- echo $view->render();
- } catch (FileNotFoundException $e) {
- processException($e);
-
- echo $e->getMessage();
- }
-
- die();
- }
}
\ No newline at end of file
diff --git a/lib/SP/Util/FileUtil.php b/lib/SP/Util/FileUtil.php
new file mode 100644
index 00000000..828bad44
--- /dev/null
+++ b/lib/SP/Util/FileUtil.php
@@ -0,0 +1,60 @@
+.
+ */
+
+namespace SP\Util;
+
+use FilesystemIterator;
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+
+/**
+ * Class FileUtil
+ *
+ * @package SP\Util
+ */
+class FileUtil
+{
+ /**
+ * Removes a directory in a recursive way
+ *
+ * @param $dir
+ * @return bool
+ * @see https://stackoverflow.com/a/7288067
+ */
+ public static function rmdir_recursive($dir)
+ {
+ if (!is_dir($dir)) {
+ return true;
+ }
+
+ $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST);
+
+ foreach ($it as $file) {
+ if ($file->isDir()) rmdir($file->getPathname());
+ else unlink($file->getPathname());
+ }
+
+ return rmdir($dir);
+ }
+}
\ No newline at end of file
diff --git a/public/js/app-actions.js b/public/js/app-actions.js
index 22802034..e495226f 100644
--- a/public/js/app-actions.js
+++ b/public/js/app-actions.js
@@ -245,7 +245,7 @@ sysPass.Actions = function (Common) {
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
- account.search();
+ account.search($obj);
});
}
}
@@ -272,7 +272,7 @@ sysPass.Actions = function (Common) {
if (json.status !== 0) {
Common.msg.out(json);
} else {
- var $container = $(json.data.html);
+ const $container = $(json.data.html);
showFloatingBox($container);
@@ -296,10 +296,10 @@ sysPass.Actions = function (Common) {
copyPass: function ($obj) {
log.info("account:copypass");
- var parentId = $obj.data("parent-id");
- var id = parentId === 0 ? $obj.data("item-id") : parentId;
+ const parentId = $obj.data("parent-id");
+ const id = parentId === 0 ? $obj.data("item-id") : parentId;
- var opts = Common.appRequests().getRequestOpts();
+ const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint;
opts.method = "get";
opts.async = false;
@@ -345,25 +345,29 @@ sysPass.Actions = function (Common) {
request: function ($obj) {
log.info("account:request");
- var opts = Common.appRequests().getRequestOpts();
- opts.url = ajaxUrl.entrypoint;
+ const opts = Common.appRequests().getRequestOpts();
+ opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route") + "/" + $obj.data("item-id");
opts.data = $obj.serialize();
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
+
+ if (json.status === 0 && json.data['nextAction'] !== undefined) {
+ getContent({r: json.data.nextAction['nextAction']}, "account");
+ }
});
},
// Mostrar los botones de acción en los resultados de búsqueda
menu: function ($obj) {
$obj.hide();
- var actions = $obj.parent().children(".actions-optional");
+ const actions = $obj.parent().children(".actions-optional");
actions.show(250);
},
sort: function ($obj) {
log.info("account:sort");
- var $frmSearch = $("#frmSearch");
+ const $frmSearch = $("#frmSearch");
$frmSearch.find("input[name=\"skey\"]").val($obj.data("key"));
$frmSearch.find("input[name=\"sorder\"]").val($obj.data("dir"));
@@ -374,8 +378,8 @@ sysPass.Actions = function (Common) {
editPass: function ($obj) {
log.info("account:editpass");
- var parentId = $obj.data("parent-id");
- var itemId = parentId === undefined ? $obj.data("item-id") : parentId;
+ const parentId = $obj.data("parent-id");
+ const itemId = parentId === undefined ? $obj.data("item-id") : parentId;
getContent(Common.appRequests().getRouteForQuery($obj.data("action-route"), itemId), "account");
},
@@ -425,7 +429,7 @@ sysPass.Actions = function (Common) {
}
const opts = Common.appRequests().getRequestOpts();
- opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route");
+ opts.url = ajaxUrl.entrypoint + "?r=" + $frmSearch.data("action-route");
opts.method = "get";
opts.data = $frmSearch.serialize();
@@ -1008,6 +1012,7 @@ sysPass.Actions = function (Common) {
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint;
+ opts.method = "get";
opts.data = {
r: $obj.data("action-route") + "/" + itemId,
sk: Common.sk.get(),
@@ -1386,17 +1391,14 @@ sysPass.Actions = function (Common) {
log.info("notification:delete");
grid.delete($obj, function (items) {
- if (items.length > 0) {
- items.join(",");
- } else {
- items = $obj.data("item-id");
- }
+ const itemId = $obj.data("item-id");
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint;
opts.method = "get";
opts.data = {
- r: $obj.data("action-route") + "/" + items,
+ r: $obj.data("action-route") + (itemId ? "/" + itemId : ''),
+ items: items,
sk: Common.sk.get(),
isAjax: 1
};
diff --git a/public/js/app-actions.min.js b/public/js/app-actions.min.js
index 12b85678..d06792ea 100644
--- a/public/js/app-actions.min.js
+++ b/public/js/app-actions.min.js
@@ -4,42 +4,42 @@ $jscomp.polyfill("Array.prototype.find",function(b){return b?b:function(b,l){ret
sysPass.Actions=function(b){var e=b.log,l=0,f={entrypoint:"/index.php"};Object.freeze(f);var g=function(a,c){e.info("getContent");a.isAjax=1;var d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.method="get";d.type="html";d.addHistory=!0;d.data=a;b.appRequests().getActionCall(d,function(a){var d=$("#content");d.empty().html(a);a=b.triggers().views;a.common(d);if(void 0!==c&&"function"===typeof a[c])a[c]();d=$(".mdl-layout__content");0 "),h=d.find("img");if(0===h.length)return m(c);h.hide();$.magnificPopup.open({items:{src:d,type:"inline"},callbacks:{open:function(){var a=
this;h.on("click",function(){a.close()});setTimeout(function(){var a=b.resizeImage(h);d.css({backgroundColor:"#fff",width:a.width,height:"auto"});h.show("slow")},500)}}})},p={view:function(a){e.info("account:show");g(b.appRequests().getRouteForQuery(a.data("action-route"),a.data("item-id")),"account")},viewHistory:function(a){e.info("account:showHistory");g(b.appRequests().getRouteForQuery(a.data("action-route"),a.val()),"account")},edit:function(a){e.info("account:edit");g(b.appRequests().getRouteForQuery(a.data("action-route"),
-a.data("item-id")),"account")},"delete":function(a){e.info("account:delete");var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(d){d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.data={r:"account/saveDelete/"+a.data("item-id"),sk:b.sk.get()};b.appRequests().getActionCall(d,function(a){b.msg.out(a);
-p.search()})}}})},viewPass:function(a){e.info("account:showpass");var c=a.data("parent-id")||0,c=0===c?a.data("item-id"):c,d=a.data("history")||0,h=b.appRequests().getRequestOpts();h.url=f.entrypoint;h.method="get";h.data={r:a.data("action-route")+"/"+c+"/"+d,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(h,function(a){0!==a.status?b.msg.out(a):(a=$(a.data.html),m(a),l=setTimeout(function(){$.magnificPopup.close()},3E4),a.on("mouseleave",function(){clearTimeout(l);l=setTimeout(function(){$.magnificPopup.close()},
+a.data("item-id")),"account")},"delete":function(a){e.info("account:delete");var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(d){d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.data={r:"account/saveDelete/"+a.data("item-id"),sk:b.sk.get()};b.appRequests().getActionCall(d,function(d){b.msg.out(d);
+p.search(a)})}}})},viewPass:function(a){e.info("account:showpass");var c=a.data("parent-id")||0,c=0===c?a.data("item-id"):c,d=a.data("history")||0,h=b.appRequests().getRequestOpts();h.url=f.entrypoint;h.method="get";h.data={r:a.data("action-route")+"/"+c+"/"+d,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(h,function(a){0!==a.status?b.msg.out(a):(a=$(a.data.html),m(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 c=a.data("parent-id"),c=0===c?a.data("item-id"):c,d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.method="get";d.async=!1;d.data={r:a.data("action-route")+"/"+c+"/"+a.data("history"),sk:b.sk.get(),isAjax:1};return b.appRequests().getActionCall(d)},copy:function(a){e.info("account:copy");g(b.appRequests().getRouteForQuery(a.data("action-route"),a.data("item-id")),"account")},saveFavorite:function(a,
-c){e.info("account:saveFavorite");var d="on"===a.data("status"),h=d?a.data("action-route-off"):a.data("action-route-on"),q=b.appRequests().getRequestOpts();q.url=f.entrypoint;q.data={r:h+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(q,function(h){b.msg.out(h);0===h.status&&(a.data("status",d?"off":"on"),"function"===typeof c&&c())})},request:function(a){e.info("account:request");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.data=a.serialize();b.appRequests().getActionCall(c,
-function(a){b.msg.out(a)})},menu:function(a){a.hide();a.parent().children(".actions-optional").show(250)},sort:function(a){e.info("account:sort");var b=$("#frmSearch");b.find('input[name="skey"]').val(a.data("key"));b.find('input[name="sorder"]').val(a.data("dir"));b.find('input[name="start"]').val(a.data("start"));p.search()},editPass:function(a){e.info("account:editpass");var c=a.data("parent-id"),c=void 0===c?a.data("item-id"):c;g(b.appRequests().getRouteForQuery(a.data("action-route"),c),"account")},
-saveEditRestore:function(a){e.info("account:restore");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route")+"/"+a.data("history-id")+"/"+a.data("item-id");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);void 0!==a.data.itemId&&void 0!==a.data.nextAction&&g(b.appRequests().getRouteForQuery(a.data.nextAction,a.data.itemId),"account")})},listFiles:function(a){e.info("account:getfiles");var c=b.appRequests().getRequestOpts();c.method="get";
-c.type="html";c.url=f.entrypoint;c.data={r:a.data("action-route")+"/"+a.data("item-id"),del:a.data("delete"),sk:b.sk.get()};b.appRequests().getActionCall(c,function(b){a.html(b)})},search:function(a){e.info("account:search");var c=$("#frmSearch");c.find("input[name='sk']").val(b.sk.get());c.find("input[name='skey']").val();c.find("input[name='sorder']").val();void 0!==a&&c.find("input[name='start']").val(0);var d=b.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");d.method=
-"get";d.data=c.serialize();b.appRequests().getActionCall(d,function(a){10===a.status&&b.msg.out(a);b.sk.set(a.data.sk);$("#res-content").empty().html(a.data.html)})},save:function(a){e.info("account:save");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route")+"/"+a.data("item-id");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);void 0!==a.data.itemId&&void 0!==a.data.nextAction&&g(b.appRequests().getRouteForQuery(a.data.nextAction,a.data.itemId),
-"account")})}},r={get:function(a){e.info("items:get");var c=a[0].selectize;c.clearOptions();c.load(function(d){var h=b.appRequests().getRequestOpts();h.url=f.entrypoint;h.method="get";h.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:a.data("sk")};b.appRequests().getActionCall(h,function(h){d(h.data);c.setValue(a.data("selected-id"),!0);b.appTriggers().updateFormHash()})})},update:function(a){e.info("items:update");var c=$("#"+a.data("item-dst"))[0].selectize;c.clearOptions();c.load(function(d){var c=
-b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={r:a.data("item-route"),sk:b.sk.get()};b.appRequests().getActionCall(c,function(a){d(a)})})}},t={logout:function(){b.redirect("index.php?r=login/logout")},login:function(a){e.info("main:login");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("route");c.method="get";c.data=a.serialize();b.appRequests().getActionCall(c,function(d){var c=$(".extra-hidden");switch(d.status){case 0:b.redirect(d.data.url);break;
-case 2:b.msg.out(d);a.find("input[type='text'],input[type='password']").val("");a.find("input:first").focus();0";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();
-b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c=a.find("input[name='useTask']");var d=$("#taskStatus");d.empty().html(b.config().LANG[62]);if(0"+b.config().LANG[62];d.empty().html(a)})}c=
-b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.useFullLoading=!0;c.data=a.serialize();b.appRequests().getActionCall(c,function(c){b.msg.out(c);0!==c.status?a.find(":input[name=h]").val(""):(void 0!==e&&e.close(),setTimeout(function(){b.redirect("index.php")},5E3))})}}})},getUpdates:function(){e.info("main:getUpdates");var a=b.appRequests().getRequestOpts();a.url=f.entrypoint;a.type="html";a.method="get";a.timeout=1E4;a.useLoading=!1;a.data={isAjax:1};b.appRequests().getActionCall(a,
-function(a){$("#updates").html(a);void 0!==componentHandler&&componentHandler.upgradeDom()},function(){$("#updates").html("!")})}},k={state:{tab:{index:0,refresh:!0,route:""},itemId:0,update:function(a){var b=$("#content").find("[id^='tabs-'].is-active");0",e=a.data("selection"),f=[];if(e&&($(e).find(".is-selected").each(function(){f.push($(this).data("item-id"))}),
-0===f.length))return;mdlDialog().show({text:d,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(a){a.preventDefault();"function"===typeof c&&c(f)}}})}};return{doAction:function(a,c){var d={r:a.r+(void 0!==a.itemId?"/"+a.itemId:""),isAjax:1},e=b.appRequests().getRequestOpts();e.url=f.entrypoint;e.method="get";e.type="html";e.addHistory=!0;e.data=d;b.appRequests().getActionCall(e,function(a){var d=
-$("#content");d.empty().html(a);a=b.triggers().views;a.common(d);if(void 0!==c&&"function"===typeof a[c])a[c]();d=$(".mdl-layout__content");0";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";
-c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get()};b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&p.listFiles($("#list-account-files"))})}}})}},checks:{wiki:function(a){e.info("checks:wiki");a=$(a.data("src"));a.find("[name='sk']").val(b.sk.get());var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&$("#dokuWikiResCheck").html(a.data)})}},config:{save:function(a){e.info("config:save");
-k.save(a)},masterpass:function(a){var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(c){c.preventDefault();b.msg.error(b.config().LANG[44]);a.find(":input[type=password]").val("")}},positive:{title:b.config().LANG[43],onClick:function(c){c=a.find("input[name='useTask']");var d=$("#taskStatus");d.empty().html(b.config().LANG[62]);0"+b.config().LANG[62];d.empty().html(a)}));c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.useFullLoading=!0;c.data=a.serialize();b.appRequests().getActionCall(c,function(c){b.msg.out(c);a.find(":input[type=password]").val("");void 0!==task&&task.close()})}}})},backup:function(a){e.info("config:backup");
-k.state.update(a);var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.useFullLoading=!0;c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&g({r:k.state.tab.route,tabIndex:k.state.tab.index})})},"export":function(a){e.info("config:export");k.save(a)},"import":function(a){e.info("config:import");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.data=a.serialize();b.appRequests().getActionCall(c,
-function(a){b.msg.out(a)})},refreshMpass:function(a){e.info("config:import");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.data={sk:a.data("sk"),isAjax:1};b.appRequests().getActionCall(c,function(a){b.msg.out(a)})}},main:t,user:{showSettings:function(a){e.info("user:showSettings");g({r:a.data("action-route")},"userSettings")},saveSettings:function(a){e.info("user:saveSettings");k.save(a)},password:function(a){e.info("user:password");var c=b.appRequests().getRequestOpts();
-c.type="html";c.method="get";c.url=f.entrypoint;c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(a){0===a.length?t.logout():m(a)})},passreset:function(a){e.info("user:passreset");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"/?r="+a.data("action-route");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&setTimeout(function(){b.redirect("index.php")},2E3)})}},link:{save:function(a){e.info("link:save");
-var c=a.data("item-id"),d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.data={r:a.data("action-route"),accountId:c,notify:0,sk:b.sk.get(),isAjax:1};var h='";mdlDialog().show({text:h,negative:{title:b.config().LANG[44],onClick:function(e){e.preventDefault();b.appRequests().getActionCall(d,function(d){b.msg.out(d);0===d.status&&g({r:a.data("action-next")+"/"+c})})}},positive:{title:b.config().LANG[43],onClick:function(e){e.preventDefault();
-d.data.notify=1;b.appRequests().getActionCall(d,function(d){b.msg.out(d);0===d.status&&g({r:a.data("action-next")+"/"+c})})}}})},refresh:function(a){e.info("link:refresh");k.state.update(a);var c=a.data("item-id"),d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.data={r:a.data("action-route")+"/"+c,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(d,function(d){b.msg.out(d);0===d.status&&((d=a.data("action-next"))?g({r:d+"/"+c}):g({r:k.state.tab.route,tabIndex:k.state.tab.index}))})}},
-eventlog:{search:function(a){e.info("eventlog:search");n.search(a)},nav:function(a){e.info("eventlog:nav");n.nav(a)},clear:function(a){var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c.preventDefault();c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");
-c.method="get";c.data={sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&g({r:a.data("nextaction")});b.sk.set(c.csrf)})}}})}},ajaxUrl:f,plugin:{toggle:function(a){e.info("plugin:enable");a={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:b.sk.get(),activeTab:a.data("activetab")};var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.data=a;b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&setTimeout(function(){b.redirect("index.php")},
-2E3)})},reset:function(a){e.info("plugin:reset");var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c.preventDefault();c={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:b.sk.get(),activeTab:a.data("activetab")};var d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.data=
-c;b.appRequests().getActionCall(d,function(a){b.msg.out(a)})}}})}},notification:{check:function(a){e.info("notification:check");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&g({r:a.data("nextaction")});b.sk.set(c.csrf)})},search:function(a){e.info("notification:search");n.search(a)},show:function(a){e.info("notification:show");
-u.show(a)},save:function(a){e.info("notification:save");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("route");c.data=a.serialize();b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&(g({r:a.data("nextaction")}),$.magnificPopup.close())})},"delete":function(a){e.info("notification:delete");n["delete"](a,function(c){0";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c=
-$(a.data("src"));c.find("[name='sk']").val(b.sk.get());var d=b.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");d.data=c.serialize();b.appRequests().getActionCall(d,function(a){b.msg.out(a)})}}})}}}};
+c){e.info("account:saveFavorite");var d="on"===a.data("status"),h=d?a.data("action-route-off"):a.data("action-route-on"),q=b.appRequests().getRequestOpts();q.url=f.entrypoint;q.data={r:h+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(q,function(h){b.msg.out(h);0===h.status&&(a.data("status",d?"off":"on"),"function"===typeof c&&c())})},request:function(a){e.info("account:request");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route")+"/"+
+a.data("item-id");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&void 0!==a.data.nextAction&&g({r:a.data.nextAction.nextAction},"account")})},menu:function(a){a.hide();a.parent().children(".actions-optional").show(250)},sort:function(a){e.info("account:sort");var b=$("#frmSearch");b.find('input[name="skey"]').val(a.data("key"));b.find('input[name="sorder"]').val(a.data("dir"));b.find('input[name="start"]').val(a.data("start"));p.search()},editPass:function(a){e.info("account:editpass");
+var c=a.data("parent-id"),c=void 0===c?a.data("item-id"):c;g(b.appRequests().getRouteForQuery(a.data("action-route"),c),"account")},saveEditRestore:function(a){e.info("account:restore");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route")+"/"+a.data("history-id")+"/"+a.data("item-id");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);void 0!==a.data.itemId&&void 0!==a.data.nextAction&&g(b.appRequests().getRouteForQuery(a.data.nextAction,
+a.data.itemId),"account")})},listFiles:function(a){e.info("account:getfiles");var c=b.appRequests().getRequestOpts();c.method="get";c.type="html";c.url=f.entrypoint;c.data={r:a.data("action-route")+"/"+a.data("item-id"),del:a.data("delete"),sk:b.sk.get()};b.appRequests().getActionCall(c,function(b){a.html(b)})},search:function(a){e.info("account:search");var c=$("#frmSearch");c.find("input[name='sk']").val(b.sk.get());c.find("input[name='skey']").val();c.find("input[name='sorder']").val();void 0!==
+a&&c.find("input[name='start']").val(0);a=b.appRequests().getRequestOpts();a.url=f.entrypoint+"?r="+c.data("action-route");a.method="get";a.data=c.serialize();b.appRequests().getActionCall(a,function(a){10===a.status&&b.msg.out(a);b.sk.set(a.data.sk);$("#res-content").empty().html(a.data.html)})},save:function(a){e.info("account:save");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route")+"/"+a.data("item-id");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);
+void 0!==a.data.itemId&&void 0!==a.data.nextAction&&g(b.appRequests().getRouteForQuery(a.data.nextAction,a.data.itemId),"account")})}},r={get:function(a){e.info("items:get");var c=a[0].selectize;c.clearOptions();c.load(function(d){var h=b.appRequests().getRequestOpts();h.url=f.entrypoint;h.method="get";h.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:a.data("sk")};b.appRequests().getActionCall(h,function(h){d(h.data);c.setValue(a.data("selected-id"),!0);b.appTriggers().updateFormHash()})})},
+update:function(a){e.info("items:update");var c=$("#"+a.data("item-dst"))[0].selectize;c.clearOptions();c.load(function(d){var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={r:a.data("item-route"),sk:b.sk.get()};b.appRequests().getActionCall(c,function(a){d(a)})})}},t={logout:function(){b.redirect("index.php?r=login/logout")},login:function(a){e.info("main:login");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("route");c.method="get";c.data=a.serialize();
+b.appRequests().getActionCall(c,function(d){var c=$(".extra-hidden");switch(d.status){case 0:b.redirect(d.data.url);break;case 2:b.msg.out(d);a.find("input[type='text'],input[type='password']").val("");a.find("input:first").focus();0";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c=a.find("input[name='useTask']");var d=$("#taskStatus");d.empty().html(b.config().LANG[62]);if(0"+b.config().LANG[62];d.empty().html(a)})}c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.useFullLoading=!0;c.data=a.serialize();b.appRequests().getActionCall(c,function(c){b.msg.out(c);0!==c.status?a.find(":input[name=h]").val(""):(void 0!==e&&e.close(),setTimeout(function(){b.redirect("index.php")},5E3))})}}})},getUpdates:function(){e.info("main:getUpdates");var a=b.appRequests().getRequestOpts();
+a.url=f.entrypoint;a.type="html";a.method="get";a.timeout=1E4;a.useLoading=!1;a.data={isAjax:1};b.appRequests().getActionCall(a,function(a){$("#updates").html(a);void 0!==componentHandler&&componentHandler.upgradeDom()},function(){$("#updates").html("!")})}},k={state:{tab:{index:0,refresh:!0,route:""},itemId:0,update:function(a){var b=$("#content").find("[id^='tabs-'].is-active");0",e=a.data("selection"),f=[];if(e&&($(e).find(".is-selected").each(function(){f.push($(this).data("item-id"))}),0===f.length))return;mdlDialog().show({text:d,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(a){a.preventDefault();"function"===typeof c&&c(f)}}})}};return{doAction:function(a,c){var d={r:a.r+(void 0!==a.itemId?"/"+a.itemId:""),isAjax:1},e=b.appRequests().getRequestOpts();
+e.url=f.entrypoint;e.method="get";e.type="html";e.addHistory=!0;e.data=d;b.appRequests().getActionCall(e,function(a){var d=$("#content");d.empty().html(a);a=b.triggers().views;a.common(d);if(void 0!==c&&"function"===typeof a[c])a[c]();d=$(".mdl-layout__content");0";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();
+b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get()};b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&p.listFiles($("#list-account-files"))})}}})}},checks:{wiki:function(a){e.info("checks:wiki");a=$(a.data("src"));a.find("[name='sk']").val(b.sk.get());var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;
+c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&$("#dokuWikiResCheck").html(a.data)})}},config:{save:function(a){e.info("config:save");k.save(a)},masterpass:function(a){var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(c){c.preventDefault();b.msg.error(b.config().LANG[44]);a.find(":input[type=password]").val("")}},positive:{title:b.config().LANG[43],
+onClick:function(c){c=a.find("input[name='useTask']");var d=$("#taskStatus");d.empty().html(b.config().LANG[62]);0"+b.config().LANG[62];d.empty().html(a)}));c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.useFullLoading=
+!0;c.data=a.serialize();b.appRequests().getActionCall(c,function(c){b.msg.out(c);a.find(":input[type=password]").val("");void 0!==task&&task.close()})}}})},backup:function(a){e.info("config:backup");k.state.update(a);var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.useFullLoading=!0;c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&g({r:k.state.tab.route,tabIndex:k.state.tab.index})})},"export":function(a){e.info("config:export");
+k.save(a)},"import":function(a){e.info("config:import");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a)})},refreshMpass:function(a){e.info("config:import");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.data={sk:a.data("sk"),isAjax:1};b.appRequests().getActionCall(c,function(a){b.msg.out(a)})}},main:t,user:{showSettings:function(a){e.info("user:showSettings");
+g({r:a.data("action-route")},"userSettings")},saveSettings:function(a){e.info("user:saveSettings");k.save(a)},password:function(a){e.info("user:password");var c=b.appRequests().getRequestOpts();c.type="html";c.method="get";c.url=f.entrypoint;c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(a){0===a.length?t.logout():m(a)})},passreset:function(a){e.info("user:passreset");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+
+"/?r="+a.data("action-route");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&setTimeout(function(){b.redirect("index.php")},2E3)})}},link:{save:function(a){e.info("link:save");var c=a.data("item-id"),d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.data={r:a.data("action-route"),accountId:c,notify:0,sk:b.sk.get(),isAjax:1};var h='";mdlDialog().show({text:h,negative:{title:b.config().LANG[44],
+onClick:function(e){e.preventDefault();b.appRequests().getActionCall(d,function(d){b.msg.out(d);0===d.status&&g({r:a.data("action-next")+"/"+c})})}},positive:{title:b.config().LANG[43],onClick:function(e){e.preventDefault();d.data.notify=1;b.appRequests().getActionCall(d,function(d){b.msg.out(d);0===d.status&&g({r:a.data("action-next")+"/"+c})})}}})},refresh:function(a){e.info("link:refresh");k.state.update(a);var c=a.data("item-id"),d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.method=
+"get";d.data={r:a.data("action-route")+"/"+c,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(d,function(d){b.msg.out(d);0===d.status&&((d=a.data("action-next"))?g({r:d+"/"+c}):g({r:k.state.tab.route,tabIndex:k.state.tab.index}))})}},eventlog:{search:function(a){e.info("eventlog:search");n.search(a)},nav:function(a){e.info("eventlog:nav");n.nav(a)},clear:function(a){var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],
+onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c.preventDefault();c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.method="get";c.data={sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&g({r:a.data("nextaction")});b.sk.set(c.csrf)})}}})}},ajaxUrl:f,plugin:{toggle:function(a){e.info("plugin:enable");a={itemId:a.data("item-id"),actionId:a.data("action-id"),
+sk:b.sk.get(),activeTab:a.data("activetab")};var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.data=a;b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&setTimeout(function(){b.redirect("index.php")},2E3)})},reset:function(a){e.info("plugin:reset");var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],
+onClick:function(c){c.preventDefault();c={itemId:a.data("item-id"),actionId:a.data("action-id"),sk:b.sk.get(),activeTab:a.data("activetab")};var d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.data=c;b.appRequests().getActionCall(d,function(a){b.msg.out(a)})}}})}},notification:{check:function(a){e.info("notification:check");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,
+function(c){b.msg.out(c);0===c.status&&g({r:a.data("nextaction")});b.sk.set(c.csrf)})},search:function(a){e.info("notification:search");n.search(a)},show:function(a){e.info("notification:show");u.show(a)},save:function(a){e.info("notification:save");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("route");c.data=a.serialize();b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&(g({r:a.data("nextaction")}),$.magnificPopup.close())})},"delete":function(a){e.info("notification:delete");
+n["delete"](a,function(c){var d=a.data("item-id"),e=b.appRequests().getRequestOpts();e.url=f.entrypoint;e.method="get";e.data={r:a.data("action-route")+(d?"/"+d:""),items:c,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(e,function(c){b.msg.out(c);g({r:a.data("nextaction")})})})},getActive:function(){e.info("notification:getActive");var a=b.appRequests().getRequestOpts();a.url=f.entrypoint;a.method="get";a.data={r:"items/notifications",sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(a,
+function(a){return a})},nav:function(a){e.info("eventlog:nav");n.nav(a)}},wiki:{show:function(a){e.info("wiki:show");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={pageName:a.data("pagename"),actionId:a.data("action-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(a){0!==a.status?b.msg.out(a):m(a.data.html)})}},items:r,ldap:{check:function(a){e.info("ldap:check");var c=$(a.data("src"));c.find("[name='sk']").val(b.sk.get());var d=b.appRequests().getRequestOpts();
+d.url=f.entrypoint+"?r="+a.data("action-route");d.data=c.serialize();b.appRequests().getActionCall(d,function(a){b.msg.out(a);0===a.status&&void 0!==a.data.template&&void 0!==a.data.items&&m(a.data.template,{open:function(){var c=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){c.append(b.appTheme().html.getList(a.items,a.icon))})}})})},"import":function(a){e.info("ldap:import");var c='";mdlDialog().show({text:c,
+negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c=$(a.data("src"));c.find("[name='sk']").val(b.sk.get());var d=b.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");d.data=c.serialize();b.appRequests().getActionCall(d,function(a){b.msg.out(a)})}}})}}}};
diff --git a/public/js/app-main.js b/public/js/app-main.js
index 93bd1e0d..e4214acf 100644
--- a/public/js/app-main.js
+++ b/public/js/app-main.js
@@ -653,10 +653,11 @@ sysPass.Main = function () {
const setupCallbacks = function () {
log.info("setupCallbacks");
- const page = $("#container").data("page");
+ const $container = $("#container");
+ const page = $container.data("page");
if (page !== "" && typeof appTriggers.views[page] === "function") {
- appTriggers.views[page]();
+ appTriggers.views[page]($container);
}
if ($("footer").length > 0) {
diff --git a/public/js/app-main.min.js b/public/js/app-main.min.js
index f342e8ab..8728fc9b 100644
--- a/public/js/app-main.min.js
+++ b/public/js/app-main.min.js
@@ -1,5 +1,5 @@
var $jscomp={scope:{},findInternal:function(b,l,h){b instanceof String&&(b=String(b));for(var m=b.length,n=0;n"+a.messages.join(" "));switch(b){case 0:e.ok(d);break;case 1:e.error(d);break;case 2:e.warn(d);break;case 10:t.main.logout();break;case 100:e.ok(d);e.sticky(d);break;case 101:e.error(d);e.sticky(d);break;case 102:e.warn(d);e.sticky(d);break;default:e.error(d)}}},html:{error:function(a){return'Oops... '+c.LANG[1]+
-" "+a+" "}}};Object.freeze(e);String.format||(String.format=function(a){var b=Array.prototype.slice.call(arguments,1);return a.replace(/{(\d+)}/g,function(a,c){return"undefined"!==typeof b[c]?b[c]:a})});var M=function(){f.info("getEnvironment");var a=window.location.pathname.split("/");c.APP_ROOT=window.location.protocol+"//"+window.location.host+function(){for(var b="",c=1;c<=a.length-2;c++)b+="/"+a[c];return b}();var b=v.getRequestOpts();b.url="/index.php?r=bootstrap/getEnvironment";b.method=
-"get";b.useLoading=!1;b.data={isAjax:1};return v.getActionCall(b,function(a){c.LANG=a.lang;c.PK=a.pk;c.CHECK_UPDATES=a.check_updates;c.CRYPT.setPublicKey(a.pk);c.TIMEZONE=a.timezone;c.LOCALE=a.locale;c.DEBUG=a.debug;c.MAX_FILE_SIZE=parseInt(a.max_file_size);c.COOKIES_ENABLED=a.cookies_enabled;c.PLUGINS=a.plugins;c.LOGGEDIN=a.loggedin;c.AUTHBASIC_AUTOLOGIN=a.authbasic_autologin;c.IMPORT_ALLOWED_EXTS=a.import_allowed_exts;c.FILES_ALLOWED_EXTS=a.files_allowed_exts;Object.freeze(c)})},H=function(a){for(var b=
+hideEasing:"linear",showMethod:"fadeIn",hideMethod:"fadeOut"};var L=function(){f.info("setupCallbacks");var a=$("#container"),b=a.data("page");if(""!==b&&"function"===typeof p.views[b])p.views[b](a);0<$("footer").length&&p.views.footer();$("#btnBack").click(function(){A("index.php")});p.bodyHooks()},e={ok:function(a){toastr.success(a)},error:function(a){toastr.error(a)},warn:function(a){toastr.warning(a)},info:function(a){toastr.info(a)},sticky:function(a,b){var d={timeOut:0};"function"===typeof b&&
+(d.onHidden=b);toastr.warning(a,c.LANG[60],d)},out:function(a){if("object"===typeof a){var b=a.status,d=a.description;void 0!==a.messages&&0"+a.messages.join(" "));switch(b){case 0:e.ok(d);break;case 1:e.error(d);break;case 2:e.warn(d);break;case 10:t.main.logout();break;case 100:e.ok(d);e.sticky(d);break;case 101:e.error(d);e.sticky(d);break;case 102:e.warn(d);e.sticky(d);break;default:e.error(d)}}},html:{error:function(a){return'Oops... '+
+c.LANG[1]+" "+a+" "}}};Object.freeze(e);String.format||(String.format=function(a){var b=Array.prototype.slice.call(arguments,1);return a.replace(/{(\d+)}/g,function(a,c){return"undefined"!==typeof b[c]?b[c]:a})});var M=function(){f.info("getEnvironment");var a=window.location.pathname.split("/");c.APP_ROOT=window.location.protocol+"//"+window.location.host+function(){for(var b="",c=1;c<=a.length-2;c++)b+="/"+a[c];return b}();var b=v.getRequestOpts();b.url="/index.php?r=bootstrap/getEnvironment";
+b.method="get";b.useLoading=!1;b.data={isAjax:1};return v.getActionCall(b,function(a){c.LANG=a.lang;c.PK=a.pk;c.CHECK_UPDATES=a.check_updates;c.CRYPT.setPublicKey(a.pk);c.TIMEZONE=a.timezone;c.LOCALE=a.locale;c.DEBUG=a.debug;c.MAX_FILE_SIZE=parseInt(a.max_file_size);c.COOKIES_ENABLED=a.cookies_enabled;c.PLUGINS=a.plugins;c.LOGGEDIN=a.loggedin;c.AUTHBASIC_AUTOLOGIN=a.authbasic_autologin;c.IMPORT_ALLOWED_EXTS=a.import_allowed_exts;c.FILES_ALLOWED_EXTS=a.files_allowed_exts;Object.freeze(c)})},H=function(a){for(var b=
[],c,e=window.location.href.slice(window.location.href.indexOf("?")+1).split("&"),f=0;fform").each(function(){var a=$(this);a.find("button.btn-clear").on("click",
-function(b){b.preventDefault();a.trigger("reset")})})},config:function(){d.info("views:config");var a=$("#drop-import-files");if(0form").each(function(){var a=$(this);a.find("button.btn-clear").on("click",function(b){b.preventDefault();a.trigger("reset")})})},config:function(){e.info("views:config");var a=$("#drop-import-files");if(0 |