Skip to content

Commit 867eb32

Browse files
committed
Initial OpenID controller to serve OpenID login
1 parent 33318b8 commit 867eb32

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package MetaCPAN::Server::Controller::Login::OpenID;
2+
3+
use strict;
4+
use warnings;
5+
6+
use Moose;
7+
use Net::OpenID::Consumer;
8+
use LWP::UserAgent::Paranoid;
9+
use MooseX::ClassAttribute;
10+
11+
BEGIN { extends 'MetaCPAN::Server::Controller::Login' }
12+
13+
class_has '_ua' => (
14+
is => 'ro',
15+
isa => 'LWP::UserAgent::Paranoid',
16+
lazy => 1,
17+
builder => '_build_ua',
18+
);
19+
20+
sub _build_ua {
21+
LWP::UserAgent::Paranoid->new(
22+
protocols_allowed => [ 'http', 'https' ],
23+
request_timeout => 10,
24+
resolver => Net::DNS::Paranoid->new(),
25+
);
26+
}
27+
28+
has 'sreg' => (
29+
is => 'rw',
30+
isa => 'Str',
31+
default => 'http://openid.net/extensions/sreg/1.1',
32+
);
33+
34+
sub index : Path {
35+
my ( $self, $c ) = @_;
36+
my $claimed_uri = $c->req->params->{openid_identifier};
37+
my $csr = Net::OpenID::Consumer->new(
38+
ua => $self->_ua,
39+
required_root => $c->uri_for(q{/}),
40+
args => $c->req->params,
41+
consumer_secret =>
42+
$c->config->{'Controller::Login::OpenID'}->{secret_key},
43+
assoc_options => [
44+
max_encrypt => 1,
45+
session_no_encrypt_https => 1,
46+
],
47+
);
48+
if ($claimed_uri) {
49+
if ( my $claimed_identity = $csr->claimed_identity("$claimed_uri") ) {
50+
$claimed_identity->set_extension_args(
51+
$self->sreg,
52+
{
53+
optional => 'email,fullname',
54+
},
55+
);
56+
57+
my $check_url = $claimed_identity->check_url(
58+
return_to => $c->uri_for( $self->action_for('index') ),
59+
trust_root => $c->uri_for(q{/}),
60+
delayed_return => 1,
61+
);
62+
63+
$c->res->redirect($check_url);
64+
}
65+
else {
66+
$c->controller('OAuth2')->redirect( $c, error => $csr->err );
67+
}
68+
}
69+
70+
if ( $c->req->params->{'openid.mode'} ) {
71+
if ( $csr->setup_needed and my $setup_url = $csr->user_setup_url ) {
72+
$c->res->redirect($setup_url);
73+
}
74+
elsif ( $csr->user_cancel ) {
75+
$c->controller('OAuth2')
76+
->redirect( $c, error => 'access denied' );
77+
}
78+
elsif ( my $vident = $csr->verified_identity ) {
79+
my $user_data = $vident->signed_extension_fields( $self->sreg );
80+
$self->update_user(
81+
$c,
82+
openid => $vident->url,
83+
$user_data,
84+
);
85+
}
86+
else {
87+
$c->controller('OAuth2')->redirect( $c, error => $csr->err );
88+
}
89+
}
90+
}
91+
92+
1;

t/server/controller/login/openid.t

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use strict;
2+
use warnings;
3+
use utf8;
4+
5+
use JSON qw( decode_json );
6+
use MetaCPAN::Server::Test;
7+
use Test::More;
8+
use Test::OpenID::Server;
9+
10+
my $openid_server = Test::OpenID::Server->new;
11+
my $url = $openid_server->started_ok('start server');
12+
13+
test_psgi app, sub {
14+
my $cb = shift;
15+
require MetaCPAN::Server::Controller::Login::OpenID;
16+
17+
MetaCPAN::Server::Controller::Login::OpenID->_ua->resolver
18+
->whitelisted_hosts( [ 'localhost', '127.0.0.1' ] );
19+
20+
ok( my $res = $cb->( GET "/login/openid?openid_identifier=$url/test" ),
21+
'login with test URL' );
22+
like( $res->header('location'),
23+
qr/openid.server/, 'get correct OpenID server url' );
24+
ok( $res = $cb->( GET "/login/openid?openid_identifier=$url/unknown" ),
25+
'get unknown ID page' );
26+
my $body = decode_json( $res->content );
27+
like( $body->{error}, qr/no_identity_server/,
28+
'get descriptive error for unknown ID' );
29+
};
30+
31+
done_testing();

0 commit comments

Comments
 (0)