Lemonldap-NG-Portal
view release on metacpan or search on metacpan
t/32-OIDC-Register.t view on Meta::CPAN
my $conf = JSON::from_json(`cat $confFile`);
my $rpId =
( grep { /^register-/ } keys %{ $conf->{oidcRPMetaDataOptions} } )[0];
return ( $conf, $rpId, $confFile );
}
subtest "Confidential only mode (value=1)" => sub {
ok( my $op = op(1), 'OP portal' );
subtest "client_secret_basic registration" => sub {
$res = post_register(
$op,
{
application_type => "web",
redirect_uris => [
"https://client.example.org/callback",
"https://client.example.org/callback2"
],
client_name => "My Example",
logo_uri => "https://client.example.org/logo.png",
subject_type => "pairwise",
token_endpoint_auth_method => "client_secret_basic",
}
);
ok( $res->[0] == 201, "Return code is 201" );
my $answer = JSON::from_json( $res->[2]->[0] );
ok( defined $answer->{client_id}, "client_id in response" );
ok( defined $answer->{client_secret}, "client_secret in response" );
is( $answer->{token_endpoint_auth_method}, 'client_secret_basic',
"token_endpoint_auth_method in response" );
my ( $conf, $rpId, $confFile ) = get_registered_rp_conf(2);
is( $conf->{oidcRPMetaDataOptions}->{$rpId}
->{oidcRPMetaDataOptionsClientID},
$answer->{client_id}, "Client ID saved in configuration" );
is( $conf->{oidcRPMetaDataOptionsExtraClaims}->{$rpId}
->{"extra_claim"},
"extra_var", "Extra claim defined" );
is( $conf->{oidcRPMetaDataExportedVars}->{$rpId}->{"extra_var"},
"mail", "Extra variable defined" );
is( $conf->{oidcRPMetaDataOptions}->{$rpId}
->{oidcRPMetaDataOptionsRequirePKCE},
2, "RequirePKCE set to 2 (pkceOrSecret)" );
unlink $confFile;
};
subtest "public client rejected" => sub {
$res = post_register(
$op,
{
redirect_uris => ["https://client.example.org/callback"],
client_name => "Public Client",
token_endpoint_auth_method => "none",
}
);
is( $res->[0], 400, "Public client rejected" );
};
subtest "private_key_jwt rejected" => sub {
$res = post_register(
$op,
{
redirect_uris => ["https://client.example.org/callback"],
client_name => "PKJ Client",
token_endpoint_auth_method => "private_key_jwt",
jwks_uri => "https://client.example.org/jwks",
}
);
is( $res->[0], 400, "private_key_jwt rejected" );
};
subtest "unsupported auth method rejected" => sub {
$res = post_register(
$op,
{
redirect_uris => ["https://client.example.org/callback"],
client_name => "Bad Method",
token_endpoint_auth_method => "tls_client_auth",
}
);
is( $res->[0], 400, "Unsupported method rejected" );
};
};
reset_tmpdir();
subtest "All clients mode (value=2)" => sub {
ok( my $op = op(2), 'OP portal' );
subtest "public client accepted" => sub {
$res = post_register(
$op,
{
redirect_uris => ["https://client.example.org/callback"],
client_name => "Public Client",
token_endpoint_auth_method => "none",
}
);
is( $res->[0], 201, "Public client accepted" );
my $answer = JSON::from_json( $res->[2]->[0] );
ok( !defined $answer->{client_secret}, "No client_secret" );
is( $answer->{token_endpoint_auth_method}, 'none',
"token_endpoint_auth_method=none" );
my ( $conf, $rpId, $confFile ) = get_registered_rp_conf(2);
is( $conf->{oidcRPMetaDataOptions}->{$rpId}
->{oidcRPMetaDataOptionsPublic},
1, "Public flag set" );
is( $conf->{oidcRPMetaDataOptions}->{$rpId}
->{oidcRPMetaDataOptionsRequirePKCE},
2, "RequirePKCE set to 2" );
unlink $confFile;
};
subtest "private_key_jwt without jwks_uri rejected" => sub {
$res = post_register(
$op,
{
redirect_uris => ["https://client.example.org/callback"],
client_name => "PKJ No JWKS",
token_endpoint_auth_method => "private_key_jwt",
}
);
is( $res->[0], 400, "Rejected without jwks_uri" );
};
subtest "private_key_jwt with jwks_uri accepted" => sub {
$res = post_register(
$op,
{
redirect_uris => ["https://client.example.org/callback"],
client_name => "PKJ Client",
token_endpoint_auth_method => "private_key_jwt",
jwks_uri => "https://client.example.org/jwks",
}
);
is( $res->[0], 201, "Accepted with jwks_uri" );
my $answer = JSON::from_json( $res->[2]->[0] );
ok( !defined $answer->{client_secret}, "No client_secret" );
is( $answer->{token_endpoint_auth_method}, 'private_key_jwt',
"token_endpoint_auth_method=private_key_jwt" );
my ( $conf, $rpId, $confFile ) = get_registered_rp_conf(3);
is( $conf->{oidcRPMetaDataOptions}->{$rpId}
->{oidcRPMetaDataOptionsJwksUri},
'https://client.example.org/jwks', "jwks_uri saved" );
ok( !$conf->{oidcRPMetaDataOptions}->{$rpId}
->{oidcRPMetaDataOptionsPublic},
"Not marked as public" );
};
subtest "client_secret_jwt generates a secret" => sub {
$res = post_register(
$op,
{
redirect_uris => ["https://client.example.org/callback"],
client_name => "CS JWT Client",
token_endpoint_auth_method => "client_secret_jwt",
}
);
is( $res->[0], 201, "Accepted" );
my $answer = JSON::from_json( $res->[2]->[0] );
ok( defined $answer->{client_secret}, "client_secret present" );
is( $answer->{token_endpoint_auth_method}, 'client_secret_jwt',
"token_endpoint_auth_method=client_secret_jwt" );
};
};
clean_sessions();
done_testing();
sub op {
my ($dynreg_level) = @_;
$dynreg_level //= 1;
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
domain => 'idp.com',
portal => 'http://auth.op.com/',
authentication => 'Demo',
userDB => 'Same',
issuerDBOpenIDConnectActivation => 1,
issuerDBOpenIDConnectRule => '$uid eq "french"',
oidcRPMetaDataExportedVars => {
rp => {
email => "mail",
family_name => "extract_sn",
name => "cn"
}
},
oidcServiceDynamicRegistrationExportedVars =>
{ "extra_var" => "mail" },
oidcServiceDynamicRegistrationExtraClaims =>
{ "extra_claim" => "extra_var" },
oidcServiceAllowHybridFlow => 1,
oidcServiceAllowImplicitFlow => 1,
oidcServiceAllowDynamicRegistration => $dynreg_level,
oidcServiceAllowAuthorizationCodeFlow => 1,
oidcRPMetaDataMacros => {
rp => {
( run in 1.338 second using v1.01-cache-2.11-cpan-8dfa8b56332 )