Skip to content

Instantly share code, notes, and snippets.

/OpenID.pm Secret

Created June 21, 2017 11:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/e4229bbefc56c8fb3b149ef7babfebf5 to your computer and use it in GitHub Desktop.
Save anonymous/e4229bbefc56c8fb3b149ef7babfebf5 to your computer and use it in GitHub Desktop.
package MyApp::Controller::Auth::OpenID;
use Mojo::Base 'Mojolicious::Controller';
use LWP::UserAgent;
use Net::OpenID::Consumer;
sub check {
my $self = shift;
my $role = $self->stash('role');
my $user = $self->current_user;
# User needs to log in
$self->redirect_to('login') and return undef unless $user;
# User needs a different role
$self->render('permissions', status => 403) and return undef
unless $self->users->has_role($user, $role);
return 1;
}
sub login {
my $self = shift;
$self->csrf_token;
$self->redirect_to('openid');
}
sub logout {
my $self = shift;
delete $self->session->{user};
$self->redirect_to('dashboard');
}
sub openid {
my $self = shift;
my $base = $self->req->url->base->to_string;
my $csr = Net::OpenID::Consumer->new(
ua => LWP::UserAgent->new,
required_root => $base,
consumer_secret => $self->csrf_token
);
my $claimed_id
= $csr->claimed_identity($self->app->config->{openid}{provider});
return $self->render(text => $csr->err, status => 403) unless $claimed_id;
$claimed_id->set_extension_args('http://openid.net/extensions/sreg/1.1',
{required => 'email', optional => 'fullname,nickname'});
$claimed_id->set_extension_args(
'http://openid.net/srv/ax/1.0',
{
mode => 'fetch_request',
required => 'email,fullname,nickname,firstname,lastname',
'type.email' => "http://schema.openid.net/contact/email",
'type.fullname' => "http://axschema.org/namePerson",
'type.nickname' => "http://axschema.org/namePerson/friendly",
'type.firstname' => 'http://axschema.org/namePerson/first',
'type.lastname' => 'http://axschema.org/namePerson/last'
}
);
my $check_url = $claimed_id->check_url(
delayed_return => 1,
return_to => $self->url_for('response')->to_abs->to_string,
trust_root => $base
);
return $self->redirect_to($check_url) if $check_url;
$self->render(text => $csr->err, status => 403);
}
sub response {
my $self = shift;
my $params = $self->req->url->query->to_hash;
my $base = $self->req->url->base->to_string;
my $csr = Net::OpenID::Consumer->new(
ua => LWP::UserAgent->new,
required_root => $base,
consumer_secret => $self->csrf_token,
args => $params
);
my ($error, $login, $email, $fullname);
$csr->handle_server_response(
not_openid => sub { $error = 'Not an OpenID message' },
setup_needed => sub { $error = 'Setup not supported' },
cancelled => sub { $error = 'Authentication cancelled' },
verified => sub {
my $vident = shift;
my $sreg = $vident->signed_extension_fields(
'http://openid.net/extensions/sreg/1.1');
my $ax = $vident->signed_extension_fields('http://openid.net/srv/ax/1.0');
$error = 'Missing username'
unless $login = $sreg->{nickname} || $ax->{'value.nickname'};
$email = $sreg->{email} || $ax->{'value.email'};
$fullname = $sreg->{fullname} || $ax->{'value.fullname'};
},
error => sub {
my ($err, $txt) = @_;
$error = "$err: $txt";
},
);
return $self->render(text => $error, status => 403) if $error;
# Create in DB
my $user = $self->users->find_or_create(
login => $login,
email => $email,
fullname => $fullname
);
$self->session(user => $user->{login});
$self->redirect_to('dashboard');
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment