File Coverage

blib/lib/Net/DRI/Protocol/EPP/Extensions/KeyRelay.pm
Criterion Covered Total %
statement 18 120 15.0
branch 0 66 0.0
condition 0 6 0.0
subroutine 6 14 42.8
pod 0 7 0.0
total 24 213 11.2


line stmt bran cond sub pod time code
1             ## Domain Registry Interface, Key Relay Mapping for EPP
2             ##
3             ## Copyright (c) 2013,2015,2016 Patrick Mevzek . All rights reserved.
4             ##
5             ## This file is part of Net::DRI
6             ##
7             ## Net::DRI is free software; you can redistribute it and/or modify
8             ## it under the terms of the GNU General Public License as published by
9             ## the Free Software Foundation; either version 2 of the License, or
10             ## (at your option) any later version.
11             ##
12             ## See the LICENSE file that comes with this distribution for more details.
13             ####################################################################################################
14              
15             package Net::DRI::Protocol::EPP::Extensions::KeyRelay;
16              
17 1     1   970 use strict;
  1         1  
  1         23  
18 1     1   3 use warnings;
  1         2  
  1         19  
19 1     1   3 use feature 'state';
  1         1  
  1         45  
20              
21 1     1   3 use Net::DRI::Util;
  1         2  
  1         13  
22 1     1   3 use Net::DRI::Exception;
  1         1  
  1         12  
23 1     1   3 use Net::DRI::Protocol::EPP::Extensions::SecDNS;
  1         2  
  1         1130  
24              
25             ####################################################################################################
26              
27             sub register_commands
28             {
29 0     0 0   my ($class,$version)=@_;
30 0           my %d=(
31             keyrelay => [ \&command, undef ],
32             notification => [ undef, \¬ification_parse ],
33             );
34              
35 0           return { 'domain' => \%d };
36             }
37              
38             sub setup
39             {
40 0     0 0   my ($class,$po,$version)=@_;
41 0           $po->ns({
42             'keyrelay' => [ 'urn:ietf:params:xml:ns:keyrelay-1.0','keyrelay-1.0.xsd' ],
43             'secDNS' => [ 'urn:ietf:params:xml:ns:secDNS-1.1','secDNS-1.1.xsd' ], ## force 1.1 here
44             });
45 0           return;
46             }
47              
48 0     0 0   sub implements { return 'http://tools.ietf.org/html/draft-ietf-eppext-keyrelay-11'; }
49              
50             ####################################################################################################
51              
52             sub format_duration
53             {
54 0     0 0   my ($d)=@_;
55              
56 0 0         return 'P0D' if $d->is_zero();
57              
58 0           my $duration='P';
59 0           my $tmp='';
60              
61 0           state $ru=[qw/years months weeks days hours minutes seconds/];
62 0           my @d=$d->in_units(@$ru[0..3]);
63 0           foreach my $wi (0..$#d)
64             {
65 0 0         next unless $d[$wi] > 0;
66 0           $tmp.=$d[$wi].uc(substr($ru->[$wi],0,1));
67             }
68 0 0         $duration.=$tmp if length $tmp;
69 0           $tmp='';
70              
71 0           @d=$d->in_units(@$ru[4..6]);
72 0           foreach my $wi (0..$#d)
73             {
74 0 0         next unless $d[$wi] > 0;
75 0           $tmp.=$d[$wi].uc(substr($ru->[4+$wi],0,1));
76             }
77 0 0         $duration.='T'.$tmp if length $tmp;
78 0 0         $duration='-'.$duration if $d->is_negative();
79 0           return $duration;
80             }
81              
82             sub command
83             {
84 0     0 0   my ($epp,$domain,$rd)=@_;
85 0           my $mes=$epp->message();
86              
87 0 0 0       Net::DRI::Exception::usererr_insufficient_parameters('One domain name must be specified for keyrelay operation') unless defined $domain && length $domain;
88 0 0         Net::DRI::Exception::usererr_invalid_parameters('Invalid syntax for domain name: '.$domain) unless Net::DRI::Util::xml_is_token($domain,1,255);
89              
90 0           my @d;
91 0           push @d,['keyrelay:name',$domain];
92              
93 0 0         Net::DRI::Exception::usererr_insufficient_parameters('authInfo is mandatory') unless Net::DRI::Util::has_auth($rd);
94 0 0         push @d,['keyrelay:authInfo',['domain:pw',$rd->{auth}->{pw},exists $rd->{auth}->{roid} ? { 'roid' => $rd->{auth}->{roid} } : undef]];
95              
96 0 0         Net::DRI::Exception::usererr_insufficient_parameters('key is mandatory') unless Net::DRI::Util::has_key($rd,'key');
97 0 0 0       Net::DRI::Exception::usererr_invalid_parameters('key must be a single ref hash or a ref array of ref hashes') unless ref $rd->{key} eq 'ARRAY' || ref $rd->{key} eq 'HASH';
98 0 0         my @keys = ref $rd->{key} eq 'ARRAY' ? @{$rd->{key}} : ($rd->{key});
  0            
99 0 0         Net::DRI::Exception::usererr_invalid_parameters('key must be a single ref hash or a ref array of ref hashes') if grep { ref $_ ne 'HASH' } @keys;
  0            
100 0           foreach my $kd (@keys)
101             {
102 0           my @dd;
103 0 0         Net::DRI::Exception::usererr_insufficient_parameters('secdns is mandatory') unless Net::DRI::Util::has_key($kd,'secdns');
104 0 0         Net::DRI::Exception::usererr_invalid_parameters('secdns value must be a single ref hash') unless ref $kd->{secdns} eq 'HASH';
105 0           push @dd,['keyrelay:keyData',Net::DRI::Protocol::EPP::Extensions::SecDNS::format_keydata($kd->{secdns})];
106              
107             ## Now optional parameters
108 0 0         if (Net::DRI::Util::has_key($kd,'expiry'))
109             {
110 0           my $exp=$kd->{expiry};
111 0 0         if (Net::DRI::Util::is_class($exp,'DateTime'))
    0          
112             {
113 0           push @dd,['keyrelay:expiry',['keyrelay:absolute',$exp->strftime('%FT%T.%6N%z')]];
114             } elsif (Net::DRI::Util::is_class($exp,'DateTime::Duration'))
115             {
116 0           push @dd,['keyrelay:expiry',['keyrelay:relative',format_duration($exp)]];
117             } else {
118 0           Net::DRI::Exception::usererr_invalid_parameters('expiry value must be a DateTime or a DateTime::Duration object');
119             }
120             }
121 0           push @d,['keyrelay:keyRelayData',@dd];
122             }
123              
124 0           $mes->command(['create','keyrelay:create',sprintf('xmlns:keyrelay="%s" xsi:schemaLocation="%s %s"',$mes->nsattrs('keyrelay'))]);
125 0           $mes->command_body(\@d);
126              
127 0           return;
128             }
129              
130             sub parse_duration
131             {
132 0     0 0   my ($po,$dur)=@_;
133 0           state $rm1={ qw/Y years M months W weeks D days/ };
134 0           state $rm2={ qw/H hours M minutes S seconds/ };
135 0           my $rm=$rm1;
136 0           my $tmp=$dur;
137 0           my @d;
138 0 0         Net::DRI::Exception::err_assert('Unknown duration format: '.$tmp) unless $tmp=~s/^P//;
139 0           while($tmp=~m/(\d+\S|T)/g)
140             {
141 0           my $token=$1;
142 0 0         if ($token eq 'T')
143             {
144 0           $rm=$rm2;
145 0           next;
146             }
147 0           my ($v,$t)=($token=~m/^(\d+)(\S)$/);
148 0 0         Net::DRI::Exception::err_assert('Unknown duration token: '.$token.' in '.$dur) unless exists $rm->{$t};
149 0           push @d,$rm->{$t},$v;
150             }
151 0           return $po->create_local_object('duration',@d);
152             }
153              
154             sub notification_parse
155             {
156 0     0 0   my ($po,$otype,$oaction,$oname,$rinfo)=@_;
157 0           my $mes=$po->message();
158 0 0         return unless $mes->is_success();
159              
160 0           my $data=$mes->get_response($mes->ns('keyrelay'),'infData');
161 0 0         return unless defined $data;
162              
163 0           my %r = ( type => 'keyrelay' );
164 0           foreach my $el (Net::DRI::Util::xml_list_children($data))
165             {
166 0           my ($name,$node)=@$el;
167 0 0         if ($name eq 'name')
    0          
    0          
    0          
    0          
168             {
169 0           $r{name} = $oname = $node->textContent();
170             } elsif ($name eq 'authInfo')
171             {
172 0           $r{auth}={pw => Net::DRI::Util::xml_child_content($node,$mes->ns('domain'),'pw')};
173             } elsif ($name eq 'keyRelayData')
174             {
175 0           push @{$r{key}}, _parse_keyrelay($po,$node);
  0            
176             } elsif ($name eq 'crDate')
177             {
178 0           $r{date}=$po->parse_iso8601($node->textContent());
179             } elsif ($name=~m/^(?:reID|acID)$/)
180             {
181 0           $r{$name}=$node->textContent();
182             }
183             }
184              
185 0           $rinfo->{domain}->{$oname}->{relay}=\%r;
186              
187 0           return;
188             }
189              
190             sub _parse_keyrelay
191             {
192 0     0     my ($po, $data)=@_;
193              
194 0           my $mes=$po->message();
195 0           my $ns=$mes->ns('keyrelay');
196              
197 0           my %r;
198 0           foreach my $el (Net::DRI::Util::xml_list_children($data))
199             {
200 0           my ($name,$node)=@$el;
201 0 0         if ($name eq 'keyData')
    0          
202             {
203 0           my %n;
204 0           Net::DRI::Protocol::EPP::Extensions::SecDNS::parse_keydata($node,\%n);
205 0           $r{secdns}=\%n;
206             } elsif ($name eq 'expiry')
207             {
208 0           my $exp;
209 0 0         if (defined($exp=Net::DRI::Util::xml_child_content($node,$ns,'absolute')))
    0          
210             {
211 0           $r{expiry}=$po->parse_iso8601($exp);
212             } elsif (defined($exp=Net::DRI::Util::xml_child_content($node,$ns,'relative')))
213             {
214 0           $r{expiry}=parse_duration($po,$exp);
215             }
216             }
217             }
218              
219 0           return \%r;
220             }
221              
222             ####################################################################################################
223             1;
224              
225             __END__