File Coverage

blib/lib/Net/Moip/V2.pm
Criterion Covered Total %
statement 40 48 83.3
branch 7 10 70.0
condition 2 6 33.3
subroutine 10 13 76.9
pod 5 6 83.3
total 64 83 77.1


line stmt bran cond sub pod time code
1             package Net::Moip::V2;
2              
3 2     2   435600 use IO::Socket::SSL;
  2         129007  
  2         15  
4 2     2   1240 use MIME::Base64;
  2         1012  
  2         103  
5 2     2   10 use Furl;
  2         7  
  2         41  
6 2     2   762 use JSON::MaybeXS ();
  2         9033  
  2         43  
7 2     2   863 use Moo;
  2         16737  
  2         11  
8 2     2   3048 use URI;
  2         6382  
  2         57  
9              
10 2     2   749 use Net::Moip::V2::Endpoint;
  2         6  
  2         1291  
11              
12             our $VERSION = "0.05";
13              
14             my $JSON = JSON::MaybeXS->new->utf8;
15              
16             has 'ua', is => 'ro', default => sub {
17             Furl->new(
18             agent => "Net-Moip-V2/$VERSION",
19             timeout => 15,
20             max_redirects => 3,
21             # "SSL Wants a read first" I think is suggesting you
22             # haven't read OpenSSL a bedtime story in too long and perhaps
23             # it's feeling neglected and lonely?
24             # see also: https://metacpan.org/pod/IO::Socket::SSL#SNI-Support
25             # https://metacpan.org/pod/Furl#FAQ
26             # https://rt.cpan.org/Public/Bug/Display.html?id=86684
27             ssl_opts => {
28             SSL_verify_mode => SSL_VERIFY_PEER(),
29             # forcing version yields better error message:
30             SSL_version => 'TLSv1_2',
31             },
32             );
33             };
34              
35             has 'token', is => 'ro', required => 1;
36              
37             has 'key', is => 'ro', required => 1;
38              
39             has 'client_id', is => 'ro';
40              
41             has 'client_secret', is => 'ro';
42              
43             has 'access_token', is => 'rw';
44              
45              
46             has 'api_url', (
47             is => 'ro',
48             writer => '_set_api_url',
49             default => 'https://api.moip.com.br/v2'
50             );
51              
52             has 'oauth_url', (
53             is => 'ro',
54             writer => '_set_oauth_url',
55             default => 'https://connect.moip.com.br'
56             );
57              
58              
59             has 'sandbox', (
60             is => 'rw',
61             default => 0,
62             trigger => sub {
63             my ($self, $sandbox) = @_;
64             $self->_set_api_url( $sandbox
65             ? 'https://sandbox.moip.com.br/v2'
66             : 'https://api.moip.com.br/v2'
67             );
68             $self->_set_oauth_url( $sandbox
69             ? 'https://connect-sandbox.moip.com.br'
70             : 'https://connect.moip.com.br'
71             );
72             }
73             );
74              
75             has '_basic_auth_token', is => 'ro', lazy => 1, default => sub {
76             my $self = shift;
77             'Basic '.MIME::Base64::encode_base64( $self->token .':'. $self->key, '');
78             };
79              
80             sub build_authorization_url {
81 1     1 1 962 my ($self, $redirect_uri, $scope) = @_;
82 1 50 33     8 die 'Method signature is: build_authorization_url($redirect_uri, $scope)'
83             unless $redirect_uri && $scope;
84              
85 1         13 my $url = URI->new($self->oauth_url.'/oauth/authorize');
86             $url->query_form(
87             response_type => 'code',
88             client_id => $self->client_id,
89             redirect_uri => $redirect_uri,
90 1         7598 scope => join(',', map { uc } @$scope)
  3         14  
91             );
92 1         241 $url;
93             }
94              
95             sub request_access_token {
96 2     2 1 516 my ($self, $redirect_uri, $code) = @_;
97 2 50 33     17 die 'Method signature is: request_access_token($redirect_uri, $code)'
98             unless $redirect_uri && $code;
99              
100 2         14 my $uri = URI->new($self->oauth_url.'/oauth/token');
101 2         129 $uri->query_form(
102             client_id => $self->client_id,
103             client_secret => $self->client_secret,
104             grant_type => 'authorization_code',
105             redirect_uri => $redirect_uri,
106             code => $code
107             );
108              
109 2         240 my ($url, $body) = $uri->as_string =~ /(.*?)\?(.*)/;
110 2         58 my $res = $self->ua->post($url, [
111             'Content-Type' => 'application/x-www-form-urlencoded',
112             'Authorization' => $self->_basic_auth_token,
113             'Cache-Control' => 'no-cache'
114             ], $body);
115              
116 2 100       1383 return { error => $res->status_line } if $res->code >= 500;
117 1         52 $JSON->decode($res->content);
118             }
119              
120              
121              
122              
123             sub endpoint {
124 8     8 1 1257 my ($self, $path, $params) = @_;
125 8 50       27 die "Syntax: moip->endpoint()" unless $path;
126             Net::Moip::V2::Endpoint->new(
127 56         169 (map { $_ => $self->$_ } qw/ ua api_url token key client_id client_secret access_token /),
128 8 100       20 %{ $params || {} },
  8         256  
129             path => $path,
130             );
131             }
132              
133             sub get {
134 0     0 1   my $self = shift;
135 0           my $endpoint = shift;
136 0           $self->endpoint($endpoint)->get(@_);
137             }
138              
139             sub post {
140 0     0 1   my $self = shift;
141 0           my $endpoint = shift;
142 0           $self->endpoint($endpoint)->post(@_);
143             }
144              
145              
146             sub decode_json {
147 0     0 0   my $self = shift;
148 0           $JSON->decode($_[0]);
149             }
150              
151              
152              
153              
154             1;
155             __END__