2017-01-16 20:45:14 +01:00
|
|
|
package Lemonldap::NG::Portal::Auth::Demo;
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use Mouse;
|
|
|
|
use URI::Escape;
|
|
|
|
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_ERROR);
|
|
|
|
|
|
|
|
our $VERSION = '2.0.0';
|
|
|
|
|
|
|
|
# INITIALIZATION
|
|
|
|
|
|
|
|
has twitterRequestTokenURL => (
|
|
|
|
is => 'ro',
|
2017-03-27 18:51:18 +02:00
|
|
|
lazy => 1,
|
2017-01-16 20:45:14 +01:00
|
|
|
default => sub {
|
|
|
|
$_[0]->conf->{twitterRequestTokenURL}
|
|
|
|
|| 'https://api.twitter.com/oauth/request_token';
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
has twitterAuthorizeURL => (
|
|
|
|
is => 'ro',
|
2017-03-27 18:51:18 +02:00
|
|
|
lazy => 1,
|
2017-01-16 20:45:14 +01:00
|
|
|
default => sub {
|
|
|
|
$_[0]->conf->{twitterAuthorizeURL}
|
|
|
|
|| 'https://api.twitter.com/oauth/authorize';
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
has twitterAccessTokenURL => (
|
|
|
|
is => 'ro',
|
2017-03-27 18:51:18 +02:00
|
|
|
lazy => 1,
|
2017-01-16 20:45:14 +01:00
|
|
|
default => sub {
|
|
|
|
$_[0]->conf->{twitterAccessTokenURL}
|
|
|
|
|| 'https://api.twitter.com/oauth/access_token';
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
sub init {
|
|
|
|
my ($self) = @_;
|
|
|
|
unless ( $self->conf->{twitterKey} and $self->conf->{twitterSecret} ) {
|
|
|
|
$self->error('twitterKey and twitterSecret parameters are required');
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
eval {
|
|
|
|
require Net::OAuth;
|
|
|
|
$Net::OAuth::PROTOCOL_VERSION = &Net::OAuth::PROTOCOL_VERSION_1_0A();
|
|
|
|
};
|
|
|
|
if ($@) {
|
|
|
|
$self->error("Unable to load Net::OAuth: $@");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub extractFormInfo {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
my $nonce = time;
|
|
|
|
|
|
|
|
# 1. Request to authenticate
|
|
|
|
unless ( $req->param('twitterback') ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug('Redirection to Twitter');
|
2017-01-16 20:45:14 +01:00
|
|
|
|
|
|
|
# 1.1 Try to get token to dialog with Twitter
|
|
|
|
my $callback_url = $self->url();
|
|
|
|
|
|
|
|
# Twitter callback parameter
|
|
|
|
$callback_url .=
|
|
|
|
( $callback_url =~ /\?/ ? '&' : '?' ) . "twitterback=1";
|
|
|
|
|
|
|
|
# Add request state parameters
|
|
|
|
if ( $req->datas->{_url} ) {
|
|
|
|
my $url_param = 'url=' . uri_escape( $req->datas->{_url} );
|
|
|
|
$callback_url .= ( $callback_url =~ /\?/ ? '&' : '?' ) . $url_param;
|
|
|
|
}
|
|
|
|
if ( $req->param( $self->conf->{authChoiceParam} ) ) {
|
|
|
|
my $url_param =
|
|
|
|
$self->conf->{authChoiceParam} . '='
|
|
|
|
. uri_escape( $req->param( $self->conf->{authChoiceParam} ) );
|
|
|
|
$callback_url .= ( $callback_url =~ /\?/ ? '&' : '?' ) . $url_param;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Forward hidden fields
|
|
|
|
if ( exists $req->{portalHiddenFormValues} ) {
|
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("Add hidden values to Twitter redirect URL");
|
2017-01-16 20:45:14 +01:00
|
|
|
|
|
|
|
foreach ( keys %{ $req->{portalHiddenFormValues} } ) {
|
|
|
|
$callback_url .=
|
|
|
|
( $callback_url =~ /\?/ ? '&' : '?' )
|
|
|
|
. $_ . '='
|
|
|
|
. uri_escape( $req->{portalHiddenFormValues}->{$_} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
my $request = Net::OAuth->request("request token")->new(
|
|
|
|
consumer_key => $self->conf->{twitterKey},
|
|
|
|
consumer_secret => $self->conf->{twitterSecret},
|
|
|
|
request_url => $self->twitterRequestTokenURL,
|
|
|
|
request_method => 'POST',
|
|
|
|
signature_method => 'HMAC-SHA1',
|
|
|
|
timestamp => time,
|
|
|
|
nonce => $nonce,
|
|
|
|
callback => $callback_url,
|
|
|
|
);
|
|
|
|
|
|
|
|
$request->sign;
|
|
|
|
|
|
|
|
my $request_url = $request->to_url;
|
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("POST $request_url to Twitter");
|
2017-01-16 20:45:14 +01:00
|
|
|
|
|
|
|
my $res = $self->ua()->post($request_url);
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug( "Twitter response: " . $res->as_string );
|
2017-01-16 20:45:14 +01:00
|
|
|
|
|
|
|
if ( $res->is_success ) {
|
|
|
|
my $response = Net::OAuth->response('request token')
|
|
|
|
->from_post_body( $res->content );
|
|
|
|
|
2017-03-15 11:01:29 +01:00
|
|
|
# 1.2 Store token key and secret in cookies (available 180s)
|
2017-01-16 20:45:14 +01:00
|
|
|
$req->addCookie(
|
|
|
|
$self->cookie(
|
|
|
|
name => '_twitSec',
|
|
|
|
value => $response->token_secret,
|
2017-03-15 11:01:29 +01:00
|
|
|
max_age => 180,
|
2017-01-16 20:45:14 +01:00
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
# 1.3 Redirect user to Twitter
|
|
|
|
my $authorize_url =
|
|
|
|
$self->twitterAuthorizeURL . "?oauth_token=" . $response->token;
|
|
|
|
$self->redirect( -uri => $authorize_url );
|
|
|
|
$self->quit();
|
|
|
|
}
|
|
|
|
else {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error(
|
|
|
|
'Twitter OAuth protocol error: ' . $res->content );
|
2017-01-16 20:45:14 +01:00
|
|
|
return PE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# 2. User is back from Twitter
|
|
|
|
my $request_token = $req->param('oauth_token');
|
|
|
|
my $verifier = $req->param('oauth_verifier');
|
|
|
|
unless ( $request_token and $verifier ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error('Twitter OAuth protocol error');
|
2017-01-16 20:45:14 +01:00
|
|
|
return PE_ERROR;
|
|
|
|
}
|
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug(
|
|
|
|
"Get token $request_token and verifier $verifier from Twitter");
|
2017-01-16 20:45:14 +01:00
|
|
|
|
|
|
|
# 2.1 Reconnect to Twitter
|
|
|
|
my $access = Net::OAuth->request("access token")->new(
|
|
|
|
consumer_key => $self->conf->{twitterKey},
|
|
|
|
consumer_secret => $self->conf->{twitterSecret},
|
|
|
|
request_url => $self->twitterAccessTokenURL,
|
|
|
|
request_method => 'POST',
|
|
|
|
signature_method => 'HMAC-SHA1',
|
|
|
|
verifier => $verifier,
|
|
|
|
token => $request_token,
|
|
|
|
token_secret => $self->cookie('_twitSec'),
|
|
|
|
timestamp => time,
|
|
|
|
nonce => $nonce,
|
|
|
|
);
|
|
|
|
$access->sign;
|
|
|
|
|
|
|
|
my $access_url = $access->to_url;
|
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("POST $access_url to Twitter");
|
2017-01-16 20:45:14 +01:00
|
|
|
|
|
|
|
my $res_access = $self->ua()->post($access_url);
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug( "Twitter response: " . $res_access->as_string );
|
2017-01-16 20:45:14 +01:00
|
|
|
|
|
|
|
if ( $res_access->is_success ) {
|
|
|
|
my $response = Net::OAuth->response('access token')
|
|
|
|
->from_post_body( $res_access->content );
|
|
|
|
|
|
|
|
# Get user_id and screename
|
|
|
|
$req->datas->{_twitterUserId} = $response->{extra_params}->{user_id};
|
|
|
|
$req->datas->{_twitterScreenName} =
|
|
|
|
$response->{extra_params}->{screen_name};
|
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug( "Get user id "
|
2017-01-16 20:45:14 +01:00
|
|
|
. $req->datas->{_twitterUserId}
|
|
|
|
. " and screen name "
|
2017-02-15 07:41:50 +01:00
|
|
|
. $req->datas->{_twitterScreenName} );
|
2017-01-16 20:45:14 +01:00
|
|
|
}
|
|
|
|
else {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error(
|
|
|
|
'Twitter OAuth protocol error: ' . $res_access->content );
|
2017-01-16 20:45:14 +01:00
|
|
|
return PE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
# 2.4 Set $req->{user} to screen name
|
|
|
|
$req->user( $req->datas->{_twitterScreenName} );
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("Good Twitter authentication for $req->{user}");
|
2017-01-16 20:45:14 +01:00
|
|
|
|
|
|
|
# Force redirection to avoid displaying OAuth datas
|
|
|
|
$req->{mustRedirect} = 1;
|
|
|
|
|
|
|
|
# Clean temporaries cookies
|
|
|
|
$req->addCookie(
|
2017-03-15 11:01:29 +01:00
|
|
|
$self->cookie(
|
|
|
|
name => '_twitSec',
|
|
|
|
value => 0,
|
|
|
|
expires => 'Wed, 21 Oct 2015 00:00:00 GMT'
|
|
|
|
)
|
|
|
|
);
|
2017-01-16 20:45:14 +01:00
|
|
|
PE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub setAuthSessionInfo {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
|
|
|
|
$req->{sessionInfo}->{authenticationLevel} =
|
|
|
|
$req->datas->{twitterAuthnLevel};
|
|
|
|
$req->{sessionInfo}->{_twitterUserId} = $req->datas->{_twitterUserId};
|
|
|
|
$req->{sessionInfo}->{_twitterScreenName} =
|
|
|
|
$req->datas->{_twitterScreenName};
|
|
|
|
|
|
|
|
PE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub authenticate {
|
|
|
|
PE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub authLogout {
|
|
|
|
PE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub getDisplayType {
|
|
|
|
return "logo";
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|