diff --git a/app/modules/web/Controllers/ConfigAccountController.php b/app/modules/web/Controllers/ConfigAccountController.php
index 828a2ca0..9160363d 100644
--- a/app/modules/web/Controllers/ConfigAccountController.php
+++ b/app/modules/web/Controllers/ConfigAccountController.php
@@ -46,7 +46,7 @@ class ConfigAccountController extends SimpleControllerBase
*/
public function saveAction()
{
- $configData = clone $this->config->getConfigData();
+ $configData = $this->config->getConfigData();
$eventMessage = EventMessage::factory();
diff --git a/app/modules/web/Controllers/ConfigBackupController.php b/app/modules/web/Controllers/ConfigBackupController.php
index 2aa77f66..86dcbfa4 100644
--- a/app/modules/web/Controllers/ConfigBackupController.php
+++ b/app/modules/web/Controllers/ConfigBackupController.php
@@ -54,8 +54,7 @@ class ConfigBackupController extends SimpleControllerBase
}
try {
- $backupService = new FileBackupService();
- $backupService->doBackup();
+ $this->dic->get(FileBackupService::class)->doBackup();
$this->eventDispatcher->notifyEvent('run.backup.end',
new Event($this, EventMessage::factory()
diff --git a/app/modules/web/Controllers/ConfigGeneralController.php b/app/modules/web/Controllers/ConfigGeneralController.php
index d17a1a56..3facd175 100644
--- a/app/modules/web/Controllers/ConfigGeneralController.php
+++ b/app/modules/web/Controllers/ConfigGeneralController.php
@@ -46,7 +46,7 @@ class ConfigGeneralController extends SimpleControllerBase
*/
public function saveAction()
{
- $configData = clone $this->config->getConfigData();
+ $configData = $this->config->getConfigData();
$eventMessage = EventMessage::factory();
// General
diff --git a/app/modules/web/Controllers/ConfigLdapController.php b/app/modules/web/Controllers/ConfigLdapController.php
index 00250aa1..dd7c7e29 100644
--- a/app/modules/web/Controllers/ConfigLdapController.php
+++ b/app/modules/web/Controllers/ConfigLdapController.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,9 +28,15 @@ use SP\Core\Acl\ActionsInterface;
use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
+use SP\Core\Exceptions\SPException;
+use SP\Core\Exceptions\ValidationException;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Modules\Web\Controllers\Traits\ConfigTrait;
+use SP\Providers\Auth\Ldap\LdapParams;
+use SP\Services\Ldap\LdapCheckService;
+use SP\Services\Ldap\LdapImportParams;
+use SP\Services\Ldap\LdapImportService;
/**
* Class ConfigLdapController
@@ -46,48 +52,168 @@ class ConfigLdapController extends SimpleControllerBase
*/
public function saveAction()
{
- $eventMessage = EventMessage::factory();
- $configData = clone $this->config->getConfigData();
+ try {
+ $eventMessage = EventMessage::factory();
+ $configData = $this->config->getConfigData();
- // LDAP
- $ldapEnabled = Request::analyze('ldap_enabled', false, false, true);
- $ldapADSEnabled = Request::analyze('ldap_ads', false, false, true);
- $ldapServer = Request::analyze('ldap_server');
- $ldapBase = Request::analyze('ldap_base');
- $ldapGroup = Request::analyze('ldap_group');
- $ldapDefaultGroup = Request::analyze('ldap_defaultgroup', 0);
- $ldapDefaultProfile = Request::analyze('ldap_defaultprofile', 0);
- $ldapBindUser = Request::analyze('ldap_binduser');
- $ldapBindPass = Request::analyzeEncrypted('ldap_bindpass');
+ // LDAP
+ $ldapEnabled = Request::analyze('ldap_enabled', false, false, true);
+ $ldapDefaultGroup = Request::analyze('ldap_defaultgroup', 0);
+ $ldapDefaultProfile = Request::analyze('ldap_defaultprofile', 0);
- // Valores para la configuración de LDAP
- if ($ldapEnabled && (!$ldapServer || !$ldapBase || !$ldapBindUser)) {
- $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de LDAP'));
- }
+ $ldapParams = $this->getLdapParamsFromRequest();
- if ($ldapEnabled) {
- $configData->setLdapEnabled(true);
- $configData->setLdapAds($ldapADSEnabled);
- $configData->setLdapServer($ldapServer);
- $configData->setLdapBase($ldapBase);
- $configData->setLdapGroup($ldapGroup);
- $configData->setLdapDefaultGroup($ldapDefaultGroup);
- $configData->setLdapDefaultProfile($ldapDefaultProfile);
- $configData->setLdapBindUser($ldapBindUser);
- $configData->setLdapBindPass($ldapBindPass);
-
- if ($configData->isLdapEnabled() === false) {
- $eventMessage->addDescription(__u('LDAP habiltado'));
+ // Valores para la configuración de LDAP
+ if ($ldapEnabled && !($ldapParams->getServer() || $ldapParams->getSearchBase() || $ldapParams->getBindDn())) {
+ $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de LDAP'));
}
- } elseif ($ldapEnabled === false && $configData->isLdapEnabled()) {
- $configData->setLdapEnabled(false);
- $eventMessage->addDescription(__u('LDAP deshabilitado'));
+ if ($ldapEnabled) {
+ $configData->setLdapEnabled(true);
+ $configData->setLdapAds($ldapParams->isAds());
+ $configData->setLdapServer($ldapParams->getServer());
+ $configData->setLdapBase($ldapParams->getSearchBase());
+ $configData->setLdapGroup($ldapParams->getGroup());
+ $configData->setLdapDefaultGroup($ldapDefaultGroup);
+ $configData->setLdapDefaultProfile($ldapDefaultProfile);
+ $configData->setLdapBindUser($ldapParams->getBindDn());
+ $configData->setLdapBindPass($ldapParams->getBindPass());
+
+ if ($configData->isLdapEnabled() === false) {
+ $eventMessage->addDescription(__u('LDAP habiltado'));
+ }
+ } elseif ($ldapEnabled === false && $configData->isLdapEnabled()) {
+ $configData->setLdapEnabled(false);
+
+ $eventMessage->addDescription(__u('LDAP deshabilitado'));
+ }
+
+ $this->saveConfig($configData, $this->config, function () use ($eventMessage) {
+ $this->eventDispatcher->notifyEvent('save.config.ldap', new Event($this, $eventMessage));
+ });
+ } catch (ValidationException $e) {
+ $this->returnJsonResponseException($e);
+ }
+ }
+
+ /**
+ * @return LdapParams
+ * @throws ValidationException
+ */
+ protected function getLdapParamsFromRequest()
+ {
+ $data = LdapParams::getServerAndPort(Request::analyze('ldap_server'));
+
+ if ($data === false) {
+ throw new ValidationException(__u('Parámetros de LDAP incorrectos'));
}
- $this->saveConfig($configData, $this->config, function () use ($eventMessage) {
- $this->eventDispatcher->notifyEvent('save.config.ldap', new Event($this, $eventMessage));
- });
+ return (new LdapParams())
+ ->setServer($data['server'])
+ ->setPort(isset($data['port']) ? $data['port'] : 389)
+ ->setSearchBase(Request::analyze('ldap_base'))
+ ->setGroup(Request::analyze('ldap_group'))
+ ->setBindDn(Request::analyze('ldap_binduser'))
+ ->setBindPass(Request::analyzeEncrypted('ldap_bindpass'))
+ ->setAds(Request::analyze('ldap_ads', false, false, true));
+ }
+
+ /**
+ * checkAction
+ */
+ public function checkAction()
+ {
+ try {
+ $ldapParams = $this->getLdapParamsFromRequest();
+
+ // Valores para la configuración de LDAP
+ if (!($ldapParams->getServer() || $ldapParams->getSearchBase() || $ldapParams->getBindDn())) {
+ $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Faltan parámetros de LDAP'));
+ }
+
+ $ldapCheckService = $this->dic->get(LdapCheckService::class);
+ $ldapCheckService->checkConnection($ldapParams);
+
+ $results = $ldapCheckService->getUsersAndGroups();
+
+ $this->returnJsonResponseData(
+ $results,
+ JsonResponse::JSON_SUCCESS,
+ __u('Conexión a LDAP correcta'),
+ [sprintf(__('Objetos encontrados: %d'), $results['count'])]
+ );
+ } catch (\Exception $e) {
+ processException($e);
+
+ $this->returnJsonResponseException($e);
+// $this->JsonResponse->addMessage(__('Revise el registro de eventos para más detalles', false));
+ }
+ }
+
+ /**
+ * importAction
+ *
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
+ */
+ public function importAction()
+ {
+ try {
+ $ldapImportParams = new LdapImportParams();
+
+ $ldapImportParams->loginAttribute = Request::analyze('ldap_login_attribute');
+ $ldapImportParams->userNameAttribute = Request::analyze('ldap_username_attribute');
+ $ldapImportParams->userGroupNameAttribute = Request::analyze('ldap_groupname_attribute');
+ $ldapImportParams->defaultUserGroup = Request::analyze('ldap_defaultgroup', 0);
+ $ldapImportParams->defaultUserProfile = Request::analyze('ldap_defaultprofile', 0);
+
+ $checkImportGroups = Request::analyze('ldap_group_import', false, false, true);
+
+ if ((empty($ldapImportParams->loginAttribute)
+ || empty($ldapImportParams->userNameAttribute)
+ || empty($ldapImportParams->defaultUserGroup)
+ || empty($ldapImportParams->defaultUserProfile))
+ && ($checkImportGroups === true && empty($ldapImportParams->userGroupNameAttribute))
+ ) {
+ throw new ValidationException(__u('Parámetros de LDAP incorrectos'));
+ }
+
+ $ldapParams = $this->getLdapParamsFromRequest();
+
+ $userLdapService = $this->dic->get(LdapImportService::class);
+
+ $this->eventDispatcher->notifyEvent('import.ldap.start',
+ new Event($this, EventMessage::factory()->addDescription(__u('Importación LDAP')))
+ );
+
+ $userLdapService->importUsers($ldapParams, $ldapImportParams);
+
+ if ($checkImportGroups === true) {
+ $userLdapService->importGroups($ldapParams, $ldapImportParams);
+ }
+
+ $this->eventDispatcher->notifyEvent('import.ldap.end',
+ new Event($this, EventMessage::factory()->addDescription(__u('Importación finalizada')))
+ );
+
+ if ($userLdapService->getTotalObjects() === 0) {
+ throw new SPException(__u('No se encontraron objetos para sincronizar'));
+ }
+
+ $this->returnJsonResponse(
+ JsonResponse::JSON_SUCCESS,
+ __u('Importación de usuarios de LDAP realizada'),
+ [
+ sprintf(__('Usuarios importados: %d/%d'), $userLdapService->getSyncedObjects(), $userLdapService->getTotalObjects()),
+ sprintf(__('Errores: %d'), $userLdapService->getErrorObjects())
+
+ ]
+ );
+ } catch (\Exception $e) {
+ processException($e);
+
+ $this->returnJsonResponseException($e);
+ }
}
protected function initialize()
diff --git a/app/modules/web/Controllers/ConfigMailController.php b/app/modules/web/Controllers/ConfigMailController.php
index c981dc94..da4730bb 100644
--- a/app/modules/web/Controllers/ConfigMailController.php
+++ b/app/modules/web/Controllers/ConfigMailController.php
@@ -47,7 +47,7 @@ class ConfigMailController extends SimpleControllerBase
public function saveAction()
{
$eventMessage = EventMessage::factory();
- $configData = clone $this->config->getConfigData();
+ $configData = $this->config->getConfigData();
// Mail
$mailEnabled = Request::analyze('mail_enabled', false, false, true);
diff --git a/app/modules/web/Controllers/ConfigWikiController.php b/app/modules/web/Controllers/ConfigWikiController.php
index 9e5045b6..ce3d3e6b 100644
--- a/app/modules/web/Controllers/ConfigWikiController.php
+++ b/app/modules/web/Controllers/ConfigWikiController.php
@@ -47,7 +47,7 @@ class ConfigWikiController extends SimpleControllerBase
public function saveAction()
{
$eventMessage = EventMessage::factory();
- $configData = clone $this->config->getConfigData();
+ $configData = $this->config->getConfigData();
// Wiki
$wikiEnabled = Request::analyze('wiki_enabled', false, false, true);
diff --git a/app/modules/web/Controllers/Traits/JsonTrait.php b/app/modules/web/Controllers/Traits/JsonTrait.php
index 7a6e5daa..f317185f 100644
--- a/app/modules/web/Controllers/Traits/JsonTrait.php
+++ b/app/modules/web/Controllers/Traits/JsonTrait.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.
@@ -38,9 +38,9 @@ trait JsonTrait
/**
* Returns JSON response
*
- * @param int $status Status code
- * @param string $description Untranslated description string
- * @param array|null $messages Untranslated massages array of strings
+ * @param int $status Status code
+ * @param string $description Untranslated description string
+ * @param array|null $messages Untranslated massages array of strings
*/
protected function returnJsonResponse($status, $description, array $messages = null)
{
@@ -58,11 +58,12 @@ trait JsonTrait
/**
* Returns JSON response
*
- * @param mixed $data
- * @param int $status Status code
- * @param null $description Untranslated description string
+ * @param mixed $data
+ * @param int $status Status code
+ * @param string $description Untranslated description string
+ * @param array $messages
*/
- protected function returnJsonResponseData($data, $status = JsonResponse::JSON_SUCCESS, $description = null)
+ protected function returnJsonResponseData($data, $status = JsonResponse::JSON_SUCCESS, $description = null, array $messages = null)
{
$jsonResponse = new JsonResponse();
$jsonResponse->setStatus($status);
@@ -72,6 +73,9 @@ trait JsonTrait
$jsonResponse->setDescription($description);
}
+ if (null !== $messages) {
+ $jsonResponse->setMessages($messages);
+ }
Json::returnJson($jsonResponse);
}
@@ -80,7 +84,7 @@ trait JsonTrait
* Returns JSON response
*
* @param \Exception $exception
- * @param int $status Status code
+ * @param int $status Status code
*/
protected function returnJsonResponseException(\Exception $exception, $status = JsonResponse::JSON_ERROR)
{
diff --git a/app/modules/web/themes/material-blue/js/app-theme.js b/app/modules/web/themes/material-blue/js/app-theme.js
index 915c8591..b431aae6 100644
--- a/app/modules/web/themes/material-blue/js/app-theme.js
+++ b/app/modules/web/themes/material-blue/js/app-theme.js
@@ -479,27 +479,21 @@ sysPass.Theme = function (Common) {
/**
* Elementos HTML del tema
- *
- * @type {{getList: html.getList}}
*/
- var html = {
+ const html = {
getList: function (items, icon) {
- var $ul = $("
");
- var $li = $("");
- var $span = $("");
+ const $ul = $("");
+ const $li = $("");
+ const $span = $("");
- if (icon === undefined) {
- icon = "person";
- } else {
- icon = "" + icon + "";
- }
+ const i = "" + (icon === undefined ? "person" : icon) + "";
items.forEach(function (value) {
- var $spanClone = $span.clone();
- $spanClone.append(icon);
+ const $spanClone = $span.clone();
+ $spanClone.append(i);
$spanClone.append(value);
- var $item = $li.clone().append($spanClone);
+ const $item = $li.clone().append($spanClone);
$ul.append($item);
});
@@ -507,15 +501,15 @@ sysPass.Theme = function (Common) {
},
tabs: {
add: function (header, index, title, isActive) {
- var $header = $(header);
- var active = "";
+ const $header = $(header);
+ let active;
if (isActive === 1) {
$header.parent().find("#tabs-" + index).addClass("is-active");
active = "is-active";
}
- var tab = "" + title + "";
+ const tab = "" + title + "";
$header.append(tab);
}
diff --git a/app/modules/web/themes/material-blue/js/app-theme.min.js b/app/modules/web/themes/material-blue/js/app-theme.min.js
index 86393686..2f283f66 100644
--- a/app/modules/web/themes/material-blue/js/app-theme.min.js
+++ b/app/modules/web/themes/material-blue/js/app-theme.min.js
@@ -1,20 +1,20 @@
-var $jscomp={scope:{},findInternal:function(a,e,c){a instanceof String&&(a=String(a));for(var g=a.length,k=0;k");
-a.passwordData.complexity.numbers&&(d+="1234567890");a.passwordData.complexity.chars&&(d+="abcdefghijklmnopqrstuvwxyz",a.passwordData.complexity.uppercase&&(d+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"));for(;f++");
+a.passwordData.complexity.numbers&&(d+="1234567890");a.passwordData.complexity.chars&&(d+="abcdefghijklmnopqrstuvwxyz",a.passwordData.complexity.uppercase&&(d+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"));for(;m++";mdlDialog().show({title:a.config().LANG[29],text:b,negative:{title:a.config().LANG[44]},positive:{title:a.config().LANG[43],onClick:function(f){f.preventDefault();a.passwordData.complexity.chars=$("#checkbox-chars").is(":checked");a.passwordData.complexity.numbers=$("#checkbox-numbers").is(":checked");a.passwordData.complexity.uppercase=$("#checkbox-uppercase").is(":checked");a.passwordData.complexity.symbols=$("#checkbox-symbols").is(":checked");a.passwordData.complexity.numlength=
-parseInt($("#passlength").val())}},cancelable:!0,contentStyle:{"max-width":"300px"},onLoaded:function(){$("#checkbox-chars").prop("checked",a.passwordData.complexity.chars);$("#checkbox-numbers").prop("checked",a.passwordData.complexity.numbers);$("#checkbox-uppercase").prop("checked",a.passwordData.complexity.uppercase);$("#checkbox-symbols").prop("checked",a.passwordData.complexity.symbols);$("#passlength").val(a.passwordData.complexity.numlength)}})},l=function(b){b.find(".passwordfield__input").each(function(){var f=
-$(this);if("true"!==f.attr("data-pass-upgraded")){var d=f.parent(),b=f.attr("id"),c='',c=c+(''),e=$(''),g=$(''),f=''+(void 0===c?"person":c)+"";a.forEach(function(a){var c=g.clone();c.append(f);c.append(a);a=e.clone().append(c);b.append(a)});
+return b},tabs:{add:function(a,c,d,e){a=$(a);var b;1===e&&(a.parent().find("#tabs-"+c).addClass("is-active"),b="is-active");a.append(''+d+"")}}}}};
diff --git a/app/modules/web/themes/material-blue/views/config/ldap.inc b/app/modules/web/themes/material-blue/views/config/ldap.inc
index 907428ed..10f90559 100644
--- a/app/modules/web/themes/material-blue/views/config/ldap.inc
+++ b/app/modules/web/themes/material-blue/views/config/ldap.inc
@@ -1,7 +1,7 @@
-
+
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
+
+
+ -
+
+
+ -
+
+
+
+
\ No newline at end of file
diff --git a/lib/Definitions.php b/lib/Definitions.php
index 44b49d6c..2f8f33b4 100644
--- a/lib/Definitions.php
+++ b/lib/Definitions.php
@@ -30,7 +30,7 @@ return [
\SP\Core\Session\Session::class => object(\SP\Core\Session\Session::class),
\SP\Config\Config::class => object(\SP\Config\Config::class)
->constructor(object(\SP\Storage\XmlHandler::class)
- ->constructor(CONFIG_FILE)),
+ ->constructor(CONFIG_FILE), get(\SP\Core\Session\Session::class)),
\SP\Core\Language::class => object(\SP\Core\Language::class),
\SP\Config\ConfigData::class => function (\SP\Config\Config $config) {
return $config->getConfigData();
diff --git a/lib/SP/Config/Config.php b/lib/SP/Config/Config.php
index f8295563..5767080f 100644
--- a/lib/SP/Config/Config.php
+++ b/lib/SP/Config/Config.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,10 +24,11 @@
namespace SP\Config;
+use DI\Container;
use ReflectionObject;
use SP\Core\Exceptions\ConfigException;
use SP\Core\Session\Session;
-use SP\Core\Traits\InjectableTrait;
+use SP\Services\Config\ConfigBackupService;
use SP\Storage\XmlFileStorageInterface;
use SP\Storage\XmlHandler;
@@ -38,8 +39,6 @@ defined('APP_ROOT') || die();
*/
class Config
{
- use InjectableTrait;
-
/**
* @var bool
*/
@@ -56,18 +55,24 @@ class Config
* @var Session
*/
private $session;
+ /**
+ * @var Container
+ */
+ private $dic;
/**
* Config constructor.
*
* @param XmlFileStorageInterface $fileStorage
- * @throws \SP\Core\Exceptions\ConfigException
- * @throws \SP\Core\Dic\ContainerException
+ * @param Session $session
+ * @param Container $dic
+ * @throws ConfigException
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
*/
- public function __construct(XmlFileStorageInterface $fileStorage)
+ public function __construct(XmlFileStorageInterface $fileStorage, Session $session, Container $dic)
{
- $this->injectDependencies();
-
+ $this->session = $session;
$this->fileStorage = $fileStorage;
if (!self::$configLoaded) {
@@ -77,6 +82,7 @@ class Config
self::$configLoaded = true;
}
+ $this->dic = $dic;
}
/**
@@ -90,11 +96,11 @@ class Config
ConfigUtil::checkConfigDir();
try {
- // Mapear el array de elementos de configuración con las propieades de la clase configData
+ // Mapear el array de elementos de configuración con las propiedades de la clase configData
$items = $this->fileStorage->load('config')->getItems();
- $Reflection = new ReflectionObject($this->configData);
+ $reflectionObject = new ReflectionObject($this->configData);
- foreach ($Reflection->getProperties() as $property) {
+ foreach ($reflectionObject->getProperties() as $property) {
$property->setAccessible(true);
if (isset($items[$property->getName()])) {
@@ -112,16 +118,6 @@ class Config
return $this->configData;
}
- /**
- * Obtener la configuración o devolver una nueva
- *
- * @return void
- * @deprecated
- */
- public static function getConfig()
- {
- }
-
/**
* Cargar la configuración desde el archivo
*
@@ -156,29 +152,21 @@ class Config
*
* @param ConfigData $configData
* @param bool $backup
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
- public function saveConfig(ConfigData $configData = null, $backup = true)
+ public function saveConfig(ConfigData $configData, $backup = true)
{
- $configData = null === $configData ? $this->configData : $configData;
+ if ($backup) {
+ $this->dic->get(ConfigBackupService::class)->backup();
+ }
+
$configData->setConfigDate(time());
$configData->setConfigSaver($this->session->getUserData()->getLogin());
$configData->setConfigHash();
$this->fileStorage->setItems($configData);
$this->fileStorage->save('config');
-
-// if ($backup) {
-// $this->backupToDB();
-// }
- }
-
- /**
- * Realizar un backup de la configuración en la BD
- */
- private function backupToDB()
- {
- ConfigDB::setValue('config_backup', json_encode($this->configData), true, true);
- ConfigDB::setValue('config_backupdate', time());
}
/**
@@ -186,26 +174,6 @@ class Config
*/
public function getConfigData()
{
- return $this->configData;
- }
-
- /**
- * @param Session $session
- */
- public function inject(Session $session)
- {
- $this->session = $session;
- }
-
- /**
- * Restaurar la configuración desde la BD
- *
- * @return array
- */
- private function restoreBackupFromDB()
- {
- $configBackup = ConfigDB::getValue('config_backup');
-
- return json_decode($configBackup);
+ return clone $this->configData;
}
}
diff --git a/lib/SP/Config/ConfigUtil.php b/lib/SP/Config/ConfigUtil.php
index 485b914d..5ba05006 100644
--- a/lib/SP/Config/ConfigUtil.php
+++ b/lib/SP/Config/ConfigUtil.php
@@ -81,7 +81,7 @@ class ConfigUtil
throw new ConfigException(
__u('Los permisos del directorio "/config" son incorrectos'),
ConfigException::ERROR,
- sprintf(__u('Actual: %s - Necesario: 750'), $configPerms));
+ sprintf(__('Actual: %s - Necesario: 750'), $configPerms));
}
}
}
\ No newline at end of file
diff --git a/lib/SP/Core/CryptPKI.php b/lib/SP/Core/CryptPKI.php
index 394b90b4..df010b1a 100644
--- a/lib/SP/Core/CryptPKI.php
+++ b/lib/SP/Core/CryptPKI.php
@@ -30,7 +30,6 @@ use phpseclib\Crypt\RSA;
use SP\Core\Exceptions\FileNotFoundException;
use SP\Core\Exceptions\SPException;
use SP\Core\Traits\InjectableTrait;
-use SP\Log\Log;
/**
* Class CryptPKI para el manejo de las funciones para PKI
@@ -130,8 +129,6 @@ class CryptPKI
$file = $this->getPublicKeyFile();
if (!file_exists($file)) {
- Log::writeNewLog(__FUNCTION__, __('El archivo de clave no existe', false), Log::NOTICE);
-
throw new FileNotFoundException(SPException::ERROR, __('El archivo de clave no existe'));
}
@@ -150,7 +147,7 @@ class CryptPKI
$this->rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
$this->rsa->loadKey($this->getPrivateKey());
- return $this->rsa->decrypt($data);
+ return @$this->rsa->decrypt($data);
}
/**
@@ -164,8 +161,6 @@ class CryptPKI
$file = $this->getPrivateKeyFile();
if (!file_exists($file)) {
- Log::writeNewLog(__FUNCTION__, __('El archivo de clave no existe', false), Log::NOTICE);
-
throw new FileNotFoundException(SPException::ERROR, __('El archivo de clave no existe'));
}
diff --git a/lib/SP/DataModel/UserData.php b/lib/SP/DataModel/UserData.php
index fdca7220..8f9c354a 100644
--- a/lib/SP/DataModel/UserData.php
+++ b/lib/SP/DataModel/UserData.php
@@ -36,23 +36,23 @@ class UserData extends UserPassData implements DataModelInterface
/**
* @var string
*/
- public $login = '';
+ public $login;
/**
* @var string
*/
- public $ssoLogin = '';
+ public $ssoLogin;
/**
* @var string
*/
- public $name = '';
+ public $name;
/**
* @var string
*/
- public $email = '';
+ public $email;
/**
* @var string
*/
- public $notes = '';
+ public $notes;
/**
* @var int
*/
@@ -92,11 +92,11 @@ class UserData extends UserPassData implements DataModelInterface
/**
* @var string
*/
- public $lastLogin = '';
+ public $lastLogin;
/**
* @var string
*/
- public $lastUpdate = '';
+ public $lastUpdate;
/**
* @var bool
*/
@@ -108,7 +108,7 @@ class UserData extends UserPassData implements DataModelInterface
/**
* @var string
*/
- public $userGroupName = '';
+ public $userGroupName;
/**
* @return int
diff --git a/lib/SP/DataModel/UserPassData.php b/lib/SP/DataModel/UserPassData.php
index dbf06d29..aeb1436b 100644
--- a/lib/SP/DataModel/UserPassData.php
+++ b/lib/SP/DataModel/UserPassData.php
@@ -38,19 +38,19 @@ class UserPassData extends DataModelBase
/**
* @var string
*/
- public $pass = '';
+ public $pass;
/**
* @var string
*/
- public $hashSalt = '';
+ public $hashSalt;
/**
* @var string
*/
- public $mPass = '';
+ public $mPass;
/**
* @var string
*/
- public $mKey = '';
+ public $mKey;
/**
* @var int
*/
diff --git a/lib/SP/Http/Request.php b/lib/SP/Http/Request.php
index 97546502..46195f17 100644
--- a/lib/SP/Http/Request.php
+++ b/lib/SP/Http/Request.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.
@@ -118,10 +118,14 @@ class Request
try {
// Desencriptar con la clave RSA
- $CryptPKI = new CryptPKI();
- $clearData = $CryptPKI->decryptRSA(base64_decode($encryptedData));
+ if (($clearData = (new CryptPKI())->decryptRSA(base64_decode($encryptedData))) === false) {
+ debugLog('No RSA encrypted data from request');
+
+ return $encryptedData;
+ }
} catch (\Exception $e) {
- debugLog($e->getMessage());
+ processException($e);
+
return $encryptedData;
}
diff --git a/lib/SP/Providers/Auth/Auth.php b/lib/SP/Providers/Auth/Auth.php
index fb74891c..9f85d080 100644
--- a/lib/SP/Providers/Auth/Auth.php
+++ b/lib/SP/Providers/Auth/Auth.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,7 +25,6 @@
namespace SP\Providers\Auth;
use SP\Config\ConfigData;
-use SP\Core\Exceptions\SPException;
use SP\DataModel\UserLoginData;
use SP\Providers\Auth\Browser\Browser;
use SP\Providers\Auth\Browser\BrowserAuthData;
@@ -33,7 +32,12 @@ use SP\Providers\Auth\Database\Database;
use SP\Providers\Auth\Database\DatabaseAuthData;
use SP\Providers\Auth\Ldap\LdapAuthData;
use SP\Providers\Auth\Ldap\LdapMsAds;
+use SP\Providers\Auth\Ldap\LdapParams;
use SP\Providers\Auth\Ldap\LdapStd;
+use SP\Providers\Provider;
+use SP\Services\Auth\AuthException;
+use SP\Services\User\UserPassService;
+use SP\Services\User\UserService;
defined('APP_ROOT') || die();
@@ -44,7 +48,7 @@ defined('APP_ROOT') || die();
*
* @package SP\Providers\Auth
*/
-class Auth
+class Auth extends Provider
{
/**
* @var array
@@ -59,55 +63,16 @@ class Auth
*/
protected $configData;
- /**
- * Auth constructor.
- *
- * @param UserLoginData $userLoginData
- * @param ConfigData $configData
- * @throws SPException
- */
- public function __construct(UserLoginData $userLoginData, ConfigData $configData)
- {
- $this->userLoginData = $userLoginData;
- $this->configData = $configData;
-
- if ($this->configData->isAuthBasicEnabled()) {
- $this->registerAuth('authBrowser');
- }
-
- if ($this->configData->isLdapEnabled()) {
- $this->registerAuth('authLdap');
- }
-
- $this->registerAuth('authDatabase');
- }
-
- /**
- * Registrar un método de autentificación primarios
- *
- * @param string $auth Función de autentificación
- * @throws SPException
- */
- protected function registerAuth($auth)
- {
- if (array_key_exists($auth, $this->auths)) {
- throw new SPException(__u('Método ya inicializado'), SPException::ERROR, __FUNCTION__);
- }
-
- if (!method_exists($this, $auth)) {
- throw new SPException(__u('Método no disponible'), SPException::ERROR, __FUNCTION__);
- }
-
- $this->auths[$auth] = $auth;
- }
-
/**
* Probar los métodos de autentificación
*
+ * @param UserLoginData $userLoginData
* @return bool|array
*/
- public function doAuth()
+ public function doAuth(UserLoginData $userLoginData)
{
+ $this->userLoginData = $userLoginData;
+
$auths = [];
/** @var AuthDataBase $pAuth */
@@ -129,7 +94,18 @@ class Auth
*/
public function authLdap()
{
- $ldap = $this->configData->isLdapAds() ? new LdapMsAds() : new LdapStd();
+ $ldapParams = (new LdapParams())
+ ->setServer($this->configData->getLdapServer())
+ ->setBindDn($this->configData->getLdapBindUser())
+ ->setBindPass($this->configData->getLdapBindPass())
+ ->setSearchBase($this->configData->getLdapBase())
+ ->setAds($this->configData->isLdapAds());
+
+ if ($this->configData->isLdapAds()) {
+ $ldap = new LdapMsAds($ldapParams, $this->eventDispatcher, $this->configData->isDebug());
+ } else {
+ $ldap = new LdapStd($ldapParams, $this->eventDispatcher, $this->configData->isDebug());
+ }
$ldapAuthData = $ldap->getLdapAuthData();
@@ -156,12 +132,13 @@ class Auth
* se ejecuta el proceso para actualizar la clave.
*
* @return DatabaseAuthData
- * @throws \ReflectionException
- * @throws \SP\Core\Dic\ContainerException
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
*/
public function authDatabase()
{
- return (new Database())->authenticate($this->userLoginData);
+ return (new Database($this->dic->get(UserService::class), $this->dic->get(UserPassService::class)))
+ ->authenticate($this->userLoginData);
}
/**
@@ -171,6 +148,45 @@ class Auth
*/
public function authBrowser()
{
- return (new Browser())->authenticate($this->userLoginData);
+ return (new Browser($this->configData))->authenticate($this->userLoginData);
+ }
+
+ /**
+ * Auth constructor.
+ *
+ * @throws AuthException
+ */
+ protected function initialize()
+ {
+ $this->configData = $this->config->getConfigData();
+
+ if ($this->configData->isAuthBasicEnabled()) {
+ $this->registerAuth('authBrowser');
+ }
+
+ if ($this->configData->isLdapEnabled()) {
+ $this->registerAuth('authLdap');
+ }
+
+ $this->registerAuth('authDatabase');
+ }
+
+ /**
+ * Registrar un método de autentificación primarios
+ *
+ * @param string $auth Función de autentificación
+ * @throws AuthException
+ */
+ protected function registerAuth($auth)
+ {
+ if (array_key_exists($auth, $this->auths)) {
+ throw new AuthException(__u('Método ya inicializado'), AuthException::ERROR, __FUNCTION__);
+ }
+
+ if (!method_exists($this, $auth)) {
+ throw new AuthException(__u('Método no disponible'), AuthException::ERROR, __FUNCTION__);
+ }
+
+ $this->auths[$auth] = $auth;
}
}
diff --git a/lib/SP/Providers/Auth/Browser/Browser.php b/lib/SP/Providers/Auth/Browser/Browser.php
index 9bbecfd4..89b30e50 100644
--- a/lib/SP/Providers/Auth/Browser/Browser.php
+++ b/lib/SP/Providers/Auth/Browser/Browser.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,7 @@
namespace SP\Providers\Auth\Browser;
-use SP\Config\Config;
use SP\Config\ConfigData;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\UserLoginData;
use SP\Providers\Auth\AuthInterface;
@@ -39,25 +37,19 @@ use SP\Providers\Auth\AuthInterface;
*/
class Browser implements AuthInterface
{
- use InjectableTrait;
-
- /** @var ConfigData */
- protected $configData;
+ /**
+ * @var ConfigData
+ */
+ private $configData;
/**
* Browser constructor.
+ *
+ * @param ConfigData $configData
*/
- public function __construct()
+ public function __construct(ConfigData $configData)
{
- $this->injectDependencies();
- }
-
- /**
- * @param Config $config
- */
- public function inject(Config $config)
- {
- $this->configData = $config->getConfigData();
+ $this->configData = $configData;
}
/**
diff --git a/lib/SP/Providers/Auth/Database/Database.php b/lib/SP/Providers/Auth/Database/Database.php
index 341f9e11..0243b440 100644
--- a/lib/SP/Providers/Auth/Database/Database.php
+++ b/lib/SP/Providers/Auth/Database/Database.php
@@ -25,9 +25,9 @@
namespace SP\Providers\Auth\Database;
use SP\Core\Crypt\Hash;
-use SP\Core\Exceptions\SPException;
use SP\DataModel\UserLoginData;
use SP\Providers\Auth\AuthInterface;
+use SP\Services\User\UserLoginResponse;
use SP\Services\User\UserPassService;
use SP\Services\User\UserService;
@@ -44,14 +44,33 @@ class Database implements AuthInterface
* @var UserLoginData $userLoginData
*/
protected $userLoginData;
+ /**
+ * @var UserService
+ */
+ private $userService;
+ /**
+ * @var UserPassService
+ */
+ private $userPassService;
+
+ /**
+ * Database constructor.
+ *
+ * @param UserService $userService
+ * @param UserPassService $userPassService
+ */
+ public function __construct(UserService $userService, UserPassService $userPassService)
+ {
+ $this->userService = $userService;
+ $this->userPassService = $userPassService;
+ }
+
/**
* Autentificar al usuario
*
* @param UserLoginData $userLoginData Datos del usuario
* @return DatabaseAuthData
- * @throws \SP\Core\Dic\ContainerException
- * @throws \ReflectionException
*/
public function authenticate(UserLoginData $userLoginData)
{
@@ -81,23 +100,22 @@ class Database implements AuthInterface
* se ejecuta el proceso para actualizar la clave.
*
* @return bool
- * @throws \SP\Core\Dic\ContainerException
- * @throws \ReflectionException
*/
protected function authUser()
{
try {
- $userLoginResponse = (new UserService())->getByLogin($this->userLoginData->getLoginUser());
+ $userLoginResponse = $this->userService->getByLogin($this->userLoginData->getLoginUser());
$this->userLoginData->setUserLoginResponse($userLoginResponse);
- if ($userLoginResponse->getIsMigrate() && $this->checkMigrateUser()) {
- return (new UserPassService())->migrateUserPassById($userLoginResponse->getId(), $this->userLoginData->getLoginPass());
+ if ($userLoginResponse->getIsMigrate() && $this->checkMigrateUser($userLoginResponse)) {
+ return $this->userPassService->migrateUserPassById($userLoginResponse->getId(), $this->userLoginData->getLoginPass());
}
return Hash::checkHashKey($this->userLoginData->getLoginPass(), $userLoginResponse->getPass());
- } catch (SPException $e) {
+ } catch (\Exception $e) {
+ processException($e);
// $Log = new Log();
// $LogMessage = $Log->getLogMessage();
// $LogMessage->setAction(__FUNCTION__);
@@ -110,12 +128,11 @@ class Database implements AuthInterface
}
/**
+ * @param UserLoginResponse $userLoginResponse
* @return bool
*/
- protected function checkMigrateUser()
+ protected function checkMigrateUser(UserLoginResponse $userLoginResponse)
{
- $userLoginResponse = $this->userLoginData->getUserLoginResponse();
-
return ($userLoginResponse->getPass() === sha1($userLoginResponse->getHashSalt() . $this->userLoginData->getLoginPass())
|| $userLoginResponse->getPass() === md5($this->userLoginData->getLoginPass())
|| hash_equals($userLoginResponse->getPass(), crypt($this->userLoginData->getLoginPass(), $userLoginResponse->getHashSalt()))
diff --git a/lib/SP/Providers/Auth/Ldap/LdapBase.php b/lib/SP/Providers/Auth/Ldap/LdapBase.php
index dbef4a3c..7c1dd7f6 100644
--- a/lib/SP/Providers/Auth/Ldap/LdapBase.php
+++ b/lib/SP/Providers/Auth/Ldap/LdapBase.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,13 +24,10 @@
namespace SP\Providers\Auth\Ldap;
-use SP\Config\Config;
-use SP\Config\ConfigData;
-use SP\Core\Exceptions\SPException;
-use SP\Core\Messages\LogMessage;
-use SP\Core\Traits\InjectableTrait;
+use SP\Core\Events\Event;
+use SP\Core\Events\EventDispatcher;
+use SP\Core\Events\EventMessage;
use SP\DataModel\UserLoginData;
-use SP\Log\Log;
use SP\Providers\Auth\AuthInterface;
/**
@@ -62,34 +59,6 @@ abstract class LdapBase implements LdapInterface, AuthInterface
* @var resource
*/
protected $ldapHandler;
- /**
- * @var string
- */
- protected $server;
- /**
- * @var int
- */
- protected $serverPort;
- /**
- * @var string
- */
- protected $searchBase;
- /**
- * @var string
- */
- protected $bindDn;
- /**
- * @var string
- */
- protected $bindPass;
- /**
- * @var string
- */
- protected $group;
- /**
- * @var array
- */
- protected $searchData;
/**
* @var string
*/
@@ -97,237 +66,194 @@ abstract class LdapBase implements LdapInterface, AuthInterface
/**
* @var LdapAuthData
*/
- protected $LdapAuthData;
+ protected $ldapAuthData;
/**
- * @var LogMessage
+ * @var LdapParams
*/
- protected $LogMessage;
-
- use InjectableTrait;
-
- /** @var ConfigData */
- protected $ConfigData;
+ protected $ldapParams;
+ /**
+ * @var EventDispatcher
+ */
+ protected $eventDispatcher;
+ /**
+ * @var string
+ */
+ protected $server;
+ /**
+ * @var bool
+ */
+ protected $isConnected = false;
+ /**
+ * @var bool
+ */
+ protected $isBound = false;
+ /**
+ * @var bool
+ */
+ private $debug;
/**
* LdapBase constructor.
- */
- public function __construct()
- {
- $this->injectDependencies();
-
- $this->LdapAuthData = new LdapAuthData();
- $this->LogMessage = new LogMessage();
- }
-
- /**
- * @param Config $config
- */
- public function inject(Config $config)
- {
- $this->Config = $config;
- $this->ConfigData = $config->getConfigData();
- }
-
- /**
- * Indica si es requerida para acceder a la aplicación
*
- * @return boolean
+ * @param LdapParams $ldapParams
+ * @param EventDispatcher $eventDispatcher
+ * @param bool $debug
*/
- public function isAuthGranted()
+ public function __construct(LdapParams $ldapParams, EventDispatcher $eventDispatcher, $debug = false)
{
- return true;
+ $this->ldapParams = $ldapParams;
+ $this->eventDispatcher = $eventDispatcher;
+ $this->debug = (bool)$debug;
+
+ $this->ldapAuthData = new LdapAuthData();
}
/**
* Comprobar la conexión al servidor de LDAP.
*
- * @return false|array Con el número de entradas encontradas
- * @throws \SP\Core\Exceptions\SPException
+ * @throws LdapException
*/
public function checkConnection()
{
- $this->LogMessage->setAction(__FUNCTION__);
-
- if (!$this->searchBase || !$this->server || !$this->bindDn || !$this->bindPass) {
- $this->LogMessage->addDescription(__('Los parámetros de LDAP no están configurados', false));
- $this->writeLog();
-
- return false;
- }
-
try {
- $this->connect();
- $this->bind();
- $results = $this->searchBase();
- } catch (SPException $e) {
+ $this->connectAndBind();
+
+ $this->eventDispatcher->notifyEvent('ldap.check.connection',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Conexión a LDAP correcta')))
+ );
+ } catch (LdapException $e) {
throw $e;
}
-
- $this->LogMessage->addDescription(__('Conexión a LDAP correcta', false));
- $this->LogMessage->addDetails(__('Objetos encontrados', false), (int)$results['count']);
- $this->writeLog(Log::INFO);
-
- return $results;
}
/**
- * Escribir en el registro de eventos
- *
- * @param string $level
+ * @throws LdapException
*/
- protected function writeLog($level = Log::ERROR)
+ protected function connectAndBind()
{
- $Log = new Log($this->LogMessage);
- $Log->setLogLevel($level);
- $Log->writeLog();
+ if (!$this->isConnected && !$this->isBound) {
+ $this->connect();
+ $this->bind();
+ }
}
/**
* Realizar la conexión al servidor de LDAP.
*
- * @throws SPException
+ * @throws LdapException
* @return bool
*/
protected function connect()
{
+ $this->checkParams();
+
// Habilitar la traza si el modo debug está habilitado
- if ($this->ConfigData->isDebug()) {
+ if ($this->debug) {
@ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
}
- $this->ldapHandler = @ldap_connect($this->server, $this->serverPort);
+ $this->ldapHandler = @ldap_connect($this->server, $this->ldapParams->getPort());
// Conexión al servidor LDAP
if (!is_resource($this->ldapHandler)) {
- $this->LogMessage->setAction(__FUNCTION__);
- $this->LogMessage->addDescription(__('No es posible conectar con el servidor de LDAP', false));
- $this->LogMessage->addDetails(__('Servidor'), $this->server);
- $this->LogMessage->addDetails('LDAP ERROR', $this->ldapError());
- $this->writeLog();
+ $this->eventDispatcher->notifyEvent('ldap.connection',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('No es posible conectar con el servidor de LDAP'))
+ ->addDetail(__('Servidor'), $this->server)
+ ->addDetail('LDAP ERROR', $this->getLdapErrorMessage()))
+ );
- throw new SPException($this->LogMessage->getDescription(), SPException::ERROR, $this->LogMessage->getDetails());
+ throw new LdapException(__u('No es posible conectar con el servidor de LDAP'));
}
@ldap_set_option($this->ldapHandler, LDAP_OPT_NETWORK_TIMEOUT, 10);
@ldap_set_option($this->ldapHandler, LDAP_OPT_PROTOCOL_VERSION, 3);
+ $this->isConnected = true;
+
return true;
}
+ /**
+ * Comprobar si los parámetros necesario de LDAP están establecidos.
+ *
+ * @throws LdapException
+ */
+ public function checkParams()
+ {
+ if (!$this->ldapParams->getSearchBase()
+ || !$this->ldapParams->getServer()
+ || !$this->ldapParams->getBindDn()
+ ) {
+ $this->eventDispatcher->notifyEvent('ldap.check.params',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Los parámetros de LDAP no están configurados')))
+ );
+
+ throw new LdapException(__u('Los parámetros de LDAP no están configurados'));
+ }
+
+ $this->server = $this->pickServer();
+ $this->ldapAuthData->setServer($this->server);
+ }
+
+ /**
+ * Obtener el servidor de LDAP a utilizar
+ *
+ * @return mixed
+ */
+ protected abstract function pickServer();
+
/**
* Registrar error de LDAP y devolver el mensaje de error
*
* @return string
*/
- protected function ldapError()
+ protected function getLdapErrorMessage()
{
- $error = ldap_error($this->ldapHandler);
- $errno = ldap_errno($this->ldapHandler);
+ $this->ldapAuthData->setStatusCode(ldap_errno($this->ldapHandler));
- $this->LdapAuthData->setStatusCode($errno);
-
- return sprintf('%s (%d)', $error, $errno);
+ return sprintf('%s (%d)', ldap_error($this->ldapHandler), $this->ldapAuthData->getStatusCode());
}
/**
* Realizar la autentificación con el servidor de LDAP.
*
- * @param string $bindDn con el DN del usuario
+ * @param string $bindDn con el DN del usuario
* @param string $bindPass con la clave del usuario
- * @throws SPException
+ * @throws LdapException
* @return bool
*/
- protected function bind($bindDn = '', $bindPass = '')
+ protected function bind($bindDn = null, $bindPass = null)
{
- if ($bindDn && $bindPass) {
- $this->LdapAuthData->setAuthenticated(1);
+ $this->ldapAuthData->setAuthenticated($bindDn && $bindPass);
+
+ $dn = $bindDn ?: $this->ldapParams->getBindDn();
+ $pass = $bindPass ?: $this->ldapParams->getBindPass();
+
+ if (@ldap_bind($this->ldapHandler, $dn, $pass) === false) {
+ $this->eventDispatcher->notifyEvent('ldap.bind',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Error al conectar (BIND)'))
+ ->addDetail('LDAP ERROR', $this->getLdapErrorMessage())
+ ->addDetail('LDAP DN', $dn))
+ );
+
+ throw new LdapException(__u('Error al conectar (BIND)'));
}
- $dn = $bindDn ?: $this->bindDn;
- $pass = $bindPass ?: $this->bindPass;
-
- if (!@ldap_bind($this->ldapHandler, $dn, $pass)) {
- $this->LogMessage->setAction(__FUNCTION__);
- $this->LogMessage->addDescription(__('Error al conectar (BIND)', false));
- $this->LogMessage->addDetails('LDAP ERROR', $this->ldapError());
- $this->LogMessage->addDetails('LDAP DN', $dn);
- $this->writeLog();
-
- throw new SPException(__($this->LogMessage->getDescription()), SPException::ERROR);
- }
+ $this->isBound = true;
return true;
}
- /**
- * Realizar una búsqueda de objetos en la ruta indicada.
- *
- * @throws SPException
- * @return array Con los resultados de la búsqueda
- */
- protected function searchBase()
- {
- $searchResults = $this->getResults($this->getGroupDnFilter(), ['dn']);
-
- if ($searchResults === false) {
- $this->LogMessage->setAction(__FUNCTION__);
- $this->LogMessage->addDescription(__('Error al buscar objetos en DN base', false));
- $this->LogMessage->addDetails('LDAP ERROR', $this->ldapError());
- $this->LogMessage->addDetails('LDAP FILTER', $this->getGroupDnFilter());
- $this->writeLog();
-
- throw new SPException($this->LogMessage->getDescription(), SPException::ERROR);
- }
-
- return $searchResults;
- }
-
- /**
- * Devolver los resultados de una paginación
- *
- * @param string $filter Filtro a utilizar
- * @param array $attributes Atributos a devolver
- * @return bool|array
- */
- protected function getResults($filter, array $attributes = null)
- {
- $cookie = '';
- $results = [];
-
- do {
- ldap_control_paged_result($this->ldapHandler, 1000, false, $cookie);
-
- if (!$searchRes = @ldap_search($this->ldapHandler, $this->searchBase, $filter, $attributes)) {
- return false;
- }
-
- if (@ldap_count_entries($this->ldapHandler, $searchRes) === 0
- || !$entries = @ldap_get_entries($this->ldapHandler, $searchRes)
- ) {
- return false;
- }
-
- $results = array_merge($results, $entries);
-
- ldap_control_paged_result_response($this->ldapHandler, $searchRes, $cookie);
- } while (!empty($cookie));
-
- return $results;
- }
-
- /**
- * Devolver el filtro para comprobar la pertenecia al grupo
- *
- * @return mixed
- */
- protected abstract function getGroupDnFilter();
-
/**
* @return LdapAuthData
*/
public function getLdapAuthData()
{
- return $this->LdapAuthData;
+ return $this->ldapAuthData;
}
/**
@@ -340,97 +266,6 @@ abstract class LdapBase implements LdapInterface, AuthInterface
return is_resource($this->ldapHandler) ? $this->ldapHandler : false;
}
- /**
- * @return string
- */
- public function getServer()
- {
- return $this->server;
- }
-
- /**
- * @param string $server
- */
- public function setServer($server)
- {
- $this->server = $server;
- $this->serverPort = $this->getServerPort();
- }
-
- /**
- * Devolver el puerto del servidor si está establecido
- *
- * @return int
- */
- protected function getServerPort()
- {
- return preg_match('/[\d\.]+:(\d+)/', $this->server, $port) ? $port[1] : 389;
- }
-
- /**
- * @return string
- */
- public function getSearchBase()
- {
- return $this->searchBase;
- }
-
- /**
- * @param string $searchBase
- */
- public function setSearchBase($searchBase)
- {
- $this->searchBase = $searchBase;
- }
-
- /**
- * @return string
- */
- public function getBindDn()
- {
- return $this->bindDn;
- }
-
- /**
- * @param string $bindDn
- */
- public function setBindDn($bindDn)
- {
- $this->bindDn = $bindDn;
- }
-
- /**
- * @return string
- */
- public function getBindPass()
- {
- return $this->bindPass;
- }
-
- /**
- * @param string $bindPass
- */
- public function setBindPass($bindPass)
- {
- $this->bindPass = $bindPass;
- }
-
- /**
- * @return string
- */
- public function getGroup()
- {
- return $this->group;
- }
-
- /**
- * @param string $group
- */
- public function setGroup($group)
- {
- $this->group = $group;
- }
-
/**
* @return string
*/
@@ -450,25 +285,22 @@ abstract class LdapBase implements LdapInterface, AuthInterface
/**
* Autentificar al usuario
*
- * @param UserLoginData $UserData Datos del usuario
+ * @param UserLoginData $userLoginData Datos del usuario
* @return bool
*/
- public function authenticate(UserLoginData $UserData)
+ public function authenticate(UserLoginData $userLoginData)
{
- if (!$this->checkParams()) {
- return false;
- }
-
- $this->LdapAuthData->setAuthGranted($this->isAuthGranted());
try {
- $this->setUserLogin($UserData->getLoginUser());
+ $this->ldapAuthData->setAuthGranted($this->isAuthGranted());
+ $this->setUserLogin($userLoginData->getLoginUser());
- $this->connect();
- $this->bind();
+ $this->connectAndBind();
$this->getAttributes();
- $this->bind($this->LdapAuthData->getDn(), $UserData->getLoginPass());
- } catch (SPException $e) {
+ $this->bind($this->ldapAuthData->getDn(), $userLoginData->getLoginPass());
+ } catch (LdapException $e) {
+ processException($e);
+
return false;
}
@@ -476,44 +308,20 @@ abstract class LdapBase implements LdapInterface, AuthInterface
}
/**
- * Comprobar si los parámetros necesario de LDAP están establecidos.
+ * Indica si es requerida para acceder a la aplicación
*
- * @return bool
+ * @return boolean
*/
- public function checkParams()
+ public function isAuthGranted()
{
- $this->searchBase = $this->ConfigData->getLdapBase();
- $this->server = $this->pickServer();
- $this->serverPort = $this->getServerPort();
- $this->bindDn = $this->ConfigData->getLdapBindUser();
- $this->bindPass = $this->ConfigData->getLdapBindPass();
- $this->group = $this->ConfigData->getLdapGroup();
-
- if (!$this->searchBase || !$this->server || !$this->bindDn || !$this->bindPass) {
- $this->LogMessage->setAction(__FUNCTION__);
- $this->LogMessage->addDescription(__('Los parámetros de LDAP no están configurados', false));
- $this->writeLog();
-
- return false;
- }
-
- $this->LdapAuthData->setServer($this->server);
-
return true;
}
- /**
- * Obtener el servidor de LDAP a utilizar
- *
- * @return mixed
- */
- protected abstract function pickServer();
-
/**
* Obtener los atributos del usuario.
*
* @return LdapAuthData con los atributos disponibles y sus valores
- * @throws SPException
+ * @throws LdapException
*/
public function getAttributes()
{
@@ -560,44 +368,45 @@ abstract class LdapBase implements LdapInterface, AuthInterface
}
if (!empty($res['fullname'])) {
- $this->LdapAuthData->setName($res['fullname']);
+ $this->ldapAuthData->setName($res['fullname']);
} else {
- $this->LdapAuthData->setName($res['name'] . ' ' . $res['sn']);
+ $this->ldapAuthData->setName($res['name'] . ' ' . $res['sn']);
}
- $this->LdapAuthData->setDn($searchResults[0]['dn']);
- $this->LdapAuthData->setEmail($res['mail']);
- $this->LdapAuthData->setExpire($res['expire']);
- $this->LdapAuthData->setGroups($res['group']);
+ $this->ldapAuthData->setDn($searchResults[0]['dn']);
+ $this->ldapAuthData->setEmail($res['mail']);
+ $this->ldapAuthData->setExpire($res['expire']);
+ $this->ldapAuthData->setGroups($res['group']);
if (!empty($this->group) && $this->group !== '*') {
- $this->LdapAuthData->setGroupDn($this->searchGroupDN());
+ $this->ldapAuthData->setGroupDn($this->searchGroupDN());
}
- $this->LdapAuthData->setInGroup($this->searchUserInGroup());
+ $this->ldapAuthData->setInGroup($this->searchUserInGroup());
- return $this->LdapAuthData;
+ return $this->ldapAuthData;
}
/**
* Obtener el RDN del usuario que realiza el login.
*
* @return array
- * @throws SPException
+ * @throws LdapException
*/
protected function getUserAttributes()
{
$searchResults = $this->getResults($this->getUserDnFilter(), self::SEARCH_ATTRIBUTES);
if ($searchResults === false || $searchResults['count'] > 1) {
- $this->LogMessage->setAction(__FUNCTION__);
- $this->LogMessage->addDescription(__('Error al localizar el usuario en LDAP', false));
- $this->LogMessage->addDetails(__('Usuario', false), $this->userLogin);
- $this->LogMessage->addDetails('LDAP ERROR', $this->ldapError());
- $this->LogMessage->addDetails('LDAP FILTER', $this->getUserDnFilter());
- $this->writeLog();
+ $this->eventDispatcher->notifyEvent('ldap.getAttributes',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Error al localizar el usuario en LDAP'))
+ ->addDetail(__u('Usuario'), $this->userLogin)
+ ->addDetail('LDAP ERROR', $this->getLdapErrorMessage())
+ ->addDetail('LDAP DN', $this->getGroupMembershipFilter()))
+ );
- throw new SPException($this->LogMessage->getDescription(), SPException::ERROR);
+ throw new LdapException(__u('Error al localizar el usuario en LDAP'));
}
return $searchResults;
@@ -613,25 +422,26 @@ abstract class LdapBase implements LdapInterface, AuthInterface
/**
* Obtener el RDN del grupo.
*
- * @throws SPException
+ * @throws LdapException
* @return string con el RDN del grupo
*/
protected function searchGroupDN()
{
- $group = $this->getGroupName() ?: $this->group;
+ $group = $this->getGroupName() ?: $this->ldapParams->getGroup();
$filter = '(cn=' . ldap_escape($group) . ')';
$searchResults = $this->getResults($filter, ['dn', 'cn']);
if ($searchResults === false || $searchResults['count'] > 1) {
- $this->LogMessage->setAction(__FUNCTION__);
- $this->LogMessage->addDescription(__('Error al buscar RDN de grupo', false));
- $this->LogMessage->addDetails(__('Grupo', false), $filter);
- $this->LogMessage->addDetails('LDAP ERROR', $this->ldapError());
- $this->LogMessage->addDetails('LDAP FILTER', $filter);
- $this->writeLog();
+ $this->eventDispatcher->notifyEvent('ldap.search.group',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Error al buscar RDN de grupo'))
+ ->addDetail(__u('Grupo'), $filter)
+ ->addDetail('LDAP ERROR', $this->getLdapErrorMessage())
+ ->addDetail('LDAP FILTER', $filter))
+ );
- throw new SPException($this->LogMessage->getDescription(), SPException::ERROR);
+ throw new LdapException(__u('Error al buscar RDN de grupo'));
}
return $searchResults[0]['dn'];
@@ -644,10 +454,10 @@ abstract class LdapBase implements LdapInterface, AuthInterface
*/
protected function getGroupName()
{
- if (null !== $this->group
- && preg_match('/^cn=([\w\s-]+)(,.*)?/i', $this->group, $groupName)
+ if ($this->ldapParams->getGroup()
+ && preg_match('/^cn=(?P[\w\s-]+)(?:,.*)?/i', $this->ldapParams->getGroup(), $matches)
) {
- return $groupName[1];
+ return $matches['groupname'];
}
return false;
@@ -656,7 +466,6 @@ abstract class LdapBase implements LdapInterface, AuthInterface
/**
* Buscar al usuario en un grupo.
*
- * @throws SPException
* @return bool
*/
protected abstract function searchUserInGroup();
@@ -664,46 +473,118 @@ abstract class LdapBase implements LdapInterface, AuthInterface
/**
* Devolver los objetos disponibles
*
+ * @param array $attributes
* @return array|bool
+ * @throws LdapException
*/
- public function findObjects()
+ public function findUsersByGroupFilter(array $attributes = self::SEARCH_ATTRIBUTES)
{
- if (!$this->checkParams()) {
- return false;
- }
+ $this->connectAndBind();
- try {
- $this->connect();
- $this->bind();
- return $this->getObjects();
- } catch (SPException $e) {
- return false;
- }
+ return $this->getObjects($this->getGroupMembershipFilter(), $attributes);
}
/**
- * Obtener los objetos que se pertenecen al grupo filtrado
+ * Obtener los objetos según el filtro indicado
*
- * @return int
- * @throws SPException
+ * @param string $filter
+ * @param array $attributes
+ * @return array
+ * @throws LdapException
*/
- protected function getObjects()
+ protected function getObjects($filter, array $attributes = self::SEARCH_ATTRIBUTES)
{
- $searchResults = $this->getResults($this->getGroupDnFilter(), self::SEARCH_ATTRIBUTES);
+ if (($searchResults = $this->getResults($filter, $attributes)) === false) {
+ $this->eventDispatcher->notifyEvent('ldap.search',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Error al buscar objetos en DN base'))
+ ->addDetail('LDAP ERROR', $this->getLdapErrorMessage())
+ ->addDetail('LDAP FILTER', $this->getGroupMembershipFilter()))
+ );
- if ($searchResults === false) {
- $this->LogMessage->setAction(__FUNCTION__);
- $this->LogMessage->addDescription(__('Error al buscar objetos en DN base', false));
- $this->LogMessage->addDetails('LDAP ERROR', $this->ldapError());
- $this->LogMessage->addDetails('LDAP FILTER', $this->getGroupDnFilter());
- $this->writeLog();
-
- throw new SPException($this->LogMessage->getDescription(), SPException::ERROR);
+ throw new LdapException(__u('Error al buscar objetos en DN base'));
}
return $searchResults;
}
+ /**
+ * Devolver los objetos disponibles
+ *
+ * @param array $attributes
+ * @return array|bool
+ * @throws LdapException
+ */
+ public function findGroups($attributes = self::SEARCH_ATTRIBUTES)
+ {
+ $this->connectAndBind();
+
+ return $this->getObjects($this->getGroupObjectFilter(), $attributes);
+ }
+
+ /**
+ * Devolver el filtro para objetos del tipo grupo
+ *
+ * @return mixed
+ */
+ protected abstract function getGroupObjectFilter();
+
+ /**
+ * @return bool
+ */
+ public function isConnected()
+ {
+ return $this->isConnected;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isBound()
+ {
+ return $this->isBound;
+ }
+
+ /**
+ * Devolver los resultados de una paginación
+ *
+ * @param string $filter Filtro a utilizar
+ * @param array $attributes Atributos a devolver
+ * @return bool|array
+ */
+ protected function getResults($filter, array $attributes = null)
+ {
+ $cookie = '';
+ $results = [];
+
+ do {
+ ldap_control_paged_result($this->ldapHandler, 1000, false, $cookie);
+
+ if (!$searchRes = @ldap_search($this->ldapHandler, $this->ldapParams->getSearchBase(), $filter, $attributes)) {
+ return false;
+ }
+
+ if (@ldap_count_entries($this->ldapHandler, $searchRes) === 0
+ || !$entries = @ldap_get_entries($this->ldapHandler, $searchRes)
+ ) {
+ return false;
+ }
+
+ $results = array_merge($results, $entries);
+
+ ldap_control_paged_result_response($this->ldapHandler, $searchRes, $cookie);
+ } while (!empty($cookie));
+
+ return $results;
+ }
+
+ /**
+ * Devolver el filtro para comprobar la pertenecia al grupo
+ *
+ * @return mixed
+ */
+ protected abstract function getGroupMembershipFilter();
+
/**
* Realizar la desconexión del servidor de LDAP.
*/
diff --git a/lib/SP/Providers/Auth/Ldap/LdapException.php b/lib/SP/Providers/Auth/Ldap/LdapException.php
new file mode 100644
index 00000000..509b96fd
--- /dev/null
+++ b/lib/SP/Providers/Auth/Ldap/LdapException.php
@@ -0,0 +1,37 @@
+.
+ */
+
+namespace SP\Providers\Auth\Ldap;
+
+use SP\Core\Exceptions\SPException;
+
+/**
+ * Class LdapException
+ *
+ * @package SP\Providers\Auth\Ldap
+ */
+class LdapException extends SPException
+{
+
+}
\ No newline at end of file
diff --git a/lib/SP/Providers/Auth/Ldap/LdapInterface.php b/lib/SP/Providers/Auth/Ldap/LdapInterface.php
index cd60298d..6d3dd75d 100644
--- a/lib/SP/Providers/Auth/Ldap/LdapInterface.php
+++ b/lib/SP/Providers/Auth/Ldap/LdapInterface.php
@@ -33,8 +33,6 @@ interface LdapInterface
{
/**
* Comprobar la conexión al servidor de LDAP.
- *
- * @return bool
*/
public function checkConnection();
diff --git a/lib/SP/Providers/Auth/Ldap/LdapMsAds.php b/lib/SP/Providers/Auth/Ldap/LdapMsAds.php
index f84abdda..8a3f1933 100644
--- a/lib/SP/Providers/Auth/Ldap/LdapMsAds.php
+++ b/lib/SP/Providers/Auth/Ldap/LdapMsAds.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,8 +24,8 @@
namespace SP\Providers\Auth\Ldap;
-use SP\Core\Exceptions\SPException;
-use SP\Log\Log;
+use SP\Core\Events\Event;
+use SP\Core\Events\EventMessage;
/**
* Class LdapAds
@@ -36,6 +36,8 @@ use SP\Log\Log;
*/
class LdapMsAds extends LdapBase
{
+ const userObjectFilter = '(|(objectCategory=person)(objectClass=user))';
+ const groupObjectFilter = '(objectCategory=group)';
/**
* Devolver el filtro para comprobar la pertenecia al grupo
@@ -43,15 +45,15 @@ class LdapMsAds extends LdapBase
* @return mixed
* @throws \SP\Core\Exceptions\SPException
*/
- protected function getGroupDnFilter()
+ protected function getGroupMembershipFilter()
{
- if (empty($this->group)) {
- return '(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject))';
+ if (empty($this->ldapParams->getGroup())) {
+ return self::userObjectFilter;
}
$groupDN = ldap_escape($this->searchGroupDN());
- return '(&(|(memberOf=' . $groupDN . ')(groupMembership=' . $groupDN . ')(memberof:1.2.840.113556.1.4.1941:=' . $groupDN . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject)))';
+ return '(&(|(memberOf=' . $groupDN . ')(groupMembership=' . $groupDN . ')(memberof:1.2.840.113556.1.4.1941:=' . $groupDN . '))' . self::userObjectFilter . ')';
}
/**
@@ -61,7 +63,7 @@ class LdapMsAds extends LdapBase
*/
protected function pickServer()
{
- $server = $this->ConfigData->getLdapServer();
+ $server = $this->ldapParams->getServer();
if (preg_match('/[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}/', $server)) {
return $server;
@@ -101,62 +103,68 @@ class LdapMsAds extends LdapBase
{
$userLogin = ldap_escape($this->userLogin);
- return '(&(|(samaccountname=' . $userLogin . ')(cn=' . $userLogin . ')(uid=' . $userLogin . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject))(objectCategory=person))';
+ return '(&(|(samaccountname=' . $userLogin . ')(cn=' . $userLogin . ')(uid=' . $userLogin . '))' . self::userObjectFilter . ')';
}
/**
* Buscar al usuario en un grupo.
*
- * @throws SPException
+ * @throws LdapException
* @return bool
*/
protected function searchUserInGroup()
{
- $this->LogMessage->setAction(__FUNCTION__);
-
// Comprobar si está establecido el filtro de grupo o el grupo coincide con
// los grupos del usuario
- if (!$this->group
- || $this->group === '*'
- || in_array($this->LdapAuthData->getGroupDn(), $this->LdapAuthData->getGroups())
+ if (!$this->ldapParams->getGroup()
+ || $this->ldapParams->getGroup() === '*'
+ || in_array($this->ldapAuthData->getGroupDn(), $this->ldapAuthData->getGroups())
) {
- $this->LogMessage->addDescription(__('Usuario verificado en grupo', false));
- $this->writeLog(Log::INFO);
+ $this->eventDispatcher->notifyEvent('ldap.check.group',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Usuario verificado en grupo')))
+ );
return true;
}
- $groupDN = $this->LdapAuthData->getGroupDn();
+ $groupDN = $this->ldapAuthData->getGroupDn();
$filter = '(memberof:1.2.840.113556.1.4.1941:=' . ldap_escape($groupDN) . ')';
$searchResults = $this->getResults($filter, ['sAMAccountName']);
if ($searchResults === false) {
- $this->LogMessage->addDescription(__('Error al buscar el grupo de usuarios', false));
- $this->LogMessage->addDetails(__('Grupo', false), $groupDN);
- $this->LogMessage->addDetails('LDAP ERROR', sprintf('%s (%d)', ldap_error($this->ldapHandler), ldap_errno($this->ldapHandler)));
- $this->LogMessage->addDetails('LDAP FILTER', $filter);
- $this->writeLog();
+ $this->eventDispatcher->notifyEvent('ldap.check.group',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Error al buscar el grupo de usuarios'))
+ ->addDetail(__u('Grupo'), $groupDN)
+ ->addDetail('LDAP ERROR', $this->getLdapErrorMessage())
+ ->addDetail('LDAP FILTER', $filter))
+ );
- throw new SPException($this->LogMessage->getDescription(), SPException::ERROR);
+ throw new LdapException(__u('Error al buscar el grupo de usuarios'));
}
foreach ($searchResults as $entry) {
if (is_array($entry)) {
if ($this->userLogin === strtolower($entry['samaccountname'][0])) {
- $this->LogMessage->addDescription(__('Usuario verificado en grupo', false));
- $this->LogMessage->addDetails(__('Grupo', false), $groupDN);
- $this->writeLog(Log::INFO);
+ $this->eventDispatcher->notifyEvent('ldap.check.group',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Usuario verificado en grupo'))
+ ->addDetail(__u('Grupo'), $groupDN))
+ );
return true;
}
}
}
- $this->LogMessage->addDescription(__('Usuario no pertenece al grupo', false));
- $this->LogMessage->addDetails(__('Usuario', false), $this->LdapAuthData->getDn());
- $this->LogMessage->addDetails(__('Grupo', false), $groupDN);
- $this->writeLog();
+ $this->eventDispatcher->notifyEvent('ldap.check.group',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Usuario no pertenece al grupo'))
+ ->addDetail(__u('Usuario'), $this->ldapAuthData->getDn())
+ ->addDetail(__u('Grupo'), $groupDN))
+ );
return false;
}
@@ -173,4 +181,14 @@ class LdapMsAds extends LdapBase
return true;
}
+
+ /**
+ * Devolver el filtro para objetos del tipo grupo
+ *
+ * @return mixed
+ */
+ protected function getGroupObjectFilter()
+ {
+ return self::groupObjectFilter;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Providers/Auth/Ldap/LdapParams.php b/lib/SP/Providers/Auth/Ldap/LdapParams.php
new file mode 100644
index 00000000..ceb9ec66
--- /dev/null
+++ b/lib/SP/Providers/Auth/Ldap/LdapParams.php
@@ -0,0 +1,200 @@
+.
+ */
+
+namespace SP\Providers\Auth\Ldap;
+
+/**
+ * Class LdapParams
+ *
+ * @package SP\Providers\Auth\Ldap
+ */
+class LdapParams
+{
+ /**
+ * @var string
+ */
+ protected $server;
+ /**
+ * @var int
+ */
+ protected $port;
+ /**
+ * @var string
+ */
+ protected $searchBase;
+ /**
+ * @var string
+ */
+ protected $bindDn;
+ /**
+ * @var string
+ */
+ protected $bindPass;
+ /**
+ * @var string
+ */
+ protected $group;
+ /**
+ * @var bool
+ */
+ protected $ads;
+
+ /**
+ * Devolver el puerto del servidor si está establecido
+ *
+ * @param $server
+ * @return array|false
+ */
+ public static function getServerAndPort($server)
+ {
+ return preg_match('/(?P[\w\.]+)(:(?P\d+))?/', $server, $matches) ? $matches : false;
+ }
+
+ /**
+ * @return int
+ */
+ public function getPort()
+ {
+ return $this->port;
+ }
+
+ /**
+ * @param int $port
+ * @return LdapParams
+ */
+ public function setPort($port)
+ {
+ $this->port = $port;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSearchBase()
+ {
+ return $this->searchBase;
+ }
+
+ /**
+ * @param string $searchBase
+ * @return LdapParams
+ */
+ public function setSearchBase($searchBase)
+ {
+ $this->searchBase = $searchBase;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBindDn()
+ {
+ return $this->bindDn;
+ }
+
+ /**
+ * @param string $bindDn
+ * @return LdapParams
+ */
+ public function setBindDn($bindDn)
+ {
+ $this->bindDn = $bindDn;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBindPass()
+ {
+ return $this->bindPass;
+ }
+
+ /**
+ * @param string $bindPass
+ * @return LdapParams
+ */
+ public function setBindPass($bindPass)
+ {
+ $this->bindPass = $bindPass;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGroup()
+ {
+ return $this->group;
+ }
+
+ /**
+ * @param string $group
+ * @return LdapParams
+ */
+ public function setGroup($group)
+ {
+ $this->group = $group;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getServer()
+ {
+ return $this->server;
+ }
+
+ /**
+ * @param string $server
+ * @return LdapParams
+ */
+ public function setServer($server)
+ {
+ $this->server = $server;
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isAds()
+ {
+ return $this->ads;
+ }
+
+ /**
+ * @param bool $ads
+ * @return LdapParams
+ */
+ public function setAds($ads)
+ {
+ $this->ads = (bool)$ads;
+ return $this;
+ }
+
+}
\ No newline at end of file
diff --git a/lib/SP/Providers/Auth/Ldap/LdapStd.php b/lib/SP/Providers/Auth/Ldap/LdapStd.php
index c3d9bc68..3089ae16 100644
--- a/lib/SP/Providers/Auth/Ldap/LdapStd.php
+++ b/lib/SP/Providers/Auth/Ldap/LdapStd.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,8 +24,8 @@
namespace SP\Providers\Auth\Ldap;
-use SP\Core\Exceptions\SPException;
-use SP\Log\Log;
+use SP\Core\Events\Event;
+use SP\Core\Events\EventMessage;
/**
* Class LdapStd
@@ -36,21 +36,24 @@ use SP\Log\Log;
*/
class LdapStd extends LdapBase
{
+ const userObjectFilter = '(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject))';
+ const groupObjectFilter = '(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=group))';
+
/**
* Devolver el filtro para comprobar la pertenecia al grupo
*
* @return mixed
* @throws \SP\Core\Exceptions\SPException
*/
- protected function getGroupDnFilter()
+ protected function getGroupMembershipFilter()
{
- if (empty($this->group)) {
- return '(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject))';
+ if (empty($this->ldapParams->getGroup())) {
+ return self::userObjectFilter;
}
$groupDN = ldap_escape($this->searchGroupDN());
- return '(&(|(memberOf=' . $groupDN . ')(groupMembership=' . $groupDN . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject)))';
+ return '(&(|(memberOf=' . $groupDN . ')(groupMembership=' . $groupDN . '))' . self::userObjectFilter . ')';
}
/**
@@ -60,7 +63,7 @@ class LdapStd extends LdapBase
*/
protected function pickServer()
{
- return $this->ConfigData->getLdapServer();
+ return $this->ldapParams->getServer();
}
/**
@@ -72,52 +75,57 @@ class LdapStd extends LdapBase
{
$userLogin = ldap_escape($this->userLogin);
- return '(&(|(samaccountname=' . $userLogin . ')(cn=' . $userLogin . ')(uid=' . $userLogin . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject)))';
+ return '(&(|(samaccountname=' . $userLogin . ')(cn=' . $userLogin . ')(uid=' . $userLogin . '))' . self::userObjectFilter . ')';
}
/**
* Buscar al usuario en un grupo.
*
- * @throws SPException
+ * @throws LdapException
* @return bool
*/
protected function searchUserInGroup()
{
- $this->LogMessage->setAction(__FUNCTION__);
-
// Comprobar si está establecido el filtro de grupo o el grupo coincide con
// los grupos del usuario
- if (!$this->group
- || $this->group === '*'
- || in_array($this->LdapAuthData->getGroupDn(), $this->LdapAuthData->getGroups())
+ if (!$this->ldapParams->getGroup()
+ || $this->ldapParams->getGroup() === '*'
+ || in_array($this->ldapAuthData->getGroupDn(), $this->ldapAuthData->getGroups())
) {
- $this->LogMessage->addDescription(__('Usuario verificado en grupo', false));
- $this->writeLog(Log::INFO);
+ $this->eventDispatcher->notifyEvent('ldap.check.group',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Usuario verificado en grupo')))
+ );
return true;
}
- $userDN = $this->LdapAuthData->getDn();
- $groupName = $this->getGroupName() ?: $this->group;
+ $userDN = ldap_escape($this->ldapAuthData->getDn());
+ $groupName = $this->getGroupName() ?: $this->ldapParams->getGroup();
- $filter = '(&(cn=' . ldap_escape($groupName) . ')(|(member=' . ldap_escape($userDN) . ')(uniqueMember=' . ldap_escape($userDN) . '))(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=group)))';
+ $filter = '(&(cn=' . ldap_escape($groupName) . ')(|(member=' . $userDN . ')(uniqueMember=' . $userDN . '))' . self::groupObjectFilter . ')';
$searchResults = $this->getResults($filter, ['member', 'uniqueMember']);
if ($searchResults === false) {
- $this->LogMessage->addDescription(__('Error al buscar el grupo de usuarios', false));
- $this->LogMessage->addDetails(__('Grupo', false), $groupName);
- $this->LogMessage->addDetails(__('Usuario', false), $userDN);
- $this->LogMessage->addDetails('LDAP ERROR', sprintf('%s (%d)', ldap_error($this->ldapHandler), ldap_errno($this->ldapHandler)));
- $this->LogMessage->addDetails('LDAP FILTER', $filter);
- $this->writeLog();
+ $this->eventDispatcher->notifyEvent('ldap.check.group',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Error al buscar el grupo de usuarios'))
+ ->addDetail(__u('Usuario'), $this->ldapAuthData->getDn())
+ ->addDetail(__u('Grupo'), $groupName)
+ ->addDetail('LDAP ERROR', $this->getLdapErrorMessage())
+ ->addDetail('LDAP FILTER', $filter))
+ );
- throw new SPException($this->LogMessage->getDescription(), SPException::ERROR);
+ throw new LdapException(__u('Error al buscar el grupo de usuarios'));
}
- $this->LogMessage->addDescription(__('Usuario verificado en grupo', false));
- $this->LogMessage->addDescription($groupName);
- $this->writeLog(Log::INFO);
+ $this->eventDispatcher->notifyEvent('ldap.check.group',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Usuario no pertenece al grupo'))
+ ->addDetail(__u('Usuario'), $this->ldapAuthData->getDn())
+ ->addDetail(__u('Grupo'), $groupName))
+ );
return true;
}
@@ -134,4 +142,14 @@ class LdapStd extends LdapBase
return true;
}
+
+ /**
+ * Devolver el filtro para objetos del tipo grupo
+ *
+ * @return mixed
+ */
+ protected function getGroupObjectFilter()
+ {
+ return self::groupObjectFilter;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Providers/Auth/Ldap/LdapUtil.php b/lib/SP/Providers/Auth/Ldap/LdapUtil.php
index 6e13615f..87626f2b 100644
--- a/lib/SP/Providers/Auth/Ldap/LdapUtil.php
+++ b/lib/SP/Providers/Auth/Ldap/LdapUtil.php
@@ -24,7 +24,6 @@
namespace SP\Providers\Auth\Ldap;
-
/**
* Class LdapUtil
*
@@ -32,27 +31,5 @@ namespace SP\Providers\Auth\Ldap;
*/
class LdapUtil
{
- /**
- * Obtener los datos de una búsqueda de LDAP de un atributo
- *
- * @param array $results
- * @param string $attribute
- * @return array
- */
- public static function getResultsData(array &$results, $attribute)
- {
- $out = [];
- foreach ($results as $result) {
- if (is_array($result)) {
- foreach ($result as $ldapAttribute => $value) {
- if (strtolower($ldapAttribute) === $attribute) {
- $out[] = $value;
- }
- }
- }
- }
-
- return $out;
- }
}
\ No newline at end of file
diff --git a/lib/SP/Providers/Provider.php b/lib/SP/Providers/Provider.php
index c4021129..d568ee1f 100644
--- a/lib/SP/Providers/Provider.php
+++ b/lib/SP/Providers/Provider.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,8 +24,8 @@
namespace SP\Providers;
+use DI\Container;
use Psr\Container\ContainerInterface;
-use SP\Bootstrap;
use SP\Config\Config;
use SP\Core\Events\EventDispatcher;
use SP\Core\Session\Session;
@@ -57,18 +57,19 @@ abstract class Provider
protected $dic;
/**
- * Service constructor.
+ * Provider constructor.
*
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
+ * @param Container $dic
+ * @param Config $config
+ * @param Session $session
+ * @param EventDispatcher $eventDispatcher
*/
- final public function __construct()
+ final public function __construct(Container $dic, Config $config, Session $session, EventDispatcher $eventDispatcher)
{
- $this->dic = Bootstrap::getContainer();
-
- $this->config = $this->dic->get(Config::class);
- $this->session = $this->dic->get(Session::class);
- $this->eventDispatcher = $this->dic->get(EventDispatcher::class);
+ $this->dic = $dic;
+ $this->config = $config;
+ $this->session = $session;
+ $this->eventDispatcher = $eventDispatcher;
if (method_exists($this, 'initialize')) {
$this->initialize();
diff --git a/lib/SP/Repositories/Config/ConfigRepository.php b/lib/SP/Repositories/Config/ConfigRepository.php
index dcead969..ec4fa401 100644
--- a/lib/SP/Repositories/Config/ConfigRepository.php
+++ b/lib/SP/Repositories/Config/ConfigRepository.php
@@ -46,17 +46,18 @@ class ConfigRepository extends Repository
*/
public function update(ConfigData $configData)
{
- $Data = new QueryData();
- $Data->setQuery('UPDATE Config SET value = ? WHERE parameter = ?');
- $Data->addParam($configData->getValue());
- $Data->addParam($configData->getParam());
+ $queryData = new QueryData();
+ $queryData->setQuery('UPDATE Config SET value = ? WHERE parameter = ?');
+ $queryData->addParam($configData->getValue());
+ $queryData->addParam($configData->getParam());
- return DbWrapper::getQuery($Data, $this->db);
+ return DbWrapper::getQuery($queryData, $this->db);
}
/**
* @param ConfigData[] $data
* @return bool
+ * @throws \SP\Core\Exceptions\SPException
*/
public function updateBatch(array $data)
{
@@ -64,12 +65,12 @@ class ConfigRepository extends Repository
try {
foreach ($data as $configData) {
- $Data = new QueryData();
- $Data->setQuery('UPDATE Config SET value = ? WHERE parameter = ?');
- $Data->addParam($configData->getValue());
- $Data->addParam($configData->getParam());
+ $queryData = new QueryData();
+ $queryData->setQuery('UPDATE Config SET value = ? WHERE parameter = ?');
+ $queryData->addParam($configData->getValue());
+ $queryData->addParam($configData->getParam());
- DbWrapper::getQuery($Data, $this->db);
+ DbWrapper::getQuery($queryData, $this->db);
}
} catch (QueryException $e) {
debugLog($e->getMessage());
@@ -88,15 +89,12 @@ class ConfigRepository extends Repository
*/
public function create(ConfigData $configData)
{
- $query = /** @lang SQL */
- 'INSERT INTO Config SET parameter = ?, value = ?';
+ $queryData = new QueryData();
+ $queryData->setQuery('INSERT INTO Config SET parameter = ?, value = ?');
+ $queryData->addParam($configData->getParam());
+ $queryData->addParam($configData->getValue());
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($configData->getParam());
- $Data->addParam($configData->getValue());
-
- return DbWrapper::getQuery($Data, $this->db);
+ return DbWrapper::getQuery($queryData, $this->db);
}
/**
@@ -106,10 +104,10 @@ class ConfigRepository extends Repository
*/
public function getAll()
{
- $Data = new QueryData();
- $Data->setQuery('SELECT parameter, value FROM Config');
+ $queryData = new QueryData();
+ $queryData->setQuery('SELECT parameter, value FROM Config');
- return DbWrapper::getResults($Data);
+ return DbWrapper::getResults($queryData);
}
/**
@@ -118,11 +116,11 @@ class ConfigRepository extends Repository
*/
public function getByParam($param)
{
- $Data = new QueryData();
- $Data->setQuery('SELECT value FROM Config WHERE parameter = ? LIMIT 1');
- $Data->addParam($param);
+ $queryData = new QueryData();
+ $queryData->setQuery('SELECT value FROM Config WHERE parameter = ? LIMIT 1');
+ $queryData->addParam($param);
- return DbWrapper::getResults($Data, $this->db);
+ return DbWrapper::getResults($queryData, $this->db);
}
/**
@@ -133,11 +131,11 @@ class ConfigRepository extends Repository
*/
public function has($param)
{
- $Data = new QueryData();
- $Data->setQuery('SELECT parameter FROM Config WHERE parameter = ? LIMIT 1');
- $Data->addParam($param);
+ $queryData = new QueryData();
+ $queryData->setQuery('SELECT parameter FROM Config WHERE parameter = ? LIMIT 1');
+ $queryData->addParam($param);
- DbWrapper::getQuery($Data, $this->db);
+ DbWrapper::getQuery($queryData, $this->db);
return $this->db->getNumRows() === 1;
}
@@ -150,10 +148,10 @@ class ConfigRepository extends Repository
*/
public function deleteByParam($param)
{
- $Data = new QueryData();
- $Data->setQuery('DELETE FROM Config WHERE parameter = ? LIMIT 1');
- $Data->addParam($param);
+ $queryData = new QueryData();
+ $queryData->setQuery('DELETE FROM Config WHERE parameter = ? LIMIT 1');
+ $queryData->addParam($param);
- return DbWrapper::getQuery($Data, $this->db);
+ return DbWrapper::getQuery($queryData, $this->db);
}
}
\ No newline at end of file
diff --git a/lib/SP/Repositories/Repository.php b/lib/SP/Repositories/Repository.php
index 8966eb4c..7869935f 100644
--- a/lib/SP/Repositories/Repository.php
+++ b/lib/SP/Repositories/Repository.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,8 +24,8 @@
namespace SP\Repositories;
-use SP\Bootstrap;
use SP\Config\Config;
+use SP\Core\Dic\Container;
use SP\Core\Events\EventDispatcher;
use SP\Core\Session\Session;
use SP\Storage\Database;
@@ -38,29 +38,45 @@ use SP\Storage\DatabaseInterface;
*/
abstract class Repository
{
- /** @var Config */
+ /**
+ * @var Config
+ */
protected $config;
- /** @var Session */
+ /**
+ * @var Session
+ */
protected $session;
- /** @var EventDispatcher */
+ /**
+ * @var EventDispatcher
+ */
protected $eventDispatcher;
- /** @var DatabaseInterface */
+ /**
+ * @var DatabaseInterface
+ */
protected $db;
+ /**
+ * @var Container
+ */
+ private $dic;
/**
* Repository constructor.
*
+ * @param Container $dic
+ * @param Config $config
+ * @param Database $database
+ * @param Session $session
+ * @param EventDispatcher $eventDispatcher
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
- final public function __construct()
+ final public function __construct(Container $dic, Config $config, Database $database, Session $session, EventDispatcher $eventDispatcher)
{
- $dic = Bootstrap::getContainer();
-
- $this->config = $dic->get(Config::class);
- $this->db = $dic->get(Database::class);
- $this->session = $dic->get(Session::class);
- $this->eventDispatcher = $dic->get(EventDispatcher::class);
+ $this->dic = $dic;
+ $this->config = $config;
+ $this->db = $database;
+ $this->session = $session;
+ $this->eventDispatcher = $eventDispatcher;
if (method_exists($this, 'initialize')) {
$this->initialize();
diff --git a/lib/SP/Repositories/User/UserRepository.php b/lib/SP/Repositories/User/UserRepository.php
index 969c803b..6c92ac49 100644
--- a/lib/SP/Repositories/User/UserRepository.php
+++ b/lib/SP/Repositories/User/UserRepository.php
@@ -480,8 +480,8 @@ class UserRepository extends Repository implements RepositoryItemInterface
'SELECT login, email
FROM User
WHERE UPPER(login) = UPPER(?)
- OR UPPER(ssoLogin) = UPPER(?)
- OR UPPER(email) = UPPER(?)';
+ OR UPPER(?) IN (SELECT ssoLogin FROM User WHERE ssoLogin IS NOT NULL OR ssoLogin <> \'\')
+ OR UPPER(?) IN (SELECT email FROM User WHERE email IS NOT NULL OR email <> \'\')';
$queryData = new QueryData();
$queryData->setQuery($query);
diff --git a/lib/SP/Services/Auth/LoginService.php b/lib/SP/Services/Auth/LoginService.php
index 60015ca0..1978e039 100644
--- a/lib/SP/Services/Auth/LoginService.php
+++ b/lib/SP/Services/Auth/LoginService.php
@@ -147,9 +147,7 @@ class LoginService extends Service
);
}
- $auth = new Auth($this->userLoginData, $this->configData);
-
- if (($result = $auth->doAuth()) !== false) {
+ if (($result = $this->dic->get(Auth::class)->doAuth($this->userLoginData)) !== false) {
// Ejecutar la acción asociada al tipo de autentificación
foreach ($result as $authResult) {
/** @var AuthResult $authResult */
diff --git a/lib/SP/Services/Backup/FileBackupService.php b/lib/SP/Services/Backup/FileBackupService.php
index 91e194b7..919a20d0 100644
--- a/lib/SP/Services/Backup/FileBackupService.php
+++ b/lib/SP/Services/Backup/FileBackupService.php
@@ -67,7 +67,7 @@ class FileBackupService extends Service
// Generar hash unico para evitar descargas no permitidas
$backupUniqueHash = sha1(uniqid('sysPassBackup', true));
$this->configData->setBackupHash($backupUniqueHash);
- $this->config->saveConfig();
+ $this->config->saveConfig($this->configData);
$bakFileApp = BACKUP_PATH . DIRECTORY_SEPARATOR . $siteName . '-' . $backupUniqueHash . '.tar';
$bakFileDB = BACKUP_PATH . DIRECTORY_SEPARATOR . $siteName . '_db-' . $backupUniqueHash . '.sql';
@@ -130,11 +130,8 @@ class FileBackupService extends Service
* Utilizar '*' para toda la BBDD o 'table1 table2 table3...'
*
* @param string|array $tables
- * @param FileHandler $fileHandler
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- * @throws SPException
- * @throws \SP\Core\Dic\ContainerException
+ * @param FileHandler $fileHandler
+ * @throws \Exception
* @throws \SP\Storage\FileException
*/
private function backupTables($tables = '*', FileHandler $fileHandler)
diff --git a/lib/SP/Services/Config/ConfigBackupService.php b/lib/SP/Services/Config/ConfigBackupService.php
new file mode 100644
index 00000000..a5852620
--- /dev/null
+++ b/lib/SP/Services/Config/ConfigBackupService.php
@@ -0,0 +1,67 @@
+.
+ */
+
+namespace SP\Services\Config;
+
+use SP\Services\Service;
+use SP\Services\ServiceException;
+
+/**
+ * Class ConfigBackupService
+ *
+ * @package SP\Services\Config
+ */
+class ConfigBackupService extends Service
+{
+ /**
+ * @var ConfigService
+ */
+ protected $configService;
+
+ /**
+ * Backups the config data into the database
+ */
+ public function backup()
+ {
+ try {
+ $this->configService->save('config_backup', json_encode($this->config->getConfigData()));
+ $this->configService->save('config_backup_date', time());
+ } catch (\Exception $e) {
+ processException($e);
+ }
+ }
+
+ /**
+ * @throws ServiceException
+ */
+ public function restore()
+ {
+ throw new ServiceException('Not implemented');
+ }
+
+ protected function initialize()
+ {
+ $this->configService = $this->dic->get(ConfigService::class);
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Ldap/LdapCheckService.php b/lib/SP/Services/Ldap/LdapCheckService.php
new file mode 100644
index 00000000..b964931e
--- /dev/null
+++ b/lib/SP/Services/Ldap/LdapCheckService.php
@@ -0,0 +1,99 @@
+.
+ */
+
+namespace SP\Services\Ldap;
+
+use SP\Providers\Auth\Ldap\LdapBase;
+use SP\Providers\Auth\Ldap\LdapMsAds;
+use SP\Providers\Auth\Ldap\LdapParams;
+use SP\Providers\Auth\Ldap\LdapStd;
+use SP\Services\Service;
+
+/**
+ * Class LdapCheckService
+ *
+ * @package SP\Services\Ldap
+ */
+class LdapCheckService extends Service
+{
+ /**
+ * @var LdapBase
+ */
+ protected $ldap;
+
+ /**
+ * @param LdapParams $ldapParams
+ * @throws \SP\Providers\Auth\Ldap\LdapException
+ */
+ public function checkConnection(LdapParams $ldapParams)
+ {
+ if ($ldapParams->isAds()) {
+ $this->ldap = new LdapMsAds($ldapParams, $this->eventDispatcher, true);
+ } else {
+ $this->ldap = new LdapStd($ldapParams, $this->eventDispatcher, true);
+ }
+
+ $this->ldap->checkConnection();
+ }
+
+ /**
+ * @return array
+ * @throws \SP\Providers\Auth\Ldap\LdapException
+ */
+ public function getUsersAndGroups()
+ {
+ $users = $this->ldapResultsMapper($this->ldap->findUsersByGroupFilter(['dn']));
+ $groups = $this->ldapResultsMapper($this->ldap->findGroups(['dn']));
+
+ return [
+ 'count' => count($users) + count($groups),
+ 'users' => $users,
+ 'groups' => $groups
+ ];
+ }
+
+ /**
+ * Obtener los datos de una búsqueda de LDAP de un atributo
+ *
+ * @param array $data
+ * @param string $attribute
+ * @return array
+ */
+ public function ldapResultsMapper($data, $attribute = 'dn')
+ {
+ $out = [];
+
+ foreach ($data as $result) {
+ if (is_array($result)) {
+ foreach ($result as $ldapAttribute => $value) {
+ if (strtolower($ldapAttribute) === $attribute) {
+ $out[] = $value;
+ }
+ }
+ }
+ }
+
+ return $out;
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Ldap/LdapImportParams.php b/lib/SP/Services/Ldap/LdapImportParams.php
new file mode 100644
index 00000000..4fcdc45c
--- /dev/null
+++ b/lib/SP/Services/Ldap/LdapImportParams.php
@@ -0,0 +1,54 @@
+.
+ */
+
+namespace SP\Services\Ldap;
+
+/**
+ * Class LdapImportParams
+ *
+ * @package SP\Services\Ldap
+ */
+class LdapImportParams
+{
+ /**
+ * @var int
+ */
+ public $defaultUserGroup;
+ /**
+ * @var int
+ */
+ public $defaultUserProfile;
+ /**
+ * @var string
+ */
+ public $loginAttribute;
+ /**
+ * @var string
+ */
+ public $userNameAttribute;
+ /**
+ * @var string
+ */
+ public $userGroupNameAttribute;
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Ldap/LdapImportService.php b/lib/SP/Services/Ldap/LdapImportService.php
new file mode 100644
index 00000000..6c4a20f1
--- /dev/null
+++ b/lib/SP/Services/Ldap/LdapImportService.php
@@ -0,0 +1,232 @@
+.
+ */
+
+namespace SP\Services\Ldap;
+
+use SP\Core\Events\Event;
+use SP\Core\Events\EventMessage;
+use SP\DataModel\UserData;
+use SP\DataModel\UserGroupData;
+use SP\Providers\Auth\Ldap\LdapBase;
+use SP\Providers\Auth\Ldap\LdapException;
+use SP\Providers\Auth\Ldap\LdapMsAds;
+use SP\Providers\Auth\Ldap\LdapParams;
+use SP\Providers\Auth\Ldap\LdapStd;
+use SP\Services\Service;
+use SP\Services\User\UserService;
+use SP\Services\UserGroup\UserGroupService;
+
+/**
+ * Class UserLdapService
+ *
+ * @package SP\Services\User
+ */
+class LdapImportService extends Service
+{
+ /**
+ * @var int
+ */
+ protected $totalObjects = 0;
+ /**
+ * @var int
+ */
+ protected $syncedObjects = 0;
+ /**
+ * @var int
+ */
+ protected $errorObjects = 0;
+
+ /**
+ * @return int
+ */
+ public function getTotalObjects()
+ {
+ return $this->totalObjects;
+ }
+
+ /**
+ * @return int
+ */
+ public function getSyncedObjects()
+ {
+ return $this->syncedObjects;
+ }
+
+ /**
+ * @return int
+ */
+ public function getErrorObjects()
+ {
+ return $this->errorObjects;
+ }
+
+ /**
+ * Sincronizar usuarios de LDAP
+ *
+ * @param LdapParams $ldapParams
+ * @param LdapImportParams $ldapImportParams
+ * @throws LdapException
+ */
+ public function importGroups(LdapParams $ldapParams, LdapImportParams $ldapImportParams)
+ {
+ $objects = $this->getLdap($ldapParams)->findGroups();
+
+ $numObjects = (int)$objects['count'];
+
+ $this->eventDispatcher->notifyEvent('import.ldap.groups',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Objetos encontrados'), $numObjects))
+ );
+
+ $this->totalObjects += $numObjects;
+
+ if ($numObjects > 0) {
+ $userGroupService = $this->dic->get(UserGroupService::class);
+
+ foreach ($objects as $result) {
+ if (is_array($result)) {
+ $userGroupData = new UserGroupData();
+
+ foreach ($result as $attribute => $values) {
+
+ $value = $values[0];
+
+ switch (strtolower($attribute)) {
+ case $ldapImportParams->userGroupNameAttribute:
+ $userGroupData->setName($value);
+ break;
+ }
+ }
+
+ if (!empty($userGroupData->getName())) {
+ try {
+ $userGroupData->setDescription(__('Importado desde LDAP'));
+
+ $userGroupService->create($userGroupData);
+
+ $this->eventDispatcher->notifyEvent('import.ldap.progress.groups',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Grupo'), sprintf('%s', $userGroupData->getName())))
+ );
+
+ $this->syncedObjects++;
+ } catch (\Exception $e) {
+ processException($e);
+
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
+ $this->errorObjects++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param LdapParams $ldapParams
+ *
+ * @return LdapBase
+ */
+ protected function getLdap(LdapParams $ldapParams)
+ {
+ if ($ldapParams->isAds()) {
+ return new LdapMsAds($ldapParams, $this->eventDispatcher, true);
+ } else {
+ return new LdapStd($ldapParams, $this->eventDispatcher, true);
+ }
+ }
+
+ /**
+ * @param LdapParams $ldapParams
+ * @param LdapImportParams $ldapImportParams
+ * @throws LdapException
+ */
+ public function importUsers(LdapParams $ldapParams, LdapImportParams $ldapImportParams)
+ {
+ $objects = $this->getLdap($ldapParams)->findUsersByGroupFilter();
+
+ $numObjects = (int)$objects['count'];
+
+ $this->eventDispatcher->notifyEvent('import.ldap.users',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Objetos encontrados'), $numObjects))
+ );
+
+ $this->totalObjects += $numObjects;
+
+ if ($numObjects > 0) {
+ $userService = $this->dic->get(UserService::class);
+
+ foreach ($objects as $result) {
+ if (is_array($result)) {
+ $userData = new UserData();
+
+ foreach ($result as $attribute => $values) {
+
+ $value = $values[0];
+
+ switch (strtolower($attribute)) {
+ case $ldapImportParams->userNameAttribute:
+ $userData->setName($value);
+ break;
+ case $ldapImportParams->loginAttribute:
+ $userData->setLogin($value);
+ break;
+ case 'mail':
+ $userData->setEmail($value);
+ break;
+ }
+ }
+
+ if (!empty($userData->getName())
+ && !empty($userData->getLogin())
+ ) {
+ try {
+ $userData->setNotes(__('Importado desde LDAP'));
+ $userData->setUserGroupId($ldapImportParams->defaultUserGroup);
+ $userData->setUserProfileId($ldapImportParams->defaultUserProfile);
+ $userData->setIsLdap(true);
+
+ $userService->create($userData);
+
+ $this->eventDispatcher->notifyEvent('import.ldap.progress.users',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Usuario'), sprintf('%s (%s)', $userData->getName(), $userData->getLogin())))
+ );
+
+ $this->syncedObjects++;
+ } catch (\Exception $e) {
+ processException($e);
+
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
+ $this->errorObjects++;
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Service.php b/lib/SP/Services/Service.php
index 36eac5dc..f688270e 100644
--- a/lib/SP/Services/Service.php
+++ b/lib/SP/Services/Service.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,8 +24,8 @@
namespace SP\Services;
+use DI\Container;
use Psr\Container\ContainerInterface;
-use SP\Bootstrap;
use SP\Config\Config;
use SP\Core\Events\EventDispatcher;
use SP\Core\Session\Session;
@@ -59,16 +59,17 @@ abstract class Service
/**
* Service constructor.
*
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
+ * @param Container $dic
+ * @param Config $config
+ * @param Session $session
+ * @param EventDispatcher $eventDispatcher
*/
- final public function __construct()
+ final public function __construct(Container $dic, Config $config, Session $session, EventDispatcher $eventDispatcher)
{
- $this->dic = Bootstrap::getContainer();
-
- $this->config = $this->dic->get(Config::class);
- $this->session = $this->dic->get(Session::class);
- $this->eventDispatcher = $this->dic->get(EventDispatcher::class);
+ $this->dic = $dic;
+ $this->config = $config;
+ $this->session = $session;
+ $this->eventDispatcher = $eventDispatcher;
if (method_exists($this, 'initialize')) {
$this->initialize();
diff --git a/lib/SP/Services/UserGroup/UserGroupService.php b/lib/SP/Services/UserGroup/UserGroupService.php
index 2fd28a59..8c3ad184 100644
--- a/lib/SP/Services/UserGroup/UserGroupService.php
+++ b/lib/SP/Services/UserGroup/UserGroupService.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.
@@ -100,14 +100,14 @@ class UserGroupService extends Service
}
/**
- * @param $itemData
- * @param array $users
+ * @param UserGroupData $itemData
+ * @param array $users
* @return int
* @throws SPException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
- public function create($itemData, array $users)
+ public function create($itemData, array $users = [])
{
$userGroupId = $this->userGroupRepository->create($itemData);
diff --git a/public/js/app-actions.js b/public/js/app-actions.js
index e17242a7..d4e7ef2b 100644
--- a/public/js/app-actions.js
+++ b/public/js/app-actions.js
@@ -729,24 +729,6 @@ sysPass.Actions = function (Common) {
* @type {{ldap: checks.ldap, wiki: checks.wiki}}
*/
const checks = {
- ldap: function ($obj) {
- log.info("checks:ldap");
-
- const $form = $($obj.data("src"));
- $form.find("[name='sk']").val(Common.sk.get());
-
- const opts = Common.appRequests().getRequestOpts();
- opts.url = ajaxUrl.entrypoint;
- opts.data = $form.serialize();
-
- Common.appRequests().getActionCall(opts, function (json) {
- Common.msg.out(json);
-
- var $results = $("#ldap-results");
- $results.find(".list-wrap").html(Common.appTheme().html.getList(json.data));
- $results.show("slow");
- });
- },
wiki: function ($obj) {
log.info("checks:wiki");
@@ -1190,42 +1172,6 @@ sysPass.Actions = function (Common) {
log.info("appMgmt:nav");
grid.nav($obj);
- },
- ldapSync: function ($obj) {
- log.info("appMgmt:ldapSync");
-
- var atext = "" + Common.config().LANG[57] + "
";
-
- mdlDialog().show({
- text: atext,
- negative: {
- title: Common.config().LANG[44],
- onClick: function (e) {
- e.preventDefault();
-
- Common.msg.error(Common.config().LANG[44]);
- }
- },
- positive: {
- title: Common.config().LANG[43],
- onClick: function (e) {
- var opts = Common.appRequests().getRequestOpts();
- opts.url = ajaxUrl.entrypoint;
- opts.data = {
- actionId: $obj.data("action-id"),
- sk: Common.sk.get(),
- isAjax: 1,
- ldap_loginattribute: $("#ldap_loginattribute").val(),
- ldap_nameattribute: $("#ldap_nameattribute").val(),
- ldap_ads: $("#ldap_ads").prop("checked")
- };
-
- Common.appRequests().getActionCall(opts, function (json) {
- Common.msg.out(json);
- });
- }
- }
- });
}
};
@@ -1559,6 +1505,62 @@ sysPass.Actions = function (Common) {
}
};
+ const ldap = {
+ check: function ($obj) {
+ log.info("checks:ldap");
+
+ const $form = $($obj.data("src"));
+ $form.find("[name='sk']").val(Common.sk.get());
+
+ const opts = Common.appRequests().getRequestOpts();
+ opts.url = ajaxUrl.entrypoint + '?r=' + $obj.data("action-route");
+ opts.data = $form.serialize();
+
+ Common.appRequests().getActionCall(opts, function (json) {
+ Common.msg.out(json);
+
+ const $results = $("#ldap-results");
+ $results.find(".list-wrap")
+ .empty()
+ .append(Common.appTheme().html.getList(json.data.users))
+ .append(Common.appTheme().html.getList(json.data.groups, 'group'));
+ $results.show("slow");
+ });
+ },
+ import: function ($obj) {
+ log.info("appMgmt:ldapSync");
+
+ const atext = "" + Common.config().LANG[57] + "
";
+
+ mdlDialog().show({
+ text: atext,
+ negative: {
+ title: Common.config().LANG[44],
+ onClick: function (e) {
+ e.preventDefault();
+
+ Common.msg.error(Common.config().LANG[44]);
+ }
+ },
+ positive: {
+ title: Common.config().LANG[43],
+ onClick: function (e) {
+ const $form = $($obj.data("src"));
+ $form.find("[name='sk']").val(Common.sk.get());
+
+ const opts = Common.appRequests().getRequestOpts();
+ opts.url = ajaxUrl.entrypoint + "?r=" + $obj.data("action-route");
+ opts.data = $form.serialize();
+
+ Common.appRequests().getActionCall(opts, function (json) {
+ Common.msg.out(json);
+ });
+ }
+ }
+ });
+ }
+ };
+
return {
doAction: doAction,
appMgmt: appMgmt,
@@ -1574,6 +1576,7 @@ sysPass.Actions = function (Common) {
plugin: plugin,
notification: notification,
wiki: wiki,
- items: items
+ items: items,
+ ldap: ldap
};
};
diff --git a/public/js/app-actions.min.js b/public/js/app-actions.min.js
index ceb5d7e0..27e154a9 100644
--- a/public/js/app-actions.min.js
+++ b/public/js/app-actions.min.js
@@ -1,45 +1,45 @@
-var $jscomp={scope:{},findInternal:function(c,e,l){c instanceof String&&(c=String(c));for(var f=c.length,g=0;g