File Coverage

blib/lib/IO/EPP/RRPProxy.pm
Criterion Covered Total %
statement 12 141 8.5
branch 0 80 0.0
condition 0 31 0.0
subroutine 4 16 25.0
pod 11 11 100.0
total 27 279 9.6


line stmt bran cond sub pod time code
1             package IO::EPP::RRPProxy;
2              
3             =encoding utf8
4              
5             =head1 NAME
6              
7             IO::EPP::RRPProxy
8              
9             =head1 SYNOPSIS
10              
11             use IO::EPP::RRPProxy;
12              
13             # Parameters for IO::Socket::SSL
14             my %sock_params = (
15             PeerHost => 'epp.rrpproxy.net',
16             PeerPort => 700,
17             Timeout => 30,
18             );
19              
20             # Create object, get greeting and call login()
21             my $conn = IO::EPP::RRPProxy->new( {
22             user => 'login',
23             pass => 'xxxxx',
24             sock_params => \%sock_params,
25             test_mode => 0, # real connect
26             } );
27              
28             # Check domain
29             my ( $answ, $code, $msg ) = $conn->check_domains( { domains => [ 'info.name', 'name.info' ] } );
30              
31             # Call logout() and destroy object
32             undef $conn;
33              
34             =head1 DESCRIPTION
35              
36             Work with RRPProxy EPP API
37              
38             Features:
39              
40             =over 3
41              
42             item *
43              
44             has its own epp extension for specifying additional parameters;
45              
46             =item *
47              
48             has additional functions.
49              
50             =back
51              
52             Examples: L, L.
53              
54             =cut
55              
56 1     1   2283 use IO::EPP::Base;
  1         4  
  1         40  
57 1     1   7 use parent qw( IO::EPP::Base );
  1         2  
  1         8  
58              
59 1     1   64 use strict;
  1         2  
  1         19  
60 1     1   4 use warnings;
  1         2  
  1         1974  
61              
62             my $ks_ext = 'xmlns:keysys="http://www.key-systems.net/epp/keysys-1.0"';
63              
64             sub make_request {
65 0     0 1   my ( $action, $params ) = @_;
66              
67 0           my ( $self, $code, $msg, $answ );
68              
69 0 0         unless ( $params->{conn} ) {
70 0   0       $params->{sock_params}{PeerHost} ||= 'epp.rrpproxy.net';
71 0   0       $params->{sock_params}{PeerPort} ||= 700;
72              
73 0           ( $self, $code, $msg ) = __PACKAGE__->new( $params );
74              
75 0 0 0       unless ( $code and $code == 1000 ) {
76 0           goto END_MR;
77             }
78             }
79             else {
80 0           $self = $params->{conn};
81             }
82              
83              
84 0           $self->{critical_error} = '';
85              
86 0 0         if ( $self->can( $action ) ) {
87 0           ( $answ, $code, $msg ) = $self->$action( $params );
88             }
89             else {
90 0           $msg = "undefined command <$action>, request cancelled";
91 0           $code = 0;
92             }
93              
94              
95             END_MR:
96              
97 0 0         $msg .= '; ' . $self->{critical_error} if $self->{critical_error};
98              
99 0           my $full_answ = "code: $code\nmsg: $msg";
100              
101 0 0 0       $answ = {} unless $answ && ref $answ;
102              
103 0           $answ->{code} = $code;
104 0           $answ->{msg} = $msg;
105              
106 0 0         return wantarray ? ( $answ, $full_answ, $self ) : $answ;
107             }
108              
109             =head1 METHODS
110              
111             Further overlap functions where the provider has features
112              
113             =head2 login
114              
115             Ext params for login,
116              
117             INPUT: new password for change
118              
119             =cut
120              
121             sub login {
122 0     0 1   my ( $self, $pw ) = @_;
123              
124 0           my $svcs = '
125             urn:ietf:params:xml:ns:contact-1.0
126             urn:ietf:params:xml:ns:domain-1.0
127             urn:ietf:params:xml:ns:host-1.0';
128              
129 0           my $extension = '
130             http://www.key-systems.net/epp/keysys-1.0
131             http://www.key-systems.net/epp/query-1.0
132             urn:ietf:params:xml:ns:secDNS-1.1
133             urn:ietf:params:xml:ns:rgp-1.0
134             urn:ietf:params:xml:ns:launchphase-1.0
135             urn:ietf:params:xml:ns:launch-1.0
136             urn:ietf:params:xml:ns:idn-1.0
137             urn:ietf:params:xml:ns:fee-0.7';
138              
139 0           return $self->SUPER::login( $pw, $svcs, $extension );
140             }
141              
142             =head2 create_contact
143              
144             Contact id is generated automatically by the reseller
145              
146             =cut
147              
148             sub create_contact {
149 0     0 1   my ( $self, $params ) = @_;
150              
151 0           $params->{id} = 'AUTO';
152              
153 0 0         $params->{company} =~ s/&/&/g if $params->{company};
154 0 0         $params->{addr} =~ s/&/&/g if $params->{addr};
155              
156             =pod
157              
158             For german characters changes html codes to double symbols:
159             ß = ss
160             ä = ae
161             ü = ue
162             ö = oe
163              
164             =cut
165 0           foreach my $f ( 'name', 'company', 'addr', 'city', 'state' ) {
166 0 0         next unless $params->{$f};
167              
168 0           $params->{$f} =~ s/Ä/Ae/g;
169 0           $params->{$f} =~ s/Ö/Oe/g;
170 0           $params->{$f} =~ s/Ü/Ue/g;
171 0           $params->{$f} =~ s/ß/ss/g;
172 0           $params->{$f} =~ s/ä/ae/g;
173 0           $params->{$f} =~ s/ö/oe/g;
174 0           $params->{$f} =~ s/ü/ue/g;
175             }
176              
177             # the extension fields must be arranged in alphabetical order
178              
179 0           my $fields = "\n 1\n";
180              
181             # each contact is registered separately even if they are the same
182             $params->{extension} =
183 0           qq|
184             $fields
185            
186            
187             |;
188              
189 0           return $self->SUPER::create_contact( $params );
190             }
191              
192             =head2 get_contact_ext
193              
194             Parsing the keysys extension for get_contact_info:
195              
196             Additional contact statuses in extension: C, C, C
197              
198             An Examples:
199              
200             {
201             'msg' => 'Command completed successfully',
202             'owner' => 'login',
203             'roid' => '333376460_CONTACT-KEYSYS',
204             'cre_date' => '2017-12-11 07:20:17',
205             'phone' => [
206             '+7.9066329999'
207             ],
208             'email' => [
209             'aleks@gmail.com'
210             ],
211             'cont_id' => 'P-JDA6666',
212             'loc' => {
213             'city' => 'Tyumen',
214             'org' => 'Aleks Aleksandra',
215             'country_code' => 'RU',
216             'name' => 'Alesk Aleksandra',
217             'postcode' => '123456',
218             'addr' => 'ul Aleksa d 16 kv 16',
219             'state' => undef
220             },
221             'fax' => [
222             '+7.9066329999'
223             ],
224             'creater' => 'login',
225             'statuses' => {
226             'ok' => '+',
227             'linked' => '+',
228             'validated' => '+'
229             },
230             'authinfo' => ':1ADE:ZEh:',
231             'code' => '1000'
232             };
233              
234             =cut
235              
236             sub get_contact_ext {
237 0     0 1   my ( undef, $cont, $ext ) = @_;
238              
239 0 0         if ( $ext =~ /]*>(.+)<\/keysys:resData>/s ) {
240             # key-system extension TODO: move
241 0           my $krdata = $1;
242              
243 0 0         $cont->{statuses}{'validated'} = '+' if $krdata =~ /1<\/keysys:validated>/;
244 0 0         $cont->{statuses}{'verified'} = '+' if $krdata =~ /1<\/keysys:verified>/;
245 0 0         $cont->{statuses}{'verification-requested'} = '+'
246             if $krdata =~ /1<\/keysys:verification-requested>/;
247             }
248             }
249              
250             =head2 check_claims
251              
252             Get info on Claims Notice
253              
254             For details see L
255              
256             INPUT:
257              
258             key of params:
259              
260             C -- domain name
261              
262             OUTPUT:
263              
264             see L
265              
266             =cut
267              
268             sub check_claims {
269 0     0 1   my ( $self, $params ) = @_;
270              
271 0           $params->{domains} = [ $params->{dname} ];
272              
273             $params->{extension} =
274 0           '
275             claims
276            
277             ';
278              
279 0           return $self->SUPER::check_domains( $params );
280             }
281              
282              
283             # Compile trade, premium and tlds extension
284              
285             sub _keysys_domain_ext {
286 0     0     my ( $params ) = @_;
287              
288 0           foreach my $f ( keys %$params ) {
289 0 0         if ( $f =~ /^x-/ ) {
290 0           $params->{ uc($f) } = delete $params->{$f};
291             }
292             }
293              
294 0 0         unless ( $params->{tld} ) {
295 0           ( $params->{tld} ) = $params->{dname} =~ /\.([0-9A-Za-z\-]+)$/;
296             }
297              
298 0           my $tld = uc $params->{tld};
299              
300 0           my %ext;
301              
302             # for epp need lc
303 0           foreach my $f ( keys %$params ) {
304 0 0 0       if ( $f =~ /^X-$tld-$/ or $f eq 'X-ACCEPT-PREMIUMPRICE' or $f eq 'X-ACCEPT-TRADE' ) {
      0        
305 0           $ext{ lc($f) } = delete $params->{$f};
306             }
307             }
308              
309 0           my $extension = '';
310             # the extension fields must be arranged in alphabetical order
311 0           foreach my $f ( sort keys %ext ) {
312 0           my $f1 = $f;
313 0           $f1 =~ s/^x-//;
314 0           $extension .= " $ext{$f}\n";
315             }
316              
317 0           return $extension;
318             }
319              
320             =head2 create_domain
321              
322             additional keys of params:
323              
324             C -- register a premium domain without specifying the price, but it must be allowed in the panel;
325              
326             C, C -- price for premium domain;
327              
328             C -- currency for price for premium domain;
329              
330             C -- subhash for claims parameters:
331             C, C, C.
332             For details see L;
333              
334             The other parameters are zone-specific and are set as specified in The RRPProxy documentation: C.
335              
336             =cut
337              
338             sub create_domain {
339 0     0 1   my ( $self, $params ) = @_;
340              
341 0           $params->{authinfo} = ''; # need empty
342              
343             # Set as RRPProxy documentation, but not epp extension documentation
344 0 0         $params->{'X-ACCEPT-PREMIUMPRICE'} = 1 if delete $params->{is_premium}; # https://wiki.rrpproxy.net/domains/premium-domains
345 0 0         $params->{'X-FEE-AMOUNT'} = delete $params->{premium_price} if defined $params->{premium_price}; # zero is correct price
346 0 0         $params->{'X-FEE-AMOUNT'} = delete $params->{'fee-fee'} if defined $params->{'fee-fee'};
347 0 0         $params->{'X-FEE-CURRENCY'} = delete $params->{premium_currency} if $params->{premium_currency};
348              
349 0           my $extension = _keysys_domain_ext( $params );
350              
351             # closing special domain extensions
352 0 0         if ( $extension ) {
353 0           $extension =
354             qq|
355             $extension
356            
357            
358             |;
359             }
360              
361              
362 0 0         if ( defined $params->{'X-FEE-AMOUNT'} ) { # https://wiki.rrpproxy.net/domains/premium-domains/x-fee-parameters
363             # price can be zero
364 0           $extension .= qq| \n|;
365              
366 0 0         if ( $params->{'X-FEE-CURRENCY'} ) {
367 0           $extension .= ' ' . $params->{'X-FEE-CURRENCY'} . "\n";
368             }
369              
370 0           $extension .= ' ' . $params->{'X-FEE-AMOUNT'} . "\n \n";
371             }
372              
373              
374 0 0         if ( $params->{claims} ) {
375             $extension .=
376             '
377             claims
378            
379             '. $params->{claims}{noticeID} .'
380             '. $params->{claims}{notAfter} .'
381 0           '.$params->{claims}{acceptedDate}.'
382            
383            
384             ';
385             }
386              
387 0 0         $params->{extension} = $extension if $extension;
388              
389 0           return $self->SUPER::create_domain( $params );
390             }
391              
392              
393             =head2 transfer
394              
395             INPUT
396              
397             For premium domains, you need to pass a special parameter is_premium
398              
399             You can also specify contact id for some tlds: C, C, C, C
400              
401             All other parameters such as L.
402              
403             =cut
404              
405             sub transfer {
406 0     0 1   my ( $self, $params ) = @_;
407              
408 0 0         if ( defined $params->{authinfo} ) {
409 0           $params->{authinfo} =~ s/&/&/g;
410 0           $params->{authinfo} =~ s/
411 0           $params->{authinfo} =~ s/>/>/g;
412             }
413              
414 0           my $extension = '';
415              
416 0 0 0       if ( $params->{is_premium} || $params->{'X-ACCEPT-PREMIUMPRICE'} || $params->{'x-accept-premiumprice'} ) {
      0        
417 0           $extension .= " 1\n";
418             }
419              
420 0 0 0       if ( $params->{reg_id} || $params->{admin_id} ) {
421 0 0         $extension .= " $$params{reg_id}\n" if $params->{reg_id};
422 0 0         $extension .= " $$params{admin_id}\n" if $params->{admin_id};
423 0 0         $extension .= " $$params{tech_id}\n" if $params->{tech_id};
424 0 0         $extension .= " $$params{billing_id}\n" if $params->{billing_id};
425             }
426              
427 0 0         if ( $extension ) {
428             $params->{extension} =
429 0           qq|
430            
431             $extension
432            
433             |;
434             }
435              
436 0           return $self->SUPER::transfer( $params );
437             }
438              
439             =head2 renew_domain
440              
441             For renewal of the premium domain name, you need to pass a parameter C or C
442              
443             =cut
444              
445             sub renew_domain {
446 0     0 1   my ( $self, $params ) = @_;
447              
448 0 0 0       if ( $params->{is_premium} || $params->{'X-ACCEPT-PREMIUMPRICE'} || $params->{'x-accept-premiumprice'} ) {
      0        
449             # https://wiki.rrpproxy.net/domains/premium-domains
450             $params->{extension} =
451 0           qq|
452            
453             1
454            
455            
456             |;
457             }
458              
459 0           return $self->SUPER::renew_domain( $params );
460             }
461              
462              
463             =head2 update_domain
464              
465             C – option for special change of domain owner – paid or requires confirmation;
466              
467             =cut
468              
469             sub update_domain {
470 0     0 1   my ( $self, $params ) = @_;
471              
472 0 0         $params->{'X-ACCEPT-TRADE'} = 1 if delete $params->{trade};
473              
474 0           my $extension = _keysys_domain_ext( $params );
475              
476 0 0         if ( $extension ) {
477             $params->{extension} =
478 0           qq|
479             $extension
480            
481            
482             |;
483             }
484              
485 0           return $self->SUPER::update_domain( $params );
486             }
487              
488              
489             =head2 set_domain_renewal_mode
490              
491             Set renewal mode for domain.
492              
493             INPUT:
494              
495             params with key:
496              
497             C – valid values: C, C, C, C, C
498              
499             For details see L
500              
501             OUTPUT:
502             see L
503              
504             =cut
505              
506             sub set_domain_renewal_mode {
507 0     0 1   my ( $self, $params ) = @_;
508              
509 0           $params->{renewal_mode} = uc $params->{renewal_mode};
510              
511             $params->{extension} =
512 0           qq|
513            
514             $$params{renewal_mode}
515            
516            
517             |;
518              
519 0           return $self->update_domain( $params );
520             }
521              
522              
523             =head2 req_poll_ext
524              
525             keysys extension for the req poll
526              
527             =cut
528              
529             sub req_poll_ext {
530 0     0 1   my ( undef, $ext ) = @_;
531              
532 0           my %info;
533              
534 0 0         if ( $ext =~ /]+>(.+?)<\/keysys:poll>/s ) {
535 0           my $key_ext = $1;
536              
537 0           foreach my $type ( 'data', 'info' ) {
538 0 0         if ( $key_ext =~ /(.+?)<\/keysys:$type>/s ) {
539 0           my $data = $1;
540              
541 0           my @data = $data =~ /<[^<>]+>[^<>]+<\/[^<>]+>/g;
542              
543 0 0         if ( scalar @data ) {
544 0           foreach my $row ( @data ) {
545 0 0         if ( $row =~ /<([^<>]+)>([^<>]+)<\/[^<>]+>/ ) {
546 0           $info{$1} = $2;
547             }
548             }
549             }
550             else {
551 0           $info{$type} = $data;
552             }
553             }
554             }
555             }
556              
557 0           return \%info;
558             }
559              
560              
561             1;
562              
563             __END__