File Coverage

blib/lib/OAuth/Lite2/Client/UsernameAndPassword.pm
Criterion Covered Total %
statement 34 36 94.4
branch n/a
condition n/a
subroutine 12 12 100.0
pod n/a
total 46 48 95.8


line stmt bran cond sub pod time code
1             package OAuth::Lite2::Client::UsernameAndPassword;
2              
3 1     1   5 use strict;
  1         2  
  1         25  
4 1     1   4 use warnings;
  1         1  
  1         22  
5              
6 1     1   3 use base 'Class::ErrorHandler';
  1         1  
  1         60  
7              
8 1     1   3 use Params::Validate qw(HASHREF);
  1         1  
  1         30  
9 1     1   4 use Carp ();
  1         1  
  1         19  
10 1     1   3 use Try::Tiny;
  1         1  
  1         35  
11 1     1   3 use URI;
  1         2  
  1         20  
12 1     1   3 use LWP::UserAgent;
  1         1  
  1         13  
13 1     1   3 use HTTP::Request;
  1         1  
  1         13  
14              
15 1     1   4 use OAuth::Lite2;
  1         1  
  1         14  
16 1     1   3 use OAuth::Lite2::Util qw(build_content);
  1         2  
  1         32  
17 1     1   41 use OAuth::Lite2::Formatters;
  0            
  0            
18             use OAuth::Lite2::Client::TokenResponseParser;
19              
20             =head1 NAME
21              
22             OAuth::Lite2::Client::UsernameAndPassword - OAuth 2.0 Username And Password Profile Client
23              
24             =head1 SYNOPSIS
25              
26             my $client = OAuth::Lite2::Client::WebServer->new(
27             id => q{my_client_id},
28             secret => q{my_client_secret},
29             access_token_uri => q{http://example.org/token},
30             );
31              
32             sub get_access_token {
33             my $your_app = shift;
34              
35             my $access_token = $client->get_access_token(
36             username => $your_app->request->param("username"),
37             password => $your_app->request->param("password"),
38             scope => q{photo},
39             ) or return $your_app->error( $client->errstr );
40              
41             $your_app->store->save( access_token => $access_token->access_token );
42             $your_app->store->save( expires_at => time() + $access_token->expires_in );
43             $your_app->store->save( refresh_token => $access_token->refresh_token );
44             }
45              
46             sub refresh_access_token {
47             my $your_app = shift;
48              
49             my $access_token = $client->refresh_access_token(
50             refresh_token => $refresh_token,
51             ) or return $your_app->error( $client->errstr );
52              
53             $your_app->store->save( access_token => $access_token->access_token );
54             $your_app->store->save( expires_at => time() + $access_token->expires_in );
55             $your_app->store->save( refresh_token => $access_token->refresh_token );
56             }
57              
58             sub access_to_protected_resource {
59             my $your_app = shift;
60              
61             my $access_token = $your_app->store->get("access_token");
62             my $expires_at = $your_app->store->get("expires_at");
63             my $refresh_token = $your_app->store->get("refresh_token");
64              
65             unless ($access_token) {
66             $your_app->show_reauthorize_page();
67             return;
68             }
69              
70             if ($expires_at < time()) {
71             $your_app->refresh_access_token();
72             return;
73             }
74              
75             my $req = HTTP::Request->new( GET => q{http://example.org/photo} );
76             $req->header( Authorization => sprintf(q{OAuth %s}, $access_token) );
77             my $agent = LWP::UserAgent->new;
78             my $res = $agent->request($req);
79             ...
80             }
81              
82              
83             =head1 DESCRIPTION
84              
85             OAuth 2.0 Username And Password Profile Client.
86              
87              
88             =head2 new( %params )
89              
90             =over 4
91              
92             =item id
93              
94             Client ID
95              
96             =item secret
97              
98             Client secret
99              
100             =item access_token_uri
101              
102             token endpoint uri on auth-server.
103              
104             =item refresh_token_uri
105              
106             refresh-token endpoint uri on auth-server.
107             if you omit this, access_token_uri is used instead.
108              
109             =item agent
110              
111             user agent. if you omit this, LWP::UserAgent's object is set by default.
112             You can use your custom agent or preset-agents.
113              
114             See also
115              
116             L
117             L
118             L
119              
120             =back
121              
122             =cut
123              
124             sub new {
125             my $class = shift;
126              
127             my %args = Params::Validate::validate(@_, {
128             id => 1,
129             secret => 1,
130             # format => { optional => 1 },
131             access_token_uri => { optional => 1 },
132             refresh_token_uri => { optional => 1 },
133             agent => { optional => 1 },
134             });
135              
136             my $self = bless {
137             id => undef,
138             secret => undef,
139             access_token_uri => undef,
140             refresh_token_uri => undef,
141             last_request => undef,
142             last_response => undef,
143             %args,
144             }, $class;
145              
146             unless ($self->{agent}) {
147             $self->{agent} = LWP::UserAgent->new;
148             $self->{agent}->agent(
149             join "/", __PACKAGE__, $OAuth::Lite2::VERSION);
150             }
151              
152             # $self->{format} ||= 'json';
153             $self->{response_parser} = OAuth::Lite2::Client::TokenResponseParser->new;
154              
155             return $self;
156             }
157              
158             =head2 get_access_token( %params )
159              
160             =over 4
161              
162             =item username
163              
164             =item password
165              
166             =item scope
167              
168             =back
169              
170             =cut
171              
172             sub get_access_token {
173             my $self = shift;
174              
175             my %args = Params::Validate::validate(@_, {
176             username => 1,
177             password => 1,
178             scope => { optional => 1 },
179             uri => { optional => 1 },
180             # secret_type => { optional => 1 },
181             # format => { optional => 1 },
182             });
183              
184             unless (exists $args{uri}) {
185             $args{uri} = $self->{access_token_uri}
186             || Carp::croak "uri not found";
187             }
188              
189             # $args{format} ||= $self->{format};
190              
191             my %params = (
192             grant_type => 'password',
193             client_id => $self->{id},
194             client_secret => $self->{secret},
195             username => $args{username},
196             password => $args{password},
197             # format => $args{format},
198             );
199              
200             $params{scope} = $args{scope}
201             if $args{scope};
202              
203             # $params{secret_type} = $args{secret_type}
204             # if $args{secret_type};
205              
206             my $content = build_content(\%params);
207             my $headers = HTTP::Headers->new;
208             $headers->header("Content-Type" => q{application/x-www-form-urlencoded});
209             $headers->header("Content-Length" => bytes::length($content));
210             my $req = HTTP::Request->new( POST => $args{uri}, $headers, $content );
211              
212             my $res = $self->{agent}->request($req);
213             $self->{last_request} = $req;
214             $self->{last_response} = $res;
215              
216             my ($token, $errmsg);
217             try {
218             $token = $self->{response_parser}->parse($res);
219             } catch {
220             $errmsg = "$_";
221             };
222             return $token || $self->error($errmsg);
223              
224             }
225              
226             =head2 refresh_access_token( %params )
227              
228             =over 4
229              
230             =item refresh_token
231              
232             =back
233              
234             =cut
235              
236             sub refresh_access_token {
237             my $self = shift;
238              
239             my %args = Params::Validate::validate(@_, {
240             refresh_token => 1,
241             uri => { optional => 1 },
242             # secret_type => { optional => 1 },
243             # format => { optional => 1 },
244             });
245              
246             unless (exists $args{uri}) {
247             $args{uri} = $self->{access_token_uri}
248             || Carp::croak "uri not found";
249             }
250              
251             # $args{format} ||= $self->{format};
252              
253             my %params = (
254             grant_type => 'refresh_token',
255             client_id => $self->{id},
256             client_secret => $self->{secret},
257             refresh_token => $args{refresh_token},
258             # format => $args{format},
259             );
260              
261             # $params{secret_type} = $args{secret_type}
262             # if $args{secret_type};
263              
264             my $content = build_content(\%params);
265             my $headers = HTTP::Headers->new;
266             $headers->header("Content-Type" => q{application/x-www-form-urlencoded});
267             $headers->header("Content-Length" => bytes::length($content));
268             my $req = HTTP::Request->new( POST => $args{uri}, $headers, $content );
269              
270             my $res = $self->{agent}->request($req);
271             $self->{last_request} = $req;
272             $self->{last_response} = $res;
273              
274             my ($token, $errmsg);
275             try {
276             $token = $self->{response_parser}->parse($res);
277             } catch {
278             $errmsg = "$_";
279             };
280             return $token || $self->error($errmsg);
281             }
282              
283             =head2 last_request
284              
285             Returns a HTTP::Request object that is used
286             when you obtain or refresh access token last time internally.
287              
288             =head2 last_request
289              
290             Returns a HTTP::Response object that is used
291             when you obtain or refresh access token last time internally.
292              
293             =cut
294              
295             sub last_request { $_[0]->{last_request} }
296             sub last_response { $_[0]->{last_response} }
297              
298             =head1 AUTHOR
299              
300             Lyo Kato, Elyo.kato@gmail.comE
301              
302             =head1 COPYRIGHT AND LICENSE
303              
304             Copyright (C) 2010 by Lyo Kato
305              
306             This library is free software; you can redistribute it and/or modify
307             it under the same terms as Perl itself, either Perl version 5.8.8 or,
308             at your option, any later version of Perl 5 you may have available.
309              
310             =cut
311              
312             1;