Commit 0b5c207fca9aca403d1b3a9be2fd4b1645d41aa1

Authored by Ross Reinhardt
Committed by Kyle Werner
1 parent 705f0922
Exists in master

Fix exception raised when patch endpoint receives invalid request

fixes lessonly/scim_rails#29

The patch endpoint isn't fully scim compliant yet and only allows for
specific operations. When we received a specific format of request that
wasn't valid, it was raising an exception instead of returning the
expected 422 response.

Add extra validation to prevent this situation when receiving an
unexpected body for a patch request.
app/controllers/scim_rails/scim_users_controller.rb
... ... @@ -126,9 +126,23 @@ module ScimRails
126 126 end
127 127  
128 128 def patch_active_param
129   - active = params.dig("Operations", 0, "value", "active")
130   - raise ScimRails::ExceptionHandler::UnsupportedPatchRequest if active.nil?
131   - active
  129 + handle_invalid = lambda do
  130 + raise ScimRails::ExceptionHandler::UnsupportedPatchRequest
  131 + end
  132 +
  133 + operations = params["Operations"] || {}
  134 +
  135 + valid_operation = operations.find(handle_invalid) do |operation|
  136 + valid_patch_operation?(operation)
  137 + end
  138 +
  139 + valid_operation.dig("value", "active")
  140 + end
  141 +
  142 + def valid_patch_operation?(operation)
  143 + operation["op"] == "replace" &&
  144 + operation["value"] &&
  145 + operation["value"]["active"]
132 146 end
133 147 end
134 148 end
... ...
spec/controllers/scim_rails/scim_users_controller_spec.rb
... ... @@ -569,6 +569,53 @@ RSpec.describe ScimRails::ScimUsersController, type: :controller do
569 569 response_body = JSON.parse(response.body)
570 570 expect(response_body.dig("schemas", 0)).to eq "urn:ietf:params:scim:api:messages:2.0:Error"
571 571 end
  572 +
  573 + it "returns 422 when value is " do
  574 + patch :patch_update, params: {
  575 + id: 1,
  576 + Operations: [
  577 + {
  578 + op: "replace",
  579 + path: "displayName",
  580 + value: "Francis"
  581 + }
  582 + ]
  583 + }
  584 +
  585 + expect(response.status).to eq 422
  586 + response_body = JSON.parse(response.body)
  587 + expect(response_body.dig("schemas", 0)).to eq "urn:ietf:params:scim:api:messages:2.0:Error"
  588 + end
  589 +
  590 + it "returns 422 when value is missing" do
  591 + patch :patch_update, params: {
  592 + id: 1,
  593 + Operations: [
  594 + {
  595 + op: "replace"
  596 + }
  597 + ]
  598 + }
  599 +
  600 + expect(response.status).to eq 422
  601 + response_body = JSON.parse(response.body)
  602 + expect(response_body.dig("schemas", 0)).to eq "urn:ietf:params:scim:api:messages:2.0:Error"
  603 + end
  604 +
  605 + it "returns 422 operations key is missing" do
  606 + patch :patch_update, params: {
  607 + id: 1,
  608 + Foobars: [
  609 + {
  610 + op: "replace"
  611 + }
  612 + ]
  613 + }
  614 +
  615 + expect(response.status).to eq 422
  616 + response_body = JSON.parse(response.body)
  617 + expect(response_body.dig("schemas", 0)).to eq "urn:ietf:params:scim:api:messages:2.0:Error"
  618 + end
572 619 end
573 620 end
574 621  
... ...