diff --git a/inc/SP/Account/AccountCrypt.class.php b/inc/SP/Account/AccountCrypt.class.php
index f2aad837..520f81e1 100644
--- a/inc/SP/Account/AccountCrypt.class.php
+++ b/inc/SP/Account/AccountCrypt.class.php
@@ -55,7 +55,7 @@ class AccountCrypt
*/
public function updateOldPass(&$currentMasterPass)
{
- set_time_limit(300);
+ set_time_limit(0);
$accountsOk = [];
$userId = Session::getUserData()->getUserId();
@@ -87,6 +87,10 @@ class AccountCrypt
$AccountDataBase = new AccountData();
foreach ($accountsPass as $account) {
+ if ($LogMessage->getDetailsCounter() >= 100) {
+ $Log->writeLog(false, true);
+ }
+
$AccountData = clone $AccountDataBase;
$AccountData->setAccountId($account->account_id);
@@ -187,6 +191,10 @@ class AccountCrypt
$AccountDataBase = new AccountData();
foreach ($accountsPass as $account) {
+ if ($LogMessage->getDetailsCounter() >= 100) {
+ $Log->writeLog(false, true);
+ }
+
$AccountData = clone $AccountDataBase;
$AccountData->setAccountId($account->account_id);
diff --git a/inc/SP/Account/AccountHistoryCrypt.class.php b/inc/SP/Account/AccountHistoryCrypt.class.php
index a69ee830..b1fbd321 100644
--- a/inc/SP/Account/AccountHistoryCrypt.class.php
+++ b/inc/SP/Account/AccountHistoryCrypt.class.php
@@ -55,7 +55,7 @@ class AccountHistoryCrypt
*/
public function updateOldPass(&$currentMasterPass)
{
- set_time_limit(300);
+ set_time_limit(0);
$accountsOk = [];
$demoEnabled = Checks::demoIsEnabled();
@@ -92,6 +92,10 @@ class AccountHistoryCrypt
$AccountDataBase->hash = Hash::hashKey($currentMasterPass);
foreach ($accountsPass as $account) {
+ if ($LogMessage->getDetailsCounter() >= 100) {
+ $Log->writeLog(false, true);
+ }
+
$AccountData = clone $AccountDataBase;
$AccountData->id = $account->acchistory_id;
@@ -200,6 +204,10 @@ class AccountHistoryCrypt
$AccountDataBase->hash = Hash::hashKey($newMasterPass);
foreach ($accountsPass as $account) {
+ if ($LogMessage->getDetailsCounter() >= 100) {
+ $Log->writeLog(false, true);
+ }
+
$AccountData = clone $AccountDataBase;
$AccountData->id = $account->acchistory_id;
diff --git a/inc/SP/Api/ApiBase.class.php b/inc/SP/Api/ApiBase.class.php
index 474e8732..113de794 100644
--- a/inc/SP/Api/ApiBase.class.php
+++ b/inc/SP/Api/ApiBase.class.php
@@ -34,6 +34,7 @@ use SP\Core\Exceptions\SPException;
use SP\Core\Session;
use SP\Core\SessionUtil;
use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
use SP\Log\Log;
use SP\Mgmt\Users\User;
use SP\Mgmt\Users\UserPass;
@@ -75,7 +76,7 @@ abstract class ApiBase implements ApiInterface
*/
protected $mPass = '';
/**
- * @var UserData
+ * @var UserLoginData
*/
protected $UserData;
/**
@@ -168,6 +169,9 @@ abstract class ApiBase implements ApiInterface
*
* @throws SPException
* @throws \SP\Core\Exceptions\InvalidClassException
+ * @throws \Defuse\Crypto\Exception\BadFormatException
+ * @throws \Defuse\Crypto\Exception\CryptoException
+ * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
*/
protected function doAuth()
{
@@ -187,14 +191,11 @@ abstract class ApiBase implements ApiInterface
throw new SPException(SPException::SP_CRITICAL, __('Acceso no permitido', false));
}
- $UserPass = UserPass::getItem($this->UserData);
-
if (!$this->UserData->isUserIsDisabled()
- && $UserPass->checkUserUpdateMPass()
- && $UserPass->loadUserMPass()
+ && UserPass::loadUserMPass($this->UserData) === UserPass::MPASS_OK
) {
$this->auth = true;
- $this->mPass = $UserPass->getClearUserMPass();
+ $this->mPass = UserPass::getClearUserMPass();
} else {
throw new SPException(SPException::SP_CRITICAL, __('Acceso no permitido', false));
}
diff --git a/inc/SP/Auth/Auth.class.php b/inc/SP/Auth/Auth.class.php
index a8fc93c8..24a31ea6 100644
--- a/inc/SP/Auth/Auth.class.php
+++ b/inc/SP/Auth/Auth.class.php
@@ -34,6 +34,7 @@ use SP\Auth\Ldap\LdapStd;
use SP\Config\Config;
use SP\Core\Exceptions\SPException;
use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
use SP\Util\Checks;
defined('APP_ROOT') || die();
@@ -52,17 +53,17 @@ class Auth
*/
protected $auths = [];
/**
- * @var UserData
+ * @var UserLoginData
*/
protected $UserData;
/**
* Auth constructor.
*
- * @param UserData $UserData
+ * @param UserLoginData $UserData
* @throws \SP\Core\Exceptions\SPException
*/
- public function __construct(UserData $UserData)
+ public function __construct(UserLoginData $UserData)
{
$this->UserData = $UserData;
@@ -146,6 +147,8 @@ class Auth
* se ejecuta el proceso para actualizar la clave.
*
* @return DatabaseAuthData
+ * @throws \phpmailer\phpmailerException
+ * @throws \SP\Core\Exceptions\SPException
*/
public function authDatabase()
{
diff --git a/inc/SP/Auth/AuthInterface.class.php b/inc/SP/Auth/AuthInterface.class.php
index 7324486a..ecc6acb9 100644
--- a/inc/SP/Auth/AuthInterface.class.php
+++ b/inc/SP/Auth/AuthInterface.class.php
@@ -24,7 +24,7 @@
namespace SP\Auth;
-use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
/**
* Interface AuthInterface
@@ -35,8 +35,8 @@ interface AuthInterface
/**
* Autentificar al usuario
*
- * @param UserData $UserData Datos del usuario
+ * @param UserLoginData $UserData Datos del usuario
* @return mixed|AuthDataBase
*/
- public function authenticate(UserData $UserData);
+ public function authenticate(UserLoginData $UserData);
}
\ No newline at end of file
diff --git a/inc/SP/Auth/Browser/Browser.class.php b/inc/SP/Auth/Browser/Browser.class.php
index 995d14d0..2d2d5bc2 100644
--- a/inc/SP/Auth/Browser/Browser.class.php
+++ b/inc/SP/Auth/Browser/Browser.class.php
@@ -25,7 +25,7 @@
namespace SP\Auth\Browser;
use SP\Auth\AuthInterface;
-use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
/**
* Class Browser
@@ -39,13 +39,13 @@ class Browser implements AuthInterface
/**
* Autentificar al usuario
*
- * @param UserData $UserData Datos del usuario
+ * @param UserLoginData $UserData Datos del usuario
* @return BrowserAuthData
*/
- public function authenticate(UserData $UserData)
+ public function authenticate(UserLoginData $UserData)
{
$AuthData = new BrowserAuthData();
- $AuthData->setAuthenticated($this->checkServerAuthUser($UserData->getUserLogin()));
+ $AuthData->setAuthenticated($this->checkServerAuthUser($UserData->getLogin()));
return $AuthData;
}
diff --git a/inc/SP/Auth/Database/Database.class.php b/inc/SP/Auth/Database/Database.class.php
index 483e8321..14fb7875 100644
--- a/inc/SP/Auth/Database/Database.class.php
+++ b/inc/SP/Auth/Database/Database.class.php
@@ -27,9 +27,10 @@ namespace SP\Auth\Database;
use SP\Auth\AuthInterface;
use SP\Core\Crypt\Hash;
use SP\Core\Exceptions\SPException;
-use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
use SP\DataModel\UserPassData;
use SP\Log\Log;
+use SP\Mgmt\Users\User;
use SP\Mgmt\Users\UserMigrate;
use SP\Storage\DB;
use SP\Storage\QueryData;
@@ -44,19 +45,19 @@ use SP\Storage\QueryData;
class Database implements AuthInterface
{
/**
- * @var UserData $UserData
+ * @var UserLoginData $UserData
*/
protected $UserData;
/**
* Autentificar al usuario
*
- * @param UserData $UserData Datos del usuario
+ * @param UserLoginData $UserData Datos del usuario
* @return DatabaseAuthData
* @throws \SP\Core\Exceptions\SPException
* @throws \phpmailer\phpmailerException
*/
- public function authenticate(UserData $UserData)
+ public function authenticate(UserLoginData $UserData)
{
$this->UserData = $UserData;
@@ -78,37 +79,23 @@ class Database implements AuthInterface
*/
protected function authUser()
{
- if (UserMigrate::checkUserIsMigrate($this->UserData->getUserLogin())) {
- try {
- UserMigrate::migrateUserPass($this->UserData->getUserLogin(), $this->UserData->getUserPass());
- } catch (SPException $e) {
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(__FUNCTION__);
- $LogMessage->addDescription($e->getMessage());
- $LogMessage->addDetails(__('Login', false), $this->UserData->getUserLogin());
- $Log->writeLog();
+ try {
+ User::getItem($this->UserData)->getByLogin($this->UserData->getLogin());
+ if ($this->UserData->isUserIsMigrate() && !UserMigrate::migrateUserPass($this->UserData)) {
return false;
}
+
+ return Hash::checkHashKey($this->UserData->getLoginPass(), $this->UserData->getUserPass());
+ } catch (SPException $e) {
+ $Log = new Log();
+ $LogMessage = $Log->getLogMessage();
+ $LogMessage->setAction(__FUNCTION__);
+ $LogMessage->addDescription($e->getMessage());
+ $LogMessage->addDetails(__('Login', false), $this->UserData->getLogin());
+ $Log->writeLog();
+
+ return false;
}
-
- $query = /** @lang SQL */
- 'SELECT user_pass, user_hashSalt
- FROM usrData
- WHERE user_login = ?
- AND user_isMigrate = 0 LIMIT 1';
-
- $Data = new QueryData();
- $Data->setMapClassName(UserPassData::class);
- $Data->setQuery($query);
- $Data->addParam($this->UserData->getUserLogin());
-
- /** @var UserPassData $queryRes */
- $queryRes = DB::getResults($Data);
-
- return $queryRes !== false
- && $Data->getQueryNumRows() === 1
- && Hash::checkHashKey($this->UserData->getUserPass(), $queryRes->getUserPass());
}
}
\ No newline at end of file
diff --git a/inc/SP/Auth/Ldap/LdapBase.class.php b/inc/SP/Auth/Ldap/LdapBase.class.php
index ce9bb2bb..143c4178 100644
--- a/inc/SP/Auth/Ldap/LdapBase.class.php
+++ b/inc/SP/Auth/Ldap/LdapBase.class.php
@@ -28,7 +28,7 @@ use SP\Auth\AuthInterface;
use SP\Config\Config;
use SP\Core\Exceptions\SPException;
use SP\Core\Messages\LogMessage;
-use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
use SP\Log\Log;
/**
@@ -405,22 +405,22 @@ abstract class LdapBase implements LdapInterface, AuthInterface
/**
* Autentificar al usuario
*
- * @param UserData $UserData Datos del usuario
+ * @param UserLoginData $UserData Datos del usuario
* @return bool
*/
- public function authenticate(UserData $UserData)
+ public function authenticate(UserLoginData $UserData)
{
if (!$this->checkParams()) {
return false;
}
try {
- $this->setUserLogin($UserData->getUserLogin());
+ $this->setUserLogin($UserData->getLogin());
$this->connect();
$this->bind();
$this->getAttributes();
- $this->bind($this->LdapAuthData->getDn(), $UserData->getUserPass());
+ $this->bind($this->LdapAuthData->getDn(), $UserData->getLoginPass());
} catch (SPException $e) {
return false;
}
@@ -511,7 +511,7 @@ abstract class LdapBase implements LdapInterface, AuthInterface
}
}
- if (!empty($res["fullname"])) {
+ if (!empty($res['fullname'])) {
$this->LdapAuthData->setName($res['fullname']);
} else {
$this->LdapAuthData->setName($res['name'] . ' ' . $res['sn']);
diff --git a/inc/SP/Controller/AccountController.class.php b/inc/SP/Controller/AccountController.class.php
index 2cb5ab60..5f13a17c 100644
--- a/inc/SP/Controller/AccountController.class.php
+++ b/inc/SP/Controller/AccountController.class.php
@@ -281,7 +281,7 @@ class AccountController extends ControllerBase implements ActionsInterface
if (!Acl::checkUserAccess($this->getAction())) {
$this->showError(self::ERR_PAGE_NO_PERMISSION);
return false;
- } elseif (!UserPass::getItem($this->UserData)->checkUserUpdateMPass()) {
+ } elseif (!UserPass::checkUserUpdateMPass($this->UserData->getUserId())) {
$this->showError(self::ERR_UPDATE_MPASS);
return false;
} elseif ($this->id > 0) {
diff --git a/inc/SP/Controller/ConfigActionController.class.php b/inc/SP/Controller/ConfigActionController.class.php
index d61a670a..fb4f30db 100644
--- a/inc/SP/Controller/ConfigActionController.class.php
+++ b/inc/SP/Controller/ConfigActionController.class.php
@@ -482,7 +482,7 @@ class ConfigActionController implements ItemControllerInterface
$confirmPassChange = Request::analyze('confirmPassChange', 0, false, 1);
$noAccountPassChange = Request::analyze('chkNoAccountChange', 0, false, 1);
- if (!UserPass::getItem(Session::getUserData())->checkUserUpdateMPass()) {
+ if (!UserPass::checkUserUpdateMPass(Session::getUserData()->getUserId())) {
$this->JsonResponse->setDescription(__('Clave maestra actualizada', false));
$this->JsonResponse->addMessage(__('Reinicie la sesión para cambiarla', false));
$this->JsonResponse->setStatus(100);
diff --git a/inc/SP/Controller/ItemShowController.class.php b/inc/SP/Controller/ItemShowController.class.php
index c14bb8e0..182a6a18 100644
--- a/inc/SP/Controller/ItemShowController.class.php
+++ b/inc/SP/Controller/ItemShowController.class.php
@@ -508,12 +508,9 @@ class ItemShowController extends ControllerBase implements ActionsInterface, Ite
$AccountAcl = new AccountAcl($Account, ActionsInterface::ACTION_ACC_VIEW_PASS);
$Acl = $AccountAcl->getAcl();
- $UserPass = new UserPass(new UserPassData());
- $UserPass->getItemData()->setUserId(Session::getUserData()->getUserId());
-
if (!$Acl->isShowViewPass()) {
throw new ItemException(__('No tiene permisos para acceder a esta cuenta', false));
- } elseif (!$UserPass->checkUserUpdateMPass()) {
+ } elseif (!UserPass::checkUserUpdateMPass(Session::getUserData()->getUserId())) {
throw new ItemException(__('Clave maestra actualizada', false) . '
' . __('Reinicie la sesión para cambiarla', false));
}
diff --git a/inc/SP/Controller/LoginController.class.php b/inc/SP/Controller/LoginController.class.php
index d2221e43..80c1eb25 100644
--- a/inc/SP/Controller/LoginController.class.php
+++ b/inc/SP/Controller/LoginController.class.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link http://syspass.org
+ * @author nuxsmin
+ * @link http://syspass.org
* @copyright 2012-2017, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -41,14 +41,13 @@ use SP\Core\Language;
use SP\Core\Messages\LogMessage;
use SP\Core\Session;
use SP\Core\SessionUtil;
-use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
use SP\DataModel\UserPassRecoverData;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Log\Log;
use SP\Mgmt\Groups\Group;
use SP\Mgmt\Profiles\Profile;
-use SP\Mgmt\Users\User;
use SP\Mgmt\Users\UserLdap;
use SP\Mgmt\Users\UserPass;
use SP\Mgmt\Users\UserPassRecover;
@@ -76,7 +75,7 @@ class LoginController
*/
protected $jsonResponse;
/**
- * @var UserData
+ * @var UserLoginData
*/
protected $UserData;
/**
@@ -90,7 +89,7 @@ class LoginController
public function __construct()
{
$this->jsonResponse = new JsonResponse();
- $this->UserData = new UserData();
+ $this->UserData = new UserLoginData();
$this->LogMessage = new LogMessage();
$this->LogMessage->setAction(__('Inicio sesión', false));
}
@@ -112,8 +111,8 @@ class LoginController
Json::returnJson($this->jsonResponse);
}
- $this->UserData->setUserLogin($userLogin);
- $this->UserData->setUserPass($userPass);
+ $this->UserData->setLogin($userLogin);
+ $this->UserData->setLoginPass($userPass);
$Log = new Log($this->LogMessage);
@@ -134,9 +133,9 @@ class LoginController
throw new AuthException(SPException::SP_INFO, __('Login incorrecto', false), '', self::STATUS_INVALID_LOGIN);
}
- $this->getUserData($userPass);
- $this->checkUserDisabled();
- $this->checkPasswordChange();
+ $this->getUserData();
+ $this->checkUser();
+ $this->loadMasterPass();
$this->setUserSession();
$this->loadUserPreferences();
} catch (SPException $e) {
@@ -166,17 +165,14 @@ class LoginController
/**
* Obtener los datos del usuario
*
- * @param $userPass
* @throws SPException
* @throws \SP\Core\Exceptions\InvalidClassException
* @throws \SP\Core\Exceptions\AuthException
* @throws \InvalidArgumentException
*/
- protected function getUserData($userPass)
+ protected function getUserData()
{
try {
- $this->UserData = User::getItem($this->UserData)->getByLogin($this->UserData->getUserLogin());
- $this->UserData->setUserPass($userPass);
$this->UserData->setUserPreferences(UserPreferences::getItem()->getById($this->UserData->getUserId()));
} catch (SPException $e) {
$this->LogMessage->addDescription(__('Error al obtener los datos del usuario de la BBDD', false));
@@ -186,23 +182,141 @@ class LoginController
}
/**
- * omprobar si el usuario está deshabilitado
+ * Comprobar estado del usuario
*
* @throws \SP\Core\Exceptions\SPException
*/
- protected function checkUserDisabled()
+ protected function checkUser()
{
// Comprobar si el usuario está deshabilitado
if ($this->UserData->isUserIsDisabled()) {
$this->LogMessage->addDescription(__('Usuario deshabilitado', false));
- $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getUserLogin());
+ $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getLogin());
throw new AuthException(SPException::SP_INFO, __('Usuario deshabilitado', false), '', self::STATUS_USER_DISABLED);
+ } elseif ($this->UserData->isUserIsChangePass()) {
+ $hash = Util::generateRandomBytes();
+
+ $UserPassRecoverData = new UserPassRecoverData();
+ $UserPassRecoverData->setUserpassrUserId($this->UserData->getUserId());
+ $UserPassRecoverData->setUserpassrHash($hash);
+
+ UserPassRecover::getItem($UserPassRecoverData)->add();
+
+ $data = ['url' => Init::$WEBURI . '/index.php?a=passreset&h=' . $hash . '&t=' . time() . '&f=1'];
+ $this->jsonResponse->setData($data);
+ $this->jsonResponse->setStatus(0);
+ Json::returnJson($this->jsonResponse);
}
return false;
}
+ /**
+ * Cargar la clave maestra o solicitarla
+ *
+ * @throws \SP\Core\Exceptions\SPException
+ * @throws \SP\Core\Exceptions\AuthException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ protected function loadMasterPass()
+ {
+ $masterPass = Request::analyzeEncrypted('mpass');
+ $oldPass = Request::analyzeEncrypted('oldpass');
+
+ try {
+ if ($masterPass) {
+ if (CryptMasterPass::checkTempMasterPass($masterPass)) {
+ $this->LogMessage->addDescription(__('Usando clave temporal', false));
+
+ $masterPass = CryptMasterPass::getTempMasterPass($masterPass);
+ }
+
+ if (!UserPass::updateUserMPass($masterPass, $this->UserData)) {
+ $this->LogMessage->addDescription(__('Clave maestra incorrecta', false));
+
+ throw new AuthException(SPException::SP_INFO, __('Clave maestra incorrecta', false), '', self::STATUS_INVALID_MASTER_PASS);
+ } else {
+ CryptSession::saveSessionKey(UserPass::getClearUserMPass());
+
+ $this->LogMessage->addDescription(__('Clave maestra actualizada', false));
+ }
+ } else if ($oldPass) {
+ if (!UserPass::updateMasterPassFromOldPass($oldPass, $this->UserData)) {
+ $this->LogMessage->addDescription(__('Clave maestra incorrecta', false));
+
+ throw new AuthException(SPException::SP_INFO, __('Clave maestra incorrecta', false), '', self::STATUS_INVALID_MASTER_PASS);
+ } else {
+ CryptSession::saveSessionKey(UserPass::getClearUserMPass());
+
+ $this->LogMessage->addDescription(__('Clave maestra actualizada', false));
+ }
+ } else {
+ switch (UserPass::loadUserMPass($this->UserData)) {
+ case UserPass::MPASS_CHECKOLD:
+ throw new AuthException(SPException::SP_INFO, __('Es necesaria su clave anterior', false), '', self::STATUS_NEED_OLD_PASS);
+ break;
+ case UserPass::MPASS_NOTSET:
+ case UserPass::MPASS_CHANGED:
+ case UserPass::MPASS_WRONG:
+ throw new AuthException(SPException::SP_INFO, __('La clave maestra no ha sido guardada o es incorrecta', false), '', self::STATUS_INVALID_MASTER_PASS);
+ break;
+ }
+ }
+ } catch (CryptoException $e) {
+ $this->LogMessage->addDescription(__('Error interno', false));
+
+ throw new AuthException(SPException::SP_INFO, $this->LogMessage->getDescription(), $e->getMessage(), self::STATUS_INTERNAL_ERROR);
+ }
+ }
+
+ /**
+ * Cargar la sesión del usuario
+ *
+ * @throws \SP\Core\Exceptions\SPException
+ * @throws \InvalidArgumentException
+ * @throws \SP\Core\Exceptions\AuthException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ protected function setUserSession()
+ {
+ // Obtenemos la clave maestra del usuario
+ if (UserPass::getClearUserMPass() !== '') {
+ // Actualizar el último login del usuario
+ UserUtil::setUserLastLogin($this->UserData->getUserId());
+
+ // Cargar las variables de sesión del usuario
+ SessionUtil::loadUserSession($this->UserData);
+
+ $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getLogin());
+ $this->LogMessage->addDetails(__('Perfil', false), Profile::getItem()->getById($this->UserData->getUserProfileId())->getUserprofileName());
+ $this->LogMessage->addDetails(__('Grupo', false), Group::getItem()->getById($this->UserData->getUserGroupId())->getUsergroupName());
+ } else {
+ $this->LogMessage->addDescription(__('Error al obtener la clave maestra del usuario', false));
+
+ throw new AuthException(SPException::SP_ERROR, __('Error interno', false), '', self::STATUS_INTERNAL_ERROR);
+ }
+ }
+
+ /**
+ * Cargar las preferencias del usuario y comprobar si usa 2FA
+ *
+ * @throws \SP\Core\Exceptions\SPException
+ * @throws \SP\Core\Exceptions\InvalidClassException
+ */
+ protected function loadUserPreferences()
+ {
+ Language::setLanguage(true);
+ DiFactory::getTheme()->initTheme(true);
+ Session::setUserPreferences($this->UserData->getUserPreferences());
+ Session::setSessionType(Session::SESSION_INTERACTIVE);
+ Session::setAuthCompleted(true);
+
+ DiFactory::getEventDispatcher()->notifyEvent('login.preferences', $this);
+ }
+
/**
* Comprobar si se ha forzado un cambio de clave
*
@@ -230,116 +344,6 @@ class LoginController
return false;
}
- /**
- * Cargar la sesión del usuario
- *
- * @throws \SP\Core\Exceptions\SPException
- * @throws \InvalidArgumentException
- * @throws \SP\Core\Exceptions\AuthException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
- */
- protected function setUserSession()
- {
- $UserPass = $this->loadMasterPass();
-
- // Obtenemos la clave maestra del usuario
- if ($UserPass->getClearUserMPass() !== '') {
- // Actualizar el último login del usuario
- UserUtil::setUserLastLogin($this->UserData->getUserId());
-
- // Cargar las variables de sesión del usuario
- SessionUtil::loadUserSession($this->UserData);
-
- $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getUserLogin());
- $this->LogMessage->addDetails(__('Perfil', false), Profile::getItem()->getById($this->UserData->getUserProfileId())->getUserprofileName());
- $this->LogMessage->addDetails(__('Grupo', false), Group::getItem()->getById($this->UserData->getUserGroupId())->getUsergroupName());
- } else {
- $this->LogMessage->addDescription(__('Error al obtener la clave maestra del usuario', false));
-
- throw new AuthException(SPException::SP_ERROR, __('Error interno', false), '', self::STATUS_INTERNAL_ERROR);
- }
- }
-
- /**
- * Cargar la clave maestra o solicitarla
- *
- * @throws \SP\Core\Exceptions\SPException
- * @throws \SP\Core\Exceptions\AuthException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
- */
- protected function loadMasterPass()
- {
- $masterPass = Request::analyzeEncrypted('mpass');
- $oldPass = Request::analyzeEncrypted('oldpass');
-
- $UserPass = UserPass::getItem($this->UserData);
-
- try {
- if ($masterPass) {
- if (CryptMasterPass::checkTempMasterPass($masterPass)) {
- $this->LogMessage->addDescription(__('Usando clave temporal', false));
-
- $masterPass = CryptMasterPass::getTempMasterPass($masterPass);
- }
-
- if (!$UserPass->updateUserMPass($masterPass)) {
- $this->LogMessage->addDescription(__('Clave maestra incorrecta', false));
-
- throw new AuthException(SPException::SP_INFO, __('Clave maestra incorrecta', false), '', self::STATUS_INVALID_MASTER_PASS);
- } else {
- CryptSession::saveSessionKey($UserPass->getClearUserMPass());
-
- $this->LogMessage->addDescription(__('Clave maestra actualizada', false));
- }
- } else if ($oldPass) {
- if (!$UserPass->updateMasterPass($oldPass)) {
- $this->LogMessage->addDescription(__('Clave maestra incorrecta', false));
-
- throw new AuthException(SPException::SP_INFO, __('Clave maestra incorrecta', false), '', self::STATUS_INVALID_MASTER_PASS);
- } else {
- CryptSession::saveSessionKey($UserPass->getClearUserMPass());
-
- $this->LogMessage->addDescription(__('Clave maestra actualizada', false));
- }
- } else {
- $loadMPass = $UserPass->loadUserMPass();
-
- // Comprobar si es necesario actualizar la clave maestra
- if ($loadMPass === null) {
- throw new AuthException(SPException::SP_INFO, __('Es necesaria su clave anterior', false), '', self::STATUS_NEED_OLD_PASS);
- // La clave no está establecida o se ha sido cambiada por el administrador
- } else if ($loadMPass === false) {
- throw new AuthException(SPException::SP_INFO, __('La clave maestra no ha sido guardada o es incorrecta', false), '', self::STATUS_INVALID_MASTER_PASS);
- }
- }
- } catch (CryptoException $e) {
- $this->LogMessage->addDescription(__('Error interno', false));
-
- throw new AuthException(SPException::SP_INFO, $this->LogMessage->getDescription(), $e->getMessage(), self::STATUS_INTERNAL_ERROR);
- }
-
- return $UserPass;
- }
-
- /**
- * Cargar las preferencias del usuario y comprobar si usa 2FA
- *
- * @throws \SP\Core\Exceptions\SPException
- * @throws \SP\Core\Exceptions\InvalidClassException
- */
- protected function loadUserPreferences()
- {
- Language::setLanguage(true);
- DiFactory::getTheme()->initTheme(true);
- Session::setUserPreferences($this->UserData->getUserPreferences());
- Session::setSessionType(Session::SESSION_INTERACTIVE);
- Session::setAuthCompleted(true);
-
- DiFactory::getEventDispatcher()->notifyEvent('login.preferences', $this);
- }
-
/**
* Autentificación LDAP
*
@@ -353,7 +357,7 @@ class LoginController
{
if ($LdapAuthData->getStatusCode() > 0) {
$this->LogMessage->addDetails(__('Tipo', false), __FUNCTION__);
- $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getUserLogin());
+ $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getLogin());
if ($LdapAuthData->getStatusCode() === 49) {
$this->LogMessage->addDescription(__('Login incorrecto', false));
@@ -382,7 +386,7 @@ class LoginController
try {
// Verificamos si el usuario existe en la BBDD
- if (UserLdap::checkLDAPUserInDB($this->UserData->getUserLogin())) {
+ if (UserLdap::checkLDAPUserInDB($this->UserData->getLogin())) {
// Actualizamos el usuario de LDAP en MySQL
UserLdap::getItem($this->UserData)->update();
} else {
@@ -411,7 +415,7 @@ class LoginController
// Autentificamos con la BBDD
if ($AuthData->getAuthenticated() === 0) {
$this->LogMessage->addDescription(__('Login incorrecto', false));
- $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getUserLogin());
+ $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getLogin());
throw new AuthException(SPException::SP_INFO, $this->LogMessage->getDescription(), '', self::STATUS_INVALID_LOGIN);
} elseif ($AuthData->getAuthenticated() === 1) {
@@ -434,7 +438,7 @@ class LoginController
if ($AuthData->getAuthenticated() === 0) {
$this->LogMessage->addDescription(__('Login incorrecto', false));
$this->LogMessage->addDetails(__('Tipo', false), __FUNCTION__);
- $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getUserLogin());
+ $this->LogMessage->addDetails(__('Usuario', false), $this->UserData->getLogin());
$this->LogMessage->addDetails(__('Autentificación', false), sprintf('%s (%s)', AuthUtil::getServerAuthType(), $AuthData->getName()));
throw new AuthException(SPException::SP_INFO, $this->LogMessage->getDescription(), '', self::STATUS_INVALID_LOGIN);
diff --git a/inc/SP/Core/Installer.class.php b/inc/SP/Core/Installer.class.php
index 20c28b5e..5012d1ed 100644
--- a/inc/SP/Core/Installer.class.php
+++ b/inc/SP/Core/Installer.class.php
@@ -36,7 +36,7 @@ use SP\Core\Exceptions\SPException;
use SP\DataModel\GroupData;
use SP\DataModel\InstallData;
use SP\DataModel\ProfileData;
-use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
use SP\Mgmt\Groups\Group;
use SP\Mgmt\Profiles\Profile;
use SP\Mgmt\Users\User;
@@ -462,11 +462,13 @@ class Installer
Profile::getItem($ProfileData)->add();
// Datos del usuario
- $UserData = new UserData();
+ $UserData = new UserLoginData();
$UserData->setUserGroupId($GroupData->getUsergroupId());
$UserData->setUserProfileId($ProfileData->getUserprofileId());
$UserData->setUserLogin($this->InstallData->getAdminLogin());
+ $UserData->setLogin($this->InstallData->getAdminLogin());
$UserData->setUserPass($this->InstallData->getAdminPass());
+ $UserData->setLoginPass($this->InstallData->getAdminPass());
$UserData->setUserName('Admin');
$UserData->setUserIsAdminApp(1);
@@ -477,10 +479,9 @@ class Installer
ConfigDB::setCacheConfigValue('lastupdatempass', time());
ConfigDB::writeConfig(true);
- if (!UserPass::getItem($UserData)->updateUserMPass($this->InstallData->getMasterPassword())) {
+ if (!UserPass::updateUserMPass($this->InstallData->getMasterPassword(), $UserData)) {
throw new SPException(SPException::SP_CRITICAL,
- __('Error al actualizar la clave maestra del usuario "admin"', false),
- __('Informe al desarrollador', false));
+ __('Error al actualizar la clave maestra del usuario "admin"', false));
}
} catch (\Exception $e) {
$this->rollback();
diff --git a/inc/SP/Core/Messages/LogMessage.class.php b/inc/SP/Core/Messages/LogMessage.class.php
index 8cff1ed9..be884ef6 100644
--- a/inc/SP/Core/Messages/LogMessage.class.php
+++ b/inc/SP/Core/Messages/LogMessage.class.php
@@ -41,6 +41,14 @@ class LogMessage extends MessageBase
* @var array Detalles de la acción en formato "detalle : descripción"
*/
protected $details = [];
+ /**
+ * @var int
+ */
+ protected $descriptionCounter = 0;
+ /**
+ * @var int
+ */
+ protected $detailsCounter = 0;
/**
* Devuelve la acción realizada
@@ -140,6 +148,8 @@ class LogMessage extends MessageBase
$this->details[] = [$this->formatString($key), $this->formatString($value)];
+ $this->detailsCounter++;
+
return $this;
}
@@ -175,6 +185,7 @@ class LogMessage extends MessageBase
public function addDescriptionLine()
{
$this->description[] = '';
+ $this->descriptionCounter++;
return $this;
}
@@ -222,7 +233,7 @@ class LogMessage extends MessageBase
* Devolver un detalle formateado
*
* @param array $detail
- * @param bool $translate
+ * @param bool $translate
* @return string
*/
protected function formatDetail(array $detail, $translate = false)
@@ -257,6 +268,18 @@ class LogMessage extends MessageBase
public function resetDescription()
{
$this->description = [];
+ $this->descriptionCounter = 0;
+
+ return $this;
+ }
+
+ /**
+ * Restablecer la variable de detalles
+ */
+ public function resetDetails()
+ {
+ $this->details = [];
+ $this->detailsCounter = 0;
return $this;
}
@@ -271,4 +294,20 @@ class LogMessage extends MessageBase
{
return nl2br($this->getDetails($translate));
}
+
+ /**
+ * @return int
+ */
+ public function getDescriptionCounter()
+ {
+ return $this->descriptionCounter;
+ }
+
+ /**
+ * @return int
+ */
+ public function getDetailsCounter()
+ {
+ return $this->detailsCounter;
+ }
}
\ No newline at end of file
diff --git a/inc/SP/Core/Upgrade/Crypt.class.php b/inc/SP/Core/Upgrade/Crypt.class.php
index 9e21ac1f..fd94246c 100644
--- a/inc/SP/Core/Upgrade/Crypt.class.php
+++ b/inc/SP/Core/Upgrade/Crypt.class.php
@@ -31,6 +31,7 @@ use SP\Account\AccountHistoryCrypt;
use SP\Config\ConfigDB;
use SP\Core\Crypt\Hash;
use SP\Core\Exceptions\SPException;
+use SP\Core\Init;
use SP\Log\Log;
use SP\Mgmt\CustomFields\CustomFieldsUtil;
use SP\Storage\DB;
@@ -75,6 +76,10 @@ class Crypt
return false;
}
+ global $timeStart;
+
+ debugLog(Init::microtime_float() - $timeStart);
+
return true;
}
diff --git a/inc/SP/Core/Upgrade/Upgrade.class.php b/inc/SP/Core/Upgrade/Upgrade.class.php
index 74f3f199..dff2f5f6 100644
--- a/inc/SP/Core/Upgrade/Upgrade.class.php
+++ b/inc/SP/Core/Upgrade/Upgrade.class.php
@@ -52,7 +52,7 @@ defined('APP_ROOT') || die();
*/
class Upgrade
{
- private static $dbUpgrade = [110, 1121, 1122, 1123, 11213, 11219, 11220, 12001, 12002, 1316011001, 1316100601, 20017011302, 20017011701, 20017012901, 20117021901];
+ private static $dbUpgrade = [110, 1121, 1122, 1123, 11213, 11219, 11220, 12001, 12002, 1316011001, 1316100601, 20017011302, 20017011701, 20017012901];
private static $cfgUpgrade = [1124, 1316020501, 20017011202];
private static $auxUpgrade = [12001, 12002, 20017010901, 20017011202];
private static $appUpgrade = [20117021901];
diff --git a/inc/SP/Core/Upgrade/User.class.php b/inc/SP/Core/Upgrade/User.class.php
index f73345f0..8d32b010 100644
--- a/inc/SP/Core/Upgrade/User.class.php
+++ b/inc/SP/Core/Upgrade/User.class.php
@@ -25,10 +25,9 @@
namespace SP\Core\Upgrade;
use Defuse\Crypto\Exception\CryptoException;
-use SP\Config\ConfigDB;
-use SP\Core\Crypt\Hash;
use SP\Core\Exceptions\SPException;
use SP\Core\OldCrypt;
+use SP\DataModel\UserLoginData;
use SP\Mgmt\Users\UserPass;
use SP\Storage\DB;
use SP\Storage\QueryData;
@@ -118,17 +117,16 @@ class User
/**
* Actualizar la clave maestra
*
- * @param UserPass $UserPass
+ * @param UserLoginData $UserData
* @return bool
*/
- public static function upgradeMasterKey(UserPass $UserPass)
+ public static function upgradeMasterKey(UserLoginData $UserData)
{
- $UserData = $UserPass->getItemData();
- $key = OldCrypt::generateAesKey($UserData->getUserPass() . $UserData->getUserLogin());
+ $key = OldCrypt::generateAesKey($UserData->getLoginPass() . $UserData->getLogin());
$mKey = OldCrypt::getDecrypt($UserData->getUserMPass(), $UserData->getUserMKey(), $key);
try {
- return $mKey && $UserPass->updateUserMPass($mKey);
+ return $mKey && UserPass::updateUserMPass($mKey, $UserData);
} catch (SPException $e) {
} catch (CryptoException $e) {
}
diff --git a/inc/SP/DataModel/UserLoginData.class.php b/inc/SP/DataModel/UserLoginData.class.php
new file mode 100644
index 00000000..1221ac33
--- /dev/null
+++ b/inc/SP/DataModel/UserLoginData.class.php
@@ -0,0 +1,74 @@
+.
+ */
+
+namespace SP\DataModel;
+
+/**
+ * Class UserLoginData
+ *
+ * @package SP\DataModel
+ */
+class UserLoginData extends UserData
+{
+ /**
+ * @var string
+ */
+ protected $login;
+ /**
+ * @var string
+ */
+ protected $loginPass;
+
+ /**
+ * @return string
+ */
+ public function getLogin()
+ {
+ return $this->login;
+ }
+
+ /**
+ * @param string $login
+ */
+ public function setLogin($login)
+ {
+ $this->login = $login;
+ }
+
+ /**
+ * @return string
+ */
+ public function getLoginPass()
+ {
+ return $this->loginPass;
+ }
+
+ /**
+ * @param string $loginPass
+ */
+ public function setLoginPass($loginPass)
+ {
+ $this->loginPass = $loginPass;
+ }
+}
\ No newline at end of file
diff --git a/inc/SP/Log/Log.class.php b/inc/SP/Log/Log.class.php
index ca54c4c1..5ac69640 100644
--- a/inc/SP/Log/Log.class.php
+++ b/inc/SP/Log/Log.class.php
@@ -115,13 +115,34 @@ class Log extends ActionLog
return $Log;
}
+ /**
+ * Escribir un nuevo evento en el registro de eventos
+ *
+ * @param string $action La acción realizada
+ * @param string $description La descripción de la acción realizada
+ * @param string $level
+ * @return Log
+ */
+ public static function writeNewLog($action, $description = null, $level = Log::INFO)
+ {
+ $LogMessage = new LogMessage();
+ $LogMessage->setAction($action);
+ $LogMessage->addDescription($description);
+
+ $Log = new Log($LogMessage, $level);
+ $Log->writeLog();
+
+ return $Log;
+ }
+
/**
* Escribir un nuevo evento en el registro de eventos
*
* @param bool $resetDescription Restablecer la descripción
+ * @param bool $resetDetails Restablecer los detalles
* @return bool
*/
- public function writeLog($resetDescription = false)
+ public function writeLog($resetDescription = false, $resetDetails = false)
{
if ((defined('IS_INSTALLER') && IS_INSTALLER === 1)
|| self::$logDbEnabled === 0
@@ -166,6 +187,10 @@ class Log extends ActionLog
$this->LogMessage->resetDescription();
}
+ if ($resetDetails === true) {
+ $this->LogMessage->resetDetails();
+ }
+
try {
DB::getQuery($Data);
} catch (SPException $e) {
@@ -218,24 +243,4 @@ class Log extends ActionLog
return new Log($LogMessage, $level);
}
-
- /**
- * Escribir un nuevo evento en el registro de eventos
- *
- * @param string $action La acción realizada
- * @param string $description La descripción de la acción realizada
- * @param string $level
- * @return Log
- */
- public static function writeNewLog($action, $description = null, $level = Log::INFO)
- {
- $LogMessage = new LogMessage();
- $LogMessage->setAction($action);
- $LogMessage->addDescription($description);
-
- $Log = new Log($LogMessage, $level);
- $Log->writeLog();
-
- return $Log;
- }
}
\ No newline at end of file
diff --git a/inc/SP/Mgmt/Users/User.class.php b/inc/SP/Mgmt/Users/User.class.php
index 9cb6c40a..75cacd5a 100644
--- a/inc/SP/Mgmt/Users/User.class.php
+++ b/inc/SP/Mgmt/Users/User.class.php
@@ -305,6 +305,10 @@ class User extends UserBase implements ItemInterface, ItemSelectInterface
user_lastUpdate,
user_lastUpdateMPass,
user_preferences,
+ user_pass,
+ user_hashSalt,
+ user_mPass,
+ user_mKey,
BIN(user_isAdminApp) AS user_isAdminApp,
BIN(user_isAdminAcc) AS user_isAdminAcc,
BIN(user_isLdap) AS user_isLdap,
@@ -357,6 +361,10 @@ class User extends UserBase implements ItemInterface, ItemSelectInterface
user_lastUpdate,
user_lastUpdateMPass,
user_preferences,
+ user_pass,
+ user_hashSalt,
+ user_mPass,
+ user_mKey,
BIN(user_isAdminApp) AS user_isAdminApp,
BIN(user_isAdminAcc) AS user_isAdminAcc,
BIN(user_isLdap) AS user_isLdap,
@@ -369,7 +377,13 @@ class User extends UserBase implements ItemInterface, ItemSelectInterface
WHERE user_login = ? LIMIT 1';
$Data = new QueryData();
- $Data->setMapClassName($this->getDataModel());
+
+ if (is_object($this->itemData)) {
+ $Data->setMapClass($this->itemData);
+ } else {
+ $Data->setMapClassName($this->getDataModel());
+ }
+
$Data->setQuery($query);
$Data->addParam($login);
diff --git a/inc/SP/Mgmt/Users/UserMigrate.class.php b/inc/SP/Mgmt/Users/UserMigrate.class.php
index 43ae196d..8e4193fa 100644
--- a/inc/SP/Mgmt/Users/UserMigrate.class.php
+++ b/inc/SP/Mgmt/Users/UserMigrate.class.php
@@ -29,6 +29,8 @@ defined('APP_ROOT') || die();
use SP\Core\Crypt\Hash;
use SP\Core\Exceptions\SPException;
use SP\DataModel\GroupUsersData;
+use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
use SP\Log\Email;
use SP\Log\Log;
use SP\Mgmt\Groups\GroupUsers;
@@ -65,48 +67,51 @@ class UserMigrate
/**
* Actualizar la clave de un usuario desde phpPMS.
*
- * @param string $userLogin con el login del usuario
- * @param string $userPass con la clave del usuario
+ * @param UserLoginData $UserData
+ * @return bool
+ * @throws \SP\Core\Exceptions\SPException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Core\Exceptions\ConstraintException
*
* Esta función actualiza la clave de un usuario que ha sido migrado desde phpPMS
- * @throws \SP\Core\Exceptions\SPException
- * @throws \phpmailer\phpmailerException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
*/
- public static function migrateUserPass($userLogin, $userPass)
+ public static function migrateUserPass(UserLoginData $UserData)
{
- $query = /** @lang SQL */
- 'UPDATE usrData SET
+ $passOk = ($UserData->getUserPass() === sha1($UserData->getUserHashSalt() . $UserData->getLoginPass())
+ || $UserData->getUserPass() === md5($UserData->getLoginPass())
+ || hash_equals($UserData->getUserPass(), crypt($UserData->getLoginPass(), $UserData->getUserHashSalt()))
+ || Hash::checkHashKey($UserData->getLoginPass(), $UserData->getUserPass()));
+
+ if ($passOk) {
+ $query = /** @lang SQL */
+ 'UPDATE usrData SET
user_pass = ?,
user_hashSalt = \'\',
user_lastUpdate = NOW(),
user_isMigrate = 0
- WHERE user_login = ?
- AND user_isMigrate = 1
- AND (user_pass = SHA1(CONCAT(user_hashSalt,?))
- OR user_pass = MD5(?)
- OR user_pass = ENCRYPT(?, user_hashSalt)) LIMIT 1';
+ WHERE user_login = ? LIMIT 1';
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam(Hash::hashKey($userPass));
- $Data->addParam($userLogin);
- $Data->addParam($userPass);
- $Data->addParam($userPass);
- $Data->addParam($userPass);
- $Data->setOnErrorMessage(__('Error al migrar cuenta de usuario', false));
+ $Data = new QueryData();
+ $Data->setQuery($query);
+ $Data->addParam(Hash::hashKey($UserData->getLoginPass()));
+ $Data->addParam($UserData->getLogin());
+ $Data->setOnErrorMessage(__('Error al migrar cuenta de usuario', false));
- DB::getQuery($Data);
+ DB::getQuery($Data);
- $Log = new Log();
- $Log->getLogMessage()
- ->setAction(__FUNCTION__)
- ->addDescription(__('Usuario actualizado', false))
- ->addDetails(__('Login', false), $userLogin);
- $Log->writeLog();
+ $Log = new Log();
+ $Log->getLogMessage()
+ ->setAction(__FUNCTION__)
+ ->addDescription(__('Usuario actualizado', false))
+ ->addDetails(__('Login', false), $UserData->getLogin());
+ $Log->writeLog();
- Email::sendEmail($Log->getLogMessage());
+ Email::sendEmail($Log->getLogMessage());
+
+ return true;
+ }
+
+ return false;
}
/**
diff --git a/inc/SP/Mgmt/Users/UserPass.class.php b/inc/SP/Mgmt/Users/UserPass.class.php
index b242bb97..a5ffac69 100644
--- a/inc/SP/Mgmt/Users/UserPass.class.php
+++ b/inc/SP/Mgmt/Users/UserPass.class.php
@@ -33,7 +33,9 @@ use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Hash;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
-use SP\Core\Upgrade\User;
+use SP\Core\Upgrade\User as UpgradeUser;
+use SP\DataModel\UserData;
+use SP\DataModel\UserLoginData;
use SP\DataModel\UserPassData;
use SP\Log\Email;
use SP\Log\Log;
@@ -48,10 +50,21 @@ use SP\Core\Crypt\Session as CryptSession;
*/
class UserPass extends UserBase
{
+ // La clave maestra incorrecta
+ const MPASS_WRONG = 0;
+ // La clave maestra correcta
+ const MPASS_OK = 1;
+ // La clave maestra no está guardada
+ const MPASS_NOTSET = 2;
+ // La clave maestra ha cambiado
+ const MPASS_CHANGED = 3;
+ // Comprobar la clave maestra con la calve del usuario anterior
+ const MPASS_CHECKOLD = 4;
+
/**
* @var string
*/
- protected $clearUserMPass = '';
+ private static $clearUserMPass = '';
/**
* Category constructor.
@@ -93,9 +106,10 @@ class UserPass extends UserBase
/**
* Comprobar si el usuario tiene actualizada la clave maestra actual.
*
+ * @param int $userId ID de usuario
* @return bool
*/
- public function checkUserUpdateMPass()
+ public static function checkUserUpdateMPass($userId)
{
$configMPassTime = ConfigDB::getValue('lastupdatempass');
@@ -109,7 +123,7 @@ class UserPass extends UserBase
$Data = new QueryData();
$Data->setMapClassName(UserPassData::class);
$Data->setQuery($query);
- $Data->addParam($this->itemData->getUserId());
+ $Data->addParam($userId);
/** @var UserPassData $queryRes */
$queryRes = DB::getResults($Data);
@@ -117,6 +131,152 @@ class UserPass extends UserBase
return ($queryRes !== false && $queryRes->getUserLastUpdateMPass() >= $configMPassTime);
}
+ /**
+ * Actualizar la clave maestra con la clave anterior del usuario
+ *
+ * @param string $oldUserPass
+ * @param UserLoginData $UserData
+ * @return bool
+ * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
+ * @throws \Defuse\Crypto\Exception\BadFormatException
+ * @throws \SP\Core\Exceptions\SPException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \Defuse\Crypto\Exception\CryptoException
+ */
+ public static function updateMasterPassFromOldPass($oldUserPass, UserLoginData $UserData)
+ {
+ if (self::loadUserMPass($UserData, $oldUserPass) === UserPass::MPASS_OK) {
+ return self::updateUserMPass(self::$clearUserMPass, $UserData);
+ }
+
+ return UserPass::MPASS_WRONG;
+ }
+
+ /**
+ * Comprueba la clave maestra del usuario.
+ *
+ * @param UserLoginData $UserData
+ * @param string $key Clave de cifrado
+ * @return bool
+ * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
+ * @throws \Defuse\Crypto\Exception\BadFormatException
+ * @throws \SP\Core\Exceptions\SPException
+ * @throws \Defuse\Crypto\Exception\CryptoException
+ */
+ public static function loadUserMPass(UserLoginData $UserData, $key = null)
+ {
+ $configHashMPass = ConfigDB::getValue('masterPwd');
+
+ if (empty($configHashMPass)
+ || empty($UserData->getUserMPass())
+ || empty($UserData->getUserMKey())
+ ) {
+ return self::MPASS_NOTSET;
+ } elseif ($UserData->getUserLastUpdateMPass() < ConfigDB::getValue('lastupdatempass')) {
+ return self::MPASS_CHANGED;
+ } elseif ($UserData->isUserIsMigrate() === 1) {
+ return UpgradeUser::upgradeMasterKey($UserData) ? self::MPASS_OK : self::MPASS_WRONG;
+ } else {
+ $securedKey = Crypt::unlockSecuredKey($UserData->getUserMKey(), self::getKey($UserData, $key));
+ $userMPass = Crypt::decrypt($UserData->getUserMPass(), $securedKey, self::getKey($UserData, $key));
+
+ // Comprobamos el hash de la clave del usuario con la guardada
+ if (Hash::checkHashKey($userMPass, $configHashMPass)) {
+ self::$clearUserMPass = $userMPass;
+
+ CryptSession::saveSessionKey($userMPass);
+
+ return self::MPASS_OK;
+ }
+ }
+
+ return self::MPASS_CHECKOLD;
+ }
+
+ /**
+ * Obtener una clave de cifrado basada en la clave del usuario y un salt.
+ *
+ * @param UserLoginData $UserData
+ * @param string $key Clave de cifrado
+ * @return string con la clave de cifrado
+ */
+ private static function getKey(UserLoginData $UserData, $key = null)
+ {
+ $pass = $key === null ? $UserData->getLoginPass() : $key;
+
+ return $pass . $UserData->getLogin() . Config::getConfig()->getPasswordSalt();
+ }
+
+ /**
+ * Actualizar la clave maestra del usuario en la BBDD.
+ *
+ * @param string $userMPass con la clave maestra
+ * @param UserData|UserLoginData $UserData $UserData
+ * @return bool
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \Defuse\Crypto\Exception\CryptoException
+ * @throws \SP\Core\Exceptions\SPException
+ * @throws QueryException
+ */
+ public static function updateUserMPass($userMPass, UserLoginData $UserData)
+ {
+ $configHashMPass = ConfigDB::getValue('masterPwd');
+
+ if ($configHashMPass === false) {
+ return self::MPASS_NOTSET;
+ } elseif (null === $configHashMPass) {
+ $configHashMPass = Hash::hashKey($userMPass);
+ ConfigDB::setValue('masterPwd', $configHashMPass);
+ }
+
+ if (Hash::checkHashKey($userMPass, $configHashMPass)
+ || \SP\Core\Upgrade\Crypt::migrateHash($userMPass)
+ ) {
+ $securedKey = Crypt::makeSecuredKey(self::getKey($UserData));
+ $cryptMPass = Crypt::encrypt($userMPass, $securedKey, self::getKey($UserData));
+
+ if (!empty($cryptMPass)) {
+ if (strlen($securedKey) > 1000 || strlen($cryptMPass) > 1000) {
+ throw new QueryException(SPException::SP_ERROR, __('Error interno', false), '', LoginController::STATUS_INTERNAL_ERROR);
+ }
+
+ $query = /** @lang SQL */
+ 'UPDATE usrData SET
+ user_mPass = ?,
+ user_mKey = ?,
+ user_lastUpdateMPass = UNIX_TIMESTAMP(),
+ user_isMigrate = 0
+ WHERE user_id = ? LIMIT 1';
+
+ $Data = new QueryData();
+ $Data->setQuery($query);
+ $Data->addParam($cryptMPass);
+ $Data->addParam($securedKey);
+ $Data->addParam($UserData->getUserId());
+
+ self::$clearUserMPass = $userMPass;
+
+ $UserData->setUserMPass($cryptMPass);
+ $UserData->setUserMKey($securedKey);
+
+ DB::getQuery($Data);
+
+ return self::MPASS_OK;
+ }
+ }
+
+ return self::MPASS_WRONG;
+ }
+
+ /**
+ * @return string
+ */
+ public static function getClearUserMPass()
+ {
+ return self::$clearUserMPass;
+ }
+
/**
* Modificar la clave de un usuario.
*
@@ -159,179 +319,4 @@ class UserPass extends UserBase
return $this;
}
-
- /**
- * Comprueba la clave maestra del usuario.
- *
- * @return bool
- * @throws \Defuse\Crypto\Exception\CryptoException
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
- * @throws \Defuse\Crypto\Exception\BadFormatException
- * @throws \SP\Core\Exceptions\SPException
- */
- public function loadUserMPass()
- {
- $userMPass = $this->getUserMPass();
- $configHashMPass = ConfigDB::getValue('masterPwd');
-
- if ($userMPass === false || empty($configHashMPass)) {
- return false;
-
- // Comprobamos el hash de la clave del usuario con la guardada
- } elseif (Hash::checkHashKey($userMPass, $configHashMPass)) {
- $this->clearUserMPass = $userMPass;
-
- CryptSession::saveSessionKey($userMPass);
-
- return true;
- }
-
- return null;
- }
-
- /**
- * Desencriptar la clave maestra del usuario para la sesión.
- *
- * @param string $key Clave de cifrado
- * @return false|string Devuelve bool se hay error o string si se devuelve la clave
- * @throws \Defuse\Crypto\Exception\CryptoException
- */
- public function getUserMPass($key = null)
- {
- $query = /** @lang SQL */
- 'SELECT user_mPass,
- user_mKey,
- user_lastUpdateMPass,
- BIN(user_isMigrate) AS user_isMigrate
- FROM usrData WHERE user_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($this->itemData->getUserId());
-
- $queryRes = DB::getResults($Data);
-
- if ($queryRes === false
- || empty($queryRes->user_mPass)
- || empty($queryRes->user_mKey)
- || $queryRes->user_lastUpdateMPass < ConfigDB::getValue('lastupdatempass')
- ) {
- return false;
- } elseif ((int)$queryRes->user_isMigrate === 1) {
- $this->itemData->setUserMPass($queryRes->user_mPass);
- $this->itemData->setUserMKey($queryRes->user_mKey);
-
- return User::upgradeMasterKey($this);
- }
-
- $this->itemData->setUserMPass($queryRes->user_mPass);
- $this->itemData->setUserMKey($queryRes->user_mKey);
-
- $securedKey = Crypt::unlockSecuredKey($queryRes->user_mKey, $this->getKey($key));
-
- return Crypt::decrypt($queryRes->user_mPass, $securedKey, $this->getKey($key));
- }
-
- /**
- * Obtener una clave de cifrado basada en la clave del usuario y un salt.
- *
- * @param string $key Clave de cifrado
- * @return string con la clave de cifrado
- * @throws \Defuse\Crypto\Exception\CryptoException
- */
- private function getKey($key = null)
- {
- $pass = $key === null ? $this->itemData->getUserPass() : $key;
-
- return $pass . $this->itemData->getUserLogin() . Config::getConfig()->getPasswordSalt();
- }
-
- /**
- * @return string
- */
- public function getClearUserMPass()
- {
- return $this->clearUserMPass;
- }
-
- /**
- * Actualizar la clave maestra con la clave anterior del usuario
- *
- * @param $oldUserPass
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \Defuse\Crypto\Exception\CryptoException
- * @throws \SP\Core\Exceptions\SPException
- */
- public function updateMasterPass($oldUserPass)
- {
- $masterPass = $this->getUserMPass($oldUserPass);
-
- if ($masterPass) {
- return $this->updateUserMPass($masterPass);
- }
-
- return false;
- }
-
- /**
- * Actualizar la clave maestra del usuario en la BBDD.
- *
- * @param string $masterPwd con la clave maestra
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \Defuse\Crypto\Exception\CryptoException
- * @throws \SP\Core\Exceptions\SPException
- */
- public function updateUserMPass($masterPwd)
- {
- $configHashMPass = ConfigDB::getValue('masterPwd');
-
- if ($configHashMPass === false) {
- return false;
- } elseif (null === $configHashMPass) {
- $configHashMPass = Hash::hashKey($masterPwd);
- ConfigDB::setValue('masterPwd', $configHashMPass);
- }
-
- if (Hash::checkHashKey($masterPwd, $configHashMPass)
- || \SP\Core\Upgrade\Crypt::migrateHash($masterPwd)
- ) {
- $securedKey = Crypt::makeSecuredKey($this->getKey());
- $cryptMPass = Crypt::encrypt($masterPwd, $securedKey, $this->getKey());
-
- if (!empty($cryptMPass)) {
- if (strlen($securedKey) > 1000 || strlen($cryptMPass) > 1000) {
- throw new QueryException(SPException::SP_ERROR, __('Error interno', false), '', LoginController::STATUS_INTERNAL_ERROR);
- }
-
- $query = /** @lang SQL */
- 'UPDATE usrData SET
- user_mPass = ?,
- user_mKey = ?,
- user_lastUpdateMPass = UNIX_TIMESTAMP(),
- user_isMigrate = 0
- WHERE user_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($cryptMPass);
- $Data->addParam($securedKey);
- $Data->addParam($this->itemData->getUserId());
-
- $this->clearUserMPass = $masterPwd;
-
- $this->itemData->setUserMPass($cryptMPass);
- $this->itemData->setUserMKey($securedKey);
-
- DB::getQuery($Data);
-
- return true;
- }
- }
-
- return false;
- }
}
\ No newline at end of file
diff --git a/js/app-triggers.min.js b/js/app-triggers.min.js
index 8c8afc31..edfb3390 100644
--- a/js/app-triggers.min.js
+++ b/js/app-triggers.min.js
@@ -1,5 +1,5 @@
var $jscomp={scope:{},findInternal:function(b,d,e){b instanceof String&&(b=String(b));for(var a=b.length,c=0;c