Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Operation with Roar JSONAPI representer forces contract to open up id #17

Closed
KonstantinKo opened this issue May 11, 2017 · 7 comments

Comments

@KonstantinKo
Copy link

I'm not sure whether this is an issue with trailblazer-operation, roar-jsonapi, or reform - but using them in conjunction with an Update call forces me to make the id field of a resource editable. That seems like a bad idea to me. I would prefer it to ignore the id part of the JSONAPI request.

Admittedly this is also a bit of an inconsistency with the JSONAPI spec. An update as a PATCH /resources/1 MUST include the id field. An inconsistency between the URL id and the given id in the document is not handled. Maybe there is an edge case where you would want to edit the ID. However whether you want to or not, it has to be provided as a parameter.

class MyResource < Struct.new(:id, :name)
  def self.find_by(id:)
     DB[id.to_i]
  end
  def save
    DB[id.to_i] = self
  end
end
DB = {1 => MyResource.new(1, 'one')} # Simulating database

class MyContract < Reform::Form
  property :name
end

class MyRepresenter < Roar::Decorator
  include Roar::JSON::JSONAPI.resource :resources
  attributes do
    property :name
  end
end

class MyOperation < Trailblazer::Operation
  step Model(MyResource, :find_by)
  step Contract::Build(constant: MyContract)
  step Contract::Validate(representer: MyRepresenter)
  step Contract::Persist()
end

MyOperation.({id: 1}, 'document' => '{"data":{"type":"resources","attributes":{"name":"changed"},"id":"9999"}}')
# => NoMethodError: undefined method `id=' for #<MyContract>

# Adding `property :id` to MyContract fixes the NoMethodError,
# but allows editing the ID field which is usually a security vulnerability:
MyOperation.({id: 1}, 'document' => '{"data":{"type":"resources","attributes":{"name":"changed"},"id":"9999"}}')
# => <Result:true ...>
DB
# => {1 => #<struct name="one">, 9999 => #<struct name="changed">}
@apotonick
Copy link
Member

Hey, @myabc, I think the field id should be writeable: false?

@apotonick
Copy link
Member

@KonstantinKo The problem lies in Reform, when it uses the representer to populate the contract. I think we have to fix the configuration in jsonapi.

@KonstantinKo
Copy link
Author

Sounds good. property :id, writeable: false is also a good workaround for now. Thanks!

@apotonick
Copy link
Member

Could you please open this issue in the roar-jsonapi repo and explain to @myabc what is the problem, so we can solve it for everybody? Thanks ❤️

@KonstantinKo
Copy link
Author

Sure thing 👍 => trailblazer/roar-jsonapi#25

@myabc
Copy link
Collaborator

myabc commented May 17, 2017

@KonstantinKo cheers. I'll try to find some time later in the week to investigate.

@panSarin
Copy link
Collaborator

Since issue was moved to roar-jsonapi i close that one and we will check if it is still to fix.
Also join us on zulipchat: https://trailblazer.zulipchat.com/join/od4yhihn6tra3ix39u4gks72/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants