File Coverage

blib/lib/Net/DRI/Protocol/EPP/Extensions/KeyRelay.pm
Criterion Covered Total %
statement 18 116 15.5
branch 0 56 0.0
condition 0 6 0.0
subroutine 6 14 42.8
pod 0 7 0.0
total 24 199 12.0


line stmt bran cond sub pod time code
1             ## Domain Registry Interface, Key Relay Mapping for EPP (draft-ietf-eppext-keyrelay-02)
2             ##
3             ## Copyright (c) 2013,2015 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   955 use strict;
  1         2  
  1         30  
18 1     1   4 use warnings;
  1         1  
  1         21  
19 1     1   4 use feature 'state';
  1         1  
  1         79  
20              
21 1     1   4 use Net::DRI::Util;
  1         3  
  1         15  
22 1     1   5 use Net::DRI::Exception;
  1         1  
  1         22  
23 1     1   5 use Net::DRI::Protocol::EPP::Extensions::SecDNS;
  1         1  
  1         1493  
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-02'; }
49              
50             ####################################################################################################
51              
52             sub format_duration
53             {
54 0     0 0   my ($d)=@_;
55 0           my $duration='P';
56 0           my $tmp='';
57              
58 0           state $ru=[qw/years months weeks days hours minutes seconds/];
59 0           my @d=$d->in_units(@$ru[0..3]);
60 0           foreach my $wi (0..$#d)
61             {
62 0 0         next unless $d[$wi] > 0;
63 0           $tmp.=$d[$wi].uc(substr($ru->[$wi],0,1));
64             }
65 0 0         $duration.=$tmp if length $tmp;
66 0           $tmp='';
67              
68 0           @d=$d->in_units(@$ru[4..6]);
69 0           foreach my $wi (0..$#d)
70             {
71 0 0         next unless $d[$wi] > 0;
72 0           $tmp.=$d[$wi].uc(substr($ru->[4+$wi],0,1));
73             }
74 0 0         $duration.='T'.$tmp if length $tmp;
75 0           return $duration;
76             }
77              
78             sub command
79             {
80 0     0 0   my ($epp,$domain,$rd)=@_;
81 0           my $mes=$epp->message();
82              
83 0 0 0       Net::DRI::Exception::usererr_insufficient_parameters('One domain name must be specified for keyrelay operation') unless defined $domain && length $domain;
84 0 0         Net::DRI::Exception::usererr_invalid_parameters('Invalid syntax for domain name: '.$domain) unless Net::DRI::Util::xml_is_token($domain,1,255);
85              
86 0           my @d;
87 0           push @d,['keyrelay:name',$domain];
88              
89 0           my @dd;
90 0 0         Net::DRI::Exception::usererr_insufficient_parameters('secdns is mandatory') unless Net::DRI::Util::has_key($rd,'secdns');
91 0 0 0       Net::DRI::Exception::usererr_invalid_parameters('secdns value must be an array reference with key data') unless ref $rd->{secdns} eq 'ARRAY' && @{$rd->{secdns}};
  0            
92 0           push @dd,map { ['keyrelay:keyData',Net::DRI::Protocol::EPP::Extensions::SecDNS::format_keydata($_)] } @{$rd->{secdns}};
  0            
  0            
93              
94 0 0         Net::DRI::Exception::usererr_insufficient_parameters('authInfo is mandatory') unless Net::DRI::Util::has_auth($rd);
95 0 0         push @dd,['keyrelay:authInfo',['domain:pw',$rd->{auth}->{pw},exists $rd->{auth}->{roid} ? { 'roid' => $rd->{auth}->{roid} } : undef]];
96              
97             ## Now optional parameters
98 0 0         if (Net::DRI::Util::has_key($rd,'expiry'))
99             {
100 0           my $exp=$rd->{expiry};
101 0 0         if (Net::DRI::Util::is_class($exp,'DateTime'))
    0          
102             {
103 0           push @dd,['keyrelay:expiry',['keyrelay:absolute',$exp->strftime('%FT%T.%6N%z')]];
104             } elsif (Net::DRI::Util::is_class($exp,'DateTime::Duration'))
105             {
106 0           push @dd,['keyrelay:expiry',['keyrelay:relative',format_duration($exp)]];
107             } else {
108 0           Net::DRI::Exception::usererr_invalid_parameters('expiry value must be a DateTime or a DateTime::Duration object');
109             }
110             }
111 0           push @d,['keyrelay:keyRelayData',@dd];
112              
113 0           $mes->command(['create','keyrelay:create',sprintf('xmlns:keyrelay="%s" xsi:schemaLocation="%s %s"',$mes->nsattrs('keyrelay'))]);
114 0           $mes->command_body(\@d);
115              
116 0           return;
117             }
118              
119             sub parse_duration
120             {
121 0     0 0   my ($po,$dur)=@_;
122 0           state $rm1={ qw/Y years M months W weeks D days/ };
123 0           state $rm2={ qw/H hours M minutes S seconds/ };
124 0           my $rm=$rm1;
125 0           my $tmp=$dur;
126 0           my @d;
127 0 0         Net::DRI::Exception::err_assert('Unknown duration format: '.$tmp) unless $tmp=~s/^P//;
128 0           while($tmp=~m/(\d+\S|T)/g)
129             {
130 0           my $token=$1;
131 0 0         if ($token eq 'T')
132             {
133 0           $rm=$rm2;
134 0           next;
135             }
136 0           my ($v,$t)=($token=~m/^(\d+)(\S)$/);
137 0 0         Net::DRI::Exception::err_assert('Unknown duration token: '.$token.' in '.$dur) unless exists $rm->{$t};
138 0           push @d,$rm->{$t},$v;
139             }
140 0           return $po->create_local_object('duration',@d);
141             }
142              
143             sub notification_parse
144             {
145 0     0 0   my ($po,$otype,$oaction,$oname,$rinfo)=@_;
146 0           my $mes=$po->message();
147 0 0         return unless $mes->is_success();
148              
149 0           my $data=$mes->get_response($mes->ns('keyrelay'),'infData');
150 0 0         return unless defined $data;
151              
152 0           my %r = ( type => 'keyrelay' );
153 0           foreach my $el (Net::DRI::Util::xml_list_children($data))
154             {
155 0           my ($name,$node)=@$el;
156 0 0         if ($name eq 'name')
    0          
    0          
    0          
157             {
158 0           $oname=$node->textContent();
159             } elsif ($name eq 'keyRelayData')
160             {
161 0           _parse_keyrelay($po,$node,\%r);
162             } elsif ($name eq 'crDate')
163             {
164 0           $r{date}=$po->parse_iso8601($node->textContent());
165             } elsif ($name=~m/^(?:reID|acID)$/)
166             {
167 0           $r{$name}=$node->textContent();
168             }
169             }
170              
171 0           $r{name}=$oname;
172 0           $rinfo->{domain}->{$oname}->{relay}=\%r;
173              
174 0           return;
175             }
176            
177             sub _parse_keyrelay
178             {
179 0     0     my ($po, $data, $rd)=@_;
180              
181 0           my $mes=$po->message();
182 0           my $ns=$mes->ns('keyrelay');
183              
184 0           my @secdns;
185 0           foreach my $el (Net::DRI::Util::xml_list_children($data))
186             {
187 0           my ($name,$node)=@$el;
188 0 0         if ($name eq 'name')
    0          
    0          
    0          
189             {
190 0           $rd->{name}=lc $node->textContent();
191             } elsif ($name eq 'keyData')
192             {
193 0           my %n;
194 0           Net::DRI::Protocol::EPP::Extensions::SecDNS::parse_keydata($node,\%n);
195 0           push @secdns,\%n;
196             } elsif ($name eq 'authInfo')
197             {
198 0           $rd->{auth}={pw => Net::DRI::Util::xml_child_content($node,$mes->ns('domain'),'pw')};
199             } elsif ($name eq 'expiry')
200             {
201 0           my $exp;
202 0 0         if (defined($exp=Net::DRI::Util::xml_child_content($node,$ns,'absolute')))
    0          
203             {
204 0           $rd->{expiry}=$po->parse_iso8601($exp);
205             } elsif (defined($exp=Net::DRI::Util::xml_child_content($node,$ns,'relative')))
206             {
207 0           $rd->{expiry}=parse_duration($po,$exp);
208             }
209             }
210             }
211              
212 0           $rd->{secdns}=\@secdns;
213              
214 0           return;
215             }
216              
217             ####################################################################################################
218             1;
219              
220             __END__