Make compatible with jsonapi-resources 0.9#52
Make compatible with jsonapi-resources 0.9#52valscion merged 23 commits intovenuu:masterfrom plantfansam:jsonapi-resources-0.9
Conversation
|
Hi, and welcome! Thank you for starting a PR for this. I'm very excited to soon jump to review it! Hopefully it's ok that this is going to take me a few days at least until I can look into this more. I've got a tight schedule at work for a while, and as my wrist is aching again I won't be able to look at this on my freetime anytime soon. I won't forget about this PR, though :). I'll check this out when I've got a good timeslot for this 💞 |
|
Closed and reopened to try to trigger a CI build... wonder what's going on 😕 |
|
This seems to be going to a good direction, thank you! I'm not sure whether we've got a good answer to the backwards compatibility here. The relationship processor hooks have changed a bit, and when we started to authorize for relationship actions we hit these changes, too: #40 (comment) I'd be OK with going by just supporting 0.9 in a future release, as it would make the relationship authorizations cleaner as well. 0.9.0 is out of beta so it's fine if we only target that version, too. Would you be OK with setting this PR up to only support 0.9 and removing the then-unnecessary checks from your changes? |
|
Yes, totally ok with the route of 0.9-only compatibility! Should make the
code a lot cleaner, too! 🙂
…On Sun, Mar 19, 2017 at 2:37 PM Vesa Laakso ***@***.***> wrote:
This seems to be going to a good direction, thank you!
I'm not sure whether we've got a good answer to the backwards
compatibility here. The relationship processor hooks have changed a bit,
and when we started to authorize for relationship actions we hit these
changes, too: #40 (comment)
<#40 (comment)>
I'd be OK with going by just supporting 0.9 in a future release, as it
would make the relationship authorizations cleaner as well. 0.9.0 is out of
beta so it's fine if we only target that version, too.
Would you be OK with setting this PR up to only support 0.9 and removing
the then-unnecessary checks from your changes?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#52 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAWmBstuTcaVNt21pQFuyKfKkRtAOPZMks5rnXXMgaJpZM4MhE-Z>
.
|
|
OK, I have updated the gemspec to require jsonapi-resources 0.9 and updated the code accordingly. I also had to update the remove_to_many_relationship calls to match the new method signature. |
| context 'unauthorized for remove_to_many_relationship' do | ||
| before do | ||
| disallow_operation('remove_to_many_relationship', article, kind_of(Comment), :comments) | ||
| disallow_operation('remove_to_many_relationship', article, kind_of(Comment), "comments") |
There was a problem hiding this comment.
Hmm I wonder whether this change was necessary?
| end | ||
|
|
||
| def authorize_replace_polymorphic_to_one_relationship | ||
| raise NotImplementedError |
There was a problem hiding this comment.
Good call with just raising NotImplementedError here.
We'll need to figure out how to authorize for this polymorphic case before shipping v1.0.0 but that might be better to discuss outside of this PR.
There was a problem hiding this comment.
Actually, I think we'd like to skip raising this here and figure out what to do with the polymorphic relationship scenario outside of this PR. This way we wouldn't add too much noise to this upgrade path.
Would you like to remove this callback from the processor?
|
|
||
| def self.creatable_fields(context) | ||
| super + [:id] | ||
| end |
There was a problem hiding this comment.
Hmm what was the reason for this change? Is there a reason why it is needed?
There was a problem hiding this comment.
I didn't discover the reason in jsonapi-resources, but there are 22 failures if this is left out. In included_resources_spec, the failures look approximately like this: "Param not allowed", "detail" : "id is not allowed." I can search for more details if you like!
There was a problem hiding this comment.
Hmm I wonder if it has got to with @thibaudgg's PR #11 and the changes done to the dummy app ArticleResource in https://github.com/venuu/jsonapi-authorization/pull/11/files#diff-cc66704bb355f2769ceb1ed76d5f02b4
I'm not really sure how the self.verify_key and id= methods work, and why exactly they were necessary to have. @thibaudgg do you have any insight to this?
There was a problem hiding this comment.
Hi, I'll have a look next week and give a try to this branch with our app.
Thanks @handlers for all the work on that one! 👍
There was a problem hiding this comment.
Thanks @thibaudgg! Let us know if you hit roadblocks.
These might be relevant to your testing, if you haven't updated in a while: #53 #40
There was a problem hiding this comment.
I'm waiting on @thibaudgg to be able to test this and confirm it works nicely :)
There was a problem hiding this comment.
I launched our test suite on our CI with jsonapi-resource 0.9 and this PR and we get a bunch of errors (unexpected 406 - Not Acceptable responses). It's hard to tell right now if it's because of upgrading to JR 0.9 or this PR specifically.
Sadly I didn't have much time to investigate more this week. I'll try to block an hour next week.
There was a problem hiding this comment.
Huh, that 406 error does indeed seem weird. It might very well be because of JR 0.9, too
There was a problem hiding this comment.
Ok turns out that these lines are indeed needed since v0.8.3 of JR as IDs are generated on the client side.
See https://github.com/cerebris/jsonapi-resources/releases/tag/v0.8.3
| source_record, | ||
| related_record, | ||
| params[:relationship_type] | ||
| ) |
There was a problem hiding this comment.
Instead of looping through all the related_records, we might want to instead change the API of remove_to_many_relationship to take an array of related_records (instead of one at a time).
That way we wouldn't even have to do the if related_resource.empty? check you're doing before calling the authorizer right now, too.
There was a comment #40 (comment) that maybe related to this not being possible before 0.9 version of JR.
There was a problem hiding this comment.
This makes sense to me. I will try!
|
You'll want to change the |
| set_callback :create_to_many_relationships, :before, :authorize_create_to_many_relationships | ||
| set_callback :replace_to_many_relationships, :before, :authorize_replace_to_many_relationships | ||
| set_callback :remove_to_many_relationships, :before, :authorize_remove_to_many_relationships | ||
| set_callback :replace_polymorphic_to_one_relationship, :before, :authorize_replace_polymorphic_to_one_relationship |
There was a problem hiding this comment.
This line is too long and will cause the linter to fail the build. Sorry about that 😥
Maybe write it like like this?
set_callback(
:replace_polymorphic_to_one_relationship,
:before,
:authorize_replace_polymorphic_to_one_relationship
)|
I've updated the PR to send records to the authorizer as a batch (7280547) instead of iterating over them individually. Travis is also now running successfully :). There is still an open thread related to an update required to make the dummy app's |
|
|
||
| # find_by_keys doesn't raise if no records, so raise explicitly here | ||
| if related_resources.empty? | ||
| fail JSONAPI::Exceptions::RecordNotFound, params[:associated_keys] |
There was a problem hiding this comment.
Do we need this check here? What specs fail if we'd remove this part of the code?
Maybe those tests that would fail have incorrect behaviour which we'd like to change. I don't know, but this seems a bit out of place here.
There was a problem hiding this comment.
Good question! If this is removed, one spec failure occurs: when "authorized for remove_to_many_relationship" and "limited by policy scope on comments" it { is_expected.to be_not_found }. The spec expects a 404 if the comments scope (CommentPolicy::Scope) is Comment.none.
With the new code, it instead tries to run remove_from_comments?, which raises NotImplementedError.
1) Relationship operations DELETE /articles/:id/relationships/comments authorized for remove_to_many_relationship limited by policy scope on comments
Failure/Error: raise NotImplementedError
NotImplementedError:
NotImplementedError
# ./spec/dummy/app/policies/article_policy.rb:44:in `remove_from_comments?'
# ./lib/jsonapi/authorization/default_pundit_authorizer.rb:238:in `public_send'
# ./lib/jsonapi/authorization/default_pundit_authorizer.rb:238:in `authorize_relationship_operation'
# ./lib/jsonapi/authorization/default_pundit_authorizer.rb:183:in `remove_to_many_relationship'
# ./lib/jsonapi/authorization/authorizing_processor.rb:201:in `authorize_remove_to_many_relationships'
# ./spec/requests/relationship_operations_spec.rb:275:in `block (3 levels) in <top (required)>'
# ./spec/requests/relationship_operations_spec.rb:302:in `block (5 levels) in <top (required)>'I included the fail to preserve the old 404 behavior. Perhaps we could move that fail to authorize_relationship_operation?
There was a problem hiding this comment.
Hmm I guess we'd really want to test that the DELETE operation authorizes properly, and doesn't use 404 when the comments can't be found.
Can you modify the tests to expect that remove_to_many_relationship authorizer method will be called with the proper arguments?
| last_response | ||
| end | ||
|
|
||
| it { is_expected.not_to be_not_found } |
There was a problem hiding this comment.
Can we write this spec as either
it { is_expected.to be_successful }or
it { is_expected.to be_forbidden }like we have done with all the other specs?
If this feels a bit over your head, I could also tackle these at some point in the future.
There was a problem hiding this comment.
No problem! I updated here 3731696. I am glad to keep revising the PR, but if it's easier for you to finish it, that's fine too!
| before do | ||
| allow_operation('remove_to_many_relationship', article, kind_of(Comment), :comments) | ||
| allow_any_instance_of(ArticlePolicy).to receive( | ||
| :remove_from_comments?).and_return(true) |
There was a problem hiding this comment.
It would be great if we didn't have to worry about policies in here at all, and could create this spec in terms of only the operations stubbing instead.
Would it be possible to restructure this spec to look something like this?
context 'limited by policy scope on comments' do
let(:comments_scope) { Comment.none }
before do
allow_operation('remove_to_many_relationship', article, [], :comments)
end
it { is_expected.to be_succesful }
endThis would also ensure that the remove_to_many_relationship is indeed called with an empty array instead of any comments.
| [article, comments_to_remove.first, :comments], | ||
| [article, comments_to_remove.second, :comments] | ||
| ]) | ||
| allow_operation('remove_to_many_relationship', article, kind_of(Array), "comments") |
There was a problem hiding this comment.
Could we restructure this to test for the actual comments instead of just kind_of(Array)? The kind_of(Array) might be a bit too vague spec and could cause bugs to slip through as it doesn't care about the type of the objects inside the array itself.
Would something like this work?
allow_operation(
'remove_to_many_relationship',
article,
[comments_to_remove.first, comments_to_remove.second],
:comments
)That would be the best. If the specs fail because of this due to some matchers not working correctly, we should fix the matchers instead of trying to work around them by using less specific assertions.
Also, as you can see, let's try to use the symbol version for the relationship name in the assertions (:comments instead of "comments") or otherwise it might result in an inconsistent API with the other authorizers)
| context 'unauthorized for remove_to_many_relationship' do | ||
| before do | ||
| disallow_operation('remove_to_many_relationship', article, kind_of(Comment), :comments) | ||
| disallow_operation('remove_to_many_relationship', article, kind_of(Array), "comments") |
There was a problem hiding this comment.
Same thing as in https://github.com/venuu/jsonapi-authorization/pull/52/files#r109101102, just that the assertion should be disallow_operation instead of allow_operation
| context 'limited by policy scope on articles' do | ||
| before do | ||
| allow_operation('remove_to_many_relationship', article, kind_of(Comment), :comments) | ||
| allow_operation('remove_to_many_relationship', article, kind_of(Array), :comments) |
There was a problem hiding this comment.
spec/support/authorization_stubs.rb
Outdated
|
|
||
| allow(AUTHORIZER_CLASS).to receive(:new).with(Hash).and_return(authorizer) | ||
| authorizer | ||
| end |
There was a problem hiding this comment.
We hopefully don't need to add this new method here, if we can satisfy the spec in https://github.com/venuu/jsonapi-authorization/pull/52/files#r109100787 with the existing matchers
|
Thanks so much @valscion! I am going to try to update the PR today or tomorrow. |
|
Thank you so much @thibaudgg for testing this out, really appreciate it! We actually just moments ago stumbled upon an issue in JR (it was this one if you're interested) and as it has been fixed in 0.9.0 we'll want to push this PR through if not today, then tomorrow.
We'd actually prefer merge commits over rebasing. We like to keep the history of the conversation in place. |
|
I'll tackle this tomorrow (which in our timezone would be around 16 hours from now). So if you feel like addressing the tests before that, @handlers, feel free to, but if you don't have the time I'll happily plow through them as well and get this PR merged Thank you so much for your efforts here! 💞 |
|
I won't be able to get to this for a while, so feel free to make any
modifications necessary!
…On Tue, Apr 11, 2017 at 11:04 AM Vesa Laakso ***@***.***> wrote:
I'll tackle this tomorrow (which in our timezone would be around 16 hours
from now).
So if you feel like addressing the tests before that, @handlers
<https://github.com/handlers>, feel free to, but if you don't have the
time I'll happily plow through them as well and get this PR merged
|
|
👏 |
Hi! In an effort to make jsonapi-authorization's test suite pass against jsonapi-resources 0.9, this PR does a few things:
:create_to_many_relationship:replace_to_many_relationship:remove_to_many_relationshipbased on whether or notJSONAPI::Processorresponds to the singular or plural version of the method (See Not compatible with v0.9.0 of jsonapi-resources #36).replace_polymorphic_to_one_relationship, which is present in jsonapi-resources 0.9 and 0.8.0.beta1. I don't think this is strictly necessary for 0.9 compatibility but is good to have in my opinion.authorize_remove_to_many_relationshipby updating the logic to find all related records and callauthorizer.remove_to_many_relationshipon each of them.When this branch is run against the suite with jsonapi-resources at 0.8.0.beta1, there are a couple of failures. I am not sure what the backwards compatibility requirements are between point releases of the gem, but I definitely tried to stay somewhat backwards compatible in the conditional callback setting strategy.
I am super new to this project and definitely want to get some experienced 👀 on this! Happy to chop it up into separate PRs and fix stuff up, as this one has a few distinct threads to it.