- md5
- ba35d58cba414d95b6e3244dbc434f30
- sha1
- 3c136013dc00422eb41203b77b8768fec7285458
- sha256
- c79cce63370a01316ce14d8676a725b34920ec442a5f19d47dbc08db8deb6e35
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
<?php
/**
* @package Joomla.Plugin
* @subpackage Apiauthentication.basic
*
* @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Plugin\ApiAuthentication\Basic\Extension;
defined('_JEXEC') or die;
use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\CMS\Authentication\Authentication;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\User\UserFactoryInterface;
use Joomla\CMS\User\UserHelper;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Event\DispatcherInterface;
/**
* Joomla Authentication plugin
*
* @since 4.0.0
*/
final class Basic extends CMSPlugin
{
use DatabaseAwareTrait;
/**
* The application object
*
* @var CMSApplicationInterface
* @since 4.0.0
*/
protected $app;
/**
* The user factory
*
* @var UserFactoryInterface
* @since 4.2.0
*/
private $userFactory;
/**
* Constructor.
*
* @param DispatcherInterface $dispatcher The dispatcher
* @param array $config An optional associative array of configuration settings
* @param UserFactoryInterface $userFactory The user factory
*
* @since 4.2.0
*/
public function __construct(DispatcherInterface $dispatcher, array $config, UserFactoryInterface $userFactory)
{
parent::__construct($dispatcher, $config);
$this->userFactory = $userFactory;
}
/**
* This method should handle any authentication and report back to the subject
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
* @param object &$response Authentication response object
*
* @return void
*
* @since 4.0.0
*/
public function onUserAuthenticate($credentials, $options, &$response)
{
$response->type = 'Basic';
$username = $this->app->input->server->get('PHP_AUTH_USER', '', 'USERNAME');
$password = $this->app->input->server->get('PHP_AUTH_PW', '', 'RAW');
if ($password === '')
{
$response->status = Authentication::STATUS_FAILURE;
$response->error_message = $this->app->getLanguage()->_('JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED');
return;
}
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select($db->quoteName(['id', 'password']))
->from($db->quoteName('#__users'))
->where($db->quoteName('username') . ' = :username')
->bind(':username', $username);
$db->setQuery($query);
$result = $db->loadObject();
if ($result)
{
$match = UserHelper::verifyPassword($password, $result->password, $result->id);
if ($match === true)
{
// Bring this in line with the rest of the system
$user = $this->userFactory->loadUserById($result->id);
$response->email = $user->email;
$response->fullname = $user->name;
$response->username = $username;
if ($this->app->isClient('administrator'))
{
$response->language = $user->getParam('admin_language');
}
else
{
$response->language = $user->getParam('language');
}
$response->status = Authentication::STATUS_SUCCESS;
$response->error_message = '';
}
else
{
// Invalid password
$response->status = Authentication::STATUS_FAILURE;
$response->error_message = $this->app->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
// By doing so, we mitigate side channel user enumeration attacks
UserHelper::hashPassword($password);
// Invalid user
$response->status = Authentication::STATUS_FAILURE;
$response->error_message = $this->app->getLanguage()->_('JGLOBAL_AUTH_NO_USER');
}
}
}
The same content is in 2 releases, Joomla 4.2.0-alpha3 to 4.2.0-beta1. See them all, or every version of this file.