Configure simple_token_authentication with devise - ruby-on-rails

After setup devise and simple_token_authentication and configure the
ApplicationController
acts_as_token_authentication_handler_for User
respond_to :html, :json
protect_from_forgery with: :null_session
before_action :configure_permitted_parameters, if: :devise_controller?
protected
#added username to signup
def configure_permitted_parameters
added_attrs = [:name, :username, :email, :password, :remember_me, :avatar, :avatar_cache, :remove_avatar]
devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
devise_parameter_sanitizer.permit :account_update, keys: added_attrs
end
#Override authenticate_user! to handle html and json separately
def authenticate_user!
if self.request.format.html?
super
elsif self.request.format.json?
if self.request.parameters["controller"].start_with?("devise")
# use the default if session related
super
else
# others
if user_signed_in?
# use the default if already signed in
super
else
redirect_to root_path
end
end
end
end
When click on the User Edit Profile shows:
ArgumentError in Devise::RegistrationsController#edit wrong number of
arguments (given 1, expected 0) Extracted source (around line #20):
the error points to authenticate_user!
def authenticate_user!
if self.request.format.html?
super
elsif self.request.format.json?
in this case cant Override the authenticate_user!?
Or this is related with rails 5.1?
Someone is having this issue with simple_token_authentication?

The error message is telling you that Devise defines a method named authenticate_user!, which takes one argument. You are overriding the method, but your method doesn't take any arguments. At some point, Devise makes the call authenticate_user!(some_arg_here), so you get the error explanation:
Called with one arg...
|
V
wrong number of arguments (given 1, expected 0)
^
|
...but the method def expects 0 args
Here's a simple example of your error:
class Dog
def bark
puts "wuff"
end
end
Dog.new.bark(3)
--output:--
1.rb:2:in `bark': wrong number of arguments
(given 1, expected 0) (ArgumentError)
Here's the fix:
class Dog
def bark(repeat)
puts (["wuff"]*repeat).join(", ")
end
end
Dog.new.bark(3)
--output:--
wuff, wuff, wuff
So you need to define your authenticate_user! method so that it takes one argument. If you don't care about the argument, then name it trash.

Related

Devise - overriding ParameterSanitizer

I am attempting to configure a different Devise strong parameter sanitizer per model following the instructions at; https://github.com/plataformatec/devise#strong-parameters
I have created a new file named parameter_sanitizer within my Employer model directory;
app/controllers/Employers/paramater_sanitizer.rb
class Employer::ParameterSanitizer < Devise::ParameterSanitizer
def initialize(*)
super
devise_parameter_sanitizer.permit(:sign_up, keys: [:forename, :surname, :username)
end
end
Within my application controller I have;
require 'employers/parameter_sanitizer'
class ApplicationController < ActionController::Base
before_filter :devise_parameter_sanitizer, if: :devise_controller?
protect_from_forgery with: :exception
protected
def devise_parameter_sanitizer
if resource_class == Employer
Employer::ParameterSanitizer.new(Employer, :employer, params)
else
super # Use the default one
end
end
end
The error I get from signing up an Employer object is;
NameError in Devise::ConfirmationsController#show
undefined local variable or method `devise_parameter_sanitizer' for #
Any advice on how to overcome this?
Thanks,
Mark
In this initialize method you save the params as an instance variables #params so in your method you should do:
class Employer::ParameterSanitizer < Devise::ParameterSanitizer
def initialize(*)
super
#params.permit(:sign_up, keys: [:forename, :surname, :username])
end
also I believe this should work without specifying #params
Explanation
to find the solution to this problem check the devise api to better understand the methods you are calling and read the `Devise::ParameterSanitizer source code
I am quoting their ruby-rocs about the #permit() method
Instance Method Details
#permit(action, keys: nil, except: nil, &block) ⇒ Object
Add or remove new parameters to the permitted list of an action.
Arguments
action - A Symbol with the action that the controller is performing, like sign_up, sign_in, etc.
keys: - An Array of keys that also should be permitted.
except: - An Array of keys that shouldn't be permitted.
block - A block that should be used to permit the action parameters instead of the Array based approach. The block will be called with an ActionController::Parameters instance.
Examples
# Adding new parameters to be permitted in the `sign_up` action.
devise_parameter_sanitizer.permit(:sign_up, keys: [:subscribe_newsletter])
# Removing the `password` parameter from the `account_update` action.
devise_parameter_sanitizer.permit(:account_update, except: [:password])
# Using the block form to completely override how we permit the
# parameters for the `sign_up` action.
devise_parameter_sanitizer.permit(:sign_up) do |user|
user.permit(:email, :password, :password_confirmation)
end
Returns nothing.
Also I quote
If you have multiple Devise models, you may want to set up a different parameter sanitizer per model. In this case, we recommend inheriting from Devise::ParameterSanitizer and adding your own logic:
class ApplicationController < ActionController::Base
protected
def devise_parameter_sanitizer
if resource_class == User
User::ParameterSanitizer.new(User, :user, params)
else
super # Use the default one
end
end
end
User::ParameterSanitizer.new(User, :user, params) will call this initializer method from parameter_sanitizer.rb source code
def initialize(resource_class, resource_name, params)
#auth_keys = extract_auth_keys(resource_class)
#params = params
#resource_name = resource_name
#permitted = {}
DEFAULT_PERMITTED_ATTRIBUTES.each_pair do |action, keys|
permit(action, keys: keys)
end
end
so basically you are calling initialize(User, :user, params), I don't understand why devise is accepting params in this method, as it has his own way of allowing attributes by saving a static hash of permitted field.
DEFAULT_PERMITTED_ATTRIBUTES = {
sign_in: [:password, :remember_me],
sign_up: [:password, :password_confirmation],
account_update: [:password, :password_confirmation, :current_password]
}
and the permitting them with a loop
DEFAULT_PERMITTED_ATTRIBUTES.each_pair do |action, keys|
permit(action, keys: keys)
end
In this initialize method you save the params as an instance variables #params so in your method you should do:
class Employer::ParameterSanitizer < Devise::ParameterSanitizer
def initialize(*)
super
#params.permit(:sign_up, keys: [:forename, :surname, :username])
end

Add additional fields to the list of permitted ones in an devise Invitation controller

I've some additional fields to the "accept inviation form" and I need to permit them in a controller. I did this according to the documentation:
class Users::InvitationsController < Devise::InvitationsController
before_filter :configure_permitted_parameters, if: :devise_controller?
private
def accept_resource
resource_class.accept_invitation!(update_resource_params)
end
def configure_permitted_parameters
# error here
devise_parameter_sanitizer.for(:accept_invitation).concat [:field1, :field2, :field3]
devise_parameter_sanitizer.for(:accept_invitation) do |u|
u.permit(:field1, :field2, :field3, :password, :password_confirmation, :invitation_token)
end
end
I need to allow ":field1, :field2, :field3". Am I doing it right? I have an error
undefined method `for' for #<Devise::ParameterSanitizer:0x007f20fe0d5220> Did you mean? fork
Method for was deprecated and successfully removed from Devise.
Use permit/sanitize instead, or downgrade to 4.0 (not recommended).

How devise methods are available in ApplicationController.rb?

Is ApplicationController inherits from DeviseController?
Otherwise how devise methods are available in ApplicationController.
ApplicationController inherits from ActionController::Base, which
defines a number of helpful methods.
ref
Devise::Controller has a several modules that's hooked up in to ActionController on_load.
For example the Devise::Controller::Helpers module defines and loads helpers below:
# Generated methods:
# authenticate_user! # Signs user in or redirect
# authenticate_admin! # Signs admin in or redirect
# user_signed_in? # Checks whether there is a user signed in or not
# admin_signed_in? # Checks whether there is an admin signed in or not
# current_user # Current signed in user
# current_admin # Current signed in admin
# user_session # Session data available only to the user scope
# admin_session # Session data available only to the admin scope
#
# Use:
# before_action :authenticate_user! # Tell devise to use :user map
# before_action :authenticate_admin! # Tell devise to use :admin map
ApplicationController doesn't inherit from DeviceController. ApplicationController inherits from ActionController::Base. In ApplicationController the method you talking about configure_permitted_parameters is used with before_filter which is callback.
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :password, :remember_me) }
end
No , Application Controller doesn't inherits from Devise controller.It is the base.To use devise methods in it, you can use the below:
before_filter :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) << [:first_name, :last_name, :is_active]
devise_parameter_sanitizer.for(:sign_in) << [:user_name]
devise_parameter_sanitizer.for(:sign_up) << [:first_name, :last_name,:username,:is_active]
end
def after_sign_in_path_for(resource)
"some path"
end
No, ApplicationController is the base, like the name, is the controller for the all application.
ApplicationController is extended from DeviseController.

devise confirmable routing - rails 4

i am new to rails and any advise and help will be much appreciated.
I am currently using devise confirmable
When a user signs up for the first time they get:
Re-directed to the application root at localhost:3000
Flash notice saying "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
So far so good.
I am trying to redirect the user to a different page when they signup
but unsure how - any advise would be much appreciated
application_controller.rb
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 after_sign_in_path_for(resources)
if userr_signed_in?
dashboard_path
elsif usera_signed_in?
admin_path
else
dashboardj_path
end
end
def after_sign_out_path_for(resources)
new_feedback_path
end
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:email) }
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:category_businesstype_id, :firstname, :lastname, :companyname, :email, :password, :category_role_id, :staff, :number, :hear, :city, :category_qualification_id, :language, :category_careerlevel_id, :desiredjob, :category_distance_id, :category_cvpreference_id, :category_joboption_id, :preferedlocation, :category_notice_id, :category_country_id, :category_positiontype_id ) }
end
end
According to your case, you want to redirect user after signup on a specific path. For that you need to override after_sign_up_path instead of after_sign_in_path.
In application controller you should have this method
def after_sign_up_path_for(resource)
after_registration_path // Your path should goes here
end
After sign_in path can only be used when you are trying to actually log in user to your system immediately after registration. Here you have to just redirect a user.

Configuring permit for 2 user models in Devise

I've been busting myself for a ton of hours now on how to do this.
I have 2 models.
intern.rb
company.rb
I've been able to add custom fields on registration, for me that was :name. I did that by adding:
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |i| i.permit(:email, :password, :name) }
end
I've been reading up on the devise readme and trying to understand how to add it so it's specific to one user model. But I get an error every single time.
I tried creating a controller called:
interns_controller.rb
with the code:
class Intern::ParameterSanitizer < Devise::ParameterSanitizer
def sign_up
default_params.permit(:email, :password, :name)
end
end
and then adding this into the
application_controller.rb
code:
protected
def devise_parameter_sanitizer
if resource_class == Intern
Intern::ParameterSanitizer.new(Intern, :intern, params)
else
super
end
end
however I get an error. What am I doing wrong here?
Image with error: http://s12.postimg.org/fqpwyzzdp/Screen_Shot_2014_06_17_at_15_41_58.png

Resources