From 59757642d32265544b9ebea5c7ae847d57f0ddd9 Mon Sep 17 00:00:00 2001 From: Maxime Besson Date: Sun, 19 Dec 2021 17:47:34 +0100 Subject: [PATCH] Unit tests for *::Custom --- lemonldap-ng-portal/t/10-AuthCustom.t | 172 ++++++++++++++++++ lemonldap-ng-portal/t/28-AuthChoice-Custom.t | 72 ++++++++ lemonldap-ng-portal/t/36-Combination-Custom.t | 129 +++++++++++++ lemonldap-ng-portal/t/42-Register-Custom.t | 102 +++++++++++ 4 files changed, 475 insertions(+) create mode 100644 lemonldap-ng-portal/t/10-AuthCustom.t create mode 100644 lemonldap-ng-portal/t/28-AuthChoice-Custom.t create mode 100644 lemonldap-ng-portal/t/36-Combination-Custom.t create mode 100644 lemonldap-ng-portal/t/42-Register-Custom.t diff --git a/lemonldap-ng-portal/t/10-AuthCustom.t b/lemonldap-ng-portal/t/10-AuthCustom.t new file mode 100644 index 000000000..059392406 --- /dev/null +++ b/lemonldap-ng-portal/t/10-AuthCustom.t @@ -0,0 +1,172 @@ +use Test::More; +use strict; +use IO::String; +use MIME::Base64; + +require 't/test-lib.pm'; + +my $res; + +my $client = LLNG::Manager::Test->new( { + ini => { + logLevel => 'error', + useSafeJail => 1, + authentication => "Custom", + customAuth => "::Auth::Demo", + customUserDB => "::UserDB::Demo" + } + } +); + +# Test normal first access +# ------------------------ +ok( $res = $client->_get('/'), 'Unauth JSON request' ); +count(1); +expectReject($res); + +# Test "first access" with an unprotected url +ok( + $res = $client->_get( + '/', + query => 'url=' . encode_base64( "http://test.example.fr/", '' ), + accept => 'text/html' + ), + 'Get Menu' +); +ok( $res->[2]->[0] =~ //, 'Rejected with PE_BADURL' ) + or print STDERR Dumper( $res->[2]->[0] ); +ok( $res->[2]->[0] =~ m%%, ' Language icons found' ) + or print STDERR Dumper( $res->[2]->[0] ); +count(3); + +# Test "first access" with a wildcard-protected url +ok( + $res = $client->_get( + '/', + query => 'url=' . encode_base64( "http://test.example.llng/", '' ), + accept => 'text/html' + ), + 'Get Menu' +); +ok( $res->[2]->[0] =~ //, 'Rejected with PE_FIRSTACCESS' ) + or print STDERR Dumper( $res->[2]->[0] ); +ok( $res->[2]->[0] =~ m%%, ' Language icons found' ) + or print STDERR Dumper( $res->[2]->[0] ); +count(3); + +# Test "first access" with good url +ok( + $res = + $client->_get( '/', query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29tLw==' ), + 'Unauth ajax request with good url' +); +count(1); +expectReject($res); + +ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu' ); +ok( $res->[2]->[0] =~ m%%, ' Language icons found' ) + or print STDERR Dumper( $res->[2]->[0] ); +count(2); + +# Try to authenticate with unknown user +# ------------------------------------- +ok( + $res = $client->_post( + '/', + IO::String->new('user=jdoe&password=jdoe'), + accept => 'text/html', + length => 23 + ), + 'Auth query' +); +ok( + $res->[2]->[0] =~ //, + 'jdoe rejected with PE_BADCREDENTIALS' +) or print STDERR Dumper( $res->[2]->[0] ); +ok( $res->[2]->[0] =~ m%Connect%, + 'Found connect button' ) + or print STDERR Dumper( $res->[2]->[0] ); +count(3); + +# Try to authenticate with bad password +# ------------------------------------- +ok( + $res = $client->_post( + '/', + IO::String->new('user=dwho&password=jdoe'), + accept => 'text/html', + length => 23 + ), + 'Auth query' +); +count(1); +ok( + $res->[2]->[0] =~ //, + 'dwho rejected with PE_BADCREDENTIALS' +) or print STDERR Dumper( $res->[2]->[0] ); +count(1); +ok( $res->[2]->[0] =~ m%Connect%, + 'Found connect button' ) + or print STDERR Dumper( $res->[2]->[0] ); +count(1); + +# Try to authenticate with good password +# -------------------------------------- +ok( + $res = $client->_post( + '/', + IO::String->new('user=dwho&password=dwho'), + length => 23, + ), + 'Auth query' +); +count(1); +expectOK($res); +my $id = expectCookie($res); + +# Try to get a redirection for an auth user with a valid url +# ---------------------------------------------------------- +ok( + $res = $client->_get( + '/', + query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29tLw==', + cookie => "lemonldap=$id", + accept => 'text/html' + ), + 'Auth ajax request with good url' +); +count(1); +expectRedirection( $res, 'http://test1.example.com/' ); +expectAuthenticatedAs( $res, 'dwho' ); + +# Try to get a redirection for an auth user with a bad url (host undeclared +# in manager) +# ------------------------------------------------------------------------- +ok( + $res = $client->_get( + '/', + query => 'url=aHR0cHM6Ly90LmV4YW1wbGUuY29tLw==', + cookie => "lemonldap=$id", + accept => 'text/html' + ), + 'Auth request with bad url' +); +count(1); +expectOK($res); +expectAuthenticatedAs( $res, 'dwho' ); + +require 't/test-psgi.pm'; + +ok( $res = mirror( cookie => "lemonldap=$id" ), 'PSGI test' ); +count(1); +expectOK($res); +expectAuthenticatedAs( $res, 'dwho' ); + +# Test logout +$client->logout($id); + +#print STDERR Dumper($res); + +clean_sessions(); + +done_testing( count() ); diff --git a/lemonldap-ng-portal/t/28-AuthChoice-Custom.t b/lemonldap-ng-portal/t/28-AuthChoice-Custom.t new file mode 100644 index 000000000..454f9f9d2 --- /dev/null +++ b/lemonldap-ng-portal/t/28-AuthChoice-Custom.t @@ -0,0 +1,72 @@ +use Test::More; +use strict; +use IO::String; +use JSON qw(from_json); + +require 't/test-lib.pm'; + +my $res; + +my $client = LLNG::Manager::Test->new( { + ini => { + logLevel => 'error', + useSafeJail => 1, + portalMainLogo => 'common/logos/logo_llng_old.png', + authentication => 'Choice', + restSessionServer => 1, + nullAuthnLevel => 1, + userDB => 'Same', + authChoiceParam => 'test', + authChoiceModules => { + '1_securenull' => +'Custom;Custom;Null;;;{"nullAuthnLevel": 3, "customAuth": "::Auth::Null", "customUserDB": "::UserDB::Null"}', + '2_null' => +'Custom;Custom;Null;;;{"customAuth": "::Auth::Null", "customUserDB": "::UserDB::Null"}', + }, + } + } +); + +ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu' ); +ok( $res->[2]->[0] =~ /1_securenull/, '1_securenull displayed' ); +ok( $res->[2]->[0] =~ /2_null/, '2_null displayed' ); + +# Authenticate on first choice +my $postString = 'user=dwho&password=dwho&test=1_securenull'; + +ok( + $res = $client->_post( + '/', + IO::String->new($postString), + length => length($postString) + ), + 'Auth query' +); +expectOK($res); +my $id = expectCookie($res); +ok( $res = $client->_get("/sessions/global/$id"), 'Get session' ); +my $sessiondata = from_json( $res->[2]->[0] ); +is( $sessiondata->{authenticationLevel}, 3, "Overriden authentication level" ); +$client->logout($id); + +# Authenticate on second choice +$postString = 'user=dwho&password=dwho&test=2_null'; + +# Try to authenticate +# ------------------- +ok( + $res = $client->_post( + '/', + IO::String->new($postString), + length => length($postString) + ), + 'Auth query' +); +expectOK($res); +$id = expectCookie($res); +ok( $res = $client->_get("/sessions/global/$id"), 'Get session' ); +$sessiondata = from_json( $res->[2]->[0] ); +is( $sessiondata->{authenticationLevel}, 1, "Default authentication level" ); +$client->logout($id); +clean_sessions(); +done_testing(); diff --git a/lemonldap-ng-portal/t/36-Combination-Custom.t b/lemonldap-ng-portal/t/36-Combination-Custom.t new file mode 100644 index 000000000..73579471c --- /dev/null +++ b/lemonldap-ng-portal/t/36-Combination-Custom.t @@ -0,0 +1,129 @@ +use Test::More; +use strict; +use IO::String; + +require 't/test-lib.pm'; + +my $res; +my $maintests = 3; +my $client; + +my $userdb = tempdb(); + +SKIP: { + eval { require DBI; require DBD::SQLite; }; + if ($@) { + skip 'DBD::SQLite not found', $maintests; + } + my $dbh = DBI->connect("dbi:SQLite:dbname=$userdb"); + $dbh->do('CREATE TABLE users (user text,password text,name text)'); + $dbh->do("INSERT INTO users VALUES ('dvador','dvador','Test user 1')"); + $dbh->do("INSERT INTO users VALUES ('rtyler','rtyler','Test user 1')"); + + $client = iniCmb('[Dm] or [DB]'); + $client->logout( expectCookie( try('dwho') ) ); + expectCookie( try('dvador') ); + + $client = iniCmb('[Dm] and [DB]'); + $client->logout( expectCookie( try('rtyler') ) ); + expectReject( try('dwho') ); + + $client = iniCmb('if($env->{HTTP_X} eq "dwho") then [Dm] else [DB]'); + $client->logout( expectCookie( try('dwho') ) ); + $client->logout( expectCookie( try('dvador') ) ); + + $client = iniCmb( +'if($env->{HTTP_X} eq "rtyler") then [Dm] and [DB] else if($env->{HTTP_X} eq "dvador") then [DB] else [DB]' + ); + my $id = expectCookie( try('rtyler') ); + my $res; + ok( $res = $client->_get("/sessions/global/$id"), 'Get session content' ); + ok( $res = eval { JSON::from_json( $res->[2]->[0] ) }, ' GET JSON' ) + or print STDERR $@; + ok( + ( $res->{demo} eq 'rtyler' and $res->{dbi} eq 'rtyler' ), + ' Demo and DBI exported variables exist in session' + ); + expectCookie( try('dvador') ); + expectReject( try('dwho') ); + $client = iniCmb( + 'if($env->{REMOTE_ADDR} =~ /^(127\.)/) then [Dm] or [DB] else [DB]'); + expectCookie( try('rtyler') ); + expectCookie( try('dwho') ); + $client = iniCmb( +'if($env->{REMOTE_ADDR} =~ /^(128\.)/) then [Dm,Dm] or [DB,DB] else [DB,DB]' + ); + expectCookie( try('rtyler') ); + expectReject( try('dwho') ); +} +count($maintests); +clean_sessions(); +done_testing( count() ); + +sub try { + my $user = shift; + my $s = "user=$user&password=$user"; + my $res; + ok( + $res = $client->_post( + '/', IO::String->new($s), + length => length($s), + custom => { HTTP_X => $user } + ), + " Try to connect with login $user" + ); + count(1); + return $res; +} + +sub iniCmb { + my $expr = shift; + &Lemonldap::NG::Handler::Main::cfgNum( 0, 0 ); + if ( + my $res = LLNG::Manager::Test->new( { + ini => { + logLevel => 'error', + useSafeJail => 1, + authentication => 'Combination', + userDB => 'Same', + restSessionServer => 1, + + combination => $expr, + combModules => { + DB => { + for => 0, + type => 'Custom', + over => { + customAuth => "::Auth::DBI", + customUserDB => "::UserDB::DBI", + }, + }, + Dm => { + for => 0, + type => 'Custom', + over => { + customAuth => "::Auth::Demo", + customUserDB => "::UserDB::Demo", + }, + }, + }, + + dbiAuthChain => "dbi:SQLite:dbname=$userdb", + dbiAuthUser => '', + dbiAuthPassword => '', + dbiAuthTable => 'users', + dbiAuthLoginCol => 'user', + dbiAuthPasswordCol => 'password', + dbiAuthPasswordHash => '', + dbiExportedVars => { dbi => 'user' }, + demoExportedVars => { demo => 'uid' }, + } + } + ) + ) + { + pass(qq'Expression loaded: "$expr"'); + count(1); + return $res; + } +} diff --git a/lemonldap-ng-portal/t/42-Register-Custom.t b/lemonldap-ng-portal/t/42-Register-Custom.t new file mode 100644 index 000000000..7871f4eca --- /dev/null +++ b/lemonldap-ng-portal/t/42-Register-Custom.t @@ -0,0 +1,102 @@ +use Test::More; +use strict; +use IO::String; + +BEGIN { + eval { + require 't/test-lib.pm'; + require 't/smtp.pm'; + }; +} + +my $maintests = 11; +my ( $res, $user, $pwd, $mail, $subject ); + +SKIP: { + eval 'require Email::Sender::Simple; use Text::Unidecode'; + if ($@) { + skip 'Missing dependencies', $maintests; + } + + my $client = LLNG::Manager::Test->new( { + ini => { + logLevel => 'error', + useSafeJail => 1, + portalDisplayRegister => 1, + authentication => 'Demo', + userDB => 'Same', + registerDB => 'Custom', + customRegister => '::Register::Demo', + registerConfirmSubject => 'Demonstration', + captcha_register_enabled => 0, + } + } + ); + + # Test normal first access + # ------------------------ + ok( + $res = $client->_get( '/register', accept => 'text/html' ), + 'Unauth request', + ); + my ( $host, $url, $query ) = + expectForm( $res, '#', undef, 'firstname', 'lastname', 'mail' ); + + ok( + $res = $client->_post( + '/register', + IO::String->new( + 'firstname=Fôo&lastname=Bà Bar&mail=foobar%40badwolf.org'), + length => 53, + accept => 'text/html' + ), + 'Ask to create account' + ); + expectOK($res); + + $mail = mail(); + $subject = subject(); + ok( $subject eq 'Demonstration', 'Found subject' ) + or explain( $subject, 'Custom subject' ); + ok( $mail =~ m#a href="http://auth.example.com/register\?(.+?)"#, + 'Found register token' ) + or explain( $mail, 'Confirm body' ); + $query = $1; + ok( $query =~ /register_token=/, 'Found register_token' ); + ok( $mail =~ /Fôo/, 'UTF-8 works' ) or explain( $mail, 'Fôo' ); + + ok( + $res = + $client->_get( '/register', query => $query, accept => 'text/html' ), + 'Push register_token' + ); + expectOK($res); + + $mail = mail(); + $subject = subject(); + ok( $subject eq '[LemonLDAP::NG] Your new account', 'Found subject' ) + or explain( $subject, 'Default subject' ); + ok( + $mail =~ + m#Your login is.+?(\w+).*?Your password is.+?(.*?)#s, + 'Found user and password' + ) or explain( $mail, 'Done body' ); + $user = $1; + $pwd = $2; + ok( $user eq 'fbabar', 'Get good login' ); + + ok( + $res = $client->_post( + '/', IO::String->new("user=fbabar&password=fbabar"), + length => 27, + accept => 'text/html' + ), + 'Try to authenticate' + ); + expectCookie($res); +} +count($maintests); + +clean_sessions(); + +done_testing( count() );