File Coverage

blib/lib/SRS/EPP/Command/Poll.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              
2             package SRS::EPP::Command::Poll;
3             {
4             $SRS::EPP::Command::Poll::VERSION = '0.22';
5             }
6              
7 1     1   3325 use Moose;
  1         10  
  1         24  
8             extends 'SRS::EPP::Command';
9              
10 1     1   7606 use MooseX::Params::Validate;
  1         2  
  1         11  
11              
12 1     1   488 use SRS::EPP::Session;
  0            
  0            
13             use XML::EPP::Domain;
14             use XML::SRS::TimeStamp;
15             use Digest::MD5 qw(md5_hex);
16             use SRS::EPP::Command::Info::Domain;
17              
18             with 'SRS::EPP::Command::PayloadClass';
19              
20             has 'ack_response' => (
21             'is' => 'rw',
22             'isa' => 'XML::EPP::MsgQ',
23             );
24              
25             # for plugin system to connect
26             sub xmlns {
27             XML::EPP::Poll::Node::xmlns();
28             }
29              
30             sub action {
31             "poll";
32             }
33              
34             sub clean_id_out {
35             my $id = shift;
36             our $min_token_type ||= Moose::Util::TypeConstraints::find_type_constraint(
37             "XML::EPP::Common::minTokenType"
38             );
39             if ( $min_token_type->check($id) and $id !~ m{[%+]}) {
40             return $id;
41             }
42              
43             # not really urlencoding, but this is very minimal.
44             $id =~ s{([%+\t\r\n\v])}{sprintf("%%%.2x",ord($1))}eg;
45             $id =~ s{ }{+}g;
46             $id;
47             }
48              
49             sub clean_id_in {
50             my $id = shift;
51             if ($id =~ m{[+%]}) {
52             $id =~ s{\+}{ }g;
53             $id =~ s{%([0-9a-f]{2})}{chr(hex($1))}ieg;
54             }
55             $id;
56             }
57              
58             sub process {
59             my $self = shift;
60            
61             my ( $session ) = pos_validated_list(
62             \@_,
63             { isa => 'SRS::EPP::Session' },
64             );
65            
66             $self->session($session);
67              
68             my $epp = $self->message;
69             my $message = $epp->message;
70             my $op = $message->argument->op;
71              
72             if ( $op eq "req" ) {
73             return XML::SRS::GetMessages->new(
74             queue => 1,
75             max_results => 1,
76             type_filter => [
77             XML::SRS::GetMessages::TypeFilter->new(Type => "third-party"),
78             XML::SRS::GetMessages::TypeFilter->new(
79             Type => "server-generated-data"
80             ),
81             ],
82             );
83             }
84              
85             if ( $op eq "ack" ) {
86             my $msgId = $message->argument->msgID;
87             my ($registrar_id,$client_id) = $msgId =~ m/(....)(.*)/
88             or return;
89             return XML::SRS::AckMessage->new(
90             transaction_id => clean_id_in($client_id),
91             originating_registrar => $registrar_id+0,
92             action_id => $self->client_id || $self->server_id,
93             );
94             }
95              
96             return $self->make_response(code => 2400);
97             }
98              
99             sub extract_fact {
100             my ($self,$action,$domain) = @_;
101              
102             if ($domain && $domain->isa('XML::SRS::Error')) {
103             return "Error";
104             }
105              
106             if ( $action eq "DomainTransfer" ) {
107             my $name = $domain->TransferredDomain();
108             return "Domain Transfer",
109             XML::EPP::Domain::Info::Response->new(
110             name => $name,
111             roid => substr(md5_hex($name), 0, 12) . '-DOM',
112             transfer_date => $domain->timestamptz,
113             status => [],
114             );
115             }
116              
117             if ( $action eq "DomainUpdate" ) {
118             if ( $domain ) {
119             if ( my $udai = $domain->UDAI() ) {
120             return "New UDAI", XML::EPP::Domain::Info::Response->new(
121             name => $domain->name,
122             roid => substr(md5_hex($domain->name), 0, 12) . '-DOM',
123             status => [
124             SRS::EPP::Command::Info::Domain::getEppStatuses($domain)
125             ],
126             auth_info => XML::EPP::Domain::AuthInfo->new(
127             pw => XML::EPP::Common::Password->new(
128             content => $udai,
129             ),
130             ),
131             );
132             }
133              
134             if ( $domain->audit()->comment() =~ m/RenewDomains/ ) {
135             return "Domain Renewal", XML::EPP::Domain::Info::Response->new(
136             name => $domain->name,
137             roid => substr(md5_hex($domain->name), 0, 12) . '-DOM',
138             status => [
139             SRS::EPP::Command::Info::Domain::getEppStatuses($domain)
140             ],
141             expiry_date => $domain->billed_until->timestamptz,
142             );
143             }
144              
145             # didn't notice anything specifically interesting, so we'll default to
146             # returning a full info response...
147             return (
148             "Domain Update",
149             SRS::EPP::Command::Info::Domain::buildInfoResponse($domain)
150             );
151             }
152             }
153              
154             if ( $action eq "DomainCreate" ) {
155             return (
156             "Domain Create",
157             SRS::EPP::Command::Info::Domain::buildInfoResponse($domain)
158             );
159             }
160              
161             return $action ? $action : "Unknown Message";
162             }
163              
164             sub notify{
165             my $self = shift;
166            
167             my ( $rs ) = pos_validated_list(
168             \@_,
169             { isa => 'ArrayRef[SRS::EPP::SRSResponse]' },
170             );
171            
172             my $epp = $self->message;
173              
174             my $message = $rs->[0]->message;
175             my $responses = $message->responses;
176              
177             if ( !(scalar @$responses) && ! $self->ack_response ) {
178             $self->log_info("$self: no responses - returning 1300");
179             return $self->make_response(code => 1300);
180             }
181              
182             if ( my $response = $responses->[0] ) {
183             if ( $response->isa("XML::SRS::Message::Ack::Response") ) {
184             $self->log_info("$self: ack response");
185             my $msgQ = XML::EPP::MsgQ->new(
186             id => sprintf(
187             "%04d%s",$response->registrar_id(),clean_id_out($response->tx_id()),
188             ),
189             );
190            
191             $self->ack_response($msgQ);
192            
193             # We now need to send a GetMessages to get the remaining count
194             return XML::SRS::GetMessages->new(
195             queue => 1,
196             max_results => 1,
197             type_filter => [
198             XML::SRS::GetMessages::TypeFilter->new(Type => "third-party"),
199             XML::SRS::GetMessages::TypeFilter->new(
200             Type => "server-generated-data"
201             ),
202             ],
203             );
204             }
205             elsif ( $response->isa("XML::SRS::Message") ) {
206             if ($self->ack_response) {
207             # If there we've got an AckResponse saved, we must
208             # have been doing a GetMessages request just to get
209             # the remaining count for the response
210             $self->ack_response->count($response->unacked());
211             return $self->make_response(code => 1000, msgQ => $self->ack_response);
212             }
213            
214            
215             my $record = $response->result();
216              
217             my $id = sprintf(
218             "%04d%s", $record->by_id, clean_id_out($record->client_id),
219             );
220              
221             my @messages;
222             my @payloads;
223             for my $resp ( @{ $record->responses() } ) {
224             my $action = $record->action();
225             $self->log_debug("$self: req processing a $action");
226             my ($reason, $payload) = $self->extract_fact($action,$resp);
227              
228             my $mixed_msg = XML::EPP::MixedMsg->new(
229             contents => [$reason],
230             nodenames => [""],
231             );
232              
233             push @messages, $mixed_msg;
234             push @payloads, $payload if $payload;
235             }
236            
237             my $msgQ = XML::EPP::MsgQ->new(
238             count => $response->unacked(),
239             id => $id,
240             qDate => $record->server_time->timestamptz,
241             msg => \@messages,
242             );
243              
244             return $self->make_response(
245             code => 1301,
246             msgQ => $msgQ,
247             payload => @payloads ? \@payloads : undef,
248             );
249             }
250             }
251             elsif ($self->ack_response) {
252             # We've done the GetMessages to find the remaining count, but it
253             # didn't contain a response. This probably means there are no messages
254             $self->ack_response->count(0);
255             return $self->make_response(code => 1000, msgQ => $self->ack_response);
256             }
257              
258             # We only end up here if there was a response we couldn't handle
259             $self->log_error("Got an unhandled response/error when processing poll/ack response");
260             return $self->make_response(code => 2400);
261             }
262              
263             1;