File Coverage

blib/lib/WebService/Xero/Agent/PrivateApplication.pm
Criterion Covered Total %
statement 28 28 100.0
branch 5 8 62.5
condition 2 5 40.0
subroutine 8 8 100.0
pod 1 1 100.0
total 44 50 88.0


line stmt bran cond sub pod time code
1             package WebService::Xero::Agent::PrivateApplication;
2              
3              
4 3     3   59661 use 5.006;
  3         8  
5 3     3   14 use strict;
  3         2  
  3         54  
6 3     3   11 use warnings;
  3         4  
  3         66  
7 3     3   10 use Carp;
  3         4  
  3         181  
8 3     3   20 use base ('WebService::Xero::Agent');
  3         5  
  3         607  
9 3     3   16 use Crypt::OpenSSL::RSA;
  3         4  
  3         846  
10              
11             =head1 NAME
12              
13             WebService::Xero::Agent::PrivateApplication - Connects to a Xero Private Application API
14              
15             =head1 VERSION
16              
17             Version 0.11
18              
19             =cut
20              
21             our $VERSION = '0.11';
22              
23              
24             =head1 SYNOPSIS
25              
26              
27              
28             Xero API Applications have a limit of 1,000/day and 60/minute request per organisation.
29              
30              
31             use WebService::Xero::Agent::PrivateApplication;
32              
33             my $xero = WebService::Xero::Agent::PrivateApplication->new( CONSUMER_KEY => 'YOUR_OAUTH_CONSUMER_KEY',
34             CONSUMER_SECRET => 'YOUR_OAUTH_CONSUMER_SECRET',
35             #KEYFILE => "/path/to/privatekey.pem"
36             PRIVATE_KEY => '-----BEGIN RSA PRIVATE KEY-----
37             MIICXQIBAAKBgQCu2PMZrIHPiFmZujY0s7dz8atk1TofVSTVqhWg5h/fn8tYbwgg
38             koTqpAigxAUCAZ63prtj9LQhIqe3TRNtCDMsxxriyN3O/cxkVD52LwCKAgEoaNmr
39             Vvt97UgxglKyQ6taNO/c6V8FCKvPC945GKd/b7BoIYZcJsrpo+E+8Ek9IQIDAQAB
40             AoGAbbPC+0XIAI0dIp256uEjZkSn89Dw8b27Ka/YeCZKs0UQEYFAiSdE6+9VVoEG
41             X1bi3XloM3PSHMQglJpwaMVvTUwZfdxCFIM0mpgXtdK8Xuh3QTZpgH9S0a2HoXrB
42             uXFEqvwMcT43ig2FCfVQU86RQZAxrb1YfyFSauEayrVtbT0CQQDe8HEXSkbxjUwj
43             I2TdCDA7yOW7rWQPAk3REZ33SqBUdo45qofpkH7vWSx+W6q65uyRYfF4N1JKmW8V
44             OhMxBpFPAkEAyMbGZ2VX6gW37g03OGSoUG6mvXe+CKRqv8hV4UoGeQIUYJTFlt2O
45             ukD2jKyHqWIdU/3tM3iP1b8CY6JyVyhOjwJBAJ/NmDMKohnJn9bcKxOpJ/HiypIh
46             8sQzcZY4W5QEYTLKHJ7HV08brXFh6VvV12bL2q1HmLAEb69bll2P2Gve+k8CQQC3
47             1Pi4lxwl1FKSjlsvMUrDSm01Mbw34YM0UlP/0W2XwoWx4MYB2p7ifrTAHQCh4IoF
48             64wSAqOADEI9w/F5SBiVAkBJVt3jNObeieMfxVU/NOtajXX51sDUj3XCIWPPui8i
49             IKzzVn7G0kH+/TqtTPdizrDJkg/rsnrTpvHi8eeMZlAy
50             -----END RSA PRIVATE KEY-----',
51             );
52             my $contact_struct = $xero->do_xero_api_call( 'https://api.xero.com/api.xro/2.0/Contacts' );
53              
54              
55             =head2 XERO PRIVATE APPLICATION API CONFIGURATION
56              
57             Private applications use a 2-legged authorisation process. When you register your application, you will select the organisation that is authorised to your application. This cannot be changed afterwards, although you can register another private application if you have multiple organisations.
58              
59             Private applications require a private RSA keypair which is used to sign each request to the API. You can generate this keypair on Mac OSX or Linux with OpenSSL. For example:
60              
61             openssl genrsa -out privatekey.pem 1024
62             openssl req -newkey rsa:1024 -x509 -key privatekey.pem -out publickey.cer -days 365
63             openssl pkcs12 -export -out public_privatekey.pfx -inkey privatekey.pem -in publickey.cer
64              
65             You need to upload this public_privatekey.pfx file to your private application in http://api.xero.com.
66              
67             https://app.xero.com/Application
68              
69             =head1 METHODS
70              
71             =cut
72              
73             =head2 as_text()
74              
75             returns 'WebService::Xero::Agent::PrivateApplication'
76              
77             =cut
78              
79             sub as_text
80             {
81 1     1 1 2 my ( $self ) = @_;
82 1         2 my $txt = 'WebService::Xero::Agent::PrivateApplication';
83 1         7 $txt .= "\nSTATUS = " . $self->get_status();
84              
85             }
86              
87              
88             sub _validate_agent
89             {
90 2     2   3 my ( $self ) = @_;
91 2 100       18 return $self->_error('CONSUMER_KEY not valid') unless ( $self->{CONSUMER_KEY} =~ /.{20,}/m ); ## min 20 chars - 30 is typical
92 1 50       11 return $self->_error('CONSUMER_SECRET not valid') unless ( $self->{CONSUMER_SECRET} =~ /.{20,}/m ); ## min 20 chars - 30 is typical
93             # KEYFILE
94             # PRIVATE_KEY
95 1 50 33     10 if ( not defined $self->{pko} and $self->{PRIVATE_KEY} =~ /BEGIN RSA PRIVATE KEY/smg )
96             {
97 1   50     136 $self->{pko} = Crypt::OpenSSL::RSA->new_private_key( $self->{PRIVATE_KEY} ) || return $self->_error('PRIVATE_KEY not valid');
98             ## TODO - sort out catching error - currently crashes if fails not return undef
99             ## could try to catch the error .. eg. RSA.xs:178: OpenSSL error: too long
100             ## FROM Crypt::OpenSSL::RSA docs
101             # NOTE: Many of the methods in this package can croak, so use eval, or
102             # Error.pm's try/catch mechanism to capture errors. Also, while some
103             # methods from earlier versions of this package return true on success,
104             # this (never documented) behavior is no longer the case.
105             }
106 1         2 $self->{_status} = 'RSA KEY SET';
107 1 50       3 return $self->_error('PRIVATE_KEY unable to create a valid RSA:' . ref($self->{pko}) ) unless ( ref($self->{pko}) eq 'Crypt::OpenSSL::RSA' );
108 1         7 return $self;
109             }
110              
111              
112             =head2 do_xero_api_call()
113              
114             INPUT PARAMETERS AS A LIST ( NOT NAMED )
115              
116             * $uri (required) - the API endpoint URI ( eg 'https://api.xero.com/api.xro/2.0/Contacts/')
117             * $method (optional) - 'POST' or 'GET' .. PUT not currently supported
118             * $xml (optional) - the payload for POST updates as XML
119              
120             RETURNS
121              
122             The response is requested in JSON format which is then processed into a Perl structure that
123             is returned to the caller.
124              
125              
126             =cut
127              
128              
129             =head1 AUTHOR
130              
131             Peter Scott, C<< >>
132              
133             =head1 BUGS
134              
135             Please report any bugs or feature requests to C, or through
136             the web interface at L. I will be notified, and then you'll
137             automatically be notified of progress on your bug as I make changes.
138              
139              
140              
141              
142             =head1 SUPPORT
143              
144             You can find documentation for this module with the perldoc command.
145              
146             perldoc WebService::Xero
147              
148              
149             You can also look for information at:
150              
151             =over 4
152              
153             =item * RT: CPAN's request tracker (report bugs here)
154              
155             L
156              
157             =item * AnnoCPAN: Annotated CPAN documentation
158              
159             L
160              
161             =item * CPAN Ratings
162              
163             L
164              
165             =item * Search CPAN
166              
167             L
168              
169             =back
170              
171              
172             =head1 ACKNOWLEDGEMENTS
173              
174              
175             =head1 LICENSE AND COPYRIGHT
176              
177             Copyright 2016 Peter Scott.
178              
179             This program is free software; you can redistribute it and/or modify it
180             under the terms of the the Artistic License (2.0). You may obtain a
181             copy of the full license at:
182              
183             L
184              
185             Any use, modification, and distribution of the Standard or Modified
186             Versions is governed by this Artistic License. By using, modifying or
187             distributing the Package, you accept this license. Do not use, modify,
188             or distribute the Package, if you do not accept this license.
189              
190             If your Modified Version has been derived from a Modified Version made
191             by someone other than you, you are nevertheless required to ensure that
192             your Modified Version complies with the requirements of this license.
193              
194             This license does not grant you the right to use any trademark, service
195             mark, tradename, or logo of the Copyright Holder.
196              
197             This license includes the non-exclusive, worldwide, free-of-charge
198             patent license to make, have made, use, offer to sell, sell, import and
199             otherwise transfer the Package with respect to any patent claims
200             licensable by the Copyright Holder that are necessarily infringed by the
201             Package. If you institute patent litigation (including a cross-claim or
202             counterclaim) against any party alleging that the Package constitutes
203             direct or contributory patent infringement, then this Artistic License
204             to you shall terminate on the date that such litigation is filed.
205              
206             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
207             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
208             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
209             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
210             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
211             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
212             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
213             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
214              
215              
216             =cut
217              
218             1; # End of WebService::Xero