package t::lib::IdP::ExternalIdP; use Mojolicious::Lite; use Mojo::IOLoop; use Mojo::IOLoop::Server; use Mojo::Server::Daemon; print "Configure idp routes\n"; any '/idp/test/authorization_endpoint' => sub { my $c = shift; print "pasa por acá\n"; return $c->render(json => {error => 'invalid_request'}, status => 500) unless (3 == grep { $c->param($_) } qw(response_type redirect_uri client_id)) && $c->param('response_type') eq 'code'; my $url = Mojo::URL->new($c->param('redirect_uri')); $url->query({code => 'authorize-code', state => $c->param('state')}); return $c->redirect_to($url); }; any '/idp/test/token_endpoint/with_id_token/with_email' => sub { my $c = shift; return $c->render(json => {error => 'invalid_request'}, status => 500) unless (4 == grep { $c->param($_) } qw(client_id client_secret redirect_uri code)) && $c->param('code') eq 'authorize-code'; my $claims = { aud => $c->param('client_id'), email => 'test.user@some.library.com', iss => $c->url_for('/idp/test')->to_abs, given_name => 'test', family_name => 'user', preferred_username => 'test.user@some.library.com', sub => 'test.user' }; my $rsa = Crypt::OpenSSL::RSA->generate_key(2048); my $id_token = Mojo::JWT->new( algorithm => 'RS256', secret => $rsa->get_private_key_string, set_iat => 1, claims => $claims, header => {kid => 'TEST_SIGNING_KEY'} ); $c->render(status => 200, json => { access_token => 'access', expires_in => 3599, ext_expires_in => 3599, id_token => $id_token, refresh_token => 'refresh-token', scope => 'openid', token_type => 'Bearer' }); }; any '/idp/test/token_endpoint/with_id_token/without_email' => sub { my $c = shift; return $c->render(json => {error => 'invalid_request'}, status => 500) unless (4 == grep { $c->param($_) } qw(client_id client_secret redirect_uri code)) && $c->param('code') eq 'authorize-code'; my $claims = { aud => $c->param('client_id'), iss => $c->url_for('/idp/test')->to_abs, given_name => 'test', family_name => 'user', preferred_username => 'test.user', sub => 'test.user' }; my $rsa = Crypt::OpenSSL::RSA->generate_key(2048); my $id_token = Mojo::JWT->new( algorithm => 'RS256', secret => $rsa->get_private_key_string, set_iat => 1, claims => $claims, header => {kid => 'TEST_SIGNING_KEY'} ); $c->render(status => 200, json => { access_token => 'access', expires_in => 3599, ext_expires_in => 3599, id_token => $id_token, refresh_token => 'refresh-token', scope => 'openid', token_type => 'Bearer' }); }; any '/idp/test/token_endpoint/without_id_token' => sub { my $c = shift; return $c->render(json => {error => 'invalid_request'}, status => 500) unless (4 == grep { $c->param($_) } qw(client_id client_secret redirect_uri code)) && $c->param('code') eq 'authorize-code'; $c->render(status => 200, json => { access_token => 'access', expires_in => 3599, ext_expires_in => 3599, refresh_token => 'refresh-token', scope => 'some list of scopes', token_type => 'Bearer' }); }; any '/idp/test/userinfo_endpoint' => sub { my $c = shift; return $c->render(text => 'Unauthorized', status => 401) unless $c->req->headers->authorization eq 'Bearer access'; $c->render(status => 200, json => { users => [ { email => 'test.user@some.library.com', custom_name => 'test', custom_surname => 'user', id => 'test.user', last_login => 'a long time ago' } ] }); }; any '/idp/test/with_email/.well_known' => sub { my $c = shift; $c->render(status => 200, json => { authorization_endpoint => $c->url_for('/idp/test/authorization_endpoint')->to_abs, token_endpoint => $c->url_for('/idp/test/token_endpoint/with_id_token/with_email')->to_abs, userinfo_endpoint => $c->url_for('/idp/test/userinfo_endpoint')->to_abs, }); }; any '/idp/test/without_email/.well_known' => sub { my $c = shift; $c->render(status => 200, json => { authorization_endpoint => $c->url_for('/idp/test/authorization_endpoint')->to_abs, token_endpoint => $c->url_for('/idp/test/token_endpoint/with_id_token/without_email')->to_abs, userinfo_endpoint => $c->url_for('/idp/test/userinfo_endpoint')->to_abs, }); }; my $port = Mojo::IOLoop::Server->generate_port; my $daemon = Mojo::Server::Daemon->new( app => app, listen => ["http://*:$port"] ); sub start { print "Run daemon\n"; $daemon->start; Mojo::IOLoop->start unless Mojo::IOLoop->is_running; return $port; } sub stop { $daemon->stop; } 1;