From 0dc9a14f621c66c76f569ed67dbc64640a1837b9 Mon Sep 17 00:00:00 2001 From: Yadd Date: Wed, 31 Jul 2024 17:31:20 +0400 Subject: [PATCH 1/4] Add reCaptcha (#3219) --- doc/sources/admin/captcha.rst | 5 ++ doc/sources/admin/index_portal.rst | 1 + doc/sources/admin/recaptcha.rst | 22 ++++++ doc/sources/admin/start.rst | 1 + .../Lemonldap/NG/Portal/Captcha/ReCaptcha.pm | 75 +++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 doc/sources/admin/recaptcha.rst create mode 100644 lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm diff --git a/doc/sources/admin/captcha.rst b/doc/sources/admin/captcha.rst index 22aa87c948..4b0e3aceb0 100644 --- a/doc/sources/admin/captcha.rst +++ b/doc/sources/admin/captcha.rst @@ -38,6 +38,11 @@ Go in ``General parameters`` > ``Portal`` > ``Captcha``: .. _customcaptcha: +Alternatives +------------ + +- :doc:`Google reCaptcha` + Custom Captcha modules ---------------------- diff --git a/doc/sources/admin/index_portal.rst b/doc/sources/admin/index_portal.rst index 85aa431514..648fde0e86 100644 --- a/doc/sources/admin/index_portal.rst +++ b/doc/sources/admin/index_portal.rst @@ -11,6 +11,7 @@ Portal configuration portalservers captcha public_pages + recaptcha secondfactor index_protocols index_authdb diff --git a/doc/sources/admin/recaptcha.rst b/doc/sources/admin/recaptcha.rst new file mode 100644 index 0000000000..88fb1e927b --- /dev/null +++ b/doc/sources/admin/recaptcha.rst @@ -0,0 +1,22 @@ +reCaptcha v3 +============ + +Presentation +------------ + +reCaptcha version 3 is an evolution of Google's reCaptcha that returns a score +for each request without user friction. The score is based on interactions with +your site and enables you to take an appropriate action for your site. + +See `Google reCAPTCHA v3 `__ +for more. + +Configuration +------------- + +Configure captcha like :doc:`LLNG internal captcha` but use a +"custom captcha module", set: +- **Captcha module** to "**::Captcha::ReCaptcha**" +- in **Captcha module options**, add the following keys + - **dataSiteKey**: the key ID given in Google console + - **secretKey**: the secret key diff --git a/doc/sources/admin/start.rst b/doc/sources/admin/start.rst index f914abbe58..d731f8126f 100644 --- a/doc/sources/admin/start.rst +++ b/doc/sources/admin/start.rst @@ -108,6 +108,7 @@ Portal - :doc:`Portal menu` - :doc:`REST/SOAP servers` - :doc:`Captcha` +- :doc:`reCaptcha` - :doc:`Public pages` diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm new file mode 100644 index 0000000000..7255d1ef83 --- /dev/null +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm @@ -0,0 +1,75 @@ +package Lemonldap::NG::Portal::Captcha::ReCaptcha; + +use strict; +use Mouse; +use Lemonldap::NG::Common::UserAgent; + +# Add constants used by this module + +our $VERSION = '2.20.0'; + +extends 'Lemonldap::NG::Portal::Main::Plugin'; + +has ua => ( + is => 'rw', + lazy => 1, + builder => sub { + my $ua = Lemonldap::NG::Common::UserAgent->new( $_[0]->{conf} ); + $ua->env_proxy(); + return $ua; + } +); + +sub init { + my ($self) = @_; + unless ($self->conf->{captchaOptions}->{dataSiteKey} + and $self->conf->{captchaOptions}->{secretKey} ) + { + $self->logger->error('Missing required options for reCaptcha'); + return 0; + } + return 1; +} + +sub init_captcha { + my ( $self, $req ) = @_; + + $req->data->{customScript} .= + ''; + + # Read option from the manager configuration + my $dataSiteKey = $self->conf->{captchaOptions}->{dataSiteKey}; + my $html = +qq'
'; + $req->captchaHtml($html); +} + +sub check_captcha { + my ( $self, $req ) = @_; + + my $captcha_input = $req->param('g-recaptcha-response'); + unless ($captcha_input) { + $self->logger->info('No captcha value submitted'); + return 0; + } + my $response = $self->ua->post( + 'https://www.google.com/recaptcha/api/siteverify', + { + secret => $self->conf->{captchaOptions}->{secretKey}, + response => $captcha_input, + } + ); + if ( $response->is_success ) { + my $res = eval { JSON::from_json( $response->decoded_content ) }; + if ($@) { + $self->logger->error("reCaptcha: $@"); + return 0; + } + return $res->{success}; + } + $self->logger->error( 'reCaptcha error: ' . $response->status_line ); + return 0; +} + +1; + -- GitLab From c58f6c406ccb2707986b1c84d6f10436f1204193 Mon Sep 17 00:00:00 2001 From: Yadd Date: Wed, 31 Jul 2024 18:04:24 +0400 Subject: [PATCH 2/4] Display reCaptcha errors in logs --- lemonldap-ng-portal/MANIFEST | 1 + .../lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lemonldap-ng-portal/MANIFEST b/lemonldap-ng-portal/MANIFEST index c7a269af0c..8d42669fd7 100644 --- a/lemonldap-ng-portal/MANIFEST +++ b/lemonldap-ng-portal/MANIFEST @@ -51,6 +51,7 @@ lib/Lemonldap/NG/Portal/Auth/SSL.pm lib/Lemonldap/NG/Portal/Auth/Twitter.pm lib/Lemonldap/NG/Portal/Auth/WebID.pm lib/Lemonldap/NG/Portal/Captcha.pod +lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm lib/Lemonldap/NG/Portal/Captcha/SecurityImage.pm lib/Lemonldap/NG/Portal/CDC.pm lib/Lemonldap/NG/Portal/CertificateResetByMail/Custom.pm diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm index 7255d1ef83..a4a1a6d418 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Captcha/ReCaptcha.pm @@ -65,6 +65,10 @@ sub check_captcha { $self->logger->error("reCaptcha: $@"); return 0; } + unless ( $res->{success} ) { + $self->logger->info( + 'reCaptcha errors:' . $response->decoded_content ); + } return $res->{success}; } $self->logger->error( 'reCaptcha error: ' . $response->status_line ); -- GitLab From b129654cd2f1e09c83581120fb394b3745a477f0 Mon Sep 17 00:00:00 2001 From: Yadd Date: Wed, 31 Jul 2024 18:15:56 +0400 Subject: [PATCH 3/4] Improve doc --- doc/sources/admin/recaptcha.rst | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/sources/admin/recaptcha.rst b/doc/sources/admin/recaptcha.rst index 88fb1e927b..e708e0b839 100644 --- a/doc/sources/admin/recaptcha.rst +++ b/doc/sources/admin/recaptcha.rst @@ -16,7 +16,16 @@ Configuration Configure captcha like :doc:`LLNG internal captcha` but use a "custom captcha module", set: -- **Captcha module** to "**::Captcha::ReCaptcha**" + +- **Captcha module** to "``::Captcha::ReCaptcha``" - in **Captcha module options**, add the following keys - - **dataSiteKey**: the key ID given in Google console - - **secretKey**: the secret key + + - ``dataSiteKey``: the key ID given in Google console + - ``secretKey``: the secret key + +Then adapt the "Content-Security-Policy" headers, cspDefault and cspScript +should be set to : + +:: + + https://www.google.com https://www.gstatic.com 'self' -- GitLab From a7b53505300da016379e37bb8c0cfba83898b423 Mon Sep 17 00:00:00 2001 From: Yadd Date: Thu, 1 Aug 2024 13:00:26 +0400 Subject: [PATCH 4/4] Fix doc --- doc/sources/admin/recaptcha.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doc/sources/admin/recaptcha.rst b/doc/sources/admin/recaptcha.rst index e708e0b839..dadc4f3040 100644 --- a/doc/sources/admin/recaptcha.rst +++ b/doc/sources/admin/recaptcha.rst @@ -1,14 +1,12 @@ -reCaptcha v3 -============ +reCaptcha +========= Presentation ------------ -reCaptcha version 3 is an evolution of Google's reCaptcha that returns a score -for each request without user friction. The score is based on interactions with -your site and enables you to take an appropriate action for your site. +Captcha system provided by `Google `__. -See `Google reCAPTCHA v3 `__ +See `Google reCAPTCHA `__ for more. Configuration -- GitLab