diff --git a/lemonldap-ng-portal/example/mail.pl b/lemonldap-ng-portal/example/mail.pl index 4d547db71..e8927d6ad 100755 --- a/lemonldap-ng-portal/example/mail.pl +++ b/lemonldap-ng-portal/example/mail.pl @@ -54,6 +54,8 @@ if ( $portal->{error} == PE_MAILFORMEMPTY or $portal->{error} == PE_MAILFIRSTACCESS or $portal->{error} == PE_MAILNOTFOUND + or $portal->{error} == PE_CAPTCHAERROR + or $portal->{error} == PE_CAPTCHAEMPTY ) and !$portal->{mail_token} ) @@ -68,7 +70,7 @@ if ( } # Display captcha if it's enabled -if ( $portal->{captcha_enabled} ) { +if ( $portal->{captcha_img} ) { $template->param( CAPTCHA_IMG => $portal->{captcha_img}, CAPTCHA_CODE => $portal->{captcha_code}, diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Display.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Display.pm index de8d3b461..68c70359a 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Display.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Display.pm @@ -205,7 +205,7 @@ sub display { ); # Display captcha if it's enabled - if ( $self->{captcha_enabled} ) { + if ( $self->{captcha_img} ) { %templateParams = ( %templateParams, CAPTCHA_IMG => $self->{captcha_img}, diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/MailReset.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/MailReset.pm index c7b32ddec..94522f77d 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/MailReset.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/MailReset.pm @@ -123,6 +123,51 @@ sub extractMailInfo { # Use submitted value $self->{mail} = $self->param('mail'); + + # Captcha for mail form + if ( $self->{captcha_mail_enabled} && $self->{mail} ) { + $self->{captcha_user_code} = $self->param('captcha_user_code'); + $self->{captcha_check_code} = $self->param('captcha_code'); + + unless ( $self->{captcha_user_code} && $self->{captcha_check_code} ) + { + $self->lmLog( "Captcha not filled", 'warn' ); + return PE_CAPTCHAEMPTY; + } + + $self->lmLog( + "Captcha data received: " + . $self->{captcha_user_code} . " and " + . $self->{captcha_check_code}, + 'debug' + ); + + # Check captcha + my $captcha_result = + $self->checkCaptcha( $self->{captcha_user_code}, + $self->{captcha_check_code} ); + + if ( $captcha_result != 1 ) { + if ( $captcha_result == -3 + or $captcha_result == -2 ) + { + $self->lmLog( "Captcha failed: wrong code", 'warn' ); + return PE_CAPTCHAERROR; + } + elsif ( $captcha_result == 0 ) { + $self->lmLog( + "Captcha failed: code not checked (file error)", + 'warn' ); + return PE_CAPTCHAERROR; + } + elsif ( $captcha_result == -1 ) { + $self->lmLog( "Captcha failed: code has expired", 'warn' ); + return PE_CAPTCHAERROR; + } + } + $self->lmLog( "Captcha code verified", 'debug' ); + } + } $self->{userControl} ||= '^[\w\.\-@]+$'; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Simple.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Simple.pm index 58fa13645..14a76bc8c 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Simple.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Simple.pm @@ -464,10 +464,10 @@ sub new { $self->{trustedDomains} =~ s/\./\\./g; } - # init the captcha feature if it's enabled - if ( $self->{captcha_enabled} ) { - eval $self->initCaptcha(); - $self->lmLog( "Can't init captcha: $@", "error" ); + # Init the captcha feature if it's enabled + if ( $self->{captcha_login_enabled} || $self->{captcha_mail_enabled} ) { + eval { $self->initCaptcha(); }; + $self->lmLog( "Can't init captcha: $@", "error" ) if $@; } return $self; @@ -647,8 +647,9 @@ sub setDefaultValues { $self->{mailOnPasswordChange} ||= 0; # Captcha parameters - $self->{captcha_enabled} = 0 unless defined $self->{captcha_enabled}; - $self->{captcha_size} = 6 unless defined $self->{captcha_size}; + $self->{captcha_login_enabled} = 0 unless defined $self->{captcha_login_enabled}; + $self->{captcha_mail_enabled} = 0 unless defined $self->{captcha_mail_enabled}; + $self->{captcha_size} = 6 unless defined $self->{captcha_size}; $self->{captcha_output} ||= '/usr/local/lemonldap-ng/htdocs/portal/captcha_output/'; $self->{captcha_data} ||= '/usr/local/lemonldap-ng/data/captcha/data/'; @@ -765,22 +766,10 @@ sub buildHiddenForm { # init captcha module and generate captcha # @return nothing sub initCaptcha { - require Authen::Captcha; - my $self = shift; - # Store captcha data - opendir( OUTPUT, $self->{captcha_output} ) - or $self->lmLog( "Can't open captcha output dir", "error" ); - opendir( DATA, $self->{captcha_data} ) - or $self->lmLog( "Can't open captcha data dir", "error" ); - - # Clean previous captcha datas - foreach ( readdir(OUTPUT) ) { - next if ( $_ eq ".." or $_ eq "." ); - system("rm -f $_ &>/dev/null") - or $self->lmLog( "Can't clean captcha output dir!", "warn" ); - } + # Load module + require Authen::Captcha; # Build Authen::Captcha object $self->{captcha} = Authen::Captcha->new( @@ -793,7 +782,9 @@ sub initCaptcha { $self->{captcha}->generate_code( $self->{captcha_size} ); $self->{captcha_img} = "/captcha_output/" . $self->{captcha_code} . ".png"; - closedir(DATA) and closedir(OUTPUT); + $self->lmLog( "Captcha code generated: " . $self->{captcha_code}, 'debug' ); + + return; } ## @method boolean isTrustedUrl(string url) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_WebForm.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_WebForm.pm index 769acdad0..fd74a3206 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_WebForm.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_WebForm.pm @@ -47,33 +47,45 @@ sub extractFormInfo { && ( $self->{confirmpassword} = $self->param('confirmpassword') ) ); } - # 4. If the captcha feature is enabled, captcha form - if ( $self->{captcha_enabled} ) { - my $captcha_user_code; - if ( $self->param('captcha_user_code') && $self->param('captcha_code') ) - { - $captcha_user_code = $self->param('captcha_user_code'); - $self->{captcha_code} = $self->param('captcha_code'); + # 4. Captcha for login form + if ( $self->{captcha_login_enabled} && $defUser && $defPassword ) { + $self->{captcha_user_code} = $self->param('captcha_user_code'); + $self->{captcha_check_code} = $self->param('captcha_code'); + + unless ( $self->{captcha_user_code} && $self->{captcha_check_code} ) { + $self->lmLog( "Captcha not filled", 'warn' ); + return PE_CAPTCHAEMPTY; } - $self->{captcha_result} = - $self->checkCaptcha( $captcha_user_code, $self->{captcha_code} ); - if ( $self->{captcha_result} != 1 ) { - if ( $self->{captcha_result} == -3 - or $self->{captcha_result} == -2 ) + + $self->lmLog( + "Captcha data received: " + . $self->{captcha_user_code} . " and " + . $self->{captcha_check_code}, + 'debug' + ); + + # Check captcha + my $captcha_result = $self->checkCaptcha( $self->{captcha_user_code}, + $self->{captcha_check_code} ); + + if ( $captcha_result != 1 ) { + if ( $captcha_result == -3 + or $captcha_result == -2 ) { - $self->lmLog( "Captcha failed: wrong code", 'error' ); + $self->lmLog( "Captcha failed: wrong code", 'warn' ); return PE_CAPTCHAERROR; } - elsif ( $self->{captcha_result} == 0 ) { + elsif ( $captcha_result == 0 ) { $self->lmLog( "Captcha failed: code not checked (file error)", - 'error' ); + 'warn' ); return PE_CAPTCHAERROR; } - elsif ( $self->{captcha_result} == -1 ) { - $self->lmLog( "Captcha failed: code has expired", 'error' ); + elsif ( $captcha_result == -1 ) { + $self->lmLog( "Captcha failed: code has expired", 'warn' ); return PE_CAPTCHAERROR; } } + $self->lmLog( "Captcha code verified", 'debug' ); } # Other parameters @@ -119,17 +131,22 @@ sub setAuthSessionInfo { ## @method int checkCaptcha(code, ccode) # Check captcha auth -# @return a constant # @param code that user enter in the form # @param captcha code generated by Authen::Captcha +# @return a constant sub checkCaptcha { my ( $self, $code, $ccode ) = splice @_; + opendir( OUTPUT, $self->{captcha_output} ) or $self->lmLog( "Can't open captcha output dir", "error" ); opendir( DATA, $self->{captcha_data} ) or $self->lmLog( "Can't open captcha data dir", "error" ); - $self->{captcha_result} = $self->{captcha}->check_code( $code, $ccode ); + + my $result = $self->{captcha}->check_code( $code, $ccode ); + closedir(OUTPUT) && closedir(DATA); + + return $result; } 1; diff --git a/lemonldap-ng-portal/t/66-Lemonldap-NG-Portal-Captcha.t b/lemonldap-ng-portal/t/66-Lemonldap-NG-Portal-Captcha.t index 6eebb9dbd..065e6e0a5 100644 --- a/lemonldap-ng-portal/t/66-Lemonldap-NG-Portal-Captcha.t +++ b/lemonldap-ng-portal/t/66-Lemonldap-NG-Portal-Captcha.t @@ -36,11 +36,12 @@ mkdir $p->{captcha_data}; ok( ref($p) eq "Lemonldap::NG::Portal::Simple" ); # try to init a captcha -ok( $p->initCaptcha() ); +$p->initCaptcha; +ok( $p->{captcha_img}, "Generation of captcha image" ); # try a wrong values to check checkCaptcha method -$p->checkCaptcha( "12D3EO", $p->{captcha_code} ); -ok( 1 ne $p->{captcha_result} ); +my $captcha_result = $p->checkCaptcha( "12D3EO", $p->{captcha_code} ); +ok( 1 ne $captcha_result, "Verification of captcha" ); END { system("rm -rf ./tmp");