Finished the architecture for captcha

This commit is contained in:
Laurent Destailleur 2024-11-09 13:58:30 +01:00
parent 576df86eac
commit e2e8cdbc4b
2 changed files with 57 additions and 7 deletions

View File

@ -109,7 +109,9 @@ class modCaptchaStandard extends ModeleCaptcha
{
global $langs;
// TODO Replace the a link with a post of form.
// Output the image by calling /core/antispamimage.php
// This antispamimage also record the value of code into $_SESSION['dol_antispam_value'] so we will be able to validate by calling
// validateCodeAfterLoginSubmit() later when we submit the login form.
$out = '<!-- Captcha -->
<div class="trinputlogin">
@ -157,6 +159,10 @@ class modCaptchaStandard extends ModeleCaptcha
*/
public function validateCodeAfterLoginSubmit()
{
return 1;
$sessionkey = 'dol_antispam_value'; // The same key than set into the /core/antispamimage.php file.
$ok = (array_key_exists($sessionkey, $_SESSION) && (strtolower($_SESSION[$sessionkey]) === strtolower(GETPOST('code', 'restricthtml'))));
return $ok;
}
}

View File

@ -845,16 +845,60 @@ if (!defined('NOLOGIN')) {
// Verification security graphic code
if ($test && GETPOST('actionlogin', 'aZ09') == 'login' && GETPOST("username", "alpha", 2) && getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA') && !isset($_SESSION['dol_bypass_antispam'])) {
$sessionkey = 'dol_antispam_value';
$ok = (array_key_exists($sessionkey, $_SESSION) && (strtolower($_SESSION[$sessionkey]) === strtolower(GETPOST('code', 'restricthtml'))));
$ok = false;
// Check code
// Use the captcha handler to validate
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
$captcha = getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_HANDLER', 'standard');
// List of directories where we can find captcha handlers
$dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array());
$fullpathclassfile = '';
foreach ($dirModCaptcha as $dir) {
$fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2);
if ($fullpathclassfile) {
break;
}
}
// The file for captcha check has been found
if ($fullpathclassfile) {
include_once $fullpathclassfile;
$captchaobj = null;
// Charging the numbering class
$classname = "modCaptcha".ucfirst($captcha);
if (class_exists($classname)) {
/** @var ModeleCaptcha $captchaobj */
$captchaobj = new $classname($db, $conf, $langs, $user);
'@phan-var-force ModeleCaptcha $captchaobj';
if (is_object($captchaobj) && method_exists($captchaobj, 'validateCodeAfterLoginSubmit')) {
$ok = $captchaobj->validateCodeAfterLoginSubmit(); // @phan-suppress-current-line PhanUndeclaredMethod
} else {
$_SESSION["dol_loginmesg"] = 'Error, the captcha handler '.get_class($captchaobj).' does not have any method validateCodeAfterLoginSubmit()';
$test = false;
$error++;
}
} else {
$_SESSION["dol_loginmesg"] = 'Error, the captcha handler class '.$classname.' was not found after the include';
$test = false;
$error++;
}
} else {
$_SESSION["dol_loginmesg"] = 'Error, the captcha handler '.$captcha.' has no class file found modCaptcha'.ucfirst($captcha);
$test = false;
$error++;
}
// Process error of captcha validation
if (!$ok) {
dol_syslog('Bad value for code, connection refused', LOG_NOTICE);
// Load translation files required by page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorBadValueForCode");
$_SESSION["dol_loginmesg"] = (empty($_SESSION["dol_loginmesg"]) ? "" : $_SESSION["dol_loginmesg"]."<br>\n").$langs->transnoentitiesnoconv("ErrorBadValueForCode");
$test = false;
// Call trigger for the "security events" log
@ -876,7 +920,7 @@ if (!defined('NOLOGIN')) {
$error++;
}
// Note: exit is done later
// Note: exit is done later ($test is false)
}
}