aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App/Controller/Waste.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Waste.pm')
-rw-r--r--perllib/FixMyStreet/App/Controller/Waste.pm107
1 files changed, 107 insertions, 0 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Waste.pm b/perllib/FixMyStreet/App/Controller/Waste.pm
index 7587795c8..152c7c28e 100644
--- a/perllib/FixMyStreet/App/Controller/Waste.pm
+++ b/perllib/FixMyStreet/App/Controller/Waste.pm
@@ -11,6 +11,7 @@ use FixMyStreet::App::Form::Waste::AboutYou;
use FixMyStreet::App::Form::Waste::Request;
use FixMyStreet::App::Form::Waste::Report;
use FixMyStreet::App::Form::Waste::Enquiry;
+use Open311::GetServiceRequestUpdates;
sub auto : Private {
my ( $self, $c ) = @_;
@@ -457,6 +458,112 @@ sub setup_categories_and_bodies : Private {
@$contacts = grep { grep { $_ eq 'Waste' } @{$_->groups} } @$contacts;
}
+sub receive_echo_event_notification : Path('/waste/echo') : Args(0) {
+ my ($self, $c) = @_;
+ $c->stash->{format} = 'xml';
+ $c->response->header(Content_Type => 'application/soap+xml');
+
+ require SOAP::Lite;
+
+ $c->detach('soap_error', [ 'Invalid method', 405 ]) unless $c->req->method eq 'POST';
+
+ my $echo = $c->cobrand->feature('echo');
+ $c->detach('soap_error', [ 'Missing config', 500 ]) unless $echo;
+
+ # Make sure we log entire request for debugging
+ $c->detach('soap_error', [ 'Missing body' ]) unless $c->req->body;
+ my $soap = join('', $c->req->body->getlines);
+ $c->log->info($soap);
+
+ my $body = $c->cobrand->body;
+ $c->detach('soap_error', [ 'Bad jurisdiction' ]) unless $body;
+
+ my $env = SOAP::Deserializer->deserialize($soap);
+
+ my $header = $env->header;
+ $c->detach('soap_error', [ 'Missing SOAP header' ]) unless $header;
+ my $action = $header->{Action};
+ $c->detach('soap_error', [ 'Incorrect Action' ]) unless $action && $action eq $echo->{receive_action};
+ $header = $header->{Security};
+ $c->detach('soap_error', [ 'Missing Security header' ]) unless $header;
+ my $token = $header->{UsernameToken};
+ $c->detach('soap_error', [ 'Authentication failed' ])
+ unless $token && $token->{Username} eq $echo->{receive_username} && $token->{Password} eq $echo->{receive_password};
+
+ my $event = $env->result;
+
+ my $cfg = { echo => Integrations::Echo->new(%$echo) };
+ my $request = $c->cobrand->construct_waste_open311_update($cfg, $event);
+ $request->{updated_datetime} = DateTime::Format::W3CDTF->format_datetime(DateTime->now);
+ $request->{service_request_id} = $event->{Guid};
+
+ my $updates = Open311::GetServiceRequestUpdates->new(
+ system_user => $body->comment_user,
+ current_body => $body,
+ );
+
+ my $p = $updates->find_problem($request);
+ if ($p) {
+ $c->forward('check_existing_update', [ $p, $request, $updates ]);
+ my $comment = $updates->process_update($request, $p);
+ }
+ # Still want to say it is okay, even if we did nothing with it
+ $c->forward('soap_ok');
+}
+
+sub soap_error : Private {
+ my ($self, $c, $comment, $code) = @_;
+ $code ||= 400;
+ $c->response->status($code);
+ my $type = $code == 500 ? 'Server' : 'Client';
+ $c->response->body(SOAP::Serializer->fault($type, "Bad request: $comment", soap_header()));
+}
+
+sub soap_ok : Private {
+ my ($self, $c) = @_;
+ $c->response->status(200);
+ my $method = SOAP::Data->name("NotifyEventUpdatedResponse")->attr({
+ xmlns => "http://www.twistedfish.com/xmlns/echo/api/v1"
+ });
+ $c->response->body(SOAP::Serializer->envelope(method => $method, soap_header()));
+}
+
+sub soap_header {
+ my $attr = "http://www.twistedfish.com/xmlns/echo/api/v1";
+ my $action = "NotifyEventUpdatedResponse";
+ my $header = SOAP::Header->name("Action")->attr({
+ xmlns => 'http://www.w3.org/2005/08/addressing',
+ 'soap:mustUnderstand' => 1,
+ })->value("$attr/ReceiverService/$action");
+
+ my $dt = DateTime->now();
+ my $dt2 = $dt->clone->add(minutes => 5);
+ my $w3c = DateTime::Format::W3CDTF->new;
+ my $header2 = SOAP::Header->name("Security")->attr({
+ 'soap:mustUnderstand' => 'true',
+ 'xmlns' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
+ })->value(
+ \SOAP::Header->name(
+ "Timestamp" => \SOAP::Header->value(
+ SOAP::Header->name('Created', $w3c->format_datetime($dt)),
+ SOAP::Header->name('Expires', $w3c->format_datetime($dt2)),
+ )
+ )->attr({
+ xmlns => "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
+ })
+ );
+ return ($header, $header2);
+}
+
+sub check_existing_update : Private {
+ my ($self, $c, $p, $request, $updates) = @_;
+
+ my $cfg = { updates => $updates };
+ $c->detach('soap_ok')
+ unless $c->cobrand->waste_check_last_update(
+ $cfg, $p, $request->{status}, $request->{external_status_code});
+}
+
__PACKAGE__->meta->make_immutable;
1;