File Coverage

blib/lib/Net/Google/DataAPI/Auth/OAuth.pm
Criterion Covered Total %
statement 60 60 100.0
branch 10 10 100.0
condition 5 5 100.0
subroutine 15 15 100.0
pod 0 4 0.0
total 90 94 95.7


line stmt bran cond sub pod time code
1             package Net::Google::DataAPI::Auth::OAuth;
2 1     1   107686 use Any::Moose;
  1         21486  
  1         5  
3 1     1   893 use Net::Google::DataAPI::Types;
  1         2  
  1         37  
4             with 'Net::Google::DataAPI::Role::Auth';
5 1     1   442 use Digest::SHA1;
  1         534  
  1         38  
6 1     1   5 use LWP::UserAgent;
  1         1  
  1         18  
7 1     1   446 use Net::OAuth;
  1         490  
  1         24  
8 1     1   4 use URI;
  1         1  
  1         714  
9             $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
10             our $VERSION = '0.05';
11              
12             has [qw(consumer_key consumer_secret)] => ( is => 'ro', isa => 'Str', required => 1 );
13              
14             for my $attr (qw(
15             request_token
16             request_token_secret
17             access_token
18             access_token_secret
19             )) {
20             has $attr => (
21             is => 'rw',
22             isa => 'Str',
23             clearer => "clear_$attr",
24             predicate => "has_$attr"
25             );
26             }
27              
28             has scope => ( is => 'ro', isa => 'ArrayRef[Str]', required => 1, auto_deref => 1 );
29             has callback => ( is => 'ro', isa => 'Net::Google::DataAPI::Types::URI', coerce => 1 );
30             has signature_method => ( is => 'ro', isa => 'Str', default => 'HMAC-SHA1' );
31             has authorize_token_hd => ( is => 'ro', isa => 'Str', default => 'default' );
32             has authorize_token_hl => ( is => 'ro', isa => 'Str', default => 'en' );
33             has mobile => ( is => 'ro', isa => 'Bool', default => 0 );
34             has ua => ( is => 'ro', isa => 'LWP::UserAgent', required => 1, lazy_build => 1 );
35             sub _build_ua {
36 3     3   23 LWP::UserAgent->new( max_redirect => 0 );
37             }
38              
39             my $url_hash = {
40             get_request_token_url => 'https://www.google.com/accounts/OAuthGetRequestToken',
41             authorize_token_url => 'https://www.google.com/accounts/OAuthAuthorizeToken',
42             get_access_token_url => 'https://www.google.com/accounts/OAuthGetAccessToken',
43             };
44              
45             while ( my ($key, $url) = each %$url_hash ) {
46             has $key => ( is => 'ro', isa => 'URI', required => 1, default => sub {URI->new($url)} );
47             }
48              
49             sub get_request_token {
50 7     7 0 3324 my ($self, $args) = @_;
51 7   100     77 my $res = $self->_oauth_request(
52             'request token',
53             {
54             request_url => $self->get_request_token_url,
55             extra_params => {
56             scope => join(' ', $self->scope),
57             },
58             callback => $self->callback || 'oob',
59             }
60             );
61 3         18 my ($token, $secret) = $self->_res_to_token($res);
62 3         30 $self->request_token($token);
63 3         14 $self->request_token_secret($secret);
64 3         20 return $self;
65             }
66              
67             sub get_authorize_token_url {
68 3     3 0 1502 my ($self) = @_;
69 3 100       20 $self->has_request_token or $self->get_request_token;
70 3         9 my $url = $self->authorize_token_url;
71 3 100       31 $url->query_form(
72             oauth_token => $self->request_token,
73             hd => $self->authorize_token_hd,
74             hl => $self->authorize_token_hl,
75             $self->mobile ? ( btmpl => 'mobile' ) : (),
76             );
77 3         162 return $url;
78             }
79              
80             sub get_access_token {
81 5     5 0 5567 my ($self, $args) = @_;
82             my $res = $self->_oauth_request(
83             'access token',
84             {
85             request_url => $self->get_access_token_url,
86             token => $self->request_token,
87             token_secret => $self->request_token_secret,
88 5 100       27 %{$args || {}},
  5         34  
89             }
90             );
91             # now clear them.
92 3         17 $self->clear_request_token;
93 3         9 $self->clear_request_token_secret;
94 3         9 my ($token, $secret) = $self->_res_to_token($res);
95 3         18 $self->access_token($token);
96 3         22 $self->access_token_secret($secret);
97             }
98              
99             sub _oauth_request {
100 12     12   55 my ($self, $type, $args) = @_;
101 12         31 my $req = $self->_make_oauth_request($type, $args);
102 10         60 my $res = $self->ua->get($req->to_url);
103 10 100 100     13193 unless ($res && $res->is_success) {
104 4 100       71 confess sprintf "request failed: %s", $res ? $res->status_line : 'no response returned';
105             }
106 6         111 return $res;
107             }
108              
109             sub _make_oauth_request {
110 18     18   96 my ($self, $type, $args) = @_;
111 18         63 my $req = Net::OAuth->request($type)->new(
112             version => '1.0',
113             consumer_key => $self->consumer_key,
114             consumer_secret => $self->consumer_secret,
115             request_method => 'GET',
116             signature_method => $self->signature_method,
117             timestamp => time,
118             nonce => Digest::SHA1::sha1_base64(time . $$ . rand),
119             %$args,
120             );
121 13         13791 $req->sign;
122 13         18176 return $req;
123             }
124              
125             sub _res_to_token {
126 6     6   14 my ($self, $res) = @_;
127 6         21 my $uri = URI->new;
128 6         139 $uri->query($res->content);
129 6         126 my %query = $uri->query_form;
130 6         245 return @query{qw(oauth_token oauth_token_secret)};
131             }
132              
133             sub sign_request {
134 6     6 0 2837 my ($self, $req) = @_;
135 6         20 my $sign = $self->_make_oauth_request(
136             'protected resource',
137             {
138             request_url => $req->uri,
139             request_method => $req->method,
140             token => $self->access_token,
141             token_secret => $self->access_token_secret,
142             }
143             );
144 3         16 $req->header(Authorization => $sign->to_authorization_header);
145 3         1530 return $req;
146             }
147              
148             __PACKAGE__->meta->make_immutable;
149 1     1   5 no Any::Moose;
  1         1  
  1         6  
150              
151             1;
152             __END__
153              
154             =head1 NAME
155              
156             Net::Google::DataAPI::Auth::OAuth - (DEPRECATED) OAuth 1.0 support for Google Data APIs
157              
158             =head1 SYNOPSIS
159              
160             use Net::Google::DataAPI::Auth::OAuth;
161              
162             my $auth = Net::Google::DataAPI::Auth::OAuth->new(
163             consumer_key => 'consumer.example.com',
164             consumer_secret => 'mys3cr3t',
165             scope => ['http://spreadsheets.google.com/feeds/'],
166             );
167             my $url = $auth->get_authorize_token_url;
168              
169             # show the user $url and get $verifier
170              
171             $auth->get_access_token({verifier => $verifier}) or die;
172             my $token = $auth->access_token;
173             my $secret = $auth->access_token_secret;
174              
175             =head1 DESCRIPTION
176              
177             Net::Google::DataAPI::Auth::OAuth interacts with google OAuth service
178             and adds Authorization header to given request.
179              
180             =head1 DEPRECATED!
181              
182             OAuth1.0 protocol is deprecated.
183             Use L<Net::Google::DataAPI::Auth::OAuth2> instead.
184              
185             =head1 ATTRIBUTES
186              
187             You can make Net::Google::DataAPI::Auth::OAuth instance with those arguments below:
188              
189             =over 2
190              
191             =item * consumer_key
192              
193             Consumer key. You can get it at L<https://www.google.com/accounts/ManageDomains>.
194              
195             =item * consumer_secret
196              
197             The consumer secret paired with the consumer key.
198              
199             =item * scope
200              
201             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>.
202              
203             =item * callback
204              
205             OAuth callback url. 'oob' will be used if you don't specify it.
206              
207             =item * signature_method
208              
209             Signature method. The default is 'HMAC-SHA1'.
210              
211             =item * authorize_token_hd
212              
213             Set hosted domain account for hosted google apps users. Defaults to 'default'.
214              
215             =item * authorize_token_hl
216              
217             An ISO 639 country code to set authorize user interface language. Defaults to 'en'.
218              
219             =item * mobile
220              
221             A boolean value whether you use this auth with mobile or not. defaults to 0.
222              
223             =back
224              
225             See L<http://code.google.com/intl/en-US/apis/accounts/docs/OAuth_ref.html> for details.
226              
227             =head1 AUTHOR
228              
229             Nobuo Danjou E<lt>danjou@soffritto.orgE<gt>
230              
231             =head1 SEE ALSO
232              
233             L<Net::Google::AuthSub>
234              
235             L<Net::OAuth>
236              
237             L<Net::Twitter::Role::OAuth>
238              
239             =head1 LICENSE
240              
241             This library is free software; you can redistribute it and/or modify
242             it under the same terms as Perl itself.
243              
244             =cut