diff --git a/plugins/authentication/cookie/cookie.xml b/plugins/authentication/cookie/cookie.xml
index 5a4a2084236f1..50963a6b5c808 100644
--- a/plugins/authentication/cookie/cookie.xml
+++ b/plugins/authentication/cookie/cookie.xml
@@ -9,8 +9,10 @@
www.joomla.org
3.0.0
PLG_AUTHENTICATION_COOKIE_XML_DESCRIPTION
+ Joomla\Plugin\Authentication\Cookie
- cookie.php
+ services
+ src
language/en-GB/plg_authentication_cookie.ini
diff --git a/plugins/authentication/cookie/services/provider.php b/plugins/authentication/cookie/services/provider.php
new file mode 100644
index 0000000000000..25ce4f9ebd0cf
--- /dev/null
+++ b/plugins/authentication/cookie/services/provider.php
@@ -0,0 +1,51 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Extension\PluginInterface;
+use Joomla\CMS\Factory;
+use Joomla\CMS\Plugin\PluginHelper;
+use Joomla\Database\DatabaseInterface;
+use Joomla\DI\Container;
+use Joomla\DI\ServiceProviderInterface;
+use Joomla\Event\DispatcherInterface;
+use Joomla\Plugin\Authentication\Cookie\Extension\Cookie;
+
+return new class implements ServiceProviderInterface
+{
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->set(
+ PluginInterface::class,
+ function (Container $container) {
+ $dispatcher = $container->get(DispatcherInterface::class);
+
+ $plugin = new Cookie(
+ $dispatcher,
+ (array) PluginHelper::getPlugin('authentication', 'cookie')
+ );
+ $plugin->setApplication(Factory::getApplication());
+ $plugin->setDatabase($container->get(DatabaseInterface::class));
+
+ return $plugin;
+ }
+ );
+ }
+};
diff --git a/plugins/authentication/cookie/cookie.php b/plugins/authentication/cookie/src/Extension/Cookie.php
similarity index 65%
rename from plugins/authentication/cookie/cookie.php
rename to plugins/authentication/cookie/src/Extension/Cookie.php
index 48d9c83ffcac7..cab2a0b88cff9 100644
--- a/plugins/authentication/cookie/cookie.php
+++ b/plugins/authentication/cookie/src/Extension/Cookie.php
@@ -6,10 +6,10 @@
*
* @copyright (C) 2013 Open Source Matters, Inc.
* @license GNU General Public License version 2 or later; see LICENSE.txt
-
- * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
*/
+namespace Joomla\Plugin\Authentication\Cookie\Extension;
+
use Joomla\CMS\Authentication\Authentication;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\Language\Text;
@@ -17,6 +17,8 @@
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserHelper;
+use Joomla\Database\DatabaseAwareTrait;
+use RuntimeException;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
@@ -29,23 +31,9 @@
* @note Code based on http://jaspan.com/improved_persistent_login_cookie_best_practice
* and http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/
*/
-class PlgAuthenticationCookie extends CMSPlugin
+final class Cookie extends CMSPlugin
{
- /**
- * Application object
- *
- * @var \Joomla\CMS\Application\CMSApplication
- * @since 3.2
- */
- protected $app;
-
- /**
- * Database object
- *
- * @var \Joomla\Database\DatabaseDriver
- * @since 3.2
- */
- protected $db;
+ use DatabaseAwareTrait;
/**
* Reports the privacy related capabilities for this plugin to site administrators.
@@ -59,8 +47,8 @@ public function onPrivacyCollectAdminCapabilities()
$this->loadLanguage();
return array(
- Text::_('PLG_AUTHENTICATION_COOKIE') => array(
- Text::_('PLG_AUTHENTICATION_COOKIE_PRIVACY_CAPABILITY_COOKIE'),
+ $this->getApplication()->getLanguage()->_('PLG_AUTHENTICATION_COOKIE') => array(
+ $this->getApplication()->getLanguage()->_('PLG_AUTHENTICATION_COOKIE_PRIVACY_CAPABILITY_COOKIE'),
),
);
}
@@ -79,18 +67,18 @@ public function onPrivacyCollectAdminCapabilities()
public function onUserAuthenticate($credentials, $options, &$response)
{
// No remember me for admin
- if ($this->app->isClient('administrator')) {
+ if ($this->getApplication()->isClient('administrator')) {
return false;
}
// Get cookie
$cookieName = 'joomla_remember_me_' . UserHelper::getShortHashedUserAgent();
- $cookieValue = $this->app->getInput()->cookie->get($cookieName);
+ $cookieValue = $this->getApplication()->getInput()->cookie->get($cookieName);
// Try with old cookieName (pre 3.6.0) if not found
if (!$cookieValue) {
$cookieName = UserHelper::getShortHashedUserAgent();
- $cookieValue = $this->app->getInput()->cookie->get($cookieName);
+ $cookieValue = $this->getApplication()->getInput()->cookie->get($cookieName);
}
if (!$cookieValue) {
@@ -102,7 +90,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
// Check for valid cookie value
if (count($cookieArray) !== 2) {
// Destroy the cookie in the browser.
- $this->app->getInput()->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
+ $this->getApplication()->getInput()->cookie->set($cookieName, '', 1, $this->getApplication()->get('cookie_path', '/'), $this->getApplication()->get('cookie_domain', ''));
Log::add('Invalid cookie detected.', Log::WARNING, 'error');
return false;
@@ -116,29 +104,29 @@ public function onUserAuthenticate($credentials, $options, &$response)
$now = time();
// Remove expired tokens
- $query = $this->db->getQuery(true)
- ->delete($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('time') . ' < :now')
+ $query = $this->getDatabase()->getQuery(true)
+ ->delete($this->getDatabase()->quoteName('#__user_keys'))
+ ->where($this->getDatabase()->quoteName('time') . ' < :now')
->bind(':now', $now);
try {
- $this->db->setQuery($query)->execute();
+ $this->getDatabase()->setQuery($query)->execute();
} catch (RuntimeException $e) {
// We aren't concerned with errors from this query, carry on
}
// Find the matching record if it exists.
- $query = $this->db->getQuery(true)
- ->select($this->db->quoteName(['user_id', 'token', 'series', 'time']))
- ->from($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('series') . ' = :series')
- ->where($this->db->quoteName('uastring') . ' = :uastring')
- ->order($this->db->quoteName('time') . ' DESC')
+ $query = $this->getDatabase()->getQuery(true)
+ ->select($this->getDatabase()->quoteName(['user_id', 'token', 'series', 'time']))
+ ->from($this->getDatabase()->quoteName('#__user_keys'))
+ ->where($this->getDatabase()->quoteName('series') . ' = :series')
+ ->where($this->getDatabase()->quoteName('uastring') . ' = :uastring')
+ ->order($this->getDatabase()->quoteName('time') . ' DESC')
->bind(':series', $series)
->bind(':uastring', $cookieName);
try {
- $results = $this->db->setQuery($query)->loadObjectList();
+ $results = $this->getDatabase()->setQuery($query)->loadObjectList();
} catch (RuntimeException $e) {
$response->status = Authentication::STATUS_FAILURE;
@@ -147,7 +135,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
if (count($results) !== 1) {
// Destroy the cookie in the browser.
- $this->app->getInput()->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
+ $this->getApplication()->getInput()->cookie->set($cookieName, '', 1, $this->getApplication()->get('cookie_path', '/'), $this->getApplication()->get('cookie_domain', ''));
$response->status = Authentication::STATUS_FAILURE;
return false;
@@ -160,13 +148,13 @@ public function onUserAuthenticate($credentials, $options, &$response)
* Either the series was guessed correctly or a cookie was stolen and used twice (once by attacker and once by victim).
* Delete all tokens for this user!
*/
- $query = $this->db->getQuery(true)
- ->delete($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('user_id') . ' = :userid')
+ $query = $this->getDatabase()->getQuery(true)
+ ->delete($this->getDatabase()->quoteName('#__user_keys'))
+ ->where($this->getDatabase()->quoteName('user_id') . ' = :userid')
->bind(':userid', $results[0]->user_id);
try {
- $this->db->setQuery($query)->execute();
+ $this->getDatabase()->setQuery($query)->execute();
} catch (RuntimeException $e) {
// Log an alert for the site admin
Log::add(
@@ -177,7 +165,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
}
// Destroy the cookie in the browser.
- $this->app->getInput()->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
+ $this->getApplication()->getInput()->cookie->set($cookieName, '', 1, $this->getApplication()->get('cookie_path', '/'), $this->getApplication()->get('cookie_domain', ''));
// Issue warning by email to user and/or admin?
Log::add(Text::sprintf('PLG_AUTHENTICATION_COOKIE_ERROR_LOG_LOGIN_FAILED', $results[0]->user_id), Log::WARNING, 'security');
@@ -187,15 +175,15 @@ public function onUserAuthenticate($credentials, $options, &$response)
}
// Make sure there really is a user with this name and get the data for the session.
- $query = $this->db->getQuery(true)
- ->select($this->db->quoteName(['id', 'username', 'password']))
- ->from($this->db->quoteName('#__users'))
- ->where($this->db->quoteName('username') . ' = :userid')
- ->where($this->db->quoteName('requireReset') . ' = 0')
+ $query = $this->getDatabase()->getQuery(true)
+ ->select($this->getDatabase()->quoteName(['id', 'username', 'password']))
+ ->from($this->getDatabase()->quoteName('#__users'))
+ ->where($this->getDatabase()->quoteName('username') . ' = :userid')
+ ->where($this->getDatabase()->quoteName('requireReset') . ' = 0')
->bind(':userid', $results[0]->user_id);
try {
- $result = $this->db->setQuery($query)->loadObject();
+ $result = $this->getDatabase()->setQuery($query)->loadObject();
} catch (RuntimeException $e) {
$response->status = Authentication::STATUS_FAILURE;
@@ -218,7 +206,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
$response->error_message = '';
} else {
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_NO_USER');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_NO_USER');
}
}
@@ -236,7 +224,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
public function onUserAfterLogin($options)
{
// No remember me for admin
- if ($this->app->isClient('administrator')) {
+ if ($this->getApplication()->isClient('administrator')) {
return false;
}
@@ -245,15 +233,15 @@ public function onUserAfterLogin($options)
$cookieName = 'joomla_remember_me_' . UserHelper::getShortHashedUserAgent();
// We need the old data to get the existing series
- $cookieValue = $this->app->getInput()->cookie->get($cookieName);
+ $cookieValue = $this->getApplication()->getInput()->cookie->get($cookieName);
// Try with old cookieName (pre 3.6.0) if not found
if (!$cookieValue) {
$oldCookieName = UserHelper::getShortHashedUserAgent();
- $cookieValue = $this->app->getInput()->cookie->get($oldCookieName);
+ $cookieValue = $this->getApplication()->getInput()->cookie->get($oldCookieName);
// Destroy the old cookie in the browser
- $this->app->getInput()->cookie->set($oldCookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
+ $this->getApplication()->getInput()->cookie->set($oldCookieName, '', 1, $this->getApplication()->get('cookie_path', '/'), $this->getApplication()->get('cookie_domain', ''));
}
$cookieArray = explode('.', $cookieValue);
@@ -271,14 +259,14 @@ public function onUserAfterLogin($options)
do {
$series = UserHelper::genRandomPassword(20);
- $query = $this->db->getQuery(true)
- ->select($this->db->quoteName('series'))
- ->from($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('series') . ' = :series')
+ $query = $this->getDatabase()->getQuery(true)
+ ->select($this->getDatabase()->quoteName('series'))
+ ->from($this->getDatabase()->quoteName('#__user_keys'))
+ ->where($this->getDatabase()->quoteName('series') . ' = :series')
->bind(':series', $series);
try {
- $results = $this->db->setQuery($query)->loadResult();
+ $results = $this->getDatabase()->setQuery($query)->loadResult();
if ($results === null) {
$unique = true;
@@ -305,28 +293,28 @@ public function onUserAfterLogin($options)
$cookieValue = $token . '.' . $series;
// Overwrite existing cookie with new value
- $this->app->getInput()->cookie->set(
+ $this->getApplication()->getInput()->cookie->set(
$cookieName,
$cookieValue,
time() + $lifetime,
- $this->app->get('cookie_path', '/'),
- $this->app->get('cookie_domain', ''),
- $this->app->isHttpsForced(),
+ $this->getApplication()->get('cookie_path', '/'),
+ $this->getApplication()->get('cookie_domain', ''),
+ $this->getApplication()->isHttpsForced(),
true
);
- $query = $this->db->getQuery(true);
+ $query = $this->getDatabase()->getQuery(true);
if (!empty($options['remember'])) {
$future = (time() + $lifetime);
// Create new record
$query
- ->insert($this->db->quoteName('#__user_keys'))
- ->set($this->db->quoteName('user_id') . ' = :userid')
- ->set($this->db->quoteName('series') . ' = :series')
- ->set($this->db->quoteName('uastring') . ' = :uastring')
- ->set($this->db->quoteName('time') . ' = :time')
+ ->insert($this->getDatabase()->quoteName('#__user_keys'))
+ ->set($this->getDatabase()->quoteName('user_id') . ' = :userid')
+ ->set($this->getDatabase()->quoteName('series') . ' = :series')
+ ->set($this->getDatabase()->quoteName('uastring') . ' = :uastring')
+ ->set($this->getDatabase()->quoteName('time') . ' = :time')
->bind(':userid', $options['user']->username)
->bind(':series', $series)
->bind(':uastring', $cookieName)
@@ -334,10 +322,10 @@ public function onUserAfterLogin($options)
} else {
// Update existing record with new token
$query
- ->update($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('user_id') . ' = :userid')
- ->where($this->db->quoteName('series') . ' = :series')
- ->where($this->db->quoteName('uastring') . ' = :uastring')
+ ->update($this->getDatabase()->quoteName('#__user_keys'))
+ ->where($this->getDatabase()->quoteName('user_id') . ' = :userid')
+ ->where($this->getDatabase()->quoteName('series') . ' = :series')
+ ->where($this->getDatabase()->quoteName('uastring') . ' = :uastring')
->bind(':userid', $options['user']->username)
->bind(':series', $series)
->bind(':uastring', $cookieName);
@@ -345,11 +333,11 @@ public function onUserAfterLogin($options)
$hashedToken = UserHelper::hashPassword($token);
- $query->set($this->db->quoteName('token') . ' = :token')
+ $query->set($this->getDatabase()->quoteName('token') . ' = :token')
->bind(':token', $hashedToken);
try {
- $this->db->setQuery($query)->execute();
+ $this->getDatabase()->setQuery($query)->execute();
} catch (RuntimeException $e) {
return false;
}
@@ -369,12 +357,12 @@ public function onUserAfterLogin($options)
public function onUserAfterLogout($options)
{
// No remember me for admin
- if ($this->app->isClient('administrator')) {
+ if ($this->getApplication()->isClient('administrator')) {
return false;
}
$cookieName = 'joomla_remember_me_' . UserHelper::getShortHashedUserAgent();
- $cookieValue = $this->app->getInput()->cookie->get($cookieName);
+ $cookieValue = $this->getApplication()->getInput()->cookie->get($cookieName);
// There are no cookies to delete.
if (!$cookieValue) {
@@ -388,19 +376,19 @@ public function onUserAfterLogout($options)
$series = $filter->clean($cookieArray[1], 'ALNUM');
// Remove the record from the database
- $query = $this->db->getQuery(true)
- ->delete($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('series') . ' = :series')
+ $query = $this->getDatabase()->getQuery(true)
+ ->delete($this->getDatabase()->quoteName('#__user_keys'))
+ ->where($this->getDatabase()->quoteName('series') . ' = :series')
->bind(':series', $series);
try {
- $this->db->setQuery($query)->execute();
+ $this->getDatabase()->setQuery($query)->execute();
} catch (RuntimeException $e) {
// We aren't concerned with errors from this query, carry on
}
// Destroy the cookie
- $this->app->getInput()->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
+ $this->getApplication()->getInput()->cookie->set($cookieName, '', 1, $this->getApplication()->get('cookie_path', '/'), $this->getApplication()->get('cookie_domain', ''));
return true;
}
diff --git a/plugins/authentication/joomla/joomla.xml b/plugins/authentication/joomla/joomla.xml
index 64758f07785b4..da9112697185b 100644
--- a/plugins/authentication/joomla/joomla.xml
+++ b/plugins/authentication/joomla/joomla.xml
@@ -9,8 +9,10 @@
www.joomla.org
3.0.0
PLG_AUTHENTICATION_JOOMLA_XML_DESCRIPTION
+ Joomla\Plugin\Authentication\Joomla
- joomla.php
+ services
+ src
language/en-GB/plg_authentication_joomla.ini
diff --git a/plugins/authentication/joomla/services/provider.php b/plugins/authentication/joomla/services/provider.php
new file mode 100644
index 0000000000000..52575131698ab
--- /dev/null
+++ b/plugins/authentication/joomla/services/provider.php
@@ -0,0 +1,51 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Extension\PluginInterface;
+use Joomla\CMS\Factory;
+use Joomla\CMS\Plugin\PluginHelper;
+use Joomla\Database\DatabaseInterface;
+use Joomla\DI\Container;
+use Joomla\DI\ServiceProviderInterface;
+use Joomla\Event\DispatcherInterface;
+use Joomla\Plugin\Authentication\Joomla\Extension\Joomla;
+
+return new class implements ServiceProviderInterface
+{
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->set(
+ PluginInterface::class,
+ function (Container $container) {
+ $dispatcher = $container->get(DispatcherInterface::class);
+
+ $plugin = new Joomla(
+ $dispatcher,
+ (array) PluginHelper::getPlugin('authentication', 'joomla')
+ );
+ $plugin->setApplication(Factory::getApplication());
+ $plugin->setDatabase($container->get(DatabaseInterface::class));
+
+ return $plugin;
+ }
+ );
+ }
+};
diff --git a/plugins/authentication/joomla/joomla.php b/plugins/authentication/joomla/src/Extension/Joomla.php
similarity index 77%
rename from plugins/authentication/joomla/joomla.php
rename to plugins/authentication/joomla/src/Extension/Joomla.php
index 7fcb7a5b2b013..6a09d1afcce77 100644
--- a/plugins/authentication/joomla/joomla.php
+++ b/plugins/authentication/joomla/src/Extension/Joomla.php
@@ -6,17 +6,15 @@
*
* @copyright (C) 2006 Open Source Matters, Inc.
* @license GNU General Public License version 2 or later; see LICENSE.txt
-
- * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
*/
+namespace Joomla\Plugin\Authentication\Joomla\Extension;
+
use Joomla\CMS\Authentication\Authentication;
-use Joomla\CMS\Helper\AuthenticationHelper;
-use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\CMSPlugin;
-use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserHelper;
+use Joomla\Database\DatabaseAwareTrait;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
@@ -27,23 +25,9 @@
*
* @since 1.5
*/
-class PlgAuthenticationJoomla extends CMSPlugin
+final class Joomla extends CMSPlugin
{
- /**
- * Application object
- *
- * @var \Joomla\CMS\Application\CMSApplication
- * @since 4.0.0
- */
- protected $app;
-
- /**
- * Database object
- *
- * @var \Joomla\Database\DatabaseDriver
- * @since 4.0.0
- */
- protected $db;
+ use DatabaseAwareTrait;
/**
* This method should handle any authentication and report back to the subject
@@ -63,12 +47,12 @@ public function onUserAuthenticate($credentials, $options, &$response)
// Joomla does not like blank passwords
if (empty($credentials['password'])) {
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED');
return;
}
- $db = $this->db;
+ $db = $this->getDatabase();
$query = $db->getQuery(true)
->select($db->quoteName(['id', 'password']))
->from($db->quoteName('#__users'))
@@ -87,7 +71,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
$response->email = $user->email;
$response->fullname = $user->name;
- if ($this->app->isClient('administrator')) {
+ if ($this->getApplication()->isClient('administrator')) {
$response->language = $user->getParam('admin_language');
} else {
$response->language = $user->getParam('language');
@@ -98,7 +82,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
} else {
// Invalid password
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_INVALID_PASS');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_INVALID_PASS');
}
} else {
// Let's hash the entered password even if we don't have a matching user for some extra response time
@@ -107,7 +91,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
// Invalid user
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_NO_USER');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_NO_USER');
}
}
}
diff --git a/plugins/authentication/ldap/ldap.xml b/plugins/authentication/ldap/ldap.xml
index 2b0e4f42596c6..758a680f4684a 100644
--- a/plugins/authentication/ldap/ldap.xml
+++ b/plugins/authentication/ldap/ldap.xml
@@ -9,8 +9,10 @@
www.joomla.org
3.0.0
PLG_LDAP_XML_DESCRIPTION
+ Joomla\Plugin\Authentication\Ldap
- ldap.php
+ services
+ src
language/en-GB/plg_authentication_ldap.ini
diff --git a/plugins/authentication/ldap/services/provider.php b/plugins/authentication/ldap/services/provider.php
new file mode 100644
index 0000000000000..dfeb4cf8296da
--- /dev/null
+++ b/plugins/authentication/ldap/services/provider.php
@@ -0,0 +1,51 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Extension\PluginInterface;
+use Joomla\CMS\Factory;
+use Joomla\CMS\Plugin\PluginHelper;
+use Joomla\Database\DatabaseInterface;
+use Joomla\DI\Container;
+use Joomla\DI\ServiceProviderInterface;
+use Joomla\Event\DispatcherInterface;
+use Joomla\Plugin\Authentication\Ldap\Extension\Ldap;
+
+return new class implements ServiceProviderInterface
+{
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->set(
+ PluginInterface::class,
+ function (Container $container) {
+ $dispatcher = $container->get(DispatcherInterface::class);
+
+ $plugin = new Ldap(
+ $dispatcher,
+ (array) PluginHelper::getPlugin('authentication', 'ldap')
+ );
+ $plugin->setApplication(Factory::getApplication());
+ $plugin->setDatabase($container->get(DatabaseInterface::class));
+
+ return $plugin;
+ }
+ );
+ }
+};
diff --git a/plugins/authentication/ldap/ldap.php b/plugins/authentication/ldap/src/Extension/Ldap.php
similarity index 85%
rename from plugins/authentication/ldap/ldap.php
rename to plugins/authentication/ldap/src/Extension/Ldap.php
index 0f2679635beb9..09f3c280b1f44 100644
--- a/plugins/authentication/ldap/ldap.php
+++ b/plugins/authentication/ldap/src/Extension/Ldap.php
@@ -6,18 +6,18 @@
*
* @copyright (C) 2006 Open Source Matters, Inc.
* @license GNU General Public License version 2 or later; see LICENSE.txt
-
- * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
*/
+namespace Joomla\Plugin\Authentication\Ldap\Extension;
+
use Joomla\CMS\Authentication\Authentication;
-use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\CMSPlugin;
+use Joomla\Database\DatabaseAwareTrait;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\ConnectionException;
use Symfony\Component\Ldap\Exception\LdapException;
-use Symfony\Component\Ldap\Ldap;
+use Symfony\Component\Ldap\Ldap as LdapProvider;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
@@ -28,8 +28,10 @@
*
* @since 1.5
*/
-class PlgAuthenticationLdap extends CMSPlugin
+final class Ldap extends CMSPlugin
{
+ use DatabaseAwareTrait;
+
/**
* This method should handle any authentication and report back to the subject
*
@@ -58,7 +60,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
// LDAP does not like Blank passwords (tries to Anon Bind which is bad)
if (empty($credentials['password'])) {
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED');
return false;
}
@@ -79,10 +81,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
Log::add(sprintf('Creating LDAP session with options: %s', json_encode($options)), Log::DEBUG, $logcategory);
$connection_string = sprintf('ldap%s://%s:%s', 'ssl' === $options['encryption'] ? 's' : '', $options['host'], $options['port']);
Log::add(sprintf('Creating LDAP session to connect to "%s" while binding', $connection_string), Log::DEBUG, $logcategory);
- $ldap = Ldap::create(
- 'ext_ldap',
- $options
- );
+ $ldap = LdapProvider::create('ext_ldap', $options);
switch ($auth_method) {
case 'search':
@@ -92,7 +91,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
$ldap->bind($dn, $this->params->get('password', ''));
} catch (ConnectionException | LdapException $exception) {
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_NOT_CONNECT');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_NOT_CONNECT');
Log::add($exception->getMessage(), Log::ERROR, $logcategory);
return;
@@ -112,7 +111,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
);
} catch (LdapException $exception) {
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED');
Log::add($exception->getMessage(), Log::ERROR, $logcategory);
return;
@@ -121,8 +120,8 @@ public function onUserAuthenticate($credentials, $options, &$response)
if (!$entry) {
// we did not find the login in LDAP
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_NO_USER');
- Log::add(Text::_('JGLOBAL_AUTH_USER_NOT_FOUND'), Log::ERROR, $logcategory);
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_NO_USER');
+ Log::add($this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_USER_NOT_FOUND'), Log::ERROR, $logcategory);
return;
} else {
@@ -135,7 +134,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
$ldap->bind($entry->getDn(), $credentials['password']);
} catch (ConnectionException $exception) {
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_INVALID_PASS');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_INVALID_PASS');
Log::add($exception->getMessage(), Log::ERROR, $logcategory);
return;
@@ -160,7 +159,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
$ldap->bind($dn, $credentials['password']);
} catch (ConnectionException | LdapException $exception) {
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_INVALID_PASS');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_INVALID_PASS');
Log::add($exception->getMessage(), Log::ERROR, $logcategory);
return;
@@ -179,7 +178,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
);
} catch (LdapException $exception) {
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED');
Log::add($exception->getMessage(), Log::ERROR, $logcategory);
return;
@@ -190,7 +189,7 @@ public function onUserAuthenticate($credentials, $options, &$response)
default:
// Unsupported configuration
$response->status = Authentication::STATUS_FAILURE;
- $response->error_message = Text::_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED');
+ $response->error_message = $this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED');
Log::add($response->error_message, Log::ERROR, $logcategory);
return;
@@ -216,14 +215,14 @@ public function onUserAuthenticate($credentials, $options, &$response)
* Note that this method requires that semicolons which should be part of the search term to be escaped
* to correctly split the search string into separate lookups
*
- * @param string $search search string of search values
- * @param Ldap $ldap The LDAP client
+ * @param string $search search string of search values
+ * @param LdapProvider $ldap The LDAP client
*
* @return Entry|null The search result entry if a matching record was found
*
* @since 3.8.2
*/
- private function searchByString($search, Ldap $ldap)
+ private function searchByString($search, LdapProvider $ldap)
{
$dn = $this->params->get('base_dn');
diff --git a/tests/Unit/Plugin/Authentication/Ldap/LdapPluginTest.php b/tests/Unit/Plugin/Authentication/Ldap/LdapPluginTest.php
index bad9351778036..ba4154a2aeceb 100644
--- a/tests/Unit/Plugin/Authentication/Ldap/LdapPluginTest.php
+++ b/tests/Unit/Plugin/Authentication/Ldap/LdapPluginTest.php
@@ -10,10 +10,12 @@
namespace Joomla\Tests\Unit\Plugin\Authentication\Ldap;
+use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\CMS\Authentication\Authentication;
use Joomla\CMS\Authentication\AuthenticationResponse;
-use Joomla\CMS\Plugin\CMSPlugin;
+use Joomla\CMS\Language\Language;
use Joomla\Event\Dispatcher;
+use Joomla\Plugin\Authentication\Ldap\Extension\Ldap as LdapPlugin;
use Joomla\Tests\Unit\UnitTestCase;
use Symfony\Component\Ldap\Ldap;
@@ -32,25 +34,43 @@ class LdapPluginTest extends UnitTestCase
public const LDAPPORT = "1389";
public const SSLPORT = "1636";
- private function getPlugin($options): CMSPlugin
+ /**
+ * The default options
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ private $default_options;
+
+ /**
+ * The default credentials
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ private $default_credentials;
+
+ private function getPlugin($options): LdapPlugin
{
- $type = "authentication";
- $plugin = "ldap";
+ $language = $this->createStub(Language::class);
+ $language->method('_')->willReturn('test');
- // based on loadPluginFromFilesystem in ExtensionManagerTrait
- $path = JPATH_PLUGINS . '/' . $type . '/' . $plugin . '/' . $plugin . '.php';
- require_once $path;
+ $app = $this->createStub(CMSApplicationInterface::class);
+ $app->method('getLanguage')->willReturn($language);
$dispatcher = new Dispatcher();
// plugin object: result from DB using PluginHelper::getPlugin
- $pluginobject = [
- 'name' => $plugin,
+ $pluginObject = [
+ 'name' => 'ldap',
'params' => json_encode($options),
- 'type' => $type
+ 'type' => 'authentication'
];
- return new \PlgAuthenticationLdap($dispatcher, $pluginobject);
+ $plugin = new LdapPlugin($dispatcher, $pluginObject);
+ $plugin->setApplication($app);
+
+ return $plugin;
}
private function acceptCertificates(): void