Omnicontact redirect_uri_mismatch with gmail account - ruby-on-rails

I'm using Omnicontact gem but I have some problem making it works with gmail: I always get "redirect_uri_mismatch" error!
Here's the code of 'config/inizializers/omnicontacts.rb'
3 require "omnicontacts"
4
5 Rails.application.middleware.use OmniContacts::Builder do
6 importer :gmail, "MySecretId", "MySecretKey", {:redirect_path => "/invites/gmail/contact_callback" }
7 end
'invites_controller.rb' controller code:
3 def index
4 #contacts = request.env['omnicontacts.contacts']
5 respond_to do |format|
6 format.html
7 end
8 end
Routes.rb code:
3 get "/invites/:provider/contact_callback" => "invites#index"
4 get "/contacts/failure" => "invites#failure"
5 root :to => "invites#index"
Here's the redirects uri of the google application:
https://www.example.com/oauth2callback
https://127.0.0.1:3000/invites/gmail/contact_callback
https://127.0.0.1/invites/gmail/contact_callback
How can I solve this?

I know this question is kind of old but this is happening because gmail won't allow you to have ip addresses as redirect uris. You will need to add something like this. yourmachine.example.com:3000/invites/gmail/contact_callback
And then in your hosts file you will need to add the following line:
192.168.1.2 devmachine yourmachine.example.com
Where 192.168.1.X, is your local ip address.
You should now be able to access your local rails application by going to this url:yourmachine.example.com:3000 in your local machine. Google will now accept this redirect_uri as it's a valid hostname and you should be able to get your contacts back.

Related

Getting authorization from iNaturalist for API

I'm trying to use iNaturalist's API via Ruby on Rails. I'm new to Ruby and iNaturalist's documentation is pretty sparse. As a first step, I need to figure out how to get authorization from their site.
iNaturalist provides the sample code below. I set up a project with iNaturalist and tried running the sample code in Rails Console with my credentials. #{url} in the following line is replaced with a url that the user is supposed to go to in order to log in to iNat:
puts "Go to #{url}, approve the app, and you should be redirected to your " +
"redirect_uri. Copy and paste the 'code' param here."
I went to the resulting url and logged in:
https://www.inaturalist.org/oauth/authorize?client_id=[my client id]&redirect_uri=https://ruby_on_rails--timrobinson41199691.codeanyapp.com/login/&response_type=code
iNaturalist responds with "The redirect uri included is not valid."
If I leave off &response_type=code, it responds with "The authorization server does not support this response type."
My website is on codeanywhere.com. The url of the main page is "https://ruby_on_rails--timrobinson41199691.codeanyapp.com/". Part of the problem is that I don't understand what kind of page I'm supposed to create for redirect_uri, since I'm still kind of new at this.
require 'rubygems'
require 'rest_client'
require 'json'
site = "https://www.inaturalist.org"
app_id = 'YOUR APP ID'
app_secret = 'YOUR APP SECRET'
redirect_uri = 'YOUR APP REDIRECT URI' # you can set this to some URL you control for testing
# REQUEST AN AUTHORIZATION CODE
# Your web app should redirect the user to this url. They should see a screen
# offering them the choice to authorize your app. If they aggree, they will be
# redirected to your redirect_uri with a "code" parameter
url = "#{site}/oauth/authorize?client_id=#{app_id}&redirect_uri=#{redirect_uri}&response_type=code"
# REQUEST AN AUTH TOKEN
# Once your app has that code parameter, you can exchange it for an access token:
puts "Go to #{url}, approve the app, and you should be redirected to your " +
"redirect_uri. Copy and paste the 'code' param here."
print "Code: "
auth_code = gets.strip
puts
payload = {
:client_id => app_id,
:client_secret => app_secret,
:code => auth_code,
:redirect_uri => redirect_uri,
:grant_type => "authorization_code"
}
puts "POST #{site}/oauth/token, payload: #{payload.inspect}"
puts response = RestClient.post("#{site}/oauth/token", payload)
puts
# response will be a chunk of JSON looking like
# {
# "access_token":"xxx",
# "token_type":"bearer",
# "expires_in":null,
# "refresh_token":null,
# "scope":"write"
# }
# Store the token (access_token) in your web app. You can now use it to make authorized
# requests on behalf of the user, like retrieving profile data:
token = JSON.parse(response)["access_token"]
headers = {"Authorization" => "Bearer #{token}"}
puts "GET /users/edit.json, headers: #{headers.inspect}"
puts RestClient.get("#{site}/users/edit.json", headers)
puts
After the user logs in to iNat, he should be redirected back to my website with the authorization code provided in the data. In routes.rb, my login route is set as:
post '/login', to: 'organisms#login'
I've tried using get, as well.
iNat is returned the error mentioned above and not redirecting back to my site.
OAuth can be a bit daunting at first. And that guide really just shows the equivalent of using cURL to test your API.
In an actual application redirect_uri is whatever endpoint in your application that handles the response when the provider redirects back from authorization.
So lets setup a minimal real rails app.
1. Register your app
Register a new application or edit your existing app.
Use http://localhost:3000/oauth/inaturalist/callback for the callback url (adjust the host as needed).
Keep the window open as you will need the client_id and secret in a moment.
2. Setup your routes
# /config/routes.rb
Rails.application.routes.draw do
# just make sure you have a root path defined.
root to: 'pages#home'
namespace :oauth do
namespace :inaturalist, controller: :callbacks do
# This is just a simple redirect route
get '/', action: :passthru, as: :authorize
# This is the route that handles the actual callback
get 'callback'
end
end
end
You can actually do this without the redirect route and just plant a link to the https://www.inaturalist.org/oauth/authorize... url in your view. But having it isolates your application against the craziness that is OAuth and its how OmniAuth does it.
3. Add your credentials to the Rails app.
In Rails 5 use the encrypted credentials to store your client_id and secret.
Run $ bin/rails credentials:edit from your shell.
inaturalist:
client_id: <from the inaturalist site>
secret: <from the inaturalist site>
In earlier versions use ENV vars instead.
4. Install the oauth2 gem
# Place this in your gemfile outside any groups
gem 'oauth2', '~> 1.4', '>= 1.4.1'
Then run bundle install.
4. Setup the controller
# app/controllers/oauth/inaturalist/callbacks_controller.rb
require 'oauth2'
module Oauth
module Inaturalist
class CallbacksController < ::ActionController::Base
# GET /oauth/inaturalist
def passthru
redirect_to client.auth_code.authorize_url
end
# This endpoint is where the provider redirects the user back to
# after authorization.
# GET /oauth/inaturalist/callback
def callback
# Fetch an auth token from the access code
token = client.auth_code.get_token(params[:code])
# Perform an authenticated request to get the users data
api_response = token.get("/users/edit.json")
#user_data = JSON.parse(api_response.body)
# This is just an example of how you can use the user data from
# the provider
#user = {
uid: #user_data["id"],
nickname: #user_data["nickname"]
}
session[:user_id] = #user[:uid]
session[:token] = token.to_hash
redirect_to root_path, success: "Hello #{#user[:nickname]}"
end
private
# Change this if you are not using Rails 5 credentials.
def client
OAuth2::Client.new(
credentials.fetch(:client_id),
credentials.fetch(:secret),
site: "https://www.inaturalist.org",
redirect_uri: oauth_inaturalist_callback_url
)
end
def credentials
Rails.application.credentials.fetch(:inaturalist)
end
end
end
end
token here is actually a new OAuth2::AccessToken instance that can be called to call endpoints with the fetched credentials.
This example stores the token in the session. You can retrieve it in subsequent requests with:
token = OAuth2::AccessToken.from_hash( session[:token] )
The docs kind of mention trading the oauth access token for an api token for api.inaturalist.org. But the details are kind of sparse.
5 Add a link to sign in:
<%= link_to 'Sign in to iNaturalist.org', oauth_inaturalist_authorize_path %>

Rails refusing to acknowledge page

I've been trying to convince Rails of the existence of a page at localhost:3000/user_forms/redir to absolutely no avail. The page appears when I try rake routes- as
user_forms_redir GET /user_forms/redir(.:format) user_forms#redir
It is definitely in the routes.rb file:
Rails.application.routes.draw do
get "user_forms/redir", to: "user_forms#redir"
And there exists a file at /views/user_forms/redir.html.haml thus:
%h1 Checking Google Auth, please wait...
%p
If this page continually hangs, please contact
= mail_to "ex#ex.co.uk"
I even have code in my user_forms_controller.rb file:
def g_check_auth
if(#authorization_code.nil?)
redirect_to user_forms_redir_url
end
end
# GET /user_forms/redir
def redir
#user_form = UserForm.new(set_user_form)
credentials = Google::Auth::UserRefreshCredentials.new(
client_id: "xxx",
client_secret: "xxx",
scope: [
"https://www.googleapis.com/auth/drive",
"https://spreadsheets.google.com/feeds/",
],
redirect_uri: user_form_url(#user_form))
#auth_url = credentials.authorization_uri
redirect_to #auth_url.to_s
end
The program even goes as far as to have user_forms_redir_url as a valid path. Yet, upon following that path I get a lovely 404 message.

How to integrate SoundCloud in Ruby on Rails?

I am new to RubyOnRails and SoundCloud.
I want to integrate SoundCloud API in my ruby on rails application.
For this I have registered on SoundCloud And I got the ClientID and ClientSecret. Also I have downloaded the SDK.
Now I have copied the files and folders from lib and spec directory to my applications lib and spec directory. Also I have added gem 'soundcloud' in the Gemfile.
After this I made simple code (copied from doc) in My Interactor:
# register a client with YOUR_CLIENT_ID as client_id_
client = SoundCloud.new(:client_id => YOUR_CLIENT_ID)
# get 10 hottest tracks
tracks = client.get('/tracks', :limit => 10, :order => 'hotness')
# print each link
tracks.each do |track|
puts track.permalink_url
end
But here I'm getting the error -
uninitialized constant MyApp::Interactors::MyInteractor::MyAction::SoundCloud
I followed the steps from APIDoc. Is there any step by step example for integrating SoundCloud in Ruby on Rails so that I can follow?
How can I resolve this error?
MyInteracor.rb
module MyApp
module Interactors
module MyInteractor
class MyAction < Struct.new(:user, :params)
def run
# SoundCloud
# register a client with YOUR_CLIENT_ID as client_id_
client = SoundCloud.new(:client_id => 'my-client-id')
# get 10 hottest tracks
tracks = client.get('/tracks', :limit => 10, :order => 'hotness')
# print each link
tracks.each do |track|
puts track.permalink_url
end
end
end
end
end
end
There's a typo in the soundcloud github page change the line:
client = SoundCloud.new(:client_id => 'my-client-id')
to
client = Soundcloud.new(:client_id => 'my-client-id')
[notice the lowercase c in Soundcloud]
Also you are going to need your client secret for SoundCloud's API to verify you.
Perhaps put client method and in it have client = SoundCloud.new(your-client-id,your-secret-key-your-redirect-uri) in a controller or helper with your client_id, client_secret, and redirect uri values protected in a .env file.
I think by leaving out your redirect_uri and client secret you might be getting this error in MyInteractor.rb
Hope this helps

ArgumentError on application requests

I've written a basic Rails 3 application that shows a form and an upload form on specific URLs. It was all working fine yesterday, but now I'm running into several problems that require fixing. I'll try to describe each problem as best as I can. The reason i'm combining them, is because I feel they're all related and preventing me from finishing my task.
1. Cannot run the application in development mode
For some unknown reason, I cannot get the application to run in development mode. Currently i've overwritten the production.rb file from the environment with the settings from the development environment to get actuall stacktraces.
I've added the RailsEnv production setting to my VirtualHost setting in apache2, but it seems to make no difference. Nor does settings ENV variable to production.
2. ArgumentError on all calls
Whatever call I seem to make, results in this error message. The logfile tells me the following:
Started GET "/" for 192.168.33.82 at
Thu Apr 07 00:54:48 -0700 2011
ArgumentError (wrong number of
arguments (1 for 0)):
Rendered
/usr/lib/ruby/gems/1.8/gems/actionpack-3.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.erb
(1.0ms) Rendered
/usr/lib/ruby/gems/1.8/gems/actionpack-3.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
(4.1ms) Rendered
/usr/lib/ruby/gems/1.8/gems/actionpack-3.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
within rescues/layout (8.4ms)
This means nothing to me really. I have no clue what's going wrong. I currently have only one controller which looks like this:
class SearchEngineController < ApplicationController
def upload
end
def search
#rows = nil
end
# This function will receive the query string from the search form and perform a search on the
# F.I.S.E index to find any matching results
def query
index = Ferret::Index::Index.new :path => "/public/F.I.S.E", :default_field => 'content'
#rows = Array.New
index.search_each "content|title:#{params[:query]}" do |id,score, title|
#rows << {:id => id, :score => score, :title => title}
end
render :search
end
# This function will receive the file uploaded by the user and process it into the
# F.I.S.E for searching on keywords and synonims
def process
index = Ferret::Index::Index.new :path => "public/F.I.S.E", :default_field => 'content'
file = File.open params[:file], "r"
xml = REXML::Document.new file
filename = params[:file]
title = xml.root.elements['//body/title/text()']
content = xml.root.elements['normalize-space(//body)']
index << { :filename => filename, :title => title, :content => content}
file.close
FileUtils.rm file
end
end
The routing of my application has the following setup: Again this is all pretty basic and probably can be done better.
Roularta::Application.routes.draw do
# define all the url paths we support
match '/upload' => 'search_engine#upload', :via => :get
match '/process' => 'search_engine#process', :via => :post
# redirect the root of the application to the search page
root :to => 'search_engine#search'
# redirect all incoming requests to the query view of the search engine
match '/:controller(/:action(/:id))' => 'search_engine#search'
end
If anyone can spot what's wrong and why this application is failing, please let me know. If needed I can edit this awnser and include additional files that might be required to solve this problem.
EDIT
i've managed to get further by renaming one of the functions on the controller. I renamed search into create and now I'm getting back HAML errors. Perhaps I used a keyword...?
woot, finally found the solutions....
Seems I used keywords to define my actions, and Rails didn't like this. This solved issue 2.
Issue 1 got solved by adding Rails.env= 'development' to the environment.rb file

Dropbox Ruby API

I want to use Dropbox Ruby API, I installed the gem and when I want to create a dropbox session I got this message:
uninitialized constant DropboxController::Dropbox
Is there anything to do if I want to use this api except install the gem?
The code is:
def authorize
if params[:oauth_token] then
dropbox_session = Dropbox::Session.deserialize(session[:dropbox_session])
dropbox_session.authorize(params)
session[:dropbox_session] = dropbox_session.serialize # re-serialize the authenticated session
redirect_to :action => 'upload'
else
dropbox_session = Dropbox::Session.new('your_consumer_key', 'your_consumer_secret')
session[:dropbox_session] = dropbox_session.serialize
redirect_to dropbox_session.authorize_url(:oauth_callback => url_for(:action => 'authorize'))
end
end
This is a rails controller not for ruby.
For ruby you may refer to this tutorial and here is the DOCs for Ruby
Require the dropbox file in your current file.

Resources