diff --git a/lemonldap-ng-portal/t/02-Password-Demo-Hook.t b/lemonldap-ng-portal/t/02-Password-Demo-Hook.t new file mode 100644 index 000000000..b6a4fd9cd --- /dev/null +++ b/lemonldap-ng-portal/t/02-Password-Demo-Hook.t @@ -0,0 +1,91 @@ +use Test::More; +use strict; +use IO::String; +use JSON; +use Lemonldap::NG::Portal::Main::Constants + qw(PE_BADOLDPASSWORD PE_PASSWORD_MISMATCH PE_PP_MUST_SUPPLY_OLD_PASSWORD); + +require 't/test-lib.pm'; + +my $res; + +my $client = LLNG::Manager::Test->new( { + ini => { + logLevel => 'error', + passwordDB => 'Demo', + portalRequireOldPassword => 1, + customPlugins => 't::PasswordHookPlugin', + } + } +); + +ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu' ); +count(1); + +# Try to authenticate +# ------------------- +ok( + $res = $client->_post( + '/', + IO::String->new('user=dwho&password=dwho'), + length => 23 + ), + 'Auth query' +); +count(1); +expectOK($res); +my $id = expectCookie($res); + +# Test bad new password +my $s = buildForm( { + oldpassword => "dwho", + newpassword => "12345", + confirmpassword => "12345", + } +); +ok( + $res = $client->_post( + '/', + IO::String->new($s), + cookie => "lemonldap=$id", + accept => 'application/json', + length => length($s), + ), + 'Bad new password' +); +count(1); +expectReject( $res, 400, 28 ); + +# Test good new password +$s = buildForm( { + oldpassword => "dwho", + newpassword => "12346", + confirmpassword => "12346", + } +); +ok( + $res = $client->_post( + '/', + IO::String->new($s), + cookie => "lemonldap=$id", + accept => 'application/json', + length => length($s), + ), + 'Correct new password' +); +count(1); + +expectReject( $res, 200, 35, "Expect PE_PASSWORD_OK" ); +my $pdata = expectPdata($res); +is( $pdata->{afterHook}, "dwho-dwho-12346", + "passwordAfterChange hook worked as expected" ); +count(1); + +# Test $client->logout +$client->logout($id); + +#print STDERR Dumper($res); + +clean_sessions(); + +done_testing( count() ); diff --git a/lemonldap-ng-portal/t/43-MailPasswordReset-Hook.t b/lemonldap-ng-portal/t/43-MailPasswordReset-Hook.t new file mode 100644 index 000000000..449a2e1be --- /dev/null +++ b/lemonldap-ng-portal/t/43-MailPasswordReset-Hook.t @@ -0,0 +1,134 @@ +use Test::More; +use strict; +use IO::String; + +BEGIN { + eval { + require 't/test-lib.pm'; + require 't/smtp.pm'; + }; +} + +my ( $res, $user, $pwd ); +my $maintests = 15; + +SKIP: { + eval + 'require Email::Sender::Simple;use GD::SecurityImage;use Image::Magick;'; + if ($@) { + skip 'Missing dependencies', $maintests; + } + + my $client = LLNG::Manager::Test->new( { + ini => { + logLevel => 'error', + useSafeJail => 1, + portalDisplayRegister => 1, + authentication => 'Demo', + userDB => 'Same', + passwordDB => 'Demo', + captcha_mail_enabled => 0, + portalDisplayResetPassword => 1, + customPlugins => 't::PasswordHookPlugin', + } + } + ); + + # Test form + # ------------------------ + ok( $res = $client->_get( '/resetpwd', accept => 'text/html' ), + 'Reset form', ); + my ( $host, $url, $query ) = expectForm( $res, '#', undef, 'mail' ); + + $query = 'mail=dwho%40badwolf.org'; + + # Post email + ok( + $res = $client->_post( + '/resetpwd', IO::String->new($query), + length => length($query), + accept => 'text/html', + cookie => 'llnglanguage=en', + ), + 'Post mail' + ); + + like( mail(), qr#Hello#, "Found english greeting" ); + + ok( mail() =~ m#a href="http://auth.example.com/resetpwd\?(.*?)"#, + 'Found link in mail' ); + $query = $1; + ok( + $res = $client->_get( + '/resetpwd', + query => $query, + accept => 'text/html' + ), + 'Post mail token received by mail' + ); + ( $host, $url, $query ) = expectForm( $res, '#', undef, 'token' ); + ok( $res->[2]->[0] =~ /newpassword/s, ' Ask for a new password' ); + + my $badquery = $query . '&newpassword=12345&confirmpassword=12345'; + + # Post failing password + ok( + $res = $client->_post( + '/resetpwd', IO::String->new($badquery), + length => length($badquery), + accept => 'text/html' + ), + 'Post new password' + ); + expectPortalError( $res, 28 ); + + # Post email again + $query = 'mail=dwho%40badwolf.org'; + ok( + $res = $client->_post( + '/resetpwd', IO::String->new($query), + length => length($query), + accept => 'text/html', + cookie => 'llnglanguage=en', + ), + 'Post mail' + ); + + like( mail(), qr#Hello#, "Found english greeting" ); + + ok( mail() =~ m#a href="http://auth.example.com/resetpwd\?(.*?)"#, + 'Found link in mail' ); + $query = $1; + ok( + $res = $client->_get( + '/resetpwd', + query => $query, + accept => 'text/html' + ), + 'Post mail token received by mail' + ); + ( $host, $url, $query ) = expectForm( $res, '#', undef, 'token' ); + ok( $res->[2]->[0] =~ /newpassword/s, ' Ask for a new password' ); + + my $goodquery = $query . '&newpassword=12346&confirmpassword=12346'; + + # Post accepted password + ok( + $res = $client->_post( + '/resetpwd', IO::String->new($goodquery), + length => length($goodquery), + accept => 'text/html' + ), + 'Post new password' + ); + my $pdata = expectPdata($res); + is( $pdata->{afterHook}, "dwho--12346", + "passwordAfterChange hook worked as expected" ); + + ok( mail() =~ /Your password was changed/, 'Password was changed' ); +} +count($maintests); + +clean_sessions(); + +done_testing( count() ); diff --git a/lemonldap-ng-portal/t/PasswordHookPlugin.pm b/lemonldap-ng-portal/t/PasswordHookPlugin.pm new file mode 100644 index 000000000..4799b04ba --- /dev/null +++ b/lemonldap-ng-portal/t/PasswordHookPlugin.pm @@ -0,0 +1,34 @@ +package t::PasswordHookPlugin; + +use Mouse; +use Lemonldap::NG::Portal::Main::Constants + qw/PE_PP_INSUFFICIENT_PASSWORD_QUALITY PE_OK/; +extends 'Lemonldap::NG::Portal::Main::Plugin'; + +use constant hook => { + passwordBeforeChange => 'beforeChange', + passwordAfterChange => 'afterChange', +}; + +sub init { + 1; +} + +sub beforeChange { + my ( $self, $req, $user, $password, $old ) = @_; + if ( $password eq "12345" ) { + $self->logger->error("I've got the same combination on my luggage"); + return PE_PP_INSUFFICIENT_PASSWORD_QUALITY; + } + return PE_OK; +} + +sub afterChange { + my ( $self, $req, $user, $password, $old ) = @_; + $old ||= ""; + $req->pdata->{afterHook} = "$user-$old-$password"; + $self->logger->debug("Password changed for $user: $old -> $password"); + return PE_OK; +} + +1;