File Coverage

blib/lib/Net/Google/DataAPI/Auth/OAuth2.pm
Criterion Covered Total %
statement 32 43 74.4
branch 3 14 21.4
condition 1 3 33.3
subroutine 11 13 84.6
pod 0 5 0.0
total 47 78 60.2


line stmt bran cond sub pod time code
1             package Net::Google::DataAPI::Auth::OAuth2;
2 1     1   128579 use Any::Moose;
  1         21025  
  1         5  
3 1     1   772 use Net::Google::DataAPI::Types;
  1         3  
  1         39  
4             with 'Net::Google::DataAPI::Role::Auth';
5 1     1   408 use Net::OAuth2::Client;
  1         5301  
  1         23  
6 1     1   6 use Net::OAuth2::Profile::WebServer;
  1         1  
  1         16  
7 1     1   3 use HTTP::Request::Common;
  1         2  
  1         450  
8             our $VERSION = '0.04';
9              
10             has [qw(client_id client_secret)] => (is => 'ro', isa => 'Str', required => 1);
11             has redirect_uri => (is => 'ro', isa => 'Str', default => 'urn:ietf:wg:oauth:2.0:oob');
12             has scope => (is => 'ro', isa => 'ArrayRef[Str]', required => 1, auto_deref => 1,
13             default => sub {[
14             'https://www.googleapis.com/auth/userinfo.profile',
15             'https://www.googleapis.com/auth/userinfo.email'
16             ]},
17             );
18             has site => (is => 'ro', isa => 'Str', default => 'https://accounts.google.com');
19             has authorize_path => (is => 'ro', isa => 'Str', default => '/o/oauth2/auth');
20             has access_token_path => (is => 'ro', isa => 'Str', default => '/o/oauth2/token');
21             has userinfo_url => (is => 'ro', isa => 'Str', default => 'https://www.googleapis.com/oauth2/v1/userinfo');
22             has oauth2_client => (is => 'ro', isa => 'Net::OAuth2::Client', required => 1, lazy_build => 1);
23             sub _build_oauth2_client {
24 3     3   3 my $self = shift;
25 3         38 Net::OAuth2::Client->new(
26             $self->client_id,
27             $self->client_secret,
28             site => $self->site,
29             authorize_path => $self->authorize_path,
30             access_token_path => $self->access_token_path,
31             refresh_token_path => $self->access_token_path,
32             );
33             }
34             has oauth2_webserver => (is => 'ro', isa => 'Net::OAuth2::Profile::WebServer', required => 1, lazy_build => 1);
35             sub _build_oauth2_webserver {
36 3     3   4 my $self = shift;
37 3         12 $self->oauth2_client->web_server( redirect_uri => $self->redirect_uri );
38             }
39             has access_token => (is => 'rw', isa => 'Net::Google::DataAPI::Types::OAuth2::AccessToken', coerce => 1);
40              
41             sub authorize_url {
42 3     3 0 5563 my $self = shift;
43 3         16 return $self->oauth2_webserver->authorize(
44             scope => join(' ', $self->scope),
45             @_
46             );
47             }
48              
49             sub get_access_token {
50 1     1 0 18584 my ($self, $code) = @_;
51 1 50       9 my $token = $self->oauth2_webserver->get_access_token($code) or return;
52 1         3347 $self->access_token($token);
53             }
54              
55             sub refresh_token {
56 0     0 0 0 my ($self, $refresh_token) = @_;
57 0         0 $self->oauth2_webserver->update_access_token($self->access_token);
58 0         0 $self->access_token->refresh;
59             }
60              
61             sub userinfo {
62 0     0 0 0 my $self = shift;
63 0 0       0 my $at = $self->access_token or die 'access_token is required';
64 0         0 my $url = URI->new($self->userinfo_url);
65 0         0 my $res = $at->get($url);
66 0 0       0 $res->is_success or die 'userinfo request failed: '.$res->as_string;
67 0 0       0 my %res_params = $self->oauth2_webserver->params_from_response($res)
68             or die 'params_from_response for userinfo response failed';
69 0         0 return \%res_params;
70             }
71              
72             sub sign_request {
73 1     1 0 1202 my ($self, $req) = @_;
74 1 50       6 my $at = $self->access_token or die 'access_token is required';
75 1 50 33     3 if ($at->expires_at && $at->expires_at < time) {
76 0 0       0 $self->refresh_token or die 'refresh_token failed';
77             }
78 1         16 $req->header(Authorization => join(' ',
79             'Bearer',
80             $at->access_token,
81             )
82             );
83              
84 1         44 return $req;
85             }
86              
87             __PACKAGE__->meta->make_immutable;
88 1     1   5 no Any::Moose;
  1         1  
  1         8  
89              
90             1;
91             __END__
92              
93             =head1 NAME
94              
95             Net::Google::DataAPI::Auth::OAuth2 - OAuth2 support for Google Data APIs
96              
97             =head1 SYNOPSIS
98              
99             use Net::Google::DataAPI::Auth::OAuth2;
100              
101             my $oauth2 = Net::Google::DataAPI::Auth::OAuth2->new(
102             client_id => 'xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
103             client_secret => 'mys3cr33333333333333t',
104             scope => ['http://spreadsheets.google.com/feeds/'],
105              
106             # with web apps, redirect_uri is needed:
107             #
108             # redirect_uri => 'http://your_app.sample.com/callback',
109              
110             );
111             my $url = $oauth2->authorize_url();
112              
113             # you can add optional parameters:
114             #
115             # my $url = $oauth2->authorize_url(
116             # access_type => 'offline',
117             # approval_prompt => 'force',
118             # );
119              
120             # show the user $url and get $code
121             # if you're making web app, you will do:
122             #
123             # return $c->redirect($auth->authorize_url());
124             #
125             # getting $code from the request to the 'redirect_uri' in web apps:
126             #
127             # my $code = $c->req->param('code');
128             #
129             # in installed apps:
130             #
131             # use Term::Prompt;
132             # my $code = prompt('x', 'paste the code: ', '', '');
133              
134             my $token = $oauth2->get_access_token($code) or die;
135              
136             # after retrieving $token, you can use $oauth2 with Net::Google::DataAPI items:
137              
138             my $client = Net::Google::Spreadsheets->new(auth => $oauth2);
139              
140             =head1 DESCRIPTION
141              
142             Net::Google::DataAPI::Auth::OAuth2 interacts with google OAuth 2.0 service
143             and adds Authorization header to given request.
144              
145             =head1 ATTRIBUTES
146              
147             You can make Net::Google::DataAPI::Auth::OAuth2 instance with those arguments below:
148              
149             =over 2
150              
151             =item * client_id
152              
153             client id. You can get it at L<https://code.google.com/apis/console#access>.
154              
155             =item * client_secret
156              
157             The client secret paired with the client id.
158              
159             =item * scope
160              
161             URL identifying the service(s) to be accessed. You can see the list of the urls to use at L<http://code.google.com/intl/en-US/apis/gdata/faq.html#AuthScopes>
162              
163             =item * redirect_url
164              
165             OAuth2 redirect url. 'urn:ietf:wg:oauth:2.0:oob' will be used if you don't specify it.
166              
167             =back
168              
169             See L<https://developers.google.com/accounts/docs/OAuth2> for details.
170              
171             =head1 AUTHOR
172              
173             Nobuo Danjou E<lt>danjou@soffritto.orgE<gt>
174              
175             =head1 SEE ALSO
176              
177             L<Net::OAuth2>
178              
179             L<https://developers.google.com/accounts/docs/OAuth2>
180              
181             you can see sample implementations for oauth2 client both as installed and web app in the eg directory of this distribution.
182              
183             =head1 LICENSE
184              
185             This library is free software; you can redistribute it and/or modify
186             it under the same terms as Perl itself.
187              
188             =cut