diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm index f7b1b6e1d7..e67ec51fa2 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm @@ -14,6 +14,8 @@ require Catalyst::ActionRole::CheckTrailingSlash; require Catalyst::ActionRole::HTTPMethods; require Catalyst::ActionRole::RequireSSL; +# curl -v -X POST --user $USER --insecure -F front_image=@sandbox/spa504g-front.jpg -F mac_image=@sandbox/spa504g-back.jpg -F json='{"reseller_id":1, "vendor":"Cisco", "model":"SPA999", "linerange":[{"name": "Phone Keys", "num_lines":4, "can_private":true, "can_shared":true, "can_blf":true}]}' https://localhost:4443/api/pbxdevicemodels/ + class_has 'api_description' => ( is => 'ro', isa => 'Str', @@ -162,11 +164,14 @@ sub POST :Allow { my $guard = $c->model('DB')->txn_scope_guard; { - my $resource = $self->get_valid_post_data( - c => $c, - media_type => 'application/json', - ); - last unless $resource; + last unless $self->forbid_link_header($c); + last unless $self->valid_media_type($c, 'multipart/form-data'); + last unless $self->require_wellformed_json($c, 'application/json', $c->req->param('json')); + my $resource = JSON::from_json($c->req->param('json')); + $resource->{front_image} = $self->get_upload($c, 'front_image'); + last unless $resource->{front_image}; + # optional, don't set error + $resource->{mac_image} = $c->req->upload('mac_image'); my $form = $self->get_form($c); last unless $self->validate_form( @@ -206,6 +211,17 @@ sub POST :Allow { last; } + my $ft = File::Type->new(); + if($resource->{front_image}) { + my $front_image = delete $resource->{front_image}; + $resource->{front_image} = $front_image->slurp; + $resource->{front_image_type} = $ft->mime_type($resource->{front_image}); + } + if($resource->{mac_image}) { + my $front_image = delete $resource->{mac_image}; + $resource->{mac_image} = $front_image->slurp; + $resource->{mac_image_type} = $ft->mime_type($resource->{mac_image}); + } try { $item = $c->model('DB')->resultset('autoprov_devices')->create($resource); diff --git a/lib/NGCP/Panel/Role/API.pm b/lib/NGCP/Panel/Role/API.pm index 198017a95d..d12496dca8 100644 --- a/lib/NGCP/Panel/Role/API.pm +++ b/lib/NGCP/Panel/Role/API.pm @@ -198,27 +198,39 @@ sub forbid_link_header { sub valid_media_type { my ($self, $c, $media_type) = @_; + my $ctype = $c->request->header('Content-Type'); + $ctype =~ s/;\s+boundary.+$//; my $type; if(ref $media_type eq "ARRAY") { $type = join ' or ', @{ $media_type }; - return 1 if $c->request->header('Content-Type') && - $c->request->header('Content-Type') ~~ $media_type; + return 1 if $ctype && $ctype ~~ $media_type; } else { $type = $media_type; - return 1 if($c->request->header('Content-Type') && - index($c->request->header('Content-Type'), $media_type) == 0); + return 1 if($ctype && index($ctype, $media_type) == 0); } - $self->error($c, HTTP_UNSUPPORTED_MEDIA_TYPE, "Unsupported media type, accepting $type only."); + $self->error($c, HTTP_UNSUPPORTED_MEDIA_TYPE, "Unsupported media type '" . ($ctype // 'undefined') . "', accepting $type only."); return; } sub require_body { my ($self, $c) = @_; return 1 if length $c->stash->{body}; + + + $self->error($c, HTTP_BAD_REQUEST, "This request is missing a message body."); return; } +# returns Catalyst::Request::Upload +sub get_upload { + my ($self, $c, $field) = @_; + my $upload = $c->req->upload($field); + return $upload if $upload; + $self->error($c, HTTP_BAD_REQUEST, "This request is missing the upload part '$field' in body."); + return; +} + sub require_precondition { my ($self, $c, $header_name) = @_; return 1 if $c->request->header($header_name); @@ -252,6 +264,7 @@ sub require_wellformed_json { NGCP::Panel::Utils::ValidateJSON->new($patch); $ret = 1; } catch($e) { + chomp $e; $self->error($c, HTTP_BAD_REQUEST, "The entity is not a well-formed '$media_type' document. $e"); } return $ret; diff --git a/lib/NGCP/Panel/Role/API/PbxDeviceModels.pm b/lib/NGCP/Panel/Role/API/PbxDeviceModels.pm index c9330e9b4a..ff9afe07cc 100644 --- a/lib/NGCP/Panel/Role/API/PbxDeviceModels.pm +++ b/lib/NGCP/Panel/Role/API/PbxDeviceModels.pm @@ -12,6 +12,7 @@ use Data::HAL qw(); use Data::HAL::Link qw(); use HTTP::Status qw(:constants); use JSON qw(); +use File::Type; use NGCP::Panel::Form::Device::ModelAPI; sub get_form { diff --git a/sandbox/spa504g-back.jpg b/sandbox/spa504g-back.jpg new file mode 100644 index 0000000000..dfa82d01af Binary files /dev/null and b/sandbox/spa504g-back.jpg differ