How to Use OmniAuth Properly with Rails 2 - ruby-on-rails

I am trying to use an OmniAuth (0.2.6) strategy for my application. The architecture is Rails 2.3.10 and Rack is version is 1.1 (this version or higher is required for OmniAuth). A problem that occurs is Rails doesn't recognize my redirect to "/auth/provider". The actual error message is "No route matches "/auth/casport". Even though that error gets thrown, the code seems to execute past that point up to this error: "request.env['omniauth.auth']", which I'm pretty sure means it doesn't recognize the "omniauth.auth" key for the env hash. I have a feeling that OmniAuth isn't being loaded properly. I've tested the same strategy and code base with Mongrel and Webrick, and I get identical error messages.
Here is my OmniAuth initializer (config/initializers/omniauth.rb):
ActionController::Dispatcher.middleware.use OmniAuth::Builder do
provider :casport, :setup => true
end
I definitely have routes in places for auth/casport/setup and auth/casport/callback.
I've also tried this approach: How do you implement OmniAuth on Rails 2.2?
config.middleware.use OmniAuth::Builder do
provider :casport, :setup => true
end
by placing that middleware code in the config/environments/development.rb file.
Does anyone have any thoughts on what I could be doing incorrectly? Thanks!
Edit: I've also tried this approach Has anyone used omniauth with rails 2.3.8?
ActionController::Dispatcher.middleware.use OmniAuth::Strategies::Casport = {
:setup => true
}
and that returns a read error: "NoMethodError: undefined method 'new' for #Hash...
Edit 2: I've upgraded to Rails 2.3.10 as OmniAuth isn't compatible with Rails 2.3.4.

I created an issue on OmniAuth's Github page https://github.com/intridea/omniauth/issues/397, with the above details and this is the response from Michael Bleigh, the creator of OmniAuth:
"OmniAuth has never officially supported Rails 2.3.x -- I've heard that some people have had luck with it but it's not something that is guaranteed. Sorry!"
So it looks like the methods I posted above may work for some folks. To guarantee correct operation, Rails 3 is needed.

Related

invalid salt (BCrypt::Errors::InvalidSalt)

Since upgraded to Ruby 2.2.0 I get the following message in my tests:
invalid salt (BCrypt::Errors::InvalidSalt)
I didn't find any upgrade notice helping me to understand the problem. I'm using Rails 4.1.8 and Sorcery 0.8.6.
Anybody else having this problem?
MORE Details:
I'm using Sorcery and not Devise. The encrypted data is the password.
It all started in Cucumber tests, in 2 cases:
When I used to send the #user to the mailer to prepare the data for the mails. Here was the code:
UserMailer.passphrase_reset_notification(#user).deliver
Which generated the exception with the message I wrote in the initial message. As a workaround instead of sending the #user I sent the fields I needed and it worked. Here's the new code:
UserMailer.passphrase_reset_notification(#user.name, #user.email).deliver
But the second case is the sign up. It failed in dev and I had to add :salt to user_params to fix it. But it does not fix the thing in the test env.
There's no stack trace, just that one liner message with the lines of my scenario leading to the error.
And I press "Sign up"
invalid salt (BCrypt::Errors::InvalidSalt)
./app/controllers/users_controller.rb:66:in block in create'
./app/controllers/users_controller.rb:64:increate'
./app/controllers/application_controller.rb:120:in scope_current_tenant'
./features/step_definitions/web_steps.rb:53:in/^(?:|I )press "([^"]*)"$/'
features/users/sign_up.feature:149:in `And I press "Sign up"'
I removed the "null: false" for the field "salt" in the user table, as suggested by a community member in a post on a more or less similar issue, it didn't help either.
My main question is still the same: what the Ruby new version (2.2.0) has to do with this? And what might be the other surprises if I upgrade the prod?
I just fixed this. Turned out it had to do with serializing an object with has_secure_password (which uses bcrypt-ruby)
More specifically, something like the following was causing the issue with Sidekiq as it tried to serialize arguments into objects for Redis queueing.
#user = User.new(
:firstname => 'Scott',
:lastname => 'Klein',
:password => 'mypass',
:password_confirmation => 'mypass'
)
#user.save!
# broken
# note that #user.password can still be called here
# and sidekiq will attempt to serialize this whole object using YAML
# and this is the serialization issue that barfs (in the depths of YAML)
UserMailer.delay.new_user_signup(#user)
# fixed
# i just passed the id and then recalled the user record in the mailer class
UserMailer.delay.new_user_signup(#user.id)
I've had similar problem. Investigation made me conclude that it's bcrypt not playing well with Psych (that's the Ruby system library for generating and parsing YAML).
There's an open bcrypt issue now. Waiting for gem author to fix it.
** FIXED **
The problem, at least mine, is fixed. I just upgraded the bcrypt gem from 3.1.
9 to 3.1.10 and it was it! Thanks Oleg to have created an issue on bcrypt account.

Rails 3.2.8 and rspec, link_to current path, params hash not properly converted

I recently upgraded by current app to Rails 3.2.8 and can't get a few tests to pass. I made a helper method that merges certain hashes with the params hash and creates a link to the current page. I used technique I saw on: link_to the current page plus/merged with a param.
Here is a stripped down version:
def simple_link
link_to "Page", params.merge(:c => nil)
end
Then I would test it with something like:
describe "simple_link" do
it { simple_link.should == "Page" }
end
Which was passing in 3.2.6.
However, now I receive the rspec error No route matches {:c=>nil}. Either Rails, rspec, or capybara is thinking the hash is the route. If I add a proper route like: users_path, then url_for seems to pick up the hash. Testing on a browser, everything works fine, no errors. Am I doing something wrong, was something changed in 3.2.8 or is this a bug?
Upgrading rails also upgrades the journey routing gem from 1.0.3 to 1.0.4. In that upgrade, there was a change to how routing treats constraints:
1.0.4 fixed a regression from Rails 3.1 where the router would return a route even if the constraints a user passed in didn't match anything.
Since you mention (in the comments) that downgrading journey to 1.0.3 fixes the problem, this change in journey is almost certainly the cause of the problem. Have a look at these github issues to find possible solutions:
1.0.3 -> 1.0.4 update breaks url_for in tests
ActionController::RoutingError in controller specs
The error is the way I'm calling link_to from a helper and not providing a current request. For now, I can get around the error by stubbing url_for, but this does not allow me to test the params hash. So trying to find a better way.
it "should return the right tag" do
self.stub!(:url_for).and_return '/bar'
simple_link.should == "Page"
end

Where's ActionController::Dispatcher in Rails 3.2?

I'm following an example in The Rails 3 way, and when I tried to send a request to dispatcher in the console, with ActionController::Dispatcher.new.call(env).last.body
I got
1.9.3p194 :001 > ActionController::Dispatcher.new.call(env).last.body
NameError: uninitialized constant ActionController::Dispatcher'
I was using rails 3.2.6, I checked the rails api and found out they removed dispatcher in the ActionController, but the rails guide said:ActionController::Dispatcher.new is the primary Rack application object of a Rails application. Any Rack compliant web server should be using ActionController::Dispatcher.new object to serve a Rails application.
I find the v3.0.7 of rails api, the Dispatcher still exist in that version.
So, here are my questions: how can I find the equivalent methods serve as ActionController.Dispatcher.new? and given that my apps work well with rails 3.2.6, which part of rails plays the role as ActionController.Dispatcher now?
This is what the Rails edge guides say about primary Rack application objects:
ApplicationName::Application is the primary Rack application object of a Rails application. Any Rack compliant web server should be using ApplicationName::Application object to serve a Rails application.
So ActionController::Dispatcher.new has just been replaced by ApplicationName::Application. I'm not sure when they made this switch. This worked for me:
Blog::Application.call(env).last.body
(The first few lines after NoMethodError: undefined method 'key?' for nil:NilClass tell us that the key? method is being called in actionpack-3.2.11/lib/action_dispatch/routing/route_set.rb. Working backwards from there, we can see that the variable
params = env['action_dispatch.request.path_parameters']
is nil when it shouldn't be. So we can set env['action_dispatch.request.path_parameters'] in the console, but that leads to another NoMethodError on a nil object set in the initialize method. So we could probably fix that by passing in an options hash to Dispatcher.new, but it's probably best just to use ApplicationName::Application.)
It has been moved to ActionDispatch (actionpack/lib/action_dispatch) and can be found here: actionpack/lib/action_dispatch/routing/route_set.rb, class called
ActionController::Routing::RouteSet::Dispatcher.new

why OmniAuth::Strategies::Facebook::NoAuthorizationCodeError is not handled in omniauth on_failure callback?

I am using Omniauth for Rails 3.2.3 application.
I have configured the on_failure callback as show below.
OmniAuth.config.on_failure = Proc.new do |env|
UsersController.action(:omniauth_failure).call(env)
end
This handles the error "OmniAuth::Strategies::CallbackError" but not "OmniAuth::Strategies::Facebook::NoAuthorizationCodeError".
How to handle this error?.Surly I can not use rescue_from as the error happens in Rack level.
Any ideas?
Thank you
Ensure that your Facebook Application is not running in "Sandbox Mode"
I've run into the same issue.
By my humble investigation it seems to be a bug in the strategy implemented in the omniauth-facebook gem (and, at a quick glance in several others). This is a nice write-up on exception handling in omniauth. It says that
... OmniAuth strategies [...], if they encounter a problem, call the method fail! and pass in a symbol describing the problem like :invalid_credentials and the exception they encountered. The fail! method ends up calling OmniAuth.config.on_failure and passing in the Rack environment (after doing a few other things like sticking the exception into the environment...
The same can be inferred from an example the original authors kindly provided. In the source it's not emphasized and I haven't found it in the wiki docs, either (but I may have overlooked).
Many strategies, including omniauth-facebook, currently raises the exception which we cannot catch at app level anymore.
#soundar: I wish that it worked this way, as advertised.
#fastcatch: As you pointed out, the strategies are not handling these failure cases correctly.
#Jon Day: I had to patch the Rack App for 'omniauth-facebook' (1.4.0) in order to get the reporting that I needed:
require 'newrelic_rpm'
module OmniAuth
class Builder < ::Rack::Builder
def call_with_error_handling(env)
begin
call_without_error_handling(env)
rescue OmniAuth::Strategies::Facebook::NoAuthorizationCodeError => error
# Do whatever you'd like when rescuing.. I wanted to report to NewRelic.
NewRelic::Agent.notice_error(error, env)
env
end
end
alias_method_chain :call, :error_handling
end
end
I'm not proud of this code, but it is one way to gain control over that exception ;).

Infamous Nil Object Error w/ OmniAuth

You can see this error on SO:
Nil object error when using OmniAuth (which normally works)
OmniAuth / Rails - You have a nil object when you didn't expect it
I have the same issue with my OmniAuth strategy. I've written my own, and have tested it both locally on Rails and Sinatra. Both instances return the same error, with Sinatra displaying more helpful information.
"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.[]="
It looks like there's some Rack stuff going on behind the scenes that I'm not understanding. Sinatra's last comment in the trace is:
"../lib/rack/utils.rb in set_cookie_header!" at line 194:
case header["Set-Cookie"]
I'm not messing with cookies, though. It seems like this problem goes away randomly for certain people, or doing something simple as clearing the cache has worked for someone. None of those techniques have worked for me. Does anyone know a tried and true way for solving this issue? You can view the repo for the project here: https://github.com/stevenhaddox/oa-casport Thanks!
EDIT: After a lot of thought, I'm guessing OmniAuth doesn't like the fact that my Rack middleware is not configured for SSL. Is there a way to tell OmniAuth to not expect SSL?
It looks like you're forgetting to redirect(callback_path) at the end of the request_phase. Once you add that in I think you'll fall right back in line with the OmniAuth workflow towards getting your auth_hash returned.

Resources