From c6931ccb54de3997ffae041dd0cc53dd6114c95b Mon Sep 17 00:00:00 2001 From: Maxime Besson Date: Tue, 19 Apr 2022 16:51:59 +0200 Subject: [PATCH] Update Portal plugins to new Captcha API (#2692) --- .../lib/Lemonldap/NG/Portal/Auth/_WebForm.pm | 19 +++-- .../Portal/Plugins/CertificateResetByMail.pm | 71 +++++++++---------- .../NG/Portal/Plugins/MailPasswordReset.pm | 64 ++++++++--------- .../Lemonldap/NG/Portal/Plugins/Register.pm | 68 ++++++++---------- 4 files changed, 103 insertions(+), 119 deletions(-) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/_WebForm.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/_WebForm.pm index 431a3f9bc..cc30c1d5f 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/_WebForm.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/_WebForm.pm @@ -44,7 +44,7 @@ sub init { my $self = shift; if ( $self->{conf}->{captcha_login_enabled} ) { - $self->captcha( $self->p->loadModule('::Lib::Captcha') ) or return 0; + $self->captcha(1); } else { $self->ott( $self->p->loadModule('::Lib::OneTimeToken') ) or return 0; @@ -117,18 +117,15 @@ sub extractFormInfo { } if ( $self->captcha ) { - my $code = $req->param('captcha'); - unless ($code) { - $self->captcha->setCaptcha($req); - return PE_CAPTCHAEMPTY; + my $result = $self->p->_captcha->check_captcha($req); + if ($result) { + $self->logger->debug("Captcha code verified"); } - unless ( $self->captcha->validateCaptcha( $token, $code ) ) { - $self->captcha->setCaptcha($req); - $self->userLogger->warn( - "Captcha failed: wrong or expired code"); + else { + $self->p->_captcha->init_captcha($req); + $self->userLogger->warn("Captcha failed"); return PE_CAPTCHAERROR; } - $self->logger->debug("Captcha code verified"); } elsif ( $self->ottRule->( $req, {} ) ) { unless ( $req->data->{tokenVerified} @@ -179,7 +176,7 @@ sub setSecurity { # If captcha is enable, prepare it if ( $self->captcha ) { - $self->captcha->setCaptcha($req); + $self->p->_captcha->init_captcha($req); } # Else get token diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm index b15e6c856..712a7a687 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm @@ -98,7 +98,7 @@ sub init { # Initialize Captcha if needed if ( $self->conf->{captcha_mail_enabled} ) { - $self->captcha( $self->p->loadModule('::Lib::Captcha') ) or return 0; + $self->captcha(1); } # Load registered module @@ -179,46 +179,32 @@ sub _certificateReset { # Use submitted value $req->{user} = $req->param('mail'); - # Check if token exists - my $token; - if ( $self->ottRule->( $req, {} ) or $self->captcha ) { - $token = $req->param('token'); + # Captcha for register form + if ( $self->captcha ) { + my $result = $self->p->_captcha->check_captcha($req); + if ($result) { + $self->logger->debug("Captcha code verified"); + } + else { + $self->setSecurity($req); + $self->userLogger->warn("Captcha failed"); + return PE_CAPTCHAERROR; + } + } + elsif ( $self->ottRule->( $req, {} ) ) { + my $token = $req->param('token'); unless ($token) { $self->setSecurity($req); $self->userLogger->warn('Reset try without token'); return PE_NOTOKEN; } - } - - # Captcha for register form - if ( $self->captcha ) { - my $captcha = $req->param('captcha'); - - unless ($captcha) { - $self->userLogger->notice('Reset try with captcha not filled'); - - # Set captcha or token - $self->setSecurity($req); - return PE_CAPTCHAEMPTY; - } - - # Check captcha - unless ( $self->captcha->validateCaptcha( $token, $captcha ) ) { - $self->userLogger->info('Captcha failed: wrong code'); - - # Set captcha or token - $self->setSecurity($req); - return PE_CAPTCHAERROR; - } - $self->logger->debug('Captcha code verified'); - } - elsif ( $self->ottRule->( $req, {} ) ) { unless ( $self->ott->getToken($token) ) { $self->setSecurity($req); $self->userLogger->warn('Reset try with expired/bad token'); return PE_TOKENEXPIRED; } } + unless ( $req->{user} =~ /$self->{conf}->{userControl}/o ) { $self->setSecurity($req); return PE_MALFORMEDUSER; @@ -581,9 +567,11 @@ sub modifyCertificate { sub setSecurity { my ( $self, $req ) = @_; + if ( $self->captcha ) { - $self->captcha->setCaptcha($req); + $self->p->_captcha->init_captcha($req); } + elsif ( $self->ottRule->( $req, {} ) ) { $self->ott->setToken($req); } @@ -608,9 +596,13 @@ sub display { STARTMAILDATE => $req->data->{startMailDate}, STARTMAILTIME => $req->data->{startMailTime}, MAILALREADYSENT => $req->data->{mailAlreadySent}, - MAIL => ( - $self->p->checkXSSAttack( 'mail', $req->{user} ) - ? '' + ( + $req->data->{customScript} + ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) + : () + ), + MAIL => ( + $self->p->checkXSSAttack( 'mail', $req->{user} ) ? '' : $req->{user} ), DISPLAY_FORM => 0, @@ -627,14 +619,19 @@ sub display { } # Display captcha if enabled - if ( $req->captcha ) { - $tplPrm{CAPTCHA_SRC} = $req->captcha; - $tplPrm{CAPTCHA_SIZE} = $self->conf->{captcha_size}; + if ( $req->captchaHtml ) { + $tplPrm{CAPTCHA_HTML} = $req->captchaHtml; } if ( $req->token ) { $tplPrm{TOKEN} = $req->token; } + # DEPRECATED: This is only used for compatibility with existing templates + if ( $req->captcha ) { + $tplPrm{CAPTCHA_SRC} = $req->captcha; + $tplPrm{CAPTCHA_SIZE} = $self->conf->{captcha_size}; + } + # Display form the first time if ( ( $req->error == PE_MAILFORMEMPTY diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm index 025ba45ab..0b3b2ae01 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm @@ -71,7 +71,7 @@ sub init { # Initialize Captcha if needed if ( $self->conf->{captcha_mail_enabled} ) { - $self->captcha( $self->p->loadModule('::Lib::Captcha') ) or return 0; + $self->captcha(1); } # Parse password policy activation rule @@ -154,46 +154,32 @@ sub _reset { # Use submitted value $req->{user} = $req->param('mail'); - # Check if token exists - my $token; - if ( $self->ottRule->( $req, {} ) or $self->captcha ) { - $token = $req->param('token'); + # Captcha for register form + if ( $self->captcha ) { + my $result = $self->p->_captcha->check_captcha($req); + if ($result) { + $self->logger->debug("Captcha code verified"); + } + else { + $self->setSecurity($req); + $self->userLogger->warn("Captcha failed"); + return PE_CAPTCHAERROR; + } + } + elsif ( $self->ottRule->( $req, {} ) ) { + my $token = $req->param('token'); unless ($token) { $self->setSecurity($req); $self->userLogger->warn('Reset try without token'); return PE_NOTOKEN; } - } - - # Captcha for register form - if ( $self->captcha ) { - my $captcha = $req->param('captcha'); - - unless ($captcha) { - $self->userLogger->notice('Reset try with captcha not filled'); - - # Set captcha or token - $self->setSecurity($req); - return PE_CAPTCHAEMPTY; - } - - # Check captcha - unless ( $self->captcha->validateCaptcha( $token, $captcha ) ) { - $self->userLogger->info('Captcha failed: wrong code'); - - # Set captcha or token - $self->setSecurity($req); - return PE_CAPTCHAERROR; - } - $self->logger->debug('Captcha code verified'); - } - elsif ( $self->ottRule->( $req, {} ) ) { unless ( $self->ott->getToken($token) ) { $self->setSecurity($req); $self->userLogger->warn('Reset try with expired/bad token'); return PE_TOKENEXPIRED; } } + unless ( $req->{user} =~ /$self->{conf}->{userControl}/o ) { $self->setSecurity($req); return PE_MALFORMEDUSER; @@ -583,7 +569,7 @@ sub changePwd { sub setSecurity { my ( $self, $req ) = @_; if ( $self->captcha ) { - $self->captcha->setCaptcha($req); + $self->p->_captcha->init_captcha($req); } elsif ( $self->ottRule->( $req, {} ) ) { $self->ott->setToken($req); @@ -623,6 +609,11 @@ sub display { STARTMAILDATE => $req->data->{startMailDate}, STARTMAILTIME => $req->data->{startMailTime}, MAILALREADYSENT => $req->data->{mailAlreadySent}, + ( + $req->data->{customScript} + ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) + : () + ), MAIL => ( $self->p->checkXSSAttack( 'mail', $req->{user} ) ? '' @@ -653,14 +644,19 @@ sub display { } # Display captcha if it's enabled - if ( $req->captcha ) { - $tplPrm{CAPTCHA_SRC} = $req->captcha; - $tplPrm{CAPTCHA_SIZE} = $self->conf->{captcha_size}; + if ( $req->captchaHtml ) { + $tplPrm{CAPTCHA_HTML} = $req->captchaHtml; } if ( $req->token ) { $tplPrm{TOKEN} = $req->token; } + # DEPRECATED: This is only used for compatibility with existing templates + if ( $req->captcha ) { + $tplPrm{CAPTCHA_SRC} = $req->captcha; + $tplPrm{CAPTCHA_SIZE} = $self->conf->{captcha_size}; + } + # Display form the first time if ( ( $req->error == PE_MAILFORMEMPTY diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Register.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Register.pm index 84e44349a..e756c929f 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Register.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Register.pm @@ -76,7 +76,7 @@ sub init { # Initialize Captcha if needed if ( $self->conf->{captcha_register_enabled} ) { - $self->captcha( $self->p->loadModule('::Lib::Captcha') ) or return 0; + $self->captcha(1); } # Initialize form token if needed (captcha provides also a token) @@ -168,44 +168,28 @@ sub _register { !$self->getRegisterSession( $req->data->{registerInfo}->{mail} ) ) { - # Check if token exists - my $token; - if ( $self->ottRule->( $req, {} ) or $self->captcha ) { - $token = $req->param('token'); + # Captcha for register form + if ( $self->captcha ) { + my $result = $self->p->_captcha->check_captcha($req); + if ($result) { + $self->logger->debug("Captcha code verified"); + } + else { + $self->setSecurity($req); + $self->userLogger->warn("Captcha failed"); + return PE_CAPTCHAERROR; + } + } + elsif ( $self->ottRule->( $req, {} ) ) { + my $token = $req->param('token'); unless ($token) { $self->setSecurity($req); $self->userLogger->warn('Register try without token'); return PE_NOTOKEN; } - } - - # Captcha for register form - if ( $self->captcha ) { - my $captcha = $req->param('captcha'); - - unless ($captcha) { - $self->userLogger->warn( - 'Register try with captcha not filled'); - - # Set captcha or token - $self->setSecurity($req); - return PE_CAPTCHAEMPTY; - } - - # Check captcha - unless ( $self->captcha->validateCaptcha( $token, $captcha ) ) { - $self->userLogger->info('Captcha failed: wrong code'); - - # Set captcha or token - $self->setSecurity($req); - return PE_CAPTCHAERROR; - } - $self->logger->debug("Captcha code verified"); - } - elsif ( $self->ottRule->( $req, {} ) ) { unless ( $self->ott->getToken($token) ) { $self->setSecurity($req); - $self->userLogger->notice( + $self->userLogger->warn( 'Register try with expired/bad token'); return PE_TOKENEXPIRED; } @@ -445,7 +429,12 @@ sub display { STARTMAILDATE => $req->data->{startMailDate}, STARTMAILTIME => $req->data->{startMailTime}, MAILALREADYSENT => $req->data->{mail_already_sent}, - MAIL => $self->p->checkXSSAttack( + ( + $req->data->{customScript} + ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) + : () + ), + MAIL => $self->p->checkXSSAttack( 'mail', $req->data->{registerInfo}->{mail} ) ? "" : $req->data->{registerInfo}->{mail}, @@ -483,14 +472,19 @@ sub display { } # Display captcha if it's enabled - if ( $req->captcha ) { - $templateParams{CAPTCHA_SRC} = $req->captcha; - $templateParams{CAPTCHA_SIZE} = $self->conf->{captcha_size} || 6; + if ( $req->captchaHtml ) { + $templateParams{CAPTCHA_HTML} = $req->captchaHtml; } if ( $req->token ) { $templateParams{TOKEN} = $req->token; } + # DEPRECATED: This is only used for compatibility with existing templates + if ( $req->captcha ) { + $templateParams{CAPTCHA_SRC} = $req->captcha; + $templateParams{CAPTCHA_SIZE} = $self->conf->{captcha_size}; + } + if ( $req->error == PE_REGISTERALREADYEXISTS ) { %templateParams = ( %templateParams, @@ -560,7 +554,7 @@ sub display { sub setSecurity { my ( $self, $req ) = @_; if ( $self->captcha ) { - $self->captcha->setCaptcha($req); + $self->p->_captcha->init_captcha($req); } elsif ( $self->ottRule->( $req, {} ) ) { $self->ott->setToken($req);