-
Notifications
You must be signed in to change notification settings - Fork 21.8k
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
Make AC::Parameters not inherited from Hash #20868
Make AC::Parameters not inherited from Hash #20868
Conversation
@@ -7,7 +7,7 @@ class UsersController < ActionController::API | |||
wrap_parameters :person, format: [:json] | |||
|
|||
def test | |||
self.last_parameters = params.except(:controller, :action) | |||
self.last_parameters = params.except(:controller, :action).to_unsafe_h |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a Parameters#to_h
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but because of #18006 to_h
only returns safe parameters (after slicing) while to_unsafe_h
returns everything as-is.
Since this test is testing all parameters and doesn't care about Strong Parameters, to_unsafe_h
works fine here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that is that I thought 👍
32d8c2f
to
bc18c33
Compare
Seems for some reason `MyModel.create(params[:my_model]) is raising an error. |
b217e4a
to
a7e19ec
Compare
@rafaelfranca yeah, I took care of it. Seems like it expects hash-like object to define |
@permitted = self.class.permit_all_parameters | ||
end | ||
|
||
def ==(other_hash) | ||
p other_hash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like a debugging remain. :-p
aa8f639
to
8b80ada
Compare
Somehow Travis lost track of the PR, but the build against the latest commit passed. Please give it another look. |
Travis is crazy lately. Just close and reopen that it run again. |
Hey Hey, whats up? |
@joshk after some force pushes to PR branches Travis lost the tracking of On Tue, Jul 14, 2015, 17:02 Josh Kalderimis notifications@github.com
|
8b80ada
to
6a759d9
Compare
(Feedback was on sikachu@8b80ada) Documentation updated. Thanks @robin850! |
def initialize(attributes = nil) | ||
super(attributes) | ||
def initialize(parameters = {}) | ||
@parameters = parameters.with_indifferent_access |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to convert all incoming hashes to HWIAs? Or can we change initialize to:
def initialize(parameters = {}.with_indifferent_access)
@parameters = parameters
I want to make sure the constructor is doing as little work as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to change the constructor to not calling .with_indifferent_access
but that totally broke the tests. I think it's better to keep it like that to make sure that params we are dealing with is HWIA. I feel like we'll run into weird issue if we don't do that.
hey @rafaelfranca, it looks like the most recent commit got picked up, or was this again the case of a 'close/open'? |
@joshk I did a close/open. I'm about to force-push to the branch, so I'll ping you once I do that. |
This is another take at rails#14384 as we decided to wait until `master` is targeting Rails 5.0. This commit is implementation-complete, as it guarantees that all the public methods on the hash-inherited Parameters are still working (based on test case). We can decide to follow-up later if we want to remove some methods out from Parameters.
6a759d9
to
39a7fcb
Compare
@joshk I just pushed sikachu@39a7fcb and https://travis-ci.org/rails/rails/pull_requests still shows the old SHA for this PR. There might be a problem with PR update hook? |
I think I know the issue, I'll get back to you though. |
Hi all! 👋 I've been struggling with this change while upgrading an app to Rails 5 that doesn't use Active Record and I'm wondering if anyone thought about making this change opt-in via new_framework_defaults or some other setting. My use-case is a bit strange, and I'm happy to talk about it in detail if anyone is interested. Basically, I'm using Action Pack and talking to an API that accepts JSON hashes instead of Active Record. So, for example, I have a controller that looks something like this: class ThingsController < ApplicationController
def update
Remote::Service.update_thing(params[:thing])
end
end Changing My colleague @rf- has been trying to figure out a way to opt-out of strong parameters entirely, and the closest we've come is with this We'll report back if/when we find a workaround, but I thought I should raise the issue to see if anyone else had thoughts. I absolutely loved having the |
Why do you need to call |
Also, even if we had a new_framework_defaults config that config would be removed in Rails 5.1 so you would still to change your application. |
Oooh I didn't realize new_framework_defaults would only be good for a point release -- I have some more work to do, then! The In the example from my last comment, imagine that you don't know what keys I suppose what I might be inquiring about, then, is what the best method might be for disabling strong parameters for this application entirely. It looked like that Apologies for the long comments here, but I suspect I'm one of the first people trying to upgrade an app to Rails 5 that truly expects params to be a hash. I'm hoping I'll be able to provide some helpful hints, documentation, or release notes that will help other people that run into similar issues after me. |
I had similar problems with this is shopify too. What we end up doing was to change the lib that do the http to actually transform the parameter in hash. There are some places in the Rails itself that we do the same like url_for helper. We also removed to_param from Parameter object to make it explicit. I'm open to suggestions to make this change easier but until now I didn't find anything better that stop letting parameter instances enter the model layer doing explicit calls to to_h. Maybe a method in active model would help? |
It is indeed generally intended that we force you to be explicit if you mean to take an arbitrary hash of user input and pass it to other code: too often controller methods are written believing That said, if you really want to dangerzone: without trying it, I'd expect your controller could just The fact HTTParty doesn't see the (deprecated) |
Ah, thanks for the additional info @matthewd. We were thinking of doing something along these lines: class ApplicationController < ActionController::Base
def params
@_params ||= request.parameters
end
def params=(val)
@_params = val
end
end ...which would bypass strong params insofar as we use them by reverting to the @rafaelfranca I was feeling negative about this change when I first encountered it, but after reading through the GitHub issues and comments etc I think I understand the reasoning, and I appreciate all of the work that has gone into making our Rails apps as secure as possible. As @matthewd said, it's so easy for people to send unexpected params that we need all the protection we can get, I'm sure. As for the best path forward in our application, I'm not sure if it's best to alter our HTTParty-based lib to do the hash transformation or to bypass strong params for the Rails app. I suppose if the app will never use Active Record then we're safe to bypass strong params. If we might use Active Record in the future, however, then I suppose our http lib should be altered instead. @rafaelfranca I'm not sure what you have in mind re: a method in active model, but I'm happy to discuss and/or test out ideas if you have any. I'm also not sure what to suggest about the overall issue re: the HTTParty bug @matthewd pointed out. As @jeremy mentioned a long time ago #14384 (comment) I suppose HTTParty et al might be able to add support for "Rails 5 params" via |
Rails 5.0 requires to explicitly permit attributes when building a URL using current `params` object. The `safe_params` helper allows developers to just call `safe_params.merge(...)` instead of manually adding `permit` to every call. rails/rails#20868
When [rails#20868][] changed the `ActionController::Parameters` ancestory from `HashWithIndifferentAccess` to `Object`, support for `#deep_merge` and `#deep_merge!` were omitted. This commit restores support by integrating with [ActiveSupport::DeepMergeable](./activesupport/lib/active_support/deep_mergeable.rb). [rails#20868]: rails#20868 Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
Following rails/rails#20868 changed how ActionController::Parameters worked. This change makes `dump_param_keys` match how the Rails side reads teh hash keys. Without this change the right keys don't make it to `Request::Utils` so the test `test_dasherized_keys_as_xml` was failing because `sub-key` wasn't being recognized as a key.
This is another take at #14384 as we decided to wait until
master
is targeting Rails 5.0. This commit is implementation-complete, as it guarantees that all the public methods on the hash-inherited Parametersare still working (based on test case). We can decide to follow-up later if we want to remove some methods out from Parameters.