User fetching with Rails, BCrypt, Mongoid, and MongoLab fails in deployment - ruby-on-rails

I'm a first-time poster trying to wade through making MongoDB play nice with Rails and Heroku. Right now, I'm getting errors that make me think there is a problem comparing user passwords (that are supposed to be obscured with Bcrypt) during log in. Eager for more advanced eyes, or a better idea of how to troubleshoot this problem.
In the app, I find and create Users like so:
def create
password_key = BCrypt::Password.create(params[:user][:password])
params[:user][:password] = password_key
newUser = User.create(params[:user])
flash[:message] = "Account created! Please log in:"
redirect_to controller: "users", action: "login"
end
def login
end
def find
username = params[:user][:username]
#user = User.where( username: username )[0]
if #user
if BCrypt::Password.new(#user.password) == params[:user][:password]
session[:user_id] = #user.id
redirect_to controller: "application", action: "home"
else
flash[:message] = "Wrong password. Try again."
redirect_to controller: "users", action: "login"
end
else
flash[:message] = "We didn't recognize that username."
redirect_to controller: "users", action: "login"
end
end
This worked fine for me in local dev. When I first deployed to Heroku, I received a "Something went wrong." error instantly upon trying to create a new user, which indicated that I didn't have my production environment configured correctly.
After more reading, I decided to use MongoLab to host my production database. I set that up with an add-on to my heroku repository following this tutorial.
Then I set my heroku env. variable MONGOLAB_URI to the appropriate URI, and included the following in my mongoid.yml file:
production:
sessions:
default:
uri: <%= ENV['MONGOLAB_URI'] %>
options:
consistency: :strong
safe: true
skip_version_check: true
Now, when I access the live app, I no longer get an error when I try to create a user! I am redirected as I would expect and receive my "Account created! Please log in:" flash message.
HOWEVEVER, when I try to login with the credentials I just saved to the database, I'm redirected and my "Wrong password. Try again." flash message fires -- which to me indicates that there is some kind of issue with how passwords are being stored or compared with the combination of BCrypt/Mongoid/MongoLab.
Help, please! Is there something I'm missing about how to use BCrypt with Mongoid? This is only happening to me in production and I'm not sure how to troubleshoot.
Thanks in advance.

Related

Sidekiq ActionMailer working in development but not i produciton (using mailgun)

I have set up Sidekiq to send an email on sign up.
The process works fine in development mode however in production it seems like my smtp settings (or something else) is not working, when i use sidekiq (sendt to redis).
Is there a gotcha to using sidekiq to send mails via Mailgun?
This is my create user action:
def create
#user = User.new(params[:user])
#user.roles << Role.find_by_role("member")
#user.subdomain = #user.subdomain.downcase
#user.generate_token(:confirm_email_token)
#user.confirm_email_sent_at = Time.zone.now
if #user.save
UserMailer.delay.new_user(#user.id)
redirect_to root_url, notice: "Thank you for registering."
else
render "new"
end
end
And this is my mailer:
def new_user(user_id)
#user = User.find(user_id)
mail :to => #user.email, :subject => "Welcome to Theatrical.co"
end
In development this works fine. However in produciton this is not working. I get this error messege:
Net::SMTPFatalError: 550 5.7.1 Relaying denied
It seems to be related to Mailgun not accepting redis or sidekiq to send mail.
Is there some secret setting i need to chenge?
You must be authorized to use a mail server for relaying .Unauthorized users will receive the "Relaying Denied" error. confirm that user has sufficient permission to send mail

Ruby on rails .authentication failing

I'm building an API for a web app I'm developing, and the following code I'm trying to use for API authentication/login is returning false on the authorization.
In my API user controller I have:
def login
if params[:user]
# Find the user by email first
#user = User.where(email: params[:user][:email]).first
if !#user
respond_with nil
else
#auth = #user.authenticate(params[:user][:password])
if #auth
respond_with #user
else
respond_with #auth
end
end
end
end
It is always responding with #auth, which is false, even when valid email and passwords are being provided. It has no problem pulling the user info from my Mongo db.
I guess I'm just not clear on what .authenticate does. According to a railscast.com video I watched, it should compare that users password digest with the password entered. When a valid password is provided for the user, #auth is always false.
This method was actually working fine, the test data in the database wasn't what i thought it was..

LDAP authentication always returning true

Im following a tutorial online (http://my.opera.com/learnror/blog/ldap-binding-and-authentication-ror) to setup authentication against an LDAp active directory (have a pretty tough time with it too). Anyway, i got the login form and everything setup but for some reason, no matter what i type into the form, (even wrong/nonexistent credentials), it comes back as true! Can anyone help?
OR can anyone provide away to have some sort of debugger run the code line by line (like done with jaavscript debugger). Heres the code that authenticates the login form: (the LDAP module is in a separate lib file):
def authenticate
if session[:person] = LDAP.authenticate(params[:login][:name], params[:login][:p
assword])
session[:username] = params[:login][:name]
if session[:return_to]
redirect_to(session[:return_to])
session[:return_to] = nil
else
redirect_to :controller => 'login' , :action => 'index'
end
else
flash[:notice] = "Login failed!"
redirect_to :action => "index"
end
It looks to me like you used = instead of == in if session[:person] = LDAP… == means equals, = means assignment.

OmniAuth / Rails - You have a nil object when you didn't expect it

I'm getting the following error in my Rails application and I have no idea how to go about debugging or fixing it:
NoMethodError in
AuthenticationsController#create
You have a nil object when you didn't
expect it! You might have expected an
instance of ActiveRecord::Base. The
error occurred while evaluating nil.[]
Rails.root:
/Users/phil/Sites/travlrapp.com
Application Trace | Framework Trace |
Full Trace
app/controllers/authentications_controller.rb:15:in
`create'
The controller is this:
class AuthenticationsController < ApplicationController
def index
#authentications = current_user.authentications if current_user
end
def create
omniauth = request.env["omniauth.auth"]
unless omniauth
redirect_to authentications_url
flash[:notice] = "Could not authenticate via #{params['provider']}."
end
authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
if authentication
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, authentication.user)
elsif current_user
current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid'], :token => omniauth['credentials']['token'], :secret => omniauth['credentials']['secret'])
flash[:notice] = "Authentication successful."
redirect_to authentications_url
else
user = User.new
user.apply_omniauth(omniauth)
if user.save
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, user)
else
session[:omniauth] = omniauth.except('extra')
redirect_to new_user_registration_url
end
end
end
def destroy
#authentication = current_user.authentications.find(params[:id])
#authentication.destroy
flash[:notice] = "Successfully destroyed authentication."
redirect_to authentications_url
end
end
OmniAuth used to work fine, then I mashed it up trying to swap to a fork by pchilton which supported flickr. I did this by setting :git => in the gemfile and trying to reinstall but im not confident I ever did it right.
I have now manually removed all omniauth and oa- foo gem files and installed first the current stable (0.1.6) and the git master copy but all errors are the same.
Really at a loss here, nobody I know has any idea what the problem is.
It's probable that omniauth is nil. While you are checking for nil with unless onmniauth, the redirect_to doesn't actually stop the controller code below from executing.
You probably want something like this:
unless omniauth
redirect_to authentications_url
flash[:notice] = "Could not authenticate via #{params['provider']}."
return
end
Now, you still need to figure out why omniauth is nil. For that, make sure you are using OmniAuth correctly by looking at the README. Is /auth/provider/callback routed to AuthenticationsController#create ?
I apologize in advance if you already know this method (you are a php developer after all).
Does rails support php style debugging similar to die() ? I have encountered weird incomprehensible error like this in both yii and kohana php frameworks.
What I do is put a die('AAAAA') at the end of the controller acion, and gradually move it up until IT gets triggered before the error does, that way I know exactly on what line the error was.
Then i move it into whatever function is called on that line and start again.
I don't know if rails supports this kind of raw debug style. Also it would help if the source code for those gems are in noncompiled code so you can insert die() all over the place like that.
You could do something like the equivalent of echo 'AAA'; exit; or something similar.
Also there is also the 'check if a function gets called: die('BBBBB'); :P
If you want to go really advanced there is also
die("AAAAA ".' '.__FILE__.'::Line:'.__LINE__);
This seemed to randomly fix itself. Go Rails!

Implicit user creation with Authlogic and Authlogic OAuth plugin

I'm trying to write a simple OAuth consumer app in Rails. I'm using Authlogic for handling authentication and the Authlogic OAuth plugin to do the oauth thing.
The oauth plugin provides a couple of helpers to render the sign in button: oauth_login_button and oauth_register_button. Together with the Authlogic logics and the plugin's request filters these two buttons somehow create the session/user.
What happens next is as follows:
- if I use the oauth_login_button helper, then the session object fails to save as there's no such user locally.
- if I use the oauth_register_button helper, then, on any login after the first one, Rails complains that the token has been taken already... that means it can't create the second copy for the same user, which is right.
The issue is: I don't want to have BOTH Register AND Login buttons on my site.
On the user side, what I want to achieve is a single button on the start page, saying smth. like "Sign In with Twitter", which the user must click to proceed to inner pages of the site.
On the server side, I want to implicitly create the local user account, if the user is a first time visitor to my site.
Any hints on how to do this?
All the samples on Authlogic+OAuth I was able to find don't seem to care about having only a single button for sign in. :(
Seems like I'm going to answer the question myself.
I use the following code to generate the Sign In button (in HAML):
- form_tag({:controller => "users", :action => "create"}, {:method => "post"}) do
= oauth_register_button :value => "Sign In with Twitter"
and then I simply create the user's session object in the create method of the UsersController class, if the user already exists:
def create
#user = User.new(params[:user])
#user.save do |result| # LINE A
if result
flash[:notice] = "Account registered!"
redirect_to some_inner_path
else
unless #user.oauth_token.nil?
#user = User.find_by_oauth_token(#user.oauth_token)
unless #user.nil?
UserSession.create(#user)
flash.now[:message] = "Welcome back!"
redirect_to some_inner_path
else
redirect_back_or_default root_path
end
else
redirect_back_or_default root_path
end
end
end
end
If the user is a first time visitor, then the user object is successfully saved in the LINE A. And if it's not and there's an oauth token available, then we try to fetch the user from the DB and log him/her in.

Resources