File Coverage

lib/Dancer/Plugin/Auth/Facebook.pm
Criterion Covered Total %
statement 41 43 95.3
branch 4 8 50.0
condition 3 6 50.0
subroutine 9 9 100.0
pod n/a
total 57 66 86.3


line stmt bran cond sub pod time code
1             package Dancer::Plugin::Auth::Facebook;
2              
3             $Dancer::Plugin::Auth::Facebook::VERSION = '0.08';
4              
5 1     1   3095 use strict;
  1         2  
  1         27  
6 1     1   5 use warnings;
  1         2  
  1         26  
7              
8 1     1   5 use Dancer ':syntax';
  1         2  
  1         6  
9 1     1   985 use Dancer::Plugin;
  1         1873  
  1         59  
10 1     1   651 use Net::Facebook::Oauth2;
  1         26885  
  1         81  
11 1     1   10 use Carp 'croak';
  1         2  
  1         661  
12              
13             my $_FB;
14 4     4   4062 sub facebook { $_FB }
15             register 'facebook' => \&facebook;
16              
17             my $application_id;
18             my $application_secret;
19             my $cb_url;
20             my $cb_success;
21             my $cb_fail;
22             my $fb_scope;
23             my @scope;
24             my $me_fields;
25             my $api_version;
26              
27             register 'auth_fb_init' => sub {
28 1     1   648 my $config = plugin_setting;
29 1         25 $application_id = $config->{application_id};
30 1         3 $application_secret = $config->{application_secret};
31 1         2 $cb_url = $config->{callback_url};
32              
33 1   50     6 $cb_success = $config->{callback_success} || '/';
34 1   50     3 $cb_fail = $config->{callback_fail} || '/fail';
35 1         2 $fb_scope = $config->{scope};
36 1         11 $me_fields = $config->{fields};
37 1   50     6 $api_version = $config->{api_version} || 'v4.0';
38              
39 1 50       3 if (defined $fb_scope) {
40 1         7 foreach my $fs (split(/\s+/, $fb_scope)) {
41 3 50       11 next unless ($fs =~ m/^[_A-Za-z0-9\.]+$/);
42 3         4 push(@scope, $fs);
43             }
44             }
45             else {
46 0         0 push(@scope, 'email');
47             }
48              
49 1         2 for my $param (qw/application_id application_secret callback_url/) {
50 3 50       8 croak "'$param' is expected but not found in configuration" unless $config->{$param};
51             }
52              
53 1         7 debug "new facebook with $application_id, $application_secret, $cb_url";
54              
55 1         81 $_FB = Net::Facebook::Oauth2->new(
56             api_version => $api_version,
57             application_id => $application_id, ##get this from your facebook developers platform
58             application_secret => $application_secret, ##get this from your facebook developers platform
59             callback => $cb_url, ##Callback URL, facebook will redirect users after authintication
60             );
61              
62             };
63              
64             register 'auth_fb_authenticate_url' => sub {
65 1 50   1   6 if (not defined facebook ) {
66 0         0 croak "auth_fb_init must be called first";
67             }
68              
69 1         3 my $url = facebook->get_authorization_url(
70             scope => \@scope,
71             display => 'page',
72             );
73              
74 1         107 session fb_access_token => '';
75 1         713 debug "fb_auth_url: $url";
76              
77 1         122 return $url;
78             };
79              
80             get '/auth/facebook/callback' => sub {
81             debug "entering facebook callback";
82              
83             return redirect $cb_fail if (params->{'error'} || !params->{'code'});
84              
85             my $access_token = session('fb_access_token');
86              
87             if (!$access_token) {
88             eval {
89             $access_token = facebook->get_access_token(code => params->{'code'});
90             };
91             if (!$access_token) {
92             error "facebook error fetching access token: $@";
93             return redirect $cb_fail;
94             }
95             session fb_access_token => $access_token;
96             }
97              
98             my $fb = Net::Facebook::Oauth2->new(
99             api_version => $api_version,
100             access_token => $access_token,
101             );
102              
103             my ($me, $fb_response);
104             eval {
105             $fb_response = $fb->get( 'https://graph.facebook.com/' . $api_version . '/me' . ($me_fields ? "?fields=$me_fields" : '') );
106             $me = $fb_response->as_hash;
107             };
108             if ($@ || !$me) {
109             error "error fetching facebook user: '$@' on response '$fb_response'";
110             return redirect $cb_fail;
111             }
112             else {
113             session fb_user => $me;
114             return redirect $cb_success;
115             }
116             };
117              
118             register_plugin;
119              
120             1;
121              
122             __END__