1# Copyright (c) 2016 CentralNic Ltd. All rights reserved. This program is 2# free software; you can redistribute it and/or modify it under the same 3# terms as Perl itself. 4# 5# $Id: Domain.pm,v 1.3 2011/12/03 11:44:52 gavin Exp $ 6package Net::EPP::Frame::Command::Update::Domain; 7use base qw(Net::EPP::Frame::Command::Update); 8use Net::EPP::Frame::ObjectSpec; 9use strict; 10use warnings; 11 12our $DNSSEC_URN = 'urn:ietf:params:xml:ns:secDNS-1.1'; 13 14=pod 15 16=head1 NAME 17 18Net::EPP::Frame::Command::Update::Domain - an instance of L<Net::EPP::Frame::Command::Update> 19for domain names. 20 21=head1 SYNOPSIS 22 23 use Net::EPP::Frame::Command::Update::Domain; 24 use strict; 25 26 my $info = Net::EPP::Frame::Command::Update::Domain->new; 27 $info->setDomain('example.tld'); 28 29 print $info->toString(1); 30 31This results in an XML document like this: 32 33 <?xml version="1.0" encoding="UTF-8"?> 34 <epp xmlns="urn:ietf:params:xml:ns:epp-1.0" 35 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 36 xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 37 epp-1.0.xsd"> 38 <command> 39 <update> 40 <domain:update 41 xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" 42 xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 43 domain-1.0.xsd"> 44 <domain:name>example-1.tldE<lt>/domain:name> 45 </domain:update> 46 </update> 47 <clTRID>0cf1b8f7e14547d26f03b7641660c641d9e79f45</clTRIDE<gt> 48 </command> 49 </epp> 50 51=head1 OBJECT HIERARCHY 52 53 L<XML::LibXML::Node> 54 +----L<XML::LibXML::Document> 55 +----L<Net::EPP::Frame> 56 +----L<Net::EPP::Frame::Command> 57 +----L<Net::EPP::Frame::Command::Update> 58 +----L<Net::EPP::Frame::Command::Update::Domain> 59 60=cut 61 62sub new { 63 my $package = shift; 64 my $self = bless($package->SUPER::new('update'), $package); 65 66 my $domain = $self->addObject(Net::EPP::Frame::ObjectSpec->spec('domain')); 67 68 foreach my $grp (qw(add rem chg)) { 69 my $el = $self->createElement(sprintf('domain:%s', $grp)); 70 $self->getNode('update')->getChildNodes->shift->appendChild($el); 71 } 72 73 return $self; 74} 75 76=pod 77 78=head1 METHODS 79 80 $frame->setDomain($domain_name); 81 82This specifies the domain name to be updated. 83 84=cut 85 86sub setDomain { 87 my ($self, $domain) = @_; 88 89 my $name = $self->createElement('domain:name'); 90 $name->appendText($domain); 91 92 my $n = $self->getNode('update')->getChildNodes->shift; 93 $n->insertBefore( $name, $n->firstChild ); 94 95 return 1; 96} 97 98=pod 99 100 $frame->addStatus($type, $info); 101 102Add a status of $type with the optional extra $info. 103 104=cut 105 106sub addStatus { 107 my ($self, $type, $info) = @_; 108 my $status = $self->createElement('domain:status'); 109 $status->setAttribute('s', $type); 110 $status->setAttribute('lang', 'en'); 111 if ($info) { 112 $status->appendText($info); 113 } 114 $self->getElementsByLocalName('domain:add')->shift->appendChild($status); 115 return 1; 116} 117 118=pod 119 120 $frame->remStatus($type); 121 122Remove a status of $type. 123 124=cut 125 126sub remStatus { 127 my ($self, $type) = @_; 128 my $status = $self->createElement('domain:status'); 129 $status->setAttribute('s', $type); 130 $self->getElementsByLocalName('domain:rem')->shift->appendChild($status); 131 return 1; 132} 133 134=pod 135 136 $frame->addContact($type, $contact); 137 138Add a contact of $type. 139 140=cut 141 142sub addContact { 143 my ($self, $type, $contact_id) = @_; 144 145 my $contact = $self->createElement('domain:contact'); 146 $contact->setAttribute('type', $type); 147 $contact->appendText($contact_id); 148 149 $self->getElementsByLocalName('domain:add')->shift->appendChild($contact); 150 return 1; 151} 152 153=pod 154 155 $frame->remContact($type, $contact); 156 157Remove a contact of $type. 158 159=cut 160 161sub remContact { 162 my ($self, $type, $contact_id) = @_; 163 164 my $contact = $self->createElement('domain:contact'); 165 $contact->setAttribute('type', $type); 166 $contact->appendText($contact_id); 167 168 $self->getElementsByLocalName('domain:rem')->shift->appendChild($contact); 169 return 1; 170} 171 172=pod 173 174 $frame->chgAuthinfo($auth); 175 176Change the authinfo. 177 178=cut 179 180sub chgAuthInfo { 181 my ($self,$authInfo) = @_; 182 183 my $el = $self->createElement('domain:authInfo'); 184 my $pw = $self->createElement('domain:pw'); 185 $pw->appendText($authInfo); 186 $el->appendChild($pw); 187 188 $self->getElementsByLocalName('domain:chg')->shift->appendChild($el); 189 return 1; 190} 191 192=pod 193 194 $frame->chgRegistrant($registrant); 195 196Change the authinfo. 197 198=cut 199 200sub chgRegistrant { 201 my ($self,$contact) = @_; 202 203 my $registrant = $self->createElement('domain:registrant'); 204 $registrant->appendText($contact); 205 206 $self->getElementsByLocalName('domain:chg')->shift->appendChild($registrant); 207 return 1; 208} 209 210=pod 211 212 $frame->addNS('ns0.example.com'); # host object mode 213 214 $frame->addNS({'name' => 'ns0.example.com', 'addrs' => [ { 'addr' => '127.0.0.1', 'type' => 4 } ] }); # host attribute mode 215 216=cut 217 218sub addNS { 219 my ($self, @ns) = @_; 220 221 if ( ref $ns[0] eq 'HASH' ) { 222 $self->addHostAttrNS(@ns); 223 } 224 else { 225 $self->addHostObjNS(@ns); 226 } 227 return 1; 228} 229 230 231sub addHostAttrNS { 232 my ($self, @ns) = @_; 233 234 my $ns = $self->createElement('domain:ns'); 235 236 # Adding attributes 237 foreach my $host (@ns) { 238 my $hostAttr = $self->createElement('domain:hostAttr'); 239 240 # Adding NS name 241 my $hostName = $self->createElement('domain:hostName'); 242 $hostName->appendText($host->{name}); 243 $hostAttr->appendChild($hostName); 244 245 # Adding IP addresses 246 if ( exists $host->{addrs} && ref $host->{addrs} eq 'ARRAY' ) { 247 foreach my $addr ( @{ $host->{addrs} } ) { 248 my $hostAddr = $self->createElement('domain:hostAddr'); 249 $hostAddr->appendText($addr->{addr}); 250 $hostAddr->setAttribute(ip => $addr->{version}); 251 $hostAttr->appendChild($hostAddr); 252 } 253 } 254 255 # Adding host info to frame 256 $ns->appendChild($hostAttr); 257 } 258 259 $self->getElementsByLocalName('domain:add')->shift->appendChild($ns); 260 return 1; 261} 262 263 264sub addHostObjNS { 265 my ($self, @ns) = @_; 266 267 my $ns = $self->createElement('domain:ns'); 268 foreach my $host (@ns) { 269 my $el = $self->createElement('domain:hostObj'); 270 $el->appendText($host); 271 $ns->appendChild($el); 272 } 273 274 $self->getElementsByLocalName('domain:add')->shift->appendChild($ns); 275 return 1; 276} 277 278=pod 279 280 $frame->remNS('ns0.example.com'); # host object mode 281 282 $frame->remNS({'name' => 'ns0.example.com', 'addrs' => [ { 'addr' => '127.0.0.1', 'type' => 4 } ] }); # host attribute mode 283 284=cut 285 286sub remNS { 287 my ($self, @ns) = @_; 288 289 if ( ref $ns[0] eq 'HASH' ) { 290 $self->remHostAttrNS(@ns); 291 } 292 else { 293 $self->remHostObjNS(@ns); 294 } 295 return 1; 296} 297 298 299sub remHostAttrNS { 300 my ($self, @ns) = @_; 301 302 my $ns = $self->createElement('domain:ns'); 303 304 # Adding attributes 305 foreach my $host (@ns) { 306 my $hostAttr = $self->createElement('domain:hostAttr'); 307 308 # Adding NS name 309 my $hostName = $self->createElement('domain:hostName'); 310 $hostName->appendText($host->{name}); 311 $hostAttr->appendChild($hostName); 312 313 # Adding IP addresses 314 if ( exists $host->{addrs} && ref $host->{addrs} eq 'ARRAY' ) { 315 foreach my $addr ( @{ $host->{addrs} } ) { 316 my $hostAddr = $self->createElement('domain:hostAddr'); 317 $hostAddr->appendText($addr->{addr}); 318 $hostAddr->setAttribute(ip => $addr->{version}); 319 $hostAttr->appendChild($hostAddr); 320 } 321 } 322 323 # Adding host info to frame 324 $ns->appendChild($hostAttr); 325 } 326 327 $self->getElementsByLocalName('domain:rem')->shift->appendChild($ns); 328 return 1; 329} 330 331 332sub remHostObjNS { 333 my ($self, @ns) = @_; 334 335 my $ns = $self->createElement('domain:ns'); 336 foreach my $host (@ns) { 337 my $el = $self->createElement('domain:hostObj'); 338 $el->appendText($host); 339 $ns->appendChild($el); 340 } 341 342 $self->getElementsByLocalName('domain:rem')->shift->appendChild($ns); 343 return 1; 344} 345 346=pod 347 348=head2 DNSSEC methods 349 350=cut 351 352sub _get_dnsssec { 353 my $self = shift; 354 my $tag = shift; 355 356 my $el = self->getElementsByTagNameNS($DNSSEC_URN, $tag); 357 return $el if $el; 358 359 my $ext = $self->getNode('extension'); 360 $ext = $self->getNode('command')->addNewChild(undef, 'extension') 361 if not defined $ext; 362 363 my $upd = $ext->addNewChild($DNSSEC_URN, 'secDNS:update'); 364 $upd->addNewChild($DNSSEC_URN, 'secDNS:add'); 365 $upd->addNewChild($DNSSEC_URN, 'secDNS:rem'); 366 367 return $self->_get_dnssec($tag); 368} 369 370=pod 371 372=head1 AUTHOR 373 374CentralNic Ltd (http://www.centralnic.com/), with contributions from United Domains AG (http://www.united-domains.de/). 375 376=head1 COPYRIGHT 377 378This module is (c) 2016 CentralNic Ltd. This module is free software; you can 379redistribute it and/or modify it under the same terms as Perl itself. 380 381=head1 SEE ALSO 382 383=over 384 385=item * L<Net::EPP::Frame> 386 387=back 388 389=cut 390 3911; 392