Issue with authorization twitter (devise gem, rails) - ruby-on-rails

Good day. Maybe my problem is nonsense but i have after singup in twitter error:
ArgumentError in Devise::RegistrationsController#new
wrong number of arguments (given 2, expected 0..1)
I use multiply singup in my app and other work good
My callback controller:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, omniauth_providers: %i[google_oauth2 twitter github]
def self.from_omniauth(auth, _signed_in_resource = nil)
user = User.where(provider: auth.provider, uid: auth.uid).first
if user.present?
user
else
user_with_email = User.find_by_email(auth.info.email)
if user_with_email.present?
user = user_with_email
else
user = User.new
if auth.provider == 'github'
user.provider = auth['provider']
user.uid = auth['uid']
user.oauth_user_name = auth['info']['name']
user.email = auth['info']['email']
user.save
elsif auth.provider == 'twitter'
user.provider = auth.provider
user.uid = auth.uid
user.oauth_token = auth.credentials.token
user.oauth_expires_at = auth.extra.raw_info.name
elsif auth.provider == 'google_oauth2'
user.provider = auth.provider
user.uid = auth.uid
user.oauth_token = auth.credentials.token
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.email = auth.info.email
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save
end
end
end
user
end
def self.new_with_session(params, session)
if session['devise.user_attributes']
new(session['devise.user_attributes'], without_protection: true) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def password_required?
super && provider.blank?
end
end
Thank you for attention and help.

Related

NoMethodError Omniauth Facebook in Rails project

I got some problem with OmniAuth FaceBook login into my webapp.
Tell me please, what should i edit to fix this error? Check the code.
Error in the browser:
undefined method `to_a' for "Name Surname":String
User.rb:
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
x = auth.info.name.to_a
user.name = x[0]
user.surname = x[1]
user.login = auth.info.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
Omniauth_callback_controller.rb :
def facebook
if request.env["omniauth.auth"].info.email.blank?
redirect_to "/users/auth/facebook?auth_type=rerequest&scope=email"
end
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
if(#user.surname.nil?)
redirect_to new_profile_path
else
redirect_to my_profile_path
end
end
end
devise.rb :
config.omniauth :facebook, '*********', '*********', {:client_options => {:ssl => {:verify => false}}}
name is a string and you are trying to convert it to array
x = auth.info.name.to_a
use split instead
x = auth.info.name.split
#=> ['Name', 'Surname']
You can make use of OmniAuth first_name and last_name:
Update your devise.rb:
config.omniauth :facebook, '*********', '*********', info_fields: 'email, first_name, last_name', {:client_options => {:ssl => {:verify => false}}}
and your user.rb:
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.name = auth.info.first_name
user.surname = auth.info.last_name
user.login = auth.info.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
your user.rb should be like this
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
x = auth.info.name.split
if x.count > 1
user.name = x[0]
user.surname = x[1]
else
user.name = x[0]
end
user.login = auth.info.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
But I would suggest to store in a single field, because name can be of more than two words so it would become difficult to identify name and surname.
this link should also help

Sign into session as preexisting_user?

I'm getting the error: "couldn't find user with id" when trying to sign in with facebook. I want it where if a user is had already been created it triggers the first set of code in the conditional and if the user is new it triggers the second set of code:
sessions_controller
def facebook
preexisting_user = User.find(params[:id]) # What should go in this line?
user = User.from_omniauth(env["omniauth.auth"])
if preexisting_user
cookies.permanent.signed[:user_id] = user.id
redirect_to root_url
flash.now[:info] = 'Welcome Back to Live to Challenge!'
else
action = session.delete(:challenge_action)
user.challenges.create(action: action)
user.send_welcome_email
user.remember
cookies.permanent.signed[:user_id] = user.id
redirect_to tutorial_url
flash.now[:info] = 'Welcome to Live to Challenge!'
end
end
user.rb
def self.from_omniauth(auth)
# Sets 60 day auth token
oauth = Koala::Facebook::OAuth.new("154037ewr2976229929", "ee917abf2ere8f1c98274cdfwqreaebb1346f4")
new_access_info = oauth.exchange_access_token_info auth.credentials.token
new_access_token = new_access_info["access_token"]
new_access_expires_at = DateTime.now + new_access_info["expires"].to_i.seconds
where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
user.provider = auth.provider
user.image = auth.info.image
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = new_access_token # auth.credentials.token <- your old token. Not needed anymore.
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.password = (0...8).map { (65 + rand(26)).chr }.join
user.email = SecureRandom.hex + "#mailinator.com" unless user.email.present?
user.activated = true
user.save!
end
end
You can try below code, i am sure it will work.
def facebook
user = User.from_omniauth(env["omniauth.auth"])
# preexisting_user = User.find(params[:id]) # What should go in this line?
# user.persisted? is what you need to add if you want to add here
# if user pre existed, it will execute if block otherwise else block.
# checks if pre-existing user
if user.persisted?
cookies.permanent.signed[:user_id] = user.id
redirect_to root_url
flash.now[:info] = 'Welcome Back to Live to Challenge!'
else
action = session.delete(:challenge_action)
user.challenges.create(action: action)
user.send_welcome_email
user.remember
cookies.permanent.signed[:user_id] = user.id
redirect_to tutorial_url
flash.now[:info] = 'Welcome to Live to Challenge!'
end
end

Rails signup with multiple ways

On My current app that i'm developing, i can sign up using Facebook and Google+. But when I added the ability for signing up with just a regular email, i got this error, I'll appreciate some help please ...
Here are some of my code
#SessionsController
def create
#user = User.from_omniauth(env["omniauth.auth"])
# session[:user_id] = #user.id
# redirect_to root_path
#user = User.find_by_email params[:email]
if #user && #user.authenticate(params[:password])
session[:user_id] = #user.id
redirect_to root_path
else
flash[:alert] = "Wrong email or password"
render :new
end
end
#user.rb
class User < ActiveRecord::Base
has_secure_password
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.image = auth.info.image
user.gender = auth.extra.raw_info.gender
user.location = auth.extra.raw_info.location.name
user.location = auth.extra.raw_info.locale
# user.url = auth_hash['info']['urls'][user.provider.capitalize]
user.save
end
end
So When attempting to signUp with using the email, here's what happen !
enter image description here
I'm guessing that error coming because i'm calling from_omniauth and i'm not passing a provider, which i don't need to use in this case.
You might consider starting fresh - using https://github.com/plataformatec/devise and then adding OmniAuth on top of this (https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview).

Rails activerecord transaction after first_or_create

How to use ActiveRecord::Base.transaction after first_or_create ?
here is my model method:
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.password = 'password'
user.password_confirmation = 'password'
user.crypted_password = 'password'
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
In my controller:
def social_login
#user = User.from_omniauth(env["omniauth.auth"])
ActiveRecord::Base.transaction do
add_sites(#user)
#user.mobile = mobile_view?
#user.addresses.last.email = #user.email
add_point_to_customer(#user)
#user.add_mail_subscription_if_doesnt_exist(active_site)
end
end

Rails how to create Authlogic session from Omniauth Facebook

Here is my controller
def social_login
user = User.from_omniauth(env["omniauth.auth"])
session_params = user.attributes.merge("email" => user.email, "password" => user.crypted_password)
#user_session ||= UserSession.new(session_params, true)
if #user_session.save
user = User.where(email: #user_session.email).first
redirect_to root_path, :notice => "Signed in succesfully from #{env["omniauth.auth"].provider.titleize}. Greetings #{user.name.titleize} ;)"
else
flash.now[:alert] = "Sign in failed."
render "new"
end
end
here is the model to handle the omniauth process
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.password = auth.credentials.token
user.password_confirmation = auth.credentials.token
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
I always getting error when trying to save the session. It says:
Authlogic::Session::Existence::SessionInvalidError: Your session is invalid and has the following errors: Email is not valid
can you guys help me? thanks
Did you enable the email permission in your facebook app config/rails's initializion?
Like this:
config.omniauth :facebook, "APP_ID", "APP_SECRET", {:scope => 'email,...'}

Resources