Create new user session without password in authlogic - ruby-on-rails

I am using authlogic and omniauth for authentication in my Rails 3.0.10 app.
However when I get the callback from the omniauth provider, I am not able to create a new user session so as to sign in the user.
In other responses (and even in the authlogic docs), it says that using UserSession.create(#user, true) should be able to create and persist a new session.
However, this does not work for me. It only works if the #user has a password in the database (by inserting a password directly in the db).
But there is no password when using third-party authentication providers, hence I cannot sign in users.
Any ideas how to sign in a user without a password in authlogic?
Thanks.

You can do something like this in your User model:
acts_as_authentic do |config|
external = Proc.new { |r| r.externally_authenticated? }
config.merge_validates_confirmation_of_password_field_options(:unless => external)
config.merge_validates_length_of_password_confirmation_field_options(:unless => external)
config.merge_validates_length_of_password_field_options(:unless => external)
end
externally_authenticated? is just a method on the user that checks what is providing the user information, and if it's one of the omniauth providers, returns true.

Related

Accessing newly singed up user in Rails app using devise

I am currently making Rails app using devise.
After a new user signs up, I need to access newly singed up user's information to run my customized function.
However it seems like devise's current_user is nil since the user is not logged in yet until the user confirms the email.
I essentially just need to check whether user's confirmed_at is nil.
Is there a way to do this?
I would do this in the User model with a callback:
# in app/model/user.rb (assuming you have a User model)
after_create :run_customized_function
private
def run_customized_function
# whatever need to be done with this user, for example:
# Rails.logger.info("User##{id} just signed up with email '#{email}'")
end

Users and admin with Doorkeeper and Omniauth

I have a main app, this app has Users and Admins (different model and table)using devise.
The main app use doorkeeper to allow users to authenticate on another service. The client app use Omniauth to consume OAuth2.
I am now reaching a point where the client app need a backend and using the admin users from the main app make sense.
Here is my current strategy :
module OmniAuth
module Strategies
class ResaNetwork < OmniAuth::Strategies::OAuth2
option :name, :resa_network
option :client_options, {
#site: "http://dylog.ubuntu-sylario.net:3000",
site: ENV["CLIENT_OPTION_SITE"],
authorize_path: "/oauth/authorize"
}
uid do
raw_info["resource_owner_id"]
end
def raw_info
#raw_info ||= access_token.get('/api/me').parsed
end
end
end
end
For doorkeeper I will will use warden scope (I know it has nothing to do with oauth scope) user or admin depending on the oauth2 Scope in resource_owner_authenticator.
Is it possible to have a specific scope entered has a param with the signin path of omniauth? How?
Is my use of scope correct or is it a really ugly hack? For info, admin will access users data while users will only see their data in the API.

Devise: after successful login hook

In my rails app, I am using devise for my authentication system. I have a situation in which I want to encrypt some data using a key that is based off of the user's password. The easiest way that I can think to do this is during a successful sign in, to generate the user's private key from their plain-text password (passed in from the login form) and store that in the user's session. I don't really want to ask the user to enter their password more than once.
Does devise provide a way to specify a callback function after a successful login? Or is there a better way to do this?
http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/DatabaseAuthenticatable#after_database_authentication-instance_method
In the user model where you're using devise create a after_database_authentication instance method.
Assume you have Devise resourse User with attribut password, then you can access user password after login in after_sign_in_path_for, which is called after sucessful login.
# app/control,lers/application_controller.rb
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
password = param[:user][:password]
do_cool_stuf_with_password(password)
#...
return url_for_root
end
end

Devise, OmniAuth & Facebook - How to let user edit password?

I'm hoping that someone else has a good solution for this issue. We let our users register using facebook (by liking an app), and at the same time they enter our database as users on our site.
Upon successful registration it seems like Devise/OmniAuth is creating a random password(?). How can I let users edit their profile, which (and should) by default in Devise requires that they enter their current password?
I had the exact same issue so I hope my solution will be helpful.
Based off the details in your question I am assuming you following the OmniAuth guide in the devise wiki: https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
In the following method:
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token.extra.raw_info
if user = User.where(:email => data.email).first
user
else # Create a user with a stub password.
User.create!(:email => data.email, :password => Devise.friendly_token[0,20])
end
end
I changed the logic in the else block because it was creating a new user in the database right away and hashing a password for them:
else # Create new user
user =User.new
user
end
Instead I just made a new user so that after getting the facebook info I direct them to the sign up page where I have their info populated in the form fields where they can edit and create a password.
You will just need to make sure to update your
def self.new_with_session(params, session)
to add all the relevant facebook information you grabbed for a new user and assign it to the new user object so all those fields are populated with their information in the sign up page. So that after they finish typing their password and adding or changing any info and click submit it create the new user. Hopefully you find this helpful.
This was a mash of ideas for the wiki page on Devise and the railscast omniauth tutorial: http://railscasts.com/episodes/235-omniauth-part-1
Had a similar problem, but in regards to updating a user profile without password confirmation. Posting a link to it - hope it helps:
stackoverflow - Allowing users to edit accounts without saving passwords in devise

Advice on HTTP authentication scheme (using request headers)

I have a rails app hosted on Heroku that am restricting access to by using a proxy service. The external server acts as intermediary for all requests and handles user authentication. Once a user has authenticated, the server (I think LDAP) adds the user name to the request header and redirects them to my app.
I would like to use the username from the request header to authenticate users in my app. Basically if the user doesn't exist I would create a user with that username (no password required) and if not I would just log them in. I will be storing the users in my app's database.
How should I do this? Is it possible to use Devise for this purpose?
Edit: I got it working with Devise/custom Warden strategy like this:
# config/initializers/my_strategy.rb
Warden::Strategies.add(:my_strategy) do
def valid?
true
end
def authenticate!
if !request.headers["my_key"]
fail!("You are not authorized to view this site.")
redirect!("proxy_url")
else
username = request.headers["my_key"]
user = User.find_by_username(username)
if user.nil?
user = User.create(:username => username)
end
success!(user)
end
end
end
#config/initializers/devise.rb
config.warden do |manager|
manager.default_strategies(:scope => :user).unshift :my_strategy
end
I need to make this as bullet proof as possible. Are there other security measures can I take to make sure someone can't spoof the request header and access my site?
I think using devise can be a little more overkill, but you can. You just need define a warden strategie. in devise or use only warden in this purpose.

Resources