File Coverage

blib/lib/OpenID/PayPal/LIPP.pm
Criterion Covered Total %
statement 93 111 83.7
branch 12 22 54.5
condition n/a
subroutine 23 24 95.8
pod 4 4 100.0
total 132 161 81.9


line stmt bran cond sub pod time code
1             package OpenID::PayPal::LIPP;
2              
3 3     3   31143 use strict;
  3         3  
  3         64  
4 3     3   49 use 5.008_005;
  3         7  
5 3     3   9 use warnings;
  3         2  
  3         111  
6             our $VERSION = '0.02';
7              
8 3     3   14 use Carp;
  3         2  
  3         150  
9 3     3   1120 use JSON;
  3         20419  
  3         10  
10 3     3   1719 use URI;
  3         9532  
  3         65  
11 3     3   1134 use URI::QueryParam;
  3         1609  
  3         67  
12 3     3   1249 use HTTP::Request::Common;
  3         37954  
  3         170  
13 3     3   1101 use Convert::Base64;
  3         2722  
  3         131  
14 3     3   1781 use LWP::UserAgent;
  3         44709  
  3         71  
15 3     3   1364 use Moo;
  3         27787  
  3         12  
16 3     3   4353 use namespace::clean;
  3         23945  
  3         10  
17              
18             has client_id => ( is => 'ro', required => 1 );
19             has client_secret => ( is => 'ro', required => 1 );
20             has account => ( is => 'ro', required => 1 );
21             has redirect_uri => ( is => 'ro', required => 1 );
22             has mode => ( is => 'ro', default => sub { 'sandbox' }, isa => sub { die 'Must be live or sandbox' unless $_[0] =~ m/^live$|^sandbox$/; } );
23             has scope => ( is => 'ro', default => sub { [ qw(openid email) ]; } );
24             has paypal_openid_endpoint => ( is => 'lazy' );
25             has paypal_auth_token_service_endpoint => ( is => 'lazy' );
26             has paypal_auth_user_profile_end_point => ( is => 'lazy' );
27             has logger => ( is => 'ro', default => sub{ sub{}; }, isa => sub { die 'Logger has to be a function' unless ref $_[0] eq 'CODE' } );
28              
29             sub _log {
30 3     3   15 my $self = shift;
31 3 50       11 if( defined $self->logger ) {
32 3         9 $self->logger->( @_ );
33             }
34             }
35              
36             sub _build_paypal_openid_endpoint {
37 2     2   599 my $self = shift;
38              
39 2 50       27 if( $self->mode eq 'live' ) {
40 0         0 return 'https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize';
41             } else {
42 2         15 return 'https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize';
43             }
44             }
45              
46             sub _build_paypal_auth_token_service_endpoint {
47 1     1   309 my $self = shift;
48              
49 1 50       5 if( $self->mode eq 'live' ) {
50 0         0 return 'https://api.paypal.com/v1/identity/openidconnect/tokenservice';
51             } else {
52 1         6 return 'https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice';
53             }
54             }
55              
56             sub _build_paypal_auth_user_profile_end_point {
57 1     1   309 my $self = shift;
58              
59 1 50       4 if( $self->mode eq 'live' ) {
60 0         0 return 'https://api.paypal.com/v1/identity/openidconnect/userinfo';
61             } else {
62 1         4 return 'https://api.sandbox.paypal.com/v1/identity/openidconnect/userinfo';
63             }
64             }
65              
66             sub login_url {
67 3     3 1 381 my $self = shift;
68 3         3 my $state = shift;
69              
70 3         26 my $login_url = URI->new( $self->paypal_openid_endpoint );
71 3         12947 $login_url->query_param( client_id => $self->client_id );
72 3         680 $login_url->query_param( response_type => 'code' );
73 3         327 $login_url->query_param( scope => join( ' ', @{$self->scope}) );
  3         14  
74 3         306 $login_url->query_param( redirect_uri => $self->redirect_uri );
75 3 100       429 $login_url->query_param( state => $state )
76             if defined $state;
77              
78 3         201 $self->_log( "Login url is : ".$login_url->as_string );
79              
80 3         10 return $login_url->as_string;
81             }
82              
83             sub exchange_code {
84 1     1 1 360 my ($self, $code) = @_;
85              
86 1         5 my $post_data = {
87             grant_type => 'authorization_code',
88             code => $code,
89             redirect_uri => $self->redirect_uri,
90             };
91              
92 1         8 my $encoded_header = encode_base64($self->client_id . ":" . $self->client_secret );
93 1         17 my $data_json = $self->_post(
94             $self->paypal_auth_token_service_endpoint,
95             $post_data,
96             { Authorization => "Basic $encoded_header" }
97             );
98 1         23 my $data_hash = decode_json($data_json);
99              
100             return {
101             access_token => $data_hash->{access_token},
102             refresh_token => $data_hash->{refresh_token},
103 1         5 };
104             }
105              
106             sub refresh_token {
107 0     0 1 0 my ($self, $refresh_token) = @_;
108              
109             my $post_data = {
110             grant_type => 'refresh_token',
111             refresh_token => $refresh_token,
112 0         0 scope => join( ' ', @{$self->scope}),
  0         0  
113             };
114              
115 0         0 my $encoded_header = encode_base64($self->client_id . ":" . $self->client_secret );
116 0         0 my $data_json = $self->_post(
117             $self->paypal_auth_token_service_endpoint,
118             $post_data,
119             { Authorization => "Basic $encoded_header" }
120             );
121 0         0 my $data_hash = decode_json($data_json);
122              
123             return {
124             access_token => $data_hash->{access_token},
125 0         0 refresh_token => $refresh_token,
126             };
127             }
128              
129             sub get_user_details {
130 1     1 1 549 my ( $self, %params ) = @_;
131              
132 1         2 my $token = undef;
133 1 50       4 if( exists $params{authorization_code} ) {
    50          
134 0         0 $token = $self->exchange_code( $params{authorization_code} )->{access_token};
135             } elsif( exists $params{access_token} ) {
136 1         1 $token = $params{access_token};
137             } else {
138 0         0 croak "Provide authorization code or access token";
139             }
140              
141 1         3 my $post_params = {
142             schema => "openid",
143             access_token => $token,
144             };
145              
146 1         3 my $customer_data_json = $self->_get( $self->paypal_auth_user_profile_end_point, $post_params );
147 1         14 my $customer_data_hash = decode_json( $customer_data_json );
148              
149 1         2 return $customer_data_hash;
150             }
151              
152             sub _user_agent {
153 2     2   10 return LWP::UserAgent->new();
154             }
155              
156             sub _post
157             {
158 1     1   2 my ( $self, $url, $post, $headers ) = @_;
159              
160 1         6 my $request = HTTP::Request::Common::POST( $url, Content => [ %$post ]);
161 1 50       436 if( defined $headers ) {
162 1         5 while( my ($header, $value) = each %$headers ) {
163 1         3 $request->header( $header => $value );
164             }
165             }
166              
167 1         29 my $response = $self->_user_agent->request( $request );
168              
169 1 50       2080 if ( $response->is_error )
170             {
171 0         0 $self->_log( "Post request failed, url : " . $url . " , parameters: " );
172 0         0 while( my ($key, $value) = each %$post ) {
173 0         0 $self->_log( "$key => $value" );
174             }
175 0         0 croak "Error calling PayPal, PayPal Response : " . $response->content;
176             }
177              
178 1         17 return $response->content;
179             }
180              
181              
182             sub _get
183             {
184 1     1   2 my ( $self, $url, $params ) = @_;
185              
186 1         3 my $uri = URI->new( $url );
187              
188 1 50       45 if( defined $params ) {
189 1         5 while( my ($param, $value) = each %$params ) {
190 2         70 $uri->query_param( $param => $value );
191             }
192             }
193              
194 1         88 my $request = HTTP::Request->new( 'GET', $uri->as_string );
195              
196 1         69 my $response = $self->_user_agent->request( $request );
197 1 50       228 if ( $response->is_error )
198             {
199 0         0 $self->_log( "Get request failed, url : " . $uri->as_string );
200 0         0 croak "Error calling PayPal, PayPal Response : " . $response->content;
201             }
202              
203 1         8 return $response->content;
204             }
205              
206 3     3   3773 no Moo;
  3         4  
  3         17  
207             1;
208             __END__