File Coverage

blib/lib/CPAN/Mini/Inject/Remote.pm
Criterion Covered Total %
statement 30 94 31.9
branch 0 32 0.0
condition 0 6 0.0
subroutine 10 17 58.8
pod 4 4 100.0
total 44 153 28.7


line stmt bran cond sub pod time code
1             # -*- indent-tabs-mode: nil -*-
2              
3             package CPAN::Mini::Inject::Remote;
4              
5 1     1   17816 use strict;
  1         2  
  1         36  
6 1     1   4 use warnings;
  1         2  
  1         28  
7 1         67 use Params::Validate qw/validate
8 1     1   664 SCALAR/;
  1         10211  
9 1     1   8 use File::Spec;
  1         1  
  1         19  
10 1     1   472 use YAML::Any qw/LoadFile/;
  1         1322  
  1         5  
11 1     1   11288 use LWP::UserAgent;
  1         43197  
  1         33  
12 1     1   9 use HTTP::Request;
  1         2  
  1         18  
13 1     1   611 use HTTP::Request::Common;
  1         1983  
  1         78  
14 1     1   689 use Data::Dumper;
  1         7278  
  1         107  
15 1     1   11 use Carp;
  1         2  
  1         1039  
16              
17             =head1 NAME
18              
19             CPAN::Mini::Inject::Remote - Inject into your CPAN mirror from over here
20              
21             =head1 VERSION
22              
23             Version 0.04
24              
25             =cut
26              
27             our $VERSION = '0.04';
28              
29              
30             =head1 SYNOPSIS
31              
32             describe the module, working code example
33              
34             =cut
35              
36             =head1 DESCRIPTION
37              
38             =cut
39              
40             =head1 FUNCTIONS
41              
42             =cut
43              
44             =head2 new
45              
46             Class constructor
47              
48             =cut
49              
50             sub new {
51 0     0 1   my $proto = shift;
52 0   0       my $class = ref($proto) || $proto;
53 0           my $self = {};
54 0           bless ($self, $class);
55 0           $self->_initialize(@_);
56 0           return $self;
57             } # end of method new
58              
59             ######
60             #
61             # _initialize
62             #
63             # Class properties initator
64             #
65             ###
66              
67             sub _initialize {
68 0     0     my $self = shift;
69 0           my %args = validate(@_,
70             {
71             config_file => {
72             type => SCALAR,
73             optional => 1,
74             },
75             remote_server => {
76             type => SCALAR,
77             optional => 1,
78             },
79             }
80             );
81              
82 0 0         if (not $args{config_file})
    0          
83             {
84 0           $args{config_file} = $self->_find_config();
85             }
86             elsif (not -r $args{config_file})
87             {
88 0           croak "Supplied config file is not readable";
89             }
90              
91 0           my $config = LoadFile($args{config_file});
92              
93 0 0         if (not $args{remote_server})
94             {
95 0           $self->{remote_server} = $config->{remote_server};
96             }
97             else
98             {
99 0           $self->{remote_server} = $args{remote_server};
100             }
101              
102             # get rid of any trailing slash as it will break things
103 0           $self->{remote_server} =~ s/\/$//;
104              
105 0           my @ssl_opt = qw/SSL_ca_file SSL_cert_file SSL_key_file verify_hostnames/;
106 0           for (@ssl_opt)
107             {
108 0 0         next unless my $c = $config->{$_};
109 0 0         if ($c =~ s/^\s*#!//)
    0          
110             {
111 0           my $output = eval { `$c` };
  0            
112 0 0         $self->{ssl_opts}{$_} = $output if $? == 0;
113             }
114             elsif ($c =~ /^~/)
115             {
116 0           $self->{ssl_opts}{$_} = (glob $c)[0];
117             }
118             else
119             {
120 0           $self->{ssl_opts}{$_} = $c;
121             }
122             }
123              
124             } # end of method _initialize
125              
126              
127             ######
128             #
129             # _find_config
130             #
131             # Attempts to find the config from a number of locations
132             #
133             # locations are:-
134             # argument passed in
135             # specified in $ENV{MCPANI_REMOTE_CONFIG},
136             # $ENV{HOME}/.mcpani_remote
137             # /usr/local/etc/mcpani_remote
138             # /etc/mcpani_remote
139             #
140             ###
141              
142             sub _find_config {
143 0     0     my $self = shift;
144 0           my %args = validate(@_,
145             {
146              
147             }
148             );
149              
150 0 0         my @config_locations = (
151             $ENV{MCPANI_REMOTE_CONFIG},
152             (
153             defined $ENV{HOME}
154             ? File::Spec->catfile( $ENV{HOME}, qw/.mcpani_remote/)
155             : ()
156             ),
157             File::Spec->catfile(
158             File::Spec->rootdir(),
159             qw/usr local etc mcpani_remote/
160             ),
161             File::Spec->catfile(
162             File::Spec->rootdir(),
163             qw/etc mcpani_remote/
164             ),
165             );
166              
167 0           for my $file ( @config_locations) {
168 0 0         next unless defined $file;
169 0 0         next unless -r $file;
170              
171 0           return $file;
172             }
173              
174 0           croak "No config file was found that existed";
175             } # end of method _load_config
176              
177              
178             ######
179             #
180             # _useragent
181             #
182             # loads up the user agent if one exists
183             #
184             ###
185              
186             sub _useragent {
187 0     0     my $self = shift;
188 0           my %args = validate(@_,
189             {
190              
191             }
192             );
193              
194 0 0         if (not $self->{useragent})
195             {
196 0           $self->{useragent} = LWP::UserAgent->new;
197              
198 0 0 0       if ($self->{remote_server} =~ /^https:/ && $self->{ssl_opts})
199             {
200 0           $self->{useragent}->ssl_opts(%{$self->{ssl_opts}});
  0            
201             }
202             }
203              
204 0           return $self->{useragent};
205             } # end of method _useragent
206              
207              
208             =head2 add
209              
210             Calls the add function on the remote server
211              
212             =cut
213              
214             sub add {
215 0     0 1   my $self = shift;
216 0           my %args = validate(@_,
217             {
218             module_name => {
219             type => SCALAR,
220             },
221             author_id => {
222             type => SCALAR,
223             },
224             version => {
225             type => SCALAR,
226             },
227             file_name => {
228             type => SCALAR,
229             },
230             }
231             );
232              
233 0 0         if (not -r $args{file_name})
234             {
235 0           croak "Module file is not readable";
236             }
237              
238              
239 0           my $ua = $self->_useragent();
240              
241 0           my $response = $ua->request(POST $self->{remote_server}.'/add',
242             Content_Type => 'form-data',
243             Content => [
244             module => $args{module_name},
245             authorid => $args{author_id},
246             version => $args{version},
247             file => [$args{file_name}],
248             ]
249             );
250              
251 0 0         if (not $response->is_success())
252             {
253             #croak 'Add failed. ' . Dumper($response);
254 0           warn 'Add failed. ' . $response->status_line . "\n";
255             }
256              
257 0           return $response;
258             } # end of method add
259              
260              
261             =head2 update
262              
263             Calls the update function on the remote server
264              
265             =cut
266              
267             sub update {
268 0     0 1   my $self = shift;
269 0           my %args = validate(@_,
270             {
271              
272             }
273             );
274              
275 0           my $ua = $self->_useragent();
276              
277 0           my $response = $ua->request(POST $self->{remote_server}.'/update');
278              
279 0 0         if (not $response->is_success())
280             {
281             #croak 'Update failed. ' . Dumper($response);
282 0           warn 'Update failed. ' . $response->status_line . "\n";
283             }
284              
285 0           return $response;
286             } # end of method update
287              
288              
289             =head2 inject
290              
291             Calls the inject function on the remote server
292              
293             =cut
294              
295             sub inject {
296 0     0 1   my $self = shift;
297 0           my %args = validate(@_,
298             {
299              
300             }
301             );
302            
303 0           my $ua = $self->_useragent();
304              
305 0           my $response = $ua->request(POST $self->{remote_server}.'/inject');
306              
307 0 0         if (not $response->is_success())
308             {
309             #croak 'Inject failed. ' . Dumper($response);
310 0           warn 'Inject failed. ' . $response->status_line . "\n";
311             }
312              
313 0           return $response;
314             } # end of method inject
315              
316              
317             =head1 CONFIGURATION FILE
318              
319             the sample configuration file ~/.mcpani_remote over SSL:
320              
321             remote_server: https://mcpani.your.org
322             SSL_cert_file: ~/.certs/your.crt
323             SSL_key_file: ~/.certs/your.key
324             SSL_ca_file: #!perl -MCACertOrg::CA -e 'print CACertOrg::CA::SSL_ca_file()'
325              
326              
327             you want to export your.crt and your.key from your.p12:
328              
329             $ openssl pkcs12 -nokeys -clcerts -in your.p12 -out your.crt
330             Enter Import Password: ******
331             MAC verified OK
332             $ openssl pkcs12 -nocerts -nodes -in your.p12 -out your.key
333             Enter Import Password: ******
334             MAC verified OK
335              
336              
337             =head1 AUTHOR
338              
339             Christopher Mckay, C<< >>
340              
341             =head1 BUGS
342              
343             Please report any bugs or feature requests to C, or through
344             the web interface at L. I will be notified, and then you'll
345             automatically be notified of progress on your bug as I make changes.
346              
347             =head1 TODO
348              
349             Fix up error messages, they currently contain $response dumps
350              
351             =head1 SUPPORT
352              
353             You can find documentation for this module with the perldoc command.
354              
355             perldoc CPAN::Mini::Inject::Remote
356              
357              
358             You can also look for information at:
359              
360             =over 4
361              
362             =item * RT: CPAN's request tracker
363              
364             L
365              
366             =item * AnnoCPAN: Annotated CPAN documentation
367              
368             L
369              
370             =item * CPAN Ratings
371              
372             L
373              
374             =item * Search CPAN
375              
376             L
377              
378             =back
379              
380              
381             =head1 ACKNOWLEDGEMENTS
382              
383              
384             =head1 COPYRIGHT & LICENSE
385              
386             Copyright 2009 Christopher Mckay.
387              
388             This program is free software; you can redistribute it and/or modify it
389             under the terms of either: the GNU General Public License as published
390             by the Free Software Foundation; or the Artistic License.
391              
392             See http://dev.perl.org/licenses/ for more information.
393              
394              
395             =cut
396              
397             1; # End of CPAN::Mini::Inject::Remote