LDAP authentication always returning true - ruby-on-rails

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.

Related

refactoring rails redirects with multiple ifs

In the app I am working on, the user can get to a new form from several different places. I need to redirect them back to where they came from. I solved it by passing a parameter in the link on the view, for example
= link_to "create a new post »", new_user_post_path(#current_user, :return_to => 'dashboard')
then in the new action in the controller like so
if params[:return_to] == 'dashboard'
session[:return_to]= 'dashboard'
end
now I am looking at the controller. what I need to do I can achieve by being really verbose, but I'm looking for a more elegant solution. Here is what I have now
if #user_post.save
flash[:notice] = "New Post Created"
if session[:return_to] == 'dashboard'
session.delete(:return_to)
redirect_to dashboard_path and return
else
redirect_to user_hub_path(#user)
end
else
flash[:error] = "Could not save post"
redirect_to new_user_post_path(#user)
end
This does what I need but I was hoping to tidy it up a little. I started looking at 1 line enumerators to see if I could do something like this...
if #user_post.save
flash[:notice] = "New post Created"
session[:return_to] == 'dashboard' ? redirect_to "#{session.delete(:return_to)}_path" : redirect_to user_hub_path(#user)
else
flash[:error] = "Could not save post"
redirect_to new_user_post_path(#user)
end
but it really doesn't like this part....redirect_to "#{session.delete(:return_to)}_path"
any advice? Guess I'm trying to get it to redirect and delete the session in one line and this is beyond my knowledge...
This looks like a good case for using Rails' built-in :back parameter, which, according to the Rails docs here, sends the user "Back to the page that issued the request. Useful for forms that are triggered from multiple places. Short-hand for redirect_to(request.env["HTTP_REFERER"])"
You can avoid passing a return_to param, and change your controller code to:
if #user_post.save
redirect_to :back, notice: "New Post Created" and return
else
redirect_to new_user_post_path(#user), flash: { error: "Could not save post" }
end
What about using send?
send takes a message name and optional arguments and forwards that to send's receiver (http://ruby-doc.org/core-2.2.0/Object.html#method-i-send)
path = send("#{session.delete(:return_to)}_path")
redirect_to path
In this case it sends the message to the current controller instance (same as just calling the ..._path method but gives the flexibility of the dynamic call)
Please instead of using a redirect_to variable of your controller, use the Referer Header.
HTTP referer (originally a misspelling of referrer) is an HTTP header field that identifies the address of the webpage (i.e. the URI or IRI) that linked to the resource being requested
In Rails is quite simple inside a controller
redirect_to request.referer
That is more elegant and efficient, because the session cookie storage can be expensive (cache storage) and could affect your HTTP cache proxies performance.

request.url incorrect after ajax calls?

I login to my Rails application using a login page which is reached either directly through a login link that uses the route
match 'ladmin/login' => 'ladmin#login'
or if I try to edit content.
In either case I get taken to the login page, which allows me to login and then returns me to the page I was trying to use or the app index page, but now as a logged in user.
Most of the time this works totally ok, I get logged in and returns to my content edit page or to the links index page as expected (if I had just use the 'login' link iself).
However I have been able to track down a bug whereby
if I use either of my ajax links the request.url is remembered incorrectly going forward
(to either toggle group shading or to toggle Summary/Details, then the next time (even if several clicks) that I try to login (assuming I am logged out initially) results in the blank page - though I am actually now logged in. Interestingly I notice that when this happens, the url that I end up at in the browser address bar is always localhost:3000/toggle_row_shading which seems like a clue to the problem - it seems like the request.url is remembered incorrectly .
I require digest/sha1 for authentication in the User model with various methods for authentication and password.
The relevant code would seem to be in my LadminController:
def login
session[:user_id] = nil
if request.post?
user = User.authenticate(params[:username], params[:password])
if user
session[:user_id] = user.id
session[:username] = user.username
uri = session[:original_uri]
session[:original_uri] = nil
redirect_to(uri || {:action => "index", :controller => :links})
else
flash.now[:notice] = "Invalid username/password combination"
end
end
end
I can temporarily got around it with
def login
session[:user_id] = nil
if request.post?
user = User.authenticate(params[:username], params[:password])
if user
session[:user_id] = user.id
session[:username] = user.username
redirect_to({:action => "index", :controller => :links})
else
flash.now[:notice] = "Invalid username/password combination"
end
end
end
However this 'forgets' the page I have come from, e.g. an 'edit' link and just uses links#index to put me on after login which is not ideal. It does get around the blank page problem though, as the steps to reproduce it now longer make it happen.
How can I have the login return me to the intended edit page and not give me the blank page?
btw my code for the ajax links is:
%a{href: '#', :data => {toggle_group_row_shading: 'toggle'}}
click to toggle
Do I need an extra route perhaps as the app started at rails 2.3.8 ?
My routes include
match 'toggle_full_details' => 'links#toggle_full_details'
match 'toggle_row_shading' => 'links#toggle_row_shading'
get 'verify_link/:id', to: 'links#verify_link', as: :verify_link
get 'unverify_link/:id', to: 'links#unverify_link', as: :unverify_link
should I have them all as gets perhaps?
My application controller includes:
before_filter :authorize, :except => :login
and
def authorize
unless User.find_by_id(session[:user_id])
session[:original_uri] = request.url #request.request_uri
flash[:notice] = "Please Log In!"
redirect_to :controller => 'ladmin', :action => 'login'
end
end
I have had this happen to me before. The problem I found was that for AJAX requests, the session[:original_uri] is still getting stored and... is bad. Basically, it's storing a uri for an ajax request which doesn't display very well after logging in. The code I ended up with is something like:
if request.get? && !request.xhr?
session[:original_uri] = request.url
end
This way we're not storing into the session[:original_uri] things that shouldn't be redirected to after logging in. You may find other things in your app to add to this conditional. For example, I had some download links that would render a send_file, but those were no good for storing for next login either.

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!

Authlogic Facebook Connect Snafu

I have an application configured with authlogic and authlogic_facebook_connect, but every time I click to "Connect" button, my UserSession fails validation, saying "You did not provide any details for authentication"
Isn't the authlogic_facebook_connect supposed to bypass login/password authentication? Am I missing some configuration step?
Any help would be appreciated!
Hey, maybe I can help on this one, just had this problem not very long time ago...
Facebook connect is outdated. All the cool kids are now using Facebook Graph with OAuth. Facebook team have even closed the documentation for Facebook Connect.
Anyway, that goes for Authlogic Facebook connect, it simply does not work anymore.
In the end, I kept using Authlogic for normal login and account management, but for Facebook connect I wrote my own code.
Chances are you may have used facebooker gem. Uninstall that gem, but keep the config/facebooker.yml file.
Try this:
Keep using config/facebooker.yml by adding this code inside config/initializers/load_config.rb (you need to create this file)
config = YAML.load_file("#{Rails.root}/config/facebooker.yml") || {}
facebook_config = config['common'] || {}
facebook_config.update(config[Rails.env] || {})
FB_CONFIG = facebook_config.symbolize_keys
Add this code inside your user_controller.rb:
def facebook_oauth_callback
if not params[:code].nil?
callback = url_for(:host => APP_CONFIG[:host], :controller => 'gallery/user', :action => 'facebook_oauth_callback')
url = URI.parse("https://graph.facebook.com/oauth/access_token?client_id=#{FB_CONFIG[:application_id]}&redirect_uri=#{callback}&client_secret=#{FB_CONFIG[:secret_key]}&code=#{CGI::escape(params[:code])}")
http = Net::HTTP.new(url.host, url.port) http.use_ssl = (url.scheme == 'https') tmp_url = url.path + "?" + url.query
request = Net::HTTP::Get.new(tmp_url)
response = http.request(request)
data = response.body
access_token = data.split("=")[1]
if access_token.blank?
flash[:notice] = 'An error occurred while connecting through Facebook, please try again later.'
else
url = URI.parse("https://graph.facebook.com/me?access_token=#{CGI::escape(access_token)}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')
tmp_url = url.path + "?" + url.query
request = Net::HTTP::Get.new(tmp_url)
response = http.request(request)
user_data = response.body
user_data_obj = JSON.parse(user_data)
#user = User.new_or_find_by_facebook_oauth_access_token(access_token, {:user_data => user_data_obj})
if #user.new_record?
session[:user] = #user
session[:external_app] = "Facebook"
redirect_to(:action => 'new_details')
else
user_session = UserSession.create(#user)
flash[:notice] = "Successfully logged in."
redirect_back_or_default root_url
end
end
end
end
def create_facebook
redirect_to("https://graph.facebook.com/oauth/authorize?client_id=#{FB_CONFIG[:application_id]}&redirect_uri=" +
url_for(:host => APP_CONFIG[:host], :controller => 'gallery/user', :action => 'facebook_oauth_callback') +
"&scope=email,offline_access")
end
Add the find method inside your User model (app/models/user.rb):
def self.new_or_find_by_facebook_oauth_access_token(access_token, options = {})
user = User.find_by_facebook_oauth_access_token(access_token)
if user.blank?
#code to create new user here
end
user
end
Add link to action create_facebook in the view, something like
<%= link_to image_tag('gallery/button-facebook.png', :title => "register with Facebook", :alt => "register with Facebook"), {:action => 'create_facebook'}, {:target => '_parent'} %>
Explanation
In the first step you created a file to get config data from facebooker.yml
In second step, you basically created two functions, one for sending user to facebook site (create_facebook) and another to capture the callback data (facebook_oauth_callback) the idea was from this page: http://www.wisejive.com/2010/05/facebook-oauth-on-rails.html
In third step, you just added a method inside User model to find, or create new if not found, a user based on the information returned from facebook.
The code only works on my project, do not just copy-paste it but learn it line-by-line. Over time I realised it is better to use simple code you can understand rather than using other's complicated plugin you cannot fix when things go awry...
I had this problem, I think my problem was in my call to
<%= authlogic_facebook_login_button :controller => 'account', :js => :jquery %>
note I had to pass in controller. I think this was my solution anyway, hit another problem further down the line now where I'm authenticating OK with facebook, but it's creating a new user on my site every time.

Flash not surviving a redirect in Facebook on a Rails application

I have the following two action methods:
def index
puts "==index== flash: #{flash.inspect}"
end
def create
flash[:notice] = "Blah"
puts "==create== flash: #{flash.inspect}"
redirect_to(:action => :index)
end
index.fbml.erb contains this:
<%= button_to_with_facebooker "Blah!", :action => :create %>
The application is used through Facebook. I click the button and the flash contains the notice while create is being executed, but after that it's empty again. It doesn't survive a redirect. Any ideas what's going on here?
I've found one workaround. While using ActiveRecord to store the session, add
ActionController::Dispatcher.middleware.delete Rack::FacebookSession
ActionController::Dispatcher.middleware.insert_before(
ActionController::Base.session_store,
Rack::FacebookSession,
ActionController::Base.session_options[:key])
in an initialization file, like config/initializers/session_store_fix_facebooker_session_key.rb
This has been done on by someone else before and he explained it on a message on the Facebooker group on but it doesn't work with the cookie session storage, Rail's default.

Resources