RIPAGlobal / scimitar

A SCIM v2 API endpoint implementation
MIT License
62 stars 43 forks source link

Invalid resource error with PUT replace action #153

Open agmcleod opened 1 week ago

agmcleod commented 1 week ago

Hi there. I'm working on integrating this gem with an internal rails service, and running into an issue as I'm setting up tests to confirm the functionality we need.

I'm getting the error here: https://github.com/RIPAGlobal/scimitar/blob/main/app/controllers/scimitar/resources_controller.rb#L183, as the validation fails when the name field I have on my model is empty.

In my test i'm sending the request as so:

  describe '#update' do
    subject { put :replace, params: params }
    let(:group) { create(:group) }
    let(:params) do
      {
        id: group.id,
        schemas: ["urn:ietf:params:scim:schemas:core:2.0:PatchOp"],
        Operations: [{
          'op' => 'replace',
          'value' => {
            'id' => group.id,
            'displayName' => 'Test SCIMv2',
          },
        }],
      }
    end

    it 'gets the expected response' do
      subject
      expect(json_response).to eq({
        'id' => group.id,
        'schemas' => ["urn:ietf:params:scim:schemas:core:2.0:Group"],
        'displayName' => "Test SCIMv2",
      })
    end
  end

The group model contains a name field, and I set it up in the scim attributes map method to correspond name & displayName. However since the with_scim_resource doesn't map the parameters being passed to the constructor of the type returned by storage_class(), the validation then fails. Is there something I'm missing here? I can't seem to find anything in the mock example app you've provided.

The scim attributes map for reference:

def scim_attributes_map
  {
    id: :id,
    externalId: :scim_uuid,
    displayName: :name,
    members: [
      list: :scim_users_and_groups,
      using: {
        value: :id,
      },
      find_with: ->(scim_list_entry) {
        id = scim_list_entry['value']
        type = scim_list_entry['type'] || 'User' # Some online examples omit 'type' and believe 'User' will be assumed

        case type.downcase
        when 'user'
          User.find_by_id(id)
        when 'group'
          Group.find_by_id(id)
        else
          raise Scimitar::InvalidSyntaxError.new("Unrecognised type #{type.inspect}")
        end
      },
    ],
  }
end
agmcleod commented 1 week ago

Ah so I misunderstood how it's setting up the Scimitar::Group & not my own model. Though i think it's getting confused with me passing an example operation I got from Okta.

Based on the code for the resource controller, I'm thinking my test is invalid, but Okta specifies this could be PATCH or PUT depending on the configuration. https://developer.okta.com/docs/api/openapi/okta-scim/guides/scim-20/#update-a-specific-group-name. I was trying the operations example they have there against the replace action