Flickr and Flickraw gem authentication - ruby-on-rails

I'm trying to use the Flickraw gem to upload some images to my account in Flickr. I get this to work, but how to get the access code, without to visit Flickr page, like this:
token = flickr.get_request_token
auth_url = flickr.get_authorize_url(token['oauth_token'], :perms => 'delete')
puts "Open this url in your process to complete the authication process : #{auth_url}"
puts "Copy here the number given when you complete the process."
verify = gets.strip
...
I donĀ“t understand this process.

This is because the auth process is done using OAuth, explained here: http://www.flickr.com/services/api/auth.oauth.html
It's basically making the request to the flickr server getting an access token for the currently signed in user and returning that to an call back URL on your server(The docs explain it way better and in much more details so I recommend reading that instead).
If however you want to use the application only in your name you can look into other authentication mechanisms, explained here: http://www.flickr.com/services/api/auth.spec.html
The one you want to use - as it looks to me - is the non web based authentication. This is a much easier way to authenticate and only uses a key and secret for authentication. Which also seems to be supported by the FlickRaw gem: http://hanklords.github.io/flickraw/ (Look at the first simple example)

Related

Authorize application, code level without hitting browser [Doorkeeper]

I found a related question with no satisfactory answer, so asking here again:
I'm using Doorkeeper GEM for API calls for my application. I have followed the steps given in oauth2 gem docs:
require 'oauth2'
client = OAuth2::Client.new('client_id', 'client_secret', :site => 'https://example.org')
client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth2/callback')
As we see the last line execution gives a URL to be used in browser and get authorization code after clicking "Authorize".
But, I want to do all these in Rails model level, so that I don't have to hit the browser for authorization code and it should internally get the code which I can use later for token generation.
Is it possible?
It sounds like you want to use the resource owner password credentials flow for OAuth2. It is best described how to set this up with Doorkeeper and the OAuth2 gem in the Doorkeeper wiki.

Permanent access to youtube api

I'm using YoutubeAPI v3.0 to automatically upload videos to my own channel. However the script still needs manual intervention during Oath2.0 authorization. How to make it completely automatic?
1) Access the API using username and password
2) Or find a way to create permanent OAuth2.0 authentication
P/S: I use this script to upload
https://developers.google.com/youtube/v3/guides/uploading_a_video
The only thing I can think of is web scraping. Basically, programmatically open the web page and get its HTML. Then find the authorization code, and store it as a string. I don't know if your scripting language of choice can do it, but Python has Beautiful Soup (links at the bottom). The problem, of course, is accessing the contents of a page like that which is pretty clearly designed to be reached by a logged in user from a web browser. I've never done that, but there's some concept of a "login handshake" where you post the data to the server that's needed as you access the page. I've a few links at the bottom.
Anyway, to give you a better idea of what I mean in pseudo-code (for those who may be confused), it'd be something like:
webURL = 'http://any-url.net";
webPageObject = openPage(webURL);
pageHTML = webPageObject.getHTML();
theHTMLTag = searchForTagById(pageHTML, "<p id='oAuthMessage'>");
//And from there, figure out where the string containing the code is.
//Probably just by getting a substring from the end of the text in the <p>
//backward until you reach the length of the oAuth code.
You'll have to look at the page source to know which tags to look for specifically, but this can all just be done programmatically/automatically, as you wanted.
Links:
Login handshake - Scraping from a website that requires a login?
Beautiful Soup - http://www.crummy.com/software/BeautifulSoup/
google.gov/webScraping - https://www.google.com/search?ie=UTF-8&oe=utf-8&q=how+to+web+scrape+logged+in+page
You can use get Google OAUTH2 for devices in order to have fully automatic token renewal process.
So all you need now is:
Request a device code and confirmation code
Enter confirmation code to confirm your application have access for specific account
Generate new or renew existing ACCESS_TOKEN for your device code
Upload Video using your device code and valid ACCESS_TOKEN
Here is documentation for it.
And here is some examples.

Does Omniauth-google-oauth2 simply allow authentication, or does it also address API needs?

I'm having trouble understanding OAuth2 conceptually. I've read about the whole handshake process a hundred times. I can login to my app using a google account, but once that's done, I need to access Google's API (read data from a Google Spreadsheet on that same account that I logged into, and whom I included spreadsheets in the :scope as per the strategy readme).
Currently, I'm using Omniauth and the omniauth-google-oauth2 strategy; this works great; it pulls up Google's authentication/login screen, and when I get back to my callback link, I'm storing [omniauth][credentials][token].
What is the best way to then use that token to do API work with Google Docs?
Is this the right approach?
I think of Oauth2 as a "way to get the user's password to confirm their existence on my site".
So instead of your User model having a password column, in essence, it uses Google to say "this guy is cool".
Now, what does that have to do with API calls, you wonder... me too.
If I recall, there is a Refresh token that lasts for more than the 20 ms of authetication and will allow you to access their Google Docs, if Google's api allows you to do that.
Having said all that, If google needs their token, plus your API token to access their spreadsheet, I'd stick it into the session.
But if their API said to stick spreadsheet in the scope, then it must say something about how to use it all together too, no?
More Edits
Google Spreadsheets Oauth 2.0 authentication piece is here, with a flow. Notice the part about refresh tokens. I'd look into that.
It says to store it somewhere, which I'd choose the session, or if you are totally paranoid a db column somewhere, but not sure if that is right either. Just spitballing here.
Final Edit
Turns out even the people helping out the Oauth 2.0 don't agree/get it conceptually either.
You may be able to find a gem that wraps the Google API to simplify your tasks.
Here's one that works with Google Drive and spreadsheets.
The google-drive-ruby gem that #Galen mentions seems to work nicely with the google-oauth-2 provider:
Guessing you're already storing the token in the session in your callback handler, e.g.
auth = request.env["omniauth.auth"]
session[:token] = auth["credentials"]["token"]
then you can use it to build a session and access the sheet:
require 'googleauth'
session = GoogleDrive::Session.from_access_token(token)
worksheet = session.spreadsheet_by_key(spreadsheet_id).worksheet_by_title(worksheet_name)
...etc
Hope this helps.

Ruby on Rails and facebook

I am trying to write a code in ruby on rails that would go into facebook and pull out data to populate my database based on key words that I manually add inside the code. Anyone has done something similar or can help me with it by pointing me towards the right direction? Also I need the code to stay "alive" after the first run in order to update my site automatically. I've looked for a fb API but i couldn't find anything.
Thanks,
Crematorio
The Facebook Graph API is what you would use to pull out data, typically the feed. As for Ruby on Rails, many ways to interact with the FB Graph, but I think the Koala gem is your ticket: https://github.com/arsduo/koala
You would need to set up an application at the FB Developers site, then pass the ID/secret to authenticate via Oauth. I use the following to pull wall feed, this little bit might get you started...
oauth = Koala::Facebook::OAuth.new('app ID here', 'app secret here', 'website/project url')
graph = Koala::Facebook::GraphAPI.new(oauth.get_app_access_token)
feed = graph.get_connections("facebook username here", "feed")
#facebook_feed = ActiveSupport::JSON.decode(feed.to_json)
Adapt this however you like, what I would probably do is a rake task that checks the results of #facebook_feed and processes them based on criteria, keywords, etc.

How to use omniauth to make authenticated calls to services?

I've received a token / secret from a service using OmniAuth and can store it for users, but I'm stuck as to how to actually use these to call a service.
The closest thing I've seen to this question is here but the way he's solved that there doesn't feel right. I feel like OmniAuth likely does this all for you if you know what you're doing.
Netflix has a pretty involved auth process, so I was hoping to skirt all of this by using OmniAuth to abstract me from all of this.
Given that I have a token and secret for a user, how to use these in calling a service like Netflix?
Many thanks :)
Hey, I'm the author of the OmniAuth gem. OmniAuth is meant to be used for the authentication process. In the case of OAuth providers like Netflix, this means exchanging a request token for an access token which is then used to pull user information from the API. These one-off calls are specifically designed for each provider and are not meant to be a generic API client for the given provider.
What you can do it use OmniAuth to obtain the credentials and then use another specific library for the site itself (such as ruby-netflix or anything else, I'm not sure what the best one is) to make calls. You can retrieve the access token and secret that is obtained in the authentication dance by accessing env['omniauth.auth']['credentials'], then use those to initialize the API client.
You can also use the OAuth library directly to make these calls, but I would strongly recommend just using an existing library, it will be much faster and easier. Does all of that make sense?
OmniAuth is all about authentication; you should probably look at another gem for making actual calls to the service. E.g., for Facebook, I use the OAuth2 gem and code like the following:
module Facebook
class Client < OAuth2::Client
# Return a new OAuth2::Client object specific to the app.
def initialize
super(
APP_CONFIG[:facebook][:api_key],
APP_CONFIG[:facebook][:app_secret],
:site => 'https://graph.facebook.com',
:parse_json => true
)
end
end
class Token < OAuth2::AccessToken
# Return a new OAuth2::AccessToken specific to the app
# and the user with the given token.
def initialize(token)
super(
Facebook::Client.new,
token
)
end
end
end
access_token = Facebook::Token.new(users_fb_token)
url = "https://graph.facebook.com/#{user_fb_id}/feed"
response = access_token.post(url, :message => "My update")
Note that there are gems for popular services, like Facebook and Twitter, that can manage the behind-the-scenes things like creating tokens, managing URLs, etc. For Netflix, you might check the following:
https://github.com/tiegz/ruby-netflix
https://github.com/rares/netflix
http://code.google.com/p/flix4r/
Also keep in mind that OmniAuth just returns the service data to you; you're free to store it and use it how you will (Devise has it's own pattern for OmniAuth that you might butt heads with if you try to go outside the lines). The other question you linked doesn't look too far fetched to me.

Resources