-
Notifications
You must be signed in to change notification settings - Fork 73
THREESCALE-12434: Migrate from protected attributes to strong parameters - Part 2 #4249
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
Changes from all commits
71e6ead
0a847b7
561896a
173e7d4
a62ccba
738b0ba
3929c52
2aec247
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,9 +43,8 @@ def update | |
|
|
||
| preload_to_present(buyer_account) | ||
|
|
||
| buyer_account.vat_rate = params[:vat_rate].to_f if params[:vat_rate] | ||
| buyer_account.settings.attributes = billing_params | ||
| buyer_account.update_with_flattened_attributes(flat_params) | ||
| buyer_account.update(account_params) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| respond_with(buyer_account) | ||
| end | ||
|
|
@@ -155,8 +154,4 @@ def find_buyer_account | |
| raise ActiveRecord::RecordNotFound | ||
| end | ||
| end | ||
|
|
||
| def flat_params | ||
| super.except(:vat_rate, :id) | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,54 +2,17 @@ class Admin::Api::BuyersApplicationPlansController < Admin::Api::BuyersBaseContr | |||||
| representer ApplicationPlan | ||||||
|
|
||||||
| # FIXME: QUESTION: these two should be deprecated or removed directly. Check if they are used, not document it on the active docs. | ||||||
| # | ||||||
| # swagger | ||||||
| ## sapi = source2swagger.namespace("Account Management API") | ||||||
| ## e = sapi.apis.add | ||||||
| ## e.path = "/admin/api/accounts/{account_id}/application_plans.xml" | ||||||
| ## e.responseClass = "List[application_plan]" | ||||||
| ## @desc = "Returns the application plans bought by a partner." | ||||||
| ## e.description = @desc | ||||||
| # | ||||||
| ## op = e.operations.add | ||||||
| ## op.nickname = "buyer_app_plans" | ||||||
| ## op.httpMethod = "GET" | ||||||
| # | ||||||
| ## @access_token = { :name => "access_token", :description => "A personal Access Token", :dataType => "string", :required => true, :paramType => "query" } | ||||||
| ## @account_id = { :name => "account_id", :description => "ID of the partner account.", :dataType => "int", :allowMultiple => false, :required => true, :paramType => "path" } | ||||||
| # | ||||||
| ## op.parameters.add @access_token | ||||||
| ## op.parameters.add @account_id | ||||||
| # | ||||||
| # Returns the application plans bought by a partner. | ||||||
| # GET /admin/api/accounts/{account_id}/application_plans.xml | ||||||
| def index | ||||||
| respond_with(bought_application_plans) | ||||||
| end | ||||||
|
|
||||||
| # swagger | ||||||
| ## e = sapi.apis.add | ||||||
| ## e.path = "/admin/api/accounts/{account_id}/application_plans/{id}/buy.xml" | ||||||
| ## e.responseClass = "application" | ||||||
| ## @desc = "Creates an application for a partner on a given application plan (deprecated)." | ||||||
| ## e.description = @desc | ||||||
| # | ||||||
| ## op = e.operations.add | ||||||
| ## op.deprecated = true | ||||||
| ## op.nickname = "buyer_app_plan_buy" | ||||||
| ## op.httpMethod = "POST" | ||||||
| ## op.summary = @desc | ||||||
| # | ||||||
| ## @id = { :name => "id", :description => "ID of the application plan.", :dataType => "int", :allowMultiple => false, :required => true, :paramType => "path" } | ||||||
| # | ||||||
| ## op.parameters.add @access_token | ||||||
| ## op.parameters.add @account_id | ||||||
| ## op.parameters.add @id | ||||||
| ## op.parameters.add :name => "name", :description => "Name of the application to be created.", :dataType => "string", :allowMultiple => false, :required => true, :paramType => "query" | ||||||
| ## op.parameters.add :name => "description", :description => "Description of the application to be created.", :dataType => "string", :allowMultiple => false, :required => true, :paramType => "query" | ||||||
| # | ||||||
|
|
||||||
|
akostadinov marked this conversation as resolved.
|
||||||
| # Creates an application for a partner on a given application plan (deprecated). | ||||||
| # POST /admin/api/accounts/{account_id}/application_plans/{id}/buy.xml | ||||||
| #TODO: deprecate this, beware there are clients using it | ||||||
| def buy | ||||||
| application = buyer.buy(application_plan, application_plan_params) | ||||||
| application = buyer.buy(application_plan, contract_params) | ||||||
| respond_with(application, serialize: application_plan) | ||||||
| end | ||||||
|
|
||||||
|
|
@@ -63,8 +26,9 @@ def application_plan | |||||
| @application_plan ||= accessible_application_plans.stock.find(params[:id]) | ||||||
| end | ||||||
|
|
||||||
| def application_plan_params | ||||||
| attributes = current_account.fields.for(Cinstance) | ||||||
| params.slice(*attributes) | ||||||
| def contract_params | ||||||
| allowed_attrs = current_account.defined_fields_names_for(Cinstance) + | ||||||
| %w[redirect_url first_traffic_at first_daily_traffic_at create_origin accepted_at] | ||||||
| params.permit(*allowed_attrs) | ||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the default fields definitions, So, in the new version these are missing (which I think is fine): On the other hand, these are added: which I am now not sure about 🤔 This is, however, a legacy endpoint that hopefully is not used by anyone, so I think it's not a big deal.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why adding
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I read this as if they were part of
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe they were not allowed to be mass assigned, but then they were assigned manually somewhere else. In that case, yes, they must be permitted here. But I don't know if that was the case. Just pointing out so @mayorova can confirm.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, I've checked this, and Lines 384 to 385 in 0a34a66
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So basically something underneath sets them approved or not so we don't permit them? If they have to be set, then permitting is also fine. But whatever, if it works - fine.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, this snippet in |
||||||
| end | ||||||
| end | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,9 +13,7 @@ def index | |
| # POST /admin/api/accounts/{account_id}/applications.xml | ||
| def create | ||
| application = applications.new(user_account: buyer, plan: application_plan, create_origin: "api") | ||
| application.unflattened_attributes = application_params | ||
| application.user_key = params[:user_key] if params[:user_key] | ||
| application.application_id = params[:application_id] if params[:application_id] | ||
| application.assign_attributes(application_params) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| Array(params[:application_key]).each do |key| | ||
| application.application_keys.build(value: key) | ||
|
|
@@ -35,10 +33,7 @@ def show | |
| # Application Update | ||
| # PUT /admin/api/accounts/{account_id}/applications/{id}.xml | ||
| def update | ||
| application.unflattened_attributes = flat_params | ||
| application.user_key = params[:user_key] if params[:user_key] | ||
|
|
||
| application.save | ||
| application.update(application_update_params) | ||
|
|
||
| respond_with application | ||
| end | ||
|
|
@@ -124,15 +119,13 @@ def application_plan | |
| end | ||
|
|
||
| def application_params | ||
| flat_params.slice(*application_attributes) | ||
| end | ||
|
|
||
| def application_attributes | ||
| current_account.fields.for(Cinstance) + %w|user_key application_id| | ||
| allowed_attrs = current_account.defined_fields_names_for(Cinstance) + | ||
| %w[user_key application_id redirect_url first_traffic_at first_daily_traffic_at accepted_at create_origin] | ||
| params.permit(*allowed_attrs) | ||
| end | ||
|
|
||
| def flat_params | ||
| super.except(:account_id) | ||
| def application_update_params | ||
| application_params.except(:application_id) | ||
|
akostadinov marked this conversation as resolved.
|
||
| end | ||
|
|
||
| def find_or_create_service_contract | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,8 @@ def create | |
| private | ||
|
|
||
| def user_params | ||
| flat_params.merge({signup_type: :minimal}) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
| defined_user_fields = current_account.defined_fields_names_for(User) | ||
| params.permit(*defined_user_fields, :password, :password_confirmation) | ||
| end | ||
|
|
||
| def check_creation_errors | ||
|
|
@@ -31,7 +32,7 @@ def check_creation_errors | |
| end | ||
|
|
||
| def signup_params | ||
| Signup::SignupParams.new(plans: plans, user_attributes: user_params, account_attributes: flat_params, defaults: defaults) | ||
| Signup::SignupParams.new(plans: plans, user_attributes: user_params.merge(signup_type: :minimal), account_attributes: account_params, defaults: defaults) | ||
| end | ||
|
|
||
| def defaults | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,10 +18,7 @@ def create | |||||||||
|
|
||||||||||
| authorize! :create, user | ||||||||||
|
|
||||||||||
| user.unflattened_attributes = flat_params | ||||||||||
| user.signup_type = :created_by_provider | ||||||||||
|
|
||||||||||
| user.save | ||||||||||
| user.update(user_params.merge(signup_type: :created_by_provider)) | ||||||||||
|
|
||||||||||
| respond_with(user) | ||||||||||
| end | ||||||||||
|
|
@@ -39,7 +36,7 @@ def show | |||||||||
| def update | ||||||||||
| authorize! :update, user | ||||||||||
|
|
||||||||||
| user.update_with_flattened_attributes(flat_params, as: current_user.try(:role)) | ||||||||||
| user.update(user_params) | ||||||||||
|
|
||||||||||
| respond_with(user) | ||||||||||
| end | ||||||||||
|
|
@@ -131,7 +128,13 @@ def can_create | |||||||||
|
|
||||||||||
| private | ||||||||||
|
|
||||||||||
| def flat_params | ||||||||||
| super.except(:id) | ||||||||||
| def user_params | ||||||||||
| defined_fields_names = current_account.provider_account.defined_fields_names_for(User) | ||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These endpoints are for managing the users of the provider account (
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it would be more understandable to have it as |
||||||||||
| # both `:member_permission_service_ids` and `member_permission_service_ids: []` need to be permitted, because the | ||||||||||
| # value can be either `nil` (meaning all services are allowed), or an array | ||||||||||
| permission_attrs = [:member_permission_service_ids, { member_permission_service_ids: [], member_permission_ids: [] }] | ||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ideally that would be a code comment for future readers. Although I think we have tests for that so one will notice. |
||||||||||
| allowed_attrs = defined_fields_names + %w[password password_confirmation cas_identifier] | ||||||||||
| allowed_attrs += permission_attrs if provider_key.present? || current_user.admin? | ||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Permission attributes were only restricted for admin users here:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit worried about this, the security depends on we remembering to always add this check in all controllers that handle these attributes. Is this properly tested? If we have to add such a check in controller, why not delegating this to cancancan like we do here? porta/app/controllers/provider/admin/account/users_controller.rb Lines 61 to 64 in 71e6ead
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also thought about cancan, this role you found is really nice. The issue though is this So it will be nice to have it but I would not require it for this PR. On the other hand, previously provider_key auth was not handled, so not handling it in this PR will not be a regression. An easy fix might be to set In summary, I'm ok with all options:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But we already have a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked this. When we authenticate via What I wonder is: are we implementing all these ugly workarounds in each API controller in order to accept provider keys? This is what claude says: This project is gonna kill me.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is what I told you :) that current_user is not set. But we can change the module to set first admin for example. Provider key means something like the provider root account. When you lost access to your admin for some reason, you can recover with the provider key. I think that not so many controllers check user permissions. In all of them though, we would need special logic to handle As this is not a regression though, I would suggest such improvements to be performed within another JIRA issue.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand you now. Yeah, I think setting
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't quite understand what Claude is suggesting... But here are some points:
I don't really understand how this is expected to work based on the But according to the tests, this is what happens: Indeed, if Probably, because of the missing role in So, with
I am not expecting us to add more controllers for handling these fields. Conclusion: I think the current implementation achieves the same behavior as before, so I wouldn't complicate things any more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, not in this PR. What I thought was that in case we already have or add in the future permissions checks in other controllers, it might be worth having a |
||||||||||
| params.permit(*allowed_attrs) | ||||||||||
| end | ||||||||||
| end | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,10 +30,7 @@ def new | |
| end | ||
|
|
||
| def update | ||
| vat = account_params[:vat_rate] | ||
| account.vat_rate = vat if vat # vat_rate is protected attribute | ||
|
|
||
| if account.update(account_params.except(:vat_rate)) | ||
| if account.update(account_params) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| redirect_to admin_buyers_account_path(account), success: t('.success') | ||
| else | ||
| render :edit | ||
|
|
@@ -109,13 +106,18 @@ def signup_params | |
| Signup::SignupParams.new(plans: [], user_attributes: user_params.merge(signup_type: :created_by_provider), account_attributes: account_params, validate_fields: false) | ||
| end | ||
|
|
||
| # TODO: using `permit` later | ||
| def account_params | ||
| @account_params ||= params.require(:account).except(:user) | ||
| defined_builtin_fields_names = current_account.defined_builtin_fields_names_for(Account) | ||
| defined_extra_fields_names = current_account.defined_extra_fields_names_for(Account) | ||
| allowed_attrs = defined_builtin_fields_names - %w[billing_address country] + %w[country_id] | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The test |
||
| params.require(:account).permit(*allowed_attrs, extra_fields: defined_extra_fields_names) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here and in other UI controllers - custom parameters (invented by the user) are submitted inside |
||
| end | ||
|
|
||
| def user_params | ||
| params.require(:account).fetch(:user, {}) | ||
| defined_builtin_fields_names = current_account.defined_builtin_fields_names_for(User) | ||
| defined_extra_fields_names = current_account.defined_extra_fields_names_for(User) | ||
| allowed_attrs = defined_builtin_fields_names + %w[password] | ||
|
akostadinov marked this conversation as resolved.
|
||
| params.require(:account).fetch(:user, {}).permit(*allowed_attrs, extra_fields: defined_extra_fields_names) | ||
| end | ||
|
|
||
| def set_plans | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.