File Coverage

lib/Dancer/Plugin/Auth/Twitter.pm
Criterion Covered Total %
statement 45 55 81.8
branch 4 10 40.0
condition 3 6 50.0
subroutine 11 12 91.6
pod n/a
total 63 83 75.9


line stmt bran cond sub pod time code
1             package Dancer::Plugin::Auth::Twitter;
2             BEGIN {
3 1     1   245203 $Dancer::Plugin::Auth::Twitter::AUTHORITY = 'cpan:SUKRIA';
4             }
5             #ABSTRACT: Authenticate with Twitter
6             $Dancer::Plugin::Auth::Twitter::VERSION = '0.07';
7 1     1   11 use strict;
  1         2  
  1         32  
8 1     1   4 use warnings;
  1         2  
  1         24  
9              
10 1     1   3 use Dancer ':syntax';
  1         1  
  1         4  
11 1     1   791 use Dancer::Plugin;
  1         1224  
  1         72  
12 1     1   8 use Carp 'croak';
  1         1  
  1         59  
13 1     1   5 use Class::Load qw/ load_class /;
  1         1  
  1         40  
14 1     1   513 use Net::Twitter::Lite::WithAPIv1_1 0.12006;
  1         16433  
  1         709  
15              
16             # Net::Twitter singleton, accessible via 'twitter'
17             our $_twitter;
18 15     15   30785 sub twitter { $_twitter }
19             register 'twitter' => \&twitter;
20              
21             # init method, to create the Net::Twitter object
22             my $consumer_key;
23             my $consumer_secret;
24             my $callback_url;
25             my $callback_success;
26             my $callback_fail;
27              
28             my $engine;
29              
30             register 'auth_twitter_init' => sub {
31 1     1   1774 my $config = plugin_setting;
32              
33 1         20 $consumer_secret = $config->{consumer_secret};
34 1         2 $consumer_key = $config->{consumer_key};
35 1         2 $callback_url = $config->{callback_url};
36              
37 1   50     5 $callback_success = $config->{callback_success} || '/';
38 1   50     3 $callback_fail = $config->{callback_fail} || '/fail';
39              
40 1         3 for my $param (qw/consumer_key consumer_secret callback_url/) {
41 3 50       9 croak "'$param' is expected but not found in configuration"
42             unless $config->{$param};
43             }
44              
45 1         7 debug "new twitter with $consumer_key , $consumer_secret, $callback_url";
46              
47 1   50     80 $engine = $config->{engine} || 'Net::Twitter::Lite::WithAPIv1_1';
48              
49 1 50       4 $engine .= '::WithAPIv1_1' if $engine eq 'Net::Twitter::Lite';
50              
51 2         6 die "engine must be 'Net::Twitter' or 'Net::Twitter::Lite::WithAPIv1_1': '$engine' not supported\n"
52 1 50       1 unless grep { $engine eq $_ } qw/ Net::Twitter Net::Twitter::Lite::WithAPIv1_1 /;
53              
54 1         4 $_twitter = load_class($engine)->new(
55             ( traits => [ qw/ API::RESTv1_1 OAuth / ] ) x ( $engine eq 'Net::Twitter' ),
56             'consumer_key' => $consumer_key,
57             'consumer_secret' => $consumer_secret,
58             ssl => 1,
59             );
60              
61             };
62              
63             # define a route handler that bounces to the OAuth authorization process
64             register 'auth_twitter_authorize_url' => sub {
65 0 0   0   0 if (not defined twitter) {
66 0         0 croak "auth_twitter_init must be called first";
67             }
68              
69 0         0 my $uri = twitter->get_authorization_url(
70             'callback' => $callback_url
71             );
72              
73 0         0 session request_token => twitter->request_token;
74 0         0 session request_token_secret => twitter->request_token_secret;
75 0         0 session access_token => '';
76 0         0 session access_token_secret => '';
77              
78 0         0 debug "auth URL : $uri";
79 0         0 return $uri;
80             };
81              
82             # define a route handler that bounces to the OAuth authentication process
83             register 'auth_twitter_authenticate_url' => sub {
84 2 50   2   3713 if (not defined twitter) {
85 0         0 croak "auth_twitter_init must be called first";
86             }
87              
88 2         5 my $uri = twitter->get_authentication_url(
89             'callback' => $callback_url
90             );
91              
92 2         127 session request_token => twitter->request_token;
93 2         394 session request_token_secret => twitter->request_token_secret;
94 2         323 session access_token => '';
95 2         216 session access_token_secret => '';
96              
97 2         213 debug "auth URL : $uri";
98 2         80 return $uri;
99             };
100              
101             get '/auth/twitter/callback' => sub {
102              
103             debug "in callback...";
104              
105             # A user denying access should be considered a failure
106             return redirect $callback_fail if (params->{'denied'});
107              
108             if ( !session('request_token')
109             || !session('request_token_secret')
110             || !params->{'oauth_verifier'})
111             {
112             return send_error 'no request token present, or no verifier';
113             }
114              
115             my $token = session('request_token');
116             my $token_secret = session('request_token_secret');
117             my $access_token = session('access_token');
118             my $access_token_secret = session('access_token_secret');
119             my $verifier = params->{'oauth_verifier'};
120              
121             if (!$access_token && !$access_token_secret) {
122             twitter->request_token($token);
123             twitter->request_token_secret($token_secret);
124             ($access_token, $access_token_secret) = twitter->request_access_token('verifier' => $verifier);
125              
126             # this is in case we need to register the user after the oauth process
127             session access_token => $access_token;
128             session access_token_secret => $access_token_secret;
129             }
130              
131             # get the user
132             twitter->access_token($access_token);
133             twitter->access_token_secret($access_token_secret);
134              
135             my $twitter_user_hash;
136             eval {
137             $twitter_user_hash = twitter->verify_credentials();
138             };
139              
140             if ($@ || !$twitter_user_hash) {
141             Dancer::Logger::core("no twitter_user_hash or error: ".$@);
142             return redirect $callback_fail;
143             }
144              
145             $twitter_user_hash->{'access_token'} = $access_token;
146             $twitter_user_hash->{'access_token_secret'} = $access_token_secret;
147              
148             # save the user
149             session 'twitter_user' => $twitter_user_hash;
150             session 'twitter_access_token' => $access_token,
151             session 'twitter_access_token_secret' => $access_token_secret,
152              
153             redirect $callback_success;
154             };
155            
156             register_plugin;
157              
158             __END__