File Coverage

blib/lib/Amon2/Auth/Site/Facebook.pm
Criterion Covered Total %
statement 24 61 39.3
branch 0 16 0.0
condition n/a
subroutine 8 11 72.7
pod 0 3 0.0
total 32 91 35.1


line stmt bran cond sub pod time code
1 1     1   659 use strict;
  1         1  
  1         23  
2 1     1   3 use warnings;
  1         1  
  1         18  
3 1     1   547 use utf8;
  1         8  
  1         4  
4              
5             package Amon2::Auth::Site::Facebook;
6 1     1   398 use Mouse;
  1         17721  
  1         3  
7 1     1   769 use LWP::UserAgent;
  1         33946  
  1         29  
8 1     1   8 use URI;
  1         1  
  1         19  
9 1     1   590 use JSON;
  1         8140  
  1         3  
10 1     1   117 use Amon2::Auth;
  1         1  
  1         496  
11              
12 0     0 0   sub moniker { 'facebook' }
13              
14             for (qw(client_id scope client_secret)) {
15             has $_ => (
16             is => 'ro',
17             isa => 'Str',
18             required => 1,
19             );
20             }
21              
22             has user_info => (
23             is => 'rw',
24             isa => 'Bool',
25             default => 1,
26             );
27              
28             has fields => (
29             is => 'rw',
30             isa => 'Str',
31             default => 'id,name',
32             );
33              
34             has ua => (
35             is => 'ro',
36             isa => 'LWP::UserAgent',
37             lazy => 1,
38             default => sub {
39             my $ua = LWP::UserAgent->new(agent => "Amon2::Auth/$Amon2::Auth::VERSION");
40             },
41             );
42              
43             sub auth_uri {
44 0     0 0   my ($self, $c, $callback_uri) = @_;
45 0 0         $callback_uri or die "Missing mandatory parameter: callback_uri";
46              
47 0           my $url = URI->new('https://www.facebook.com/dialog/oauth');
48 0           my %params;
49 0           for (qw(client_id scope)) {
50 0           $params{$_} = $self->$_;
51             }
52 0           $params{redirect_uri} = $callback_uri;
53 0           $url->query_form(%params);
54 0           return $url->as_string;
55             }
56              
57             sub callback {
58 0     0 0   my ($self, $c, $callback) = @_;
59 0 0         if (my $error_description = $c->req->param('error_description')) {
60 0           return $callback->{on_error}->($error_description);
61             }
62              
63 0           my $uri = URI->new('https://graph.facebook.com/oauth/access_token');
64 0           my %params;
65 0           for (qw(client_id client_secret)) {
66 0           $params{$_} = $self->$_;
67             }
68 0           $params{redirect_uri} = $c->req->uri->as_string;
69 0           $params{redirect_uri} =~ s/\?.+//;
70 0 0         $params{code} = $c->req->param('code') or die;
71 0           $uri->query_form(%params);
72 0           my $res = $self->ua->get($uri->as_string);
73 0 0         $res->is_success or do {
74 0           warn $res->decoded_content;
75 0           return $callback->{on_error}->($res->decoded_content);
76             };
77 0           my $dat = decode_json($res->decoded_content);
78 0 0         if (my $err = $dat->{error}) {
79 0           return $callback->{on_error}->($err);
80             }
81 0 0         my $access_token = $dat->{access_token} or die "Cannot get a access_token";
82 0           my @args = ($access_token);
83 0 0         if ($self->user_info) {
84 0           my $res = $self->ua->get("https://graph.facebook.com/me?fields=@{[$self->fields]}&access_token=${access_token}");
  0            
85 0 0         $res->is_success or return $callback->{on_error}->($res->status_line);
86 0           my $dat = decode_json($res->decoded_content);
87 0           push @args, $dat;
88             }
89 0           return $callback->{on_finished}->(@args);
90             }
91              
92             1;
93             __END__
94              
95             =head1 NAME
96              
97             Amon2::Auth::Site::Facebook - Facebook integration for Amon2
98              
99             =head1 SYNOPSIS
100              
101              
102             __PACKAGE__->load_plugin('Web::Auth', {
103             module => 'Facebook',
104             on_finished => sub {
105             my ($c, $token, $user) = @_;
106             my $name = $user->{name} || die;
107             $c->session->set('name' => $name);
108             $c->session->set('site' => 'facebook');
109             return $c->redirect('/');
110             }
111             });
112              
113             =head1 DESCRIPTION
114              
115             This is a facebook authentication module for Amon2. You can call a facebook APIs with this module.
116              
117             =head1 ATTRIBUTES
118              
119             =over 4
120              
121             =item client_id
122              
123             =item client_secret
124              
125             =item scope
126              
127             API scope in string.
128              
129             =item user_info(Default: true)
130              
131             Fetch user information after authenticate?
132              
133             =item fields(Default: "id,name")
134              
135             need fields of user information
136             L<https://developers.facebook.com/docs/facebook-login/permissions/v2.2#reference-public_profile>
137              
138             =item ua(instance of LWP::UserAgent)
139              
140             You can replace instance of L<LWP::UserAgent>.
141              
142             =back
143              
144             =head1 METHODS
145              
146             =over 4
147              
148             =item C<< $auth->auth_uri($c:Amon2::Web, $callback_uri : Str) :Str >>
149              
150             Get a authenticate URI.
151              
152             =item C<< $auth->callback($c:Amon2::Web, $callback:HashRef) : Plack::Response >>
153              
154             Process the authentication callback dispatching.
155              
156             C<< $callback >> MUST have two keys.
157              
158             =over 4
159              
160             =item on_error
161              
162             on_error callback function is called if an error was occurred.
163              
164             The arguments are following:
165              
166             sub {
167             my ($c, $error_message) = @_;
168             ...
169             }
170              
171             =item on_finished
172              
173             on_finished callback function is called if an authentication was finished.
174              
175             The arguments are following:
176              
177             sub {
178             my ($c, $access_token, $user) = @_;
179             ...
180             }
181              
182             C<< $user >> contains user information. This code contains a information like L<https://graph.facebook.com/19292868552>.
183              
184             If you set C<< $auth->user_info >> as false value, authentication engine does not pass C<< $user >>.
185              
186             =back
187              
188             =back
189