Devise Strong Parameters when trying to update user account - ruby-on-rails

I am trying to move from the account update page and submit it. I think i am having problems with devise and this submitting. I have tried a few things in the application controller but have not had any joy. Also i have read through the devise docs but this hasnt worked for me either. The error i am getting is the following: 1 error prohibited this user from being saved: Current password can't be blank
This is the case when i have input the users current password? I have included the errors from my terminal and also the code from my application controller.
Processing by Devise::RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"DVVUgIGna8TZwJTBU/ghNT7PTcO/CERC0JXUUQWOW/o=", "user"=>{"name"=>"Emma", "email"=>"n#m.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "current_password"=>"[FILTERED]", "line1"=>"", "line2"=>"", "town"=>"", "county"=>"", "postcode"=>"", "organization"=>""}, "commit"=>"Update"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 21 ORDER BY "users"."id" ASC LIMIT 1
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 21]]
Unpermitted parameters: email, password, password_confirmation, current_password, organization
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :email, :password) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :line1, :line2, :town, :county, :postcode)}
end
private
def after_sign_in_path_for(resource)
edit_user_registration_path(current_user) #basically whichever path you think meets your needs
end
end

updated with the following and solved this
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :line1, :line2, :town, :county, :postcode, :password, :password_confrimation, :current_password)}

Related

The custom field in devise user model is not being verified before login

I am a beginner in Ruby on Rails and I have been trying to solve this issue for a long time but I have not seen any success so far.
In my project I am using devise for User authentication. In the user model generated by devise, I have added two custom attributes through migrations.
1st one is the username of type string and 2nd attribute will be the role of type integer which will be used as enum to store the role of current user.
I have updated the devise views as well for showing the role drop down menu to user during signing up and signing in but I am facing following issue.
Whenever I try to login, it just checks the db for whether the given email exists or not. If there is any record against the email, it logins the user otherwise not. What I want is that during login the field of user roles should also be verified whether its true or not.
Right now my application controller contains following code
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :email, :password, :role])
devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:username, :email, :password, :current_password, :role)}
devise_parameter_sanitizer.permit(:sign_in) { |u| u.permit(:username, :email, :password, :role)}
end
end
The output during this login process on the rails terminal is shown below
Started POST "/users/sign_in" for ::1 at 2022-05-17 12:32:26 +0500
Processing by Users::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"<token>", "user"=>{"email"=>"test#gmail.com", "password"=>"[FILTERED]", "role"=>"manager", "remember_me"=>"0"}, "commit"=>"Log in"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? ORDER BY "users"."id" ASC LIMIT ? [["email", "test#gmail.com"], ["LIMIT", 1]]
↳ /Users/dev/.rvm/rubies/ruby-2.7.2/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/tempfile_reaper.rb:15
Redirected to http://localhost:3000/
Completed 302 Found in 269ms (ActiveRecord: 0.2ms)
Kindly help me out here
In the application controller you can add a method and check the roles in it.
def after_sign_in_path_for(resource)
if resource.manager? # or current_user.manager?
...
else
super
end
end
Link to the documentation of the method where exactly how it works is explained
And if you want to additionally verify the user by username, you need to uncommet config.authentication_keys in device config app/config/initializers/device.rb and add there username and email.

Getting "Filter chain halted as :validate_account_update_params rendered or redirected" when trying to update user

I am using ng-token-auth and devise_token_auth for authentication. When I am trying to update user using
$auth.updateAccount
it's showing me
Unpermitted parameters: credentials, registration
Filter chain halted as :validate_account_update_params rendered or redirected
I have included the following in application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?
private
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :name
devise_parameter_sanitizer.for(:account_update) << :name << :credentials
end
Also, credentials field is serialized as an Array in the User model
class User < ActiveRecord::Base
serialize :credentials, Array
end
I ran into the same issue and finally found a solution. For me, the problem was that the parent filter :validate_account_update_params was being called before the child :configure_permitted_parameters. This is apparently new behavior as of at least Rails 4.2 (and possibly before). Adding this in the child fixed it:
prepend_before_action :configure_permitted_params

Rails 5, Undefined method `for' for #<Devise on line devise_parameter_sanitizer.for

I am working with Rails 5
I aded new field username in model User.
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_permitted_parameters
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up).push(:username)
end
end
During registration is displayed error: undefined method `for' for # Did you mean? fork
Trace:
NoMethodError (undefined method `for' for #
Did you mean? fork):
app/controllers/users/registrations_controller.rb:7:in `configure_permitted_parameters'
Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (5.0ms)
Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.9ms)
Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.2ms)
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (118.1ms)
Who can help? How solve this problem?
According to the documentation:
The Parameter Sanitaizer API has changed for Devise 4
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
end
end
If you just change the .for to .permit it works as well. For example:
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit({ roles: [] }, :email, :password, :password_confirmation, :username) }
It works in both Rails 4.2.x and Rails 5.0.x
Don't forget devise_parameter_sanitizer.permit(:account_update, keys: [:username])
I think you missed account_update in your controller's configure_permitted_parameters method, you need to follow the devise pattern. Devise has a an account update page. You can find this in views/devise/registrations/edit.html.erb, and your code is also not going to work in the sign_up page, here you specified sign_up page
To update your user table, the minute you submit an update in your users/edit, or if you are submitting a username in the sign_up page you need to follow this devise pattern, to update the database User table. Even if you added a new column to the user table, you would have to add it to the configure_permitted_parameters method. In your case it's username, but you missed account_update as well. You're basically saying that you want to update the username or add the string to username field without following the Devise pattern. Any field you add to the User table should follow this Devise pattern. Also you can specify which page is permitted to update this username. In my example below, i'm using the devise update page. So like I said, even if you added a custom field name to Users table you need to follow this pattern. If you have another page where you need to add username, you would just do the same thing.
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
devise_parameter_sanitizer.permit(:account_update, keys: [:username])
end
end
Next make sure in your user.rb you have validate username in your User model.
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
validates :username, presence: true
end
To update your user table, the minute you submit an update in your users/edit, or if you are submitting a username in the sign_up page you need to follow this devise pattern, to update the database User table. Even if you added a new column to the user table, you would have to add it to the configure_permitted_parameters method. In your case it's username, but you missed account_update as well. You're basically saying that you want to update the username or add the string to username field without following the Devise pattern. Any field you add to the User table should follow this Devise pattern. Also you can specify which page is permitted to update this username. In my example below, i'm using the devise update page. So like I said, even if you added
class ApplicationController < ActionController::Base
before_action :configure_permitted_paramters, if: :devise_controller?
protected
def configure_permitted_paramters
devise_parameter_sanitizer.permit(:sign_up, keys: [:fullname])
devise_parameter_sanitizer.permit(:account_update, keys: [:fullname,
:phone_number, :description, :email, :password])
end
end

Devise ignoring permitted parameters on Rails 4

I am trying to pass an additional parameter for my devise user model on Rails 4. Since it needs to be permitted I added a filter to my main application controller as below.
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
prepend_before_filter :add_allowed_devise_session_params, if: :devise_controller?
def add_allowed_devise_session_params
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit("avatar") }
end
end
But when submitting for :sign_up I am still getting the error:
Unpermitted parameters: avatar
The parameters look like this:
Processing by RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"vp1ir2TJwZXwYGFtDc97bSf/dnXQQl1pksHVxdVTaWc=", "user"=>{"name"=>"stan#merkwelt5.com", "email"=>"stan#merkwelt5.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x007fa05762a918 #tempfile=#<File:/var/folders/8y/g14_rdxx31gb35dyjhltk4xc0000gn/T/RackMultipart20131219-7366-vf7of8>, #original_filename="instagram_logo.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"instagram_logo.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Sign up"}
I validated that the filter is actually called on :sign_up and its per the devise documentation:
https://github.com/plataformatec/devise#strong-parameters
What am I missing?
It turns out I overlooked that the devise controllers had to be updated. Didn't look there since the devise documentation points to ApplicationController.
class RegistrationsController < Devise::RegistrationsController
before_filter :update_sanitized_params, if: :devise_controller?
def update_sanitized_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:avatar,:name, :email, :password, :password_confirmation)}
devise_parameter_sanitizer.for(:account_update) {|u| u.permit(:avatar,:name, :email, :password, :password_confirmation, :current_password)}
end
end

Devise 3.0 after bundle update and registration stop working

I made bundle update for my project and devise stop working on it. Right now it says that email cant be blank - but it isnt. Can somebody tell my what is wrong and what change in devise 3.0?
Output in console for devise is:
Processing by Devise::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"L5182qPo2YonLhXfMbCXxXtvEHfM8YZMYr74pnPN8K0=", "user"=>{"name"=>"user_10", "email"=>"user_10#email.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
Unpermitted parameters: name, email
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :email, :password, :password_confirmation) }
end
For application_controller and devise working

Resources