How to disable discovery and specify OpenID server for omniauth-openid - ruby-on-rails

I am trying to do OmniAuth OpenID with Google Apps in Ruby on Rails. I know it should work out-of-the-box if I specify ":identifier => 'https://www.google.com/accounts/o8/site-xrds?hd=example.com'" where example.com is the domain that my targeted users come from.
The user can get redirected to Google when accessing /auth/google without a problem, and this openid.identity can be returned from Google:
... &openid.identity=http://example.com/openid?id=xxxxxxxxxxxxxxxxxxxxxxx ...
However, the example.com I am working with does not have the correct "rel='openid2.provider'" <link /> tags set up at http://example.com/, therefore the discovery fails when omniauth-openid tries to check with Google again.
Is there a quick and clean way to work around the default discovery behavior so that I can define https://www.google.com/a/example.com/o8/ud?be=o8 as the server directly without performing the automatic discovery?
Thanks!

I think omniauth-openid uses ruby-openid. If so, you should be able to get it work easily:
gem install ruby-openid-apps-discovery
Then throw in somewhere before making the request
require 'gapps_openid'
Google Apps has a slightly different discovery protocol, which is what that gem provides.

Before using the gem that Steve recommended, I came up with a workaround to make the entire discovery process happen locally only, which I find might be useful to some people. If you only accept users from a single Google Apps domain, you might want to:
Add a line like 127.0.0.1 example.com in your /etc/hosts.
set up a lightweight HTTP server like nginx, create a file called openid (do not append .html), and add your <link rel="openid2.provider" ... > tag there.
This is slightly faster than using ruby-openid-apps-discovery since it saves your application from sending some requests to an external https server.

Related

Rails rewriting link from Blogger

I use rack-reverse-proxy to setup my Blogger.com to a subdomain of my Ruby on Rails app: pulpoludo.com/blog
It's work, but I have an issue with the link of Blogger which returns to blog.pulpoludo.com (where my Blogger blog is host).
I would like to rewrite this link. But I don't know-how. Can you help me?
(I have found someone who does this in PHP: https://matt-stannard.blogspot.com/2013/02/blogger-in-subdirectory-of-my-domain.html
But I would like to do the same thing with Rails and a gem maybe)
Indeed, you cannot use rack-reverse-proxy because it does not allow you to change the response (you need to rewrite the page you retrieve using a regular expression replacement, as in the example you link to.
Also, you should probably avoid using rack-reverse-proxy in production, as it will keep your ruby processes busy waiting for the backend responses, that might fail or be slow. And:
It is not meant for production systems
You should instead proxy from your front HTTP acceptor (nginx or other). For nginx you can see a very thorough response, using a combination of proxy_pass and sub_filter, at https://stackoverflow.com/a/32543398/384417.
edit: If it's not possible to use nginx or another reverse proxy, you can still do it in ruby.
rack-reverse-proxy supports transformers, you can build one yourself, and register it so it's run on the response. This (closed) issue will help, it is exactly what you need: https://github.com/waterlink/rack-reverse-proxy/issues/65. The caveat (as always when changing responses) is that you have to update the Content-Length response header to match the updated size of the body.

Forcing Gibbon Gem (or Faraday) to use QuotaGuard Static HTTP proxy on Heroku

Full disclaimer; I'm not a strong Ruby dev, but I am learning quickly :)
I've set up a simple Ruby script on a Heroku dyno that listens for calls from our donation platform.
When a donation is made, it hits a webhook endpoint within my app, which then sends a donation receipt via Mandrill (which works fine), and updates/inserts a record in a Mailchimp list, via the 'upsert' method of the wonderful Gibbon gem.
That all works fine; except when the Heroku box happens to come up on an IP address that has done something bad in the past, and Mailchimp's API drops with a 403 (Forbidden) error.
I've had this confirmed by the Mailchimp API team; they suggest using something like QuotaGuard Static to tunnel the API requests to Mailchimp through, removing the issue of API calls from inconsistent (and sometimes untrusted) IP addresses.
I'd love some advice on how to make this happen. I can see that Gibbon uses Faraday to handle HTTP requests, but I'm not an advanced enough Ruby dev to fork the code and add in HTTP proxy functionality.
If there's a way to globally force the Faraday calls to use a HTTP proxy (ie QuotaGuard Static), that's what I'm looking for. A config setting for Faraday, for example.
Or perhaps there's a tweak I can make to my Procfile:
web: bundle exec ruby webhooks.rb -p $PORT
...that will force the outbound traffic to go via the QuotaGuard Static proxy. I know Proximo has this functionality, but it also blocks inbound access to the app, which doesn't work for this app.
Appreciate any ideas the community can offer. Thanks!
Gibbon Author here. You can simply set the proxy value to the proxy URL in Gibbon 2.2.0 and later.
From the Faraday documentation (here) the Connectionclass uses the proxy specified in the http_proxy environment variable. I have never tried it, but looking at the source code it should work.
I wanted to provide a bit more information, since the two answers pointed me on the right track but still required me to do some digging. I solved this issue by first adding the QuotaGuard Static add-on in Heroku (free for up to 250 uses per month) and then initializing Gibbon like so:
g = Gibbon::Request.new
g.proxy = ENV["QUOTAGUARDSTATIC_URL"]
And here is the relevant section from the Gibbon docs: https://github.com/amro/gibbon#other

How to setup QuotaGuard Static for a Rails app hosted on heroku?

I'm trying to setup my heroku app to have an static IP using QuotaGuard (I know proximo is the other option, but it's pretty expensive).
I added the heroku QuotaGuard Static addon and got the two IPs it generates as well as the proxy url.
What is my next step? (aka how do I tell my Rails app to use the proxy provided by QuotaGuard)
I see they have ruby code samples using REST-client and HTTParty, but do I put that somewhere like in the application.rb??
Most likely a bit too late to answer this question, but still.
Like you said, the first step to configuring QuotaGuard Static is provisioning the addon on Heroku (either via the Web Interface or the Heroku CLI). From there, you are able to get your two outbound IPs, and your proxy URL. The two IPs you were given should be whitelisted on whichever remote service you are trying to access.
As you mentioned, the documentation gives you a couple of samples using Rest Client for Ruby on Rails. This snippet should pretty much go anywhere you want to access whichever resource you need to access via the static IP Addresses. Assuming you want to access a Web Service hosted on an Amazon EC2 instance with elastic IP 1.2.3.4, your would write:
RestClient.proxy = ENV["QUOTAGUARDSTATIC_URL"]
res = RestClient.get("http://1.2.3.4/yourWebService")
And from there process the response stored in res appropriately. This code would go in say whichever controller's method you'll be using to access the remote web service. In this case, you also need to add the Rest Client to your controller, so at the top of that file you shoud also add require "rest-client" . Don't forget to add the rest-client gem to your Gemfile.
Summing up, basically the snippets from the documentation go wherever it is you want to use the proxy to access a remote service requiring a fixed, whitelisted set of IP addresses.
Source: https://devcenter.heroku.com/articles/quotaguardstatic

Heroku still responds to mysubdomain.herokuapp.com

I have added a custom domain to my Heroku application and it works fine, but the application still responds to {mysubdomain}.herokuapp.com.
To prevent duplicate content I would like to stop having my application respond to the subdomain. Is there some setting in Heroku which does this for me, or do I need to code a 301 redirect?
Another option is to use the rel="canonical" link tag. This tells search engines which URL to use for content that may appear on multiple URLs:
<link rel="canonical" href="http://www.example.com/correct_url">
Here's what google has to say: http://support.google.com/webmasters/bin/answer.py?hl=en&answer=139394
(Your use case is explicitly mentioned at the bottom.)
You would need a 301 redirect. Heroku will always respond to the .herokuapp.com domain of your app
I created the hide_heroku gem to handle this- it uses X-Robots-Tag HTTP headers to prevent search engines from indexing anything under *.herokuapp.com
I don't believe it's possible to remove the Heroku-provided domain name, either via their web interface or the command-line client. If you're concerned about it, redirect or add a robots.txt to your site that blocks when accessed via .herokuapp.com (I don't know how to do that offhand, sorry).
I suspect Google is reasonably smart about indexing Heroku sites and handles the dual-domain issue itself, but that's just a guess.

How can I get Yahoo OAuth to work when I develop locally when my local domain is not registered with Yahoo?

I'm working on an app that uses Yahoo OAuth. The OAuth had been working fine but I just registered my domain with Yahoo and now it will not let me use the OAuth when I develop locally because
"Custom port is not allowed or the host is not registered with this consumer key."
The issue is because my call back URL is to a domain that is not registered with Yahoo (http://localhost:8080/welcome).
I'm not sure what to do. I'm also new to development so if you could be specific with suggestions that would be awesome! Any help is greatly appreciated.
Hiii... yahoo works on localhost :).. what you have to do is while registering for a yahoo consumer key and secret key, the registration page asks you what type of application is yours. I guess it gives you two options , website and the oder one as stand alone app. Choose stand alone app as in your case. Then it will give you a pair of keys, and it will work on localhost :). Enjoy!
It looks like Yahoo! doesn't want you to do this. Some answers from similar questions might be helpful (or not):
How do I develop against OAuth locally?
401 Unauthorized using Yahoo OAuth
Yahoo OAuth question
EDIT: more evidence Yahoo! doesn't support this: http://developer.yahoo.net/forum/?showtopic=6496&cookiecheckonly=1
I found the simplest solution was just to register for a separate key for my development environment. As long as you don't verify the domain for that key, you shouldn't hit any issues.
After many attempts, I too came to the conclusion that Yahoo's redirect_uri does not seem to work with ports other than 80.
The one solution that worked for me:
Download ngrok
Run the app and input ngrok http xxxx in the console - where xxxx is the port you are trying to access
The command will generate a http://xxxxxx.ngrok.io forwarding link that can be used for Yahoo's needs
Create a new Installed Application at https://developer.yahoo.com/apps/create/ and input http://xxxxxx.ngrok.io in the Callback Domain field.
Links should now work with this redirect_uri
Addressing Muhammad's comment in Vignes's answer here because I can't comment. You should be able to use a callback with a stand alone app if you specify 127.0.0.1 as the callback domain. You may also needed to change the port that your local server is listening to, because you cannot request that yahoo use e.g. port 8000. Make sure your local server is listening to port 80.
As of writing, setting the Application Type to Installed Application and then leaving the Callback Domain blank will give you errors.
What works is configuring 127.0.0.1 as the Callback Domain for the app. This works regardless if you are choosing Web Application or Installed Application as the Application Type. However, Yahoo! does not accept callback URLs with ports in it so you have to make sure your app listens to port 80 (or 443 if https) when running locally.
Another less ideal option would be using some random non-existent domain like local.dev.env.com as Callback Domain and then editing your hosts file by adding this:
127.0.0.1 local.dev.env.com
This will forward all requests on local.dev.env.com to 127.0.0.1.

Resources