File Coverage

blib/lib/SRS/EPP/Command/Info/Domain.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package SRS::EPP::Command::Info::Domain;
2             {
3             $SRS::EPP::Command::Info::Domain::VERSION = '0.22';
4             }
5              
6 1     1   3034 use Moose;
  1         3  
  1         9  
7              
8             extends 'SRS::EPP::Command::Info';
9              
10 1     1   8933 use MooseX::Params::Validate;
  1         3  
  1         10  
11 1     1   475 use SRS::EPP::Session;
  0            
  0            
12             use XML::EPP::Domain;
13             use Digest::MD5 qw(md5_hex);
14             use Data::Dumper;
15              
16             use XML::EPP::Common;
17             use XML::EPP::Domain::NS;
18             use XML::EPP::Domain::HostAttr;
19             use XML::SRS::FieldList;
20             use XML::EPP::DNSSEC::DSData;
21              
22             # for plugin system to connect
23             sub xmlns {
24             XML::EPP::Domain::Node::xmlns();
25             }
26              
27             sub process {
28             my $self = shift;
29            
30             my ( $session ) = pos_validated_list(
31             \@_,
32             { isa => 'SRS::EPP::Session' },
33             );
34            
35             $self->session($session);
36             my $epp = $self->message;
37             my $payload = $epp->message->argument->payload;
38              
39             # we're not supporting authInfo, so get out of here with an
40             # EPP response
41             if ( $payload->has_auth_info ) {
42             return $self->make_response(code => 2307);
43             }
44              
45             my %ddq_fields = map { $_ => 1 }
46             qw(delegate registered_date registrar_id billed_until
47             audit_text effective_from registrant_contact
48             admin_contact technical_contact status locked_date
49             changed_by_registrar_id dns_sec cancelled_date);
50              
51             # We only want to return name servers if the 'hosts' attribute
52             # is 'all' or 'del'
53             $ddq_fields{name_servers} = 1
54             if $payload->name->hosts eq 'all'
55             || $payload->name->hosts eq 'del';
56              
57             return (
58             XML::SRS::Whois->new(
59             domain => $payload->name->value,
60             full => 0,
61             ),
62             XML::SRS::Domain::Query->new(
63             domain_name_filter => $payload->name->value,
64             field_list => XML::SRS::FieldList->new(
65             %ddq_fields,
66             ),
67             ),
68             );
69             }
70              
71             sub notify {
72             my $self = shift;
73            
74             my ( $rs ) = pos_validated_list(
75             \@_,
76             { isa => 'ArrayRef[SRS::EPP::SRSResponse]' },
77             );
78            
79              
80             my $whois = $rs->[0]->message->response;
81             my $domain = $rs->[1]->message->response;
82              
83             # if status is available, then the object doesn't exist
84             if ( $whois->status eq 'Available' ) {
85             return $self->make_response(code => 2303);
86             }
87              
88             # if there was no domain, this registrar doesn't have access
89             # to it
90             unless ($domain) {
91             return $self->make_response(code => 2201);
92             }
93              
94             # we have a domain, therefore we have a full response :)
95             # let's do this one bit at a time
96             my $payload = $self->message->message->argument->payload;
97              
98             my $extension = $self->buildExtensionResponse($domain);
99              
100             return $self->make_response(
101             code => 1000,
102             payload => buildInfoResponse($domain),
103             $extension ? (extension => $extension) : (),
104             );
105             }
106              
107             # Note, this is called by Poll (and should probably be in a role)
108             # This means we have to be pretty defensive here - the domain
109             # record we're dealing with may not have many fields, so we
110             # have to check for the existence of most things
111             sub buildInfoResponse {
112             my $domain = shift;
113              
114             # get some things out to make it easier on the eye below
115             my $nsList;
116             if ( $domain->nameservers ) {
117             my @nameservers = map {
118             convert_nameserver($_),
119             } @{$domain->nameservers->nameservers};
120              
121             $nsList = XML::EPP::Domain::NS->new(
122             ns => [@nameservers],
123             );
124             }
125              
126             my %contacts;
127             for my $type (qw(registrant admin technical)) {
128             my $method = 'contact_'.$type;
129             my $contact = $domain->$method;
130              
131             next unless $contact && $contact->handle_id;
132              
133             if ($contact) {
134             if ($type eq 'registrant') {
135             $contacts{$type} = $contact->handle_id;
136             }
137             else {
138             my $epp_type = $type eq 'technical'
139             ? 'tech' : $type;
140             push @{$contacts{contact}},
141             XML::EPP::Domain::Contact->new(
142             value => $contact->handle_id,
143             type => $epp_type,
144             );
145             }
146             }
147             }
148              
149             # If the domain's registered date is different to the audit
150             # time, we assume this domain has been updated at least once
151             # (which EPP thinks is important)
152             my $domain_updated = 0;
153             if (
154             $domain->registered_date &&
155             $domain->registered_date->timestamptz ne $domain->audit->when->begin->timestamptz
156             ) {
157             $domain_updated = 1;
158             }
159              
160             ## Do we also want to include the auth_info (UDAI) data?
161             my $auth_info;
162             if ( my $udai = $domain->UDAI() ) {
163             $auth_info = XML::EPP::Domain::AuthInfo->new(
164             pw => XML::EPP::Common::Password->new(
165             content => $udai,
166             ),
167             );
168             }
169            
170             # The 'exDate' we return depends on the domain's status
171             my $exDate = $domain->status eq 'PendingRelease' ? $domain->cancelled_date : $domain->billed_until;
172              
173             return XML::EPP::Domain::Info::Response->new(
174             name => $domain->name,
175             roid => substr(md5_hex($domain->name), 0, 12) . '-DOM',
176             status => [ getEppStatuses($domain) ],
177             %contacts,
178             ($nsList ? (ns => $nsList) : ()),
179             $domain->registrar_id() ? (client_id => sprintf("%03d",$domain->registrar_id())) : (), # clID
180             $domain->registered_date() ? (created => ($domain->registered_date())->timestamptz) : (), # crDate
181             $exDate ? (expiry_date => $exDate->timestamptz) : (), # exDate
182             $domain_updated
183             ? (
184             updated => # upDate
185             ($domain->audit->when->begin())->timestamptz,
186             updated_by_id => # upID
187             sprintf("%03d",$domain->audit->registrar_id)
188             )
189             : (),
190             ($auth_info ? (auth_info => $auth_info) : ()),
191             );
192             }
193              
194             sub buildExtensionResponse {
195             my $self = shift;
196             my $domain = shift;
197            
198             if ($self->session->extensions->enabled->{dns_sec} && $domain->dns_sec && $domain->dns_sec->ds_list) {
199             my @ds;
200             foreach my $srs_ds (@{ $domain->dns_sec->ds_list }) {
201             push @ds, XML::EPP::DNSSEC::DSData->new(
202             key_tag => $srs_ds->key_tag,
203             alg => $srs_ds->algorithm,
204             digest_type => $srs_ds->digest_type,
205             digest => $srs_ds->digest,
206             );
207             }
208            
209             my $response = XML::EPP::DNSSEC::InfoResponse->new(
210             ds_data => \@ds,
211             );
212             }
213             }
214              
215             sub getEppStatuses {
216             my ($domain) = @_;
217              
218             my @status;
219             if ( defined $domain->delegate() && $domain->delegate() == 0 ) {
220             push @status, 'clientHold';
221             }
222             if ( $domain->status && $domain->status eq 'PendingRelease' ) {
223             push @status, 'pendingDelete';
224             }
225             if ( defined $domain->locked_date() ) {
226             push @status, qw(
227             serverDeleteProhibited
228             serverRenewProhibited
229             serverTransferProhibited
230             serverUpdateProhibited
231             );
232             }
233              
234             push @status, 'ok' unless @status;
235              
236             return (
237             map {
238             XML::EPP::Domain::Status->new( status => $_ );
239             } @status
240             );
241             }
242              
243             sub convert_nameserver {
244             my $ns = shift;
245             my @addr = map { XML::EPP::Host::Address->new($_) }
246             grep {defined} (
247             $ns->ipv4_addr && +{
248             value => $ns->ipv4_addr,
249             },
250             $ns->ipv6_addr && +{
251             value => $ns->ipv6_addr,
252             ip => "v6",
253             },
254             );
255             XML::EPP::Domain::HostAttr->new(
256             name => $ns->fqdn,
257             @addr ? ( addrs => \@addr ) : (),
258             );
259             }
260              
261             1;