File Coverage

blib/lib/Plack/Middleware/Auth/OAuth2/ProtectedResource.pm
Criterion Covered Total %
statement 61 62 98.3
branch 25 34 73.5
condition 2 3 66.6
subroutine 12 12 100.0
pod 1 1 100.0
total 101 112 90.1


line stmt bran cond sub pod time code
1             package Plack::Middleware::Auth::OAuth2::ProtectedResource;
2              
3 2     2   1206 use strict;
  2         4  
  2         47  
4 2     2   7 use warnings;
  2         3  
  2         42  
5              
6 2     2   6 use parent 'Plack::Middleware';
  2         2  
  2         14  
7              
8 2     2   9043 use Plack::Request;
  2         4  
  2         52  
9 2     2   9 use Plack::Util::Accessor qw(realm data_handler error_uri);
  2         3  
  2         8  
10 2     2   96 use Try::Tiny;
  2         3  
  2         123  
11 2     2   11 use Carp ();
  2         3  
  2         42  
12              
13 2     2   10 use OAuth::Lite2::Server::Error;
  2         3  
  2         45  
14 2     2   525 use OAuth::Lite2::ParamMethods;
  2         4  
  2         1157  
15              
16             sub call {
17 30     30 1 4040962 my ($self, $env) = @_;
18 30         47 my $is_legacy = 0;
19              
20             my $error_res = try {
21              
22 30     30   1132 my $req = Plack::Request->new($env);
23              
24             # after draft-v6, signature is not required, so always each connection
25             # should be under TLS.
26             # warn "insecure bearere token request" unless $req->secure;
27              
28 30 50       380 my $parser = OAuth::Lite2::ParamMethods->get_param_parser($req)
29             or OAuth::Lite2::Server::Error::InvalidRequest->throw;
30              
31 30         4572 $is_legacy = $parser->is_legacy($req);
32              
33             # after draft-v6, $params aren't required.
34 30         167 my ($token, $params) = $parser->parse($req);
35 30 50       70 OAuth::Lite2::Server::Error::InvalidRequest->throw unless $token;
36              
37 30         250 my $dh = $self->{data_handler}->new(request => $req);
38              
39 30         82 my $access_token = $dh->get_access_token($token);
40              
41 30 100       666 OAuth::Lite2::Server::Error::InvalidToken->throw
42             unless $access_token;
43              
44 24 50       108 Carp::croak "OAuth::Lite2::Server::DataHandler::get_access_token doesn't return OAuth::Lite2::Model::AccessToken"
45             unless $access_token->isa("OAuth::Lite2::Model::AccessToken");
46              
47 24 100       48 if($is_legacy){
48 12 100       36 OAuth::Lite2::Server::Error::ExpiredTokenLegacy->throw
49             unless ($access_token->created_on + $access_token->expires_in > time());
50             }else{
51 12 100       32 OAuth::Lite2::Server::Error::ExpiredToken->throw
52             unless ($access_token->created_on + $access_token->expires_in > time());
53             }
54              
55 18         144 my $auth_info = $dh->get_auth_info_by_id($access_token->auth_id);
56              
57 18 50       136 OAuth::Lite2::Server::Error::InvalidToken->throw
58             unless $auth_info;
59              
60 18 50       74 Carp::croak "OAuth::Lite2::Server::DataHandler::get_auth_info_by_id doesn't return OAuth::Lite2::Model::AuthInfo"
61             unless $auth_info->isa("OAuth::Lite2::Model::AuthInfo");
62              
63 18 100       50 $dh->validate_client_by_id($auth_info->client_id)
64             or OAuth::Lite2::Server::Error::InvalidToken->throw;
65              
66 12 100       109 $dh->validate_user_by_id($auth_info->user_id)
67             or OAuth::Lite2::Server::Error::InvalidToken->throw;
68              
69 6         45 $env->{REMOTE_USER} = $auth_info->user_id;
70 6         28 $env->{X_OAUTH_CLIENT} = $auth_info->client_id;
71 6 50       31 $env->{X_OAUTH_SCOPE} = $auth_info->scope if $auth_info->scope;
72              
73 6         71 return;
74              
75             } catch {
76              
77 24 50   24   446 if ($_->isa("OAuth::Lite2::Server::Error")) {
78              
79 24         33 my @params;
80             push(@params, sprintf(q{realm="%s"}, $self->{realm}))
81 24 50       170 if $self->{realm};
82 24         75 push(@params, sprintf(q{error="%s"}, $_->type));
83 24 100       68 push(@params, sprintf(q{error_description="%s"}, $_->description))
84             if $_->description;
85             push(@params, sprintf(q{error_uri="%s"}, $self->{error_uri}))
86 24 50       58 if $self->{error_uri};
87             # push(@params, sprintf(q{scope='%s'}, $_->scope))
88             # if $_->scope;
89              
90 24 100       50 if($is_legacy){
91 12         30 return [ $_->code, [ "WWW-Authenticate" =>
92             "OAuth " . join(', ', @params) ], [ ] ];
93             }else{
94 12         33 return [ $_->code, [ "WWW-Authenticate" =>
95             "Bearer " . join(', ', @params) ], [ ] ];
96             }
97              
98             } else {
99              
100             # rethrow
101 0         0 die $_;
102              
103             }
104              
105 30         285 };
106              
107 30   66     743 return $error_res || $self->app->($env);
108             }
109              
110             =head1 NAME
111              
112             Plack::Middleware::Auth::OAuth2::ProtectedResource - middleware for OAuth 2.0 Protected Resource endpoint
113              
114             =head1 SYNOPSIS
115              
116             my $app = sub {...};
117             builder {
118             enable "Plack::Middleware::Auth::OAuth2::ProtectedResource",
119             data_handler => "YourApp::DataHandler",
120             error_uri => q{http://example.org/error/description};
121             enable "Plack::Middleware::JSONP";
122             enable "Plack::Middleware::ContentLength";
123             $app;
124             };
125              
126             # and on your controller
127             $plack_request->env->{REMOTE_USER};
128             $plack_request->env->{X_OAUTH_CLIENT_ID};
129             $plack_request->env->{X_OAUTH_SCOPE};
130              
131             =head1 DESCRIPTION
132              
133             middleware for OAuth 2.0 Protected Resource endpoint
134              
135             =head1 METHODS
136              
137             =head2 call( $env )
138              
139             =head1 ENV VALUES
140              
141             After successful verifying authorization within middleware layer,
142             Following 3 type of values are set in env.
143              
144             =over 4
145              
146             =item REMOTE_USER
147              
148             Identifier of user who grant the client to access the user's protected
149             resource that is stored on service provider.
150              
151             =item X_OAUTH_CLIENT
152              
153             Identifier of the client that accesses to user's protected resource
154             on beharf of the user.
155              
156             =item X_OAUTH_SCOPE
157              
158             Scope parameter that represents what kind of resources that
159             the user grant client to access.
160              
161             =back
162              
163             =head1 AUTHOR
164              
165             Lyo Kato, Elyo.kato@gmail.comE
166              
167             =head1 COPYRIGHT AND LICENSE
168              
169             Copyright (C) 2010 by Lyo Kato
170              
171             This library is free software; you can redistribute it and/or modify
172             it under the same terms as Perl itself, either Perl version 5.8.8 or,
173             at your option, any later version of Perl 5 you may have available.
174              
175             =cut
176              
177             1;