You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
7.0 KiB
234 lines
7.0 KiB
use Test::More;
|
|
|
|
BEGIN {
|
|
require 't/test-psgi-lib.pm';
|
|
}
|
|
|
|
my $maintests = 25;
|
|
|
|
init(
|
|
'Lemonldap::NG::Handler::Server',
|
|
{
|
|
logLevel => 'error',
|
|
oidcRPMetaDataOptions => {
|
|
"rp-example" => {
|
|
oidcRPMetaDataOptionsClientID => "example",
|
|
},
|
|
"rp-example2" => {
|
|
oidcRPMetaDataOptionsClientID => "example2",
|
|
},
|
|
},
|
|
vhostOptions => {
|
|
'test1.example.com' => {
|
|
vhostHttps => 0,
|
|
vhostPort => 80,
|
|
vhostMaintenance => 0,
|
|
vhostServiceTokenTTL => -1,
|
|
},
|
|
},
|
|
exportedHeaders => {
|
|
'test1.example.com' => {
|
|
'Auth-User' => '$uid',
|
|
'Auth-ClientID' => '$_clientId',
|
|
'Auth-ClientConfKey' => '$_clientConfKey',
|
|
'Auth-Scope' => '$_scope',
|
|
},
|
|
},
|
|
locationRules => {
|
|
'test1.example.com' => {
|
|
|
|
# Basic rules
|
|
'default' => 'accept',
|
|
'^/write' => '$_scope =~ /(?<!\S)write(?!\S)/',
|
|
'^/read' => '$_scope =~ /(?<!\S)read(?!\S)/',
|
|
},
|
|
},
|
|
}
|
|
);
|
|
|
|
# Inject an on-line access token session
|
|
Lemonldap::NG::Common::Session->new( {
|
|
storageModule => 'Apache::Session::File',
|
|
storageModuleOptions => { Directory => 't/sessions' },
|
|
id =>
|
|
'f0fd4e85000ce35d062f97f5b466fc00abc2fad0406e03e086605f929ec4a249',
|
|
force => 1,
|
|
kind => 'OIDCI',
|
|
info => {
|
|
"user_session_id" => $sessionId,
|
|
"_type" => "access_token",
|
|
"_utime" => ( time - 72000 + 300 ),
|
|
"rp" => "rp-example2",
|
|
"scope" => "openid email read"
|
|
}
|
|
}
|
|
);
|
|
|
|
# Inject an offline access token session
|
|
Lemonldap::NG::Common::Session->new( {
|
|
storageModule => 'Apache::Session::File',
|
|
storageModuleOptions => { Directory => 't/sessions' },
|
|
id => '999888777',
|
|
force => 1,
|
|
kind => 'OIDCI',
|
|
info => {
|
|
"offline_session_id" => '000999000',
|
|
"_type" => "refresh_token",
|
|
"_utime" => ( time - 72000 + 300 ),
|
|
"rp" => "rp-example",
|
|
"scope" => "openid email read"
|
|
}
|
|
}
|
|
);
|
|
|
|
# Inject the refresh token containing user attributes
|
|
Lemonldap::NG::Common::Session->new( {
|
|
storageModule => 'Apache::Session::File',
|
|
storageModuleOptions => { Directory => 't/sessions' },
|
|
id => '000999000',
|
|
force => 1,
|
|
kind => 'OIDCI',
|
|
info => {
|
|
"_type" => "refresh_token",
|
|
"_utime" => time,
|
|
"rp" => "rp-example2",
|
|
"scope" => "openid email",
|
|
'groups' => 'users; timelords',
|
|
'uid' => 'dwho',
|
|
'cn' => 'Doctor Who',
|
|
'hGroups' => {
|
|
'users' => {},
|
|
'timelords' => {}
|
|
},
|
|
'ipAddr' => '127.0.0.1',
|
|
'mail' => 'dwho@badwolf.org',
|
|
'authenticationLevel' => 1,
|
|
}
|
|
}
|
|
);
|
|
|
|
# Request without Access Token
|
|
ok(
|
|
$res = $client->_get(
|
|
'/read', undef, 'test1.example.com', '', VHOSTTYPE => 'OAuth2',
|
|
),
|
|
'Unauthenticated request to OAuth2 URL'
|
|
);
|
|
|
|
# Check headers
|
|
%h = @{ $res->[1] };
|
|
is( $res->[0], 401, "Got correct HTTP code" );
|
|
is( $h{'WWW-Authenticate'}, 'Bearer', 'Got WWW-Authenticate: Bearer' );
|
|
|
|
# Request with invalid Access Token
|
|
ok(
|
|
$res = $client->_get(
|
|
'/read', undef,
|
|
'test1.example.com', '',
|
|
VHOSTTYPE => 'OAuth2',
|
|
HTTP_AUTHORIZATION => 'Bearer 123',
|
|
),
|
|
'Invalid access token'
|
|
);
|
|
|
|
# Check headers
|
|
%h = @{ $res->[1] };
|
|
like(
|
|
$h{'WWW-Authenticate'},
|
|
qr#Bearer.*error="invalid_token"#,
|
|
'Got invalid token error'
|
|
);
|
|
|
|
# Request with valid Access Token
|
|
ok(
|
|
$res = $client->_get(
|
|
'/read', undef,
|
|
'test1.example.com', '',
|
|
VHOSTTYPE => 'OAuth2',
|
|
HTTP_AUTHORIZATION =>
|
|
'Bearer f0fd4e85000ce35d062f97f5b466fc00abc2fad0406e03e086605f929ec4a249',
|
|
),
|
|
'Invalid access token'
|
|
);
|
|
|
|
# Check headers
|
|
%h = @{ $res->[1] };
|
|
is( $res->[0], 200, "Request accepted" );
|
|
is( $h{'Auth-User'}, 'dwho', 'Header Auth-User is set to "dwho"' );
|
|
is( $h{'Auth-ClientID'}, 'example2', 'Client ID correctly transmitted' );
|
|
is( $h{'Auth-ClientConfKey'},
|
|
'rp-example2', 'Client confkey correctly transmitted' );
|
|
like( $h{'Auth-Scope'}, qr/\bemail\b/, 'Scope correctly transmitted' );
|
|
|
|
# Request with valid Access Token on unauthorized resource
|
|
ok(
|
|
$res = $client->_get(
|
|
'/write', undef,
|
|
'test1.example.com', '',
|
|
VHOSTTYPE => 'OAuth2',
|
|
HTTP_AUTHORIZATION =>
|
|
'Bearer f0fd4e85000ce35d062f97f5b466fc00abc2fad0406e03e086605f929ec4a249',
|
|
),
|
|
'Invalid access token'
|
|
);
|
|
is( $res->[0], 403, "Unauthorized because the write scope is not granted" );
|
|
|
|
# Request with JWT Access Token
|
|
ok(
|
|
$res = $client->_get(
|
|
'/test', undef,
|
|
'test1.example.com', '',
|
|
VHOSTTYPE => 'OAuth2',
|
|
HTTP_AUTHORIZATION =>
|
|
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwianRpIjoiZjBmZDRlODUwMDBjZTM1ZDA2MmY5N2Y1YjQ2NmZjMDBhYmMyZmFkMDQwNmUwM2UwODY2MDVmOTI5ZWM0YTI0OSJ9.h0RDBLo5Vy8lqbltEP2L496KOzJLhLCIRZZmEqcPuN8',
|
|
),
|
|
'Invalid access token'
|
|
);
|
|
|
|
# Check headers
|
|
%h = @{ $res->[1] };
|
|
is( $res->[0], 200, "Request accepted" );
|
|
ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' )
|
|
or explain( \%h, 'Auth-User => "dwho"' );
|
|
|
|
# Request with Access token from offline session
|
|
ok(
|
|
$res = $client->_get(
|
|
'/read', undef,
|
|
'test1.example.com', '',
|
|
VHOSTTYPE => 'OAuth2',
|
|
HTTP_AUTHORIZATION => 'Bearer 999888777',
|
|
),
|
|
'Invalid access token'
|
|
);
|
|
|
|
# Check headers
|
|
%h = @{ $res->[1] };
|
|
is( $res->[0], 200, "Request accepted" );
|
|
is( $h{'Auth-User'}, 'dwho', 'Header Auth-User is set to "dwho"' );
|
|
is( $h{'Auth-ClientID'}, 'example', 'Client ID correctly transmitted' );
|
|
is( $h{'Auth-ClientConfKey'},
|
|
'rp-example', 'Client confkey correctly transmitted' );
|
|
like( $h{'Auth-Scope'}, qr/\bemail\b/, 'Scope correctly transmitted' );
|
|
|
|
Time::Fake->offset("+600s");
|
|
ok(
|
|
$res = $client->_get(
|
|
'/read', undef,
|
|
'test1.example.com', '',
|
|
VHOSTTYPE => 'OAuth2',
|
|
HTTP_AUTHORIZATION => 'Bearer 999888777',
|
|
),
|
|
'Invalid access token'
|
|
);
|
|
%h = @{ $res->[1] };
|
|
is( $res->[0], 401, "Access was rejected" );
|
|
is(
|
|
$h{'WWW-Authenticate'},
|
|
'Bearer error="invalid_token"',
|
|
'Got correct error code'
|
|
);
|
|
|
|
count($maintests);
|
|
done_testing( count() );
|
|
clean();
|
|
|