i am trying to use Google OAuth to import a user 's contacts. In order to get a consumer and secret key for you app you have to verify your domain at https://www.google.com/accounts/ManageDomains Google allows you to use only domains without ports. I want to test and build the app locally so usually (Facebook, Linkedin apps) i user a reverse SSH tunnel for example http://6pna.com:30002
Has anyone use a tunnel with Google OAuth. Does it work? So far I just verified my apps domain but my requests come from the tunnel (different domain) so OAuth fails (although i get to Google and authorize my app)
Any tips, hints ? Thanks
well after trial and error i found out that the request 's domain is irrelevant
i just use the official gdata google auth library http://code.google.com/p/gdata-python-client
Here is some code
google_auth_url = None
if not current_user.gmail_authorized:
google = gdata.contacts.service.ContactsService(source=GOOGLE_OAUTH_SETTINGS['APP_NAME'])
google.SetOAuthInputParameters(GOOGLE_OAUTH_SETTINGS['SIG_METHOD'], GOOGLE_OAUTH_SETTINGS['CONSUMER_KEY'],
consumer_secret=GOOGLE_OAUTH_SETTINGS['CONSUMER_SECRET'])
if not request.vars.oauth_verifier:
req_token = google.FetchOAuthRequestToken(scopes=GOOGLE_OAUTH_SETTINGS['SCOPES'],
oauth_callback="http://"+request.env.http_host+URL(r=request,c='default',f='import_accounts'))
session['oauth_token_secret'] = req_token.secret
google_auth_url = google.GenerateOAuthAuthorizationURL()
else:
oauth_token = gdata.auth.OAuthTokenFromUrl(request.env.request_uri)
if oauth_token:
oauth_token.secret = session['oauth_token_secret']
oauth_token.oauth_input_params = google.GetOAuthInputParameters()
google.SetOAuthToken(oauth_token)
access_token = google.UpgradeToOAuthAccessToken(oauth_verifier=request.vars.oauth_verifier)
# store access_tonen
#google.GetContactsFeed() # do the process or do it in ajax (but first update the user)
Related
How can I access Google App Engine endpoints API for Python (not web, android, ios)?
I read this tutorial but it not explains it enough to understand this.
As I found on serve side I can use such code to identify user:
#endpoints.method(message_types.VoidMessage, Greeting,
path='hellogreeting/authed', http_method='POST',
name='greetings.authed')
def greeting_authed(self, request):
current_user = endpoints.get_current_user()
email = (current_user.email() if current_user is not None
else 'Anonymous')
return Greeting(message='hello %s' % (email,))
Full code of API example
How can I connect from Python client to this API and call 'hellogreeting/authed' with authentication current_user != None.
Can you share some code how to do it?
app_id = 'xxx'
user = 'xxx'
password = 'xxx'
callAPI(app_id, user, password, 'hellogreeting/authed')
You need to configure your App Engine instance to be able to serve your API. I would recommend you create a separate module dedicated to your API, like explained in these docs: https://developers.google.com/appengine/docs/python/endpoints/api_server.
Once everything is correctly set up on the server side, you can call your API using something like: http://your-module.your-app.appspot.com/_ah/spi/hellogreeting/authed.
If you're using the development server, things are a little bit different for accessing modules, but once you know which port number the App Engine development server has assigned to your API module, you can reach it locally using: http://localost:<api_module_port_#>/_ah/spi/hellogreeting/authed.
Hope this helped.
Using the docs and python libraries google provided in the oauth2client.py along with the oauth2.py library and docs I managed to successfully send mail via a user's gmail account by authenticating them through OAuth2.0. I created a project in google apis and was able to get the keys and other params needed to correctly authenticate and send mail.
Now I am trying to achieve the same goal but with a Google Marketplace App. The end-goal is that a domain administrator could add our app to their Google Apps domain so that each user would not need to go through the authentication process and our app would 'automatically' be authorized to send mail on their behalf.
The first problem came in that when registering an App in the marketplace, I was given the client key and secret, but no redirect_uri, like I was given in the other project. This means I was unable to authenticate using their OAuth2WebServerFlow class. This lead to some hours of searching and conflicting answers and broken links within Google's documentation. This doc leads me to believe that Marketplace Apps don't support OAuth 2.0 and that I would need to go back to using a 2-legged OAuth 1.0 authentication. But it was updated over a year ago and all the other Google docs tell me strongly not to use OAuth 1.0 as it's been deprecated.
Is re-writing all new code (not being able to use the same libraries or anything) to use OAuth 1.0 the only way to be able to do this with a Marketplace App? Is there another way and if not, any advice on leveraging the existing code or how best to do in in their current system?
A short snippet of how I'm doing it currently using OAuth 2.0:
flow = OAuth2WebServerFlow(
client_id="xxx",
client_secret="xxx",
scope="https://mail.google.com/",
user_agent="mytest/0.1",
redirect_uri="http://127.0.0.1:5000/oauth2callback"
)
authorize_url = flow.step1_get_authorize_url()
and on return
credentials = flow.step2_exchange(request.args['code'])
storage = Storage(request.user.email)
storage.put(credentials)
and to send the mail
conn = smtplib.SMTP('smtp.googlemail.com', 587)
conn.set_debuglevel(True)
conn.ehlo('test')
conn.starttls()
auth_string = 'user=%s\1auth=Bearer %s\1\1' % (user_address, credentials.access_token)
conn.docmd('AUTH', 'XOAUTH2 ' + base64.b64encode(auth_string))
header = 'To:' + recipient_address + '\n'
header += 'From:' + user_address + '\n'
header += 'Subject: Oauth test Email \n'
header += 'Content-Type: text/html; charset=UTF-8\n'
msg = header + '\n ' + "Waka waka" + ' \n\n'
conn.sendmail(user_address, recipient_address, msg)
If I had 50 points, I'd answer with a comment, since this won't be a full answer.
I've been wrestling with similar problems. I came to the realization that I was better off (more in control) if I interacted with the APIs directly using 'urllib2' and 'shelve' than messing with pseudo-helper stuff like OAuth2WebServerFlow and Storage.
Doing so allows me to check assumptions with 'curl' from the command line, and then code the result in Python. I can tap into the wealth of blogs and Q & A about OAuth for Google without the fragmentation into all their different spotilly supported libraries (Jave, C#, PHP, etc.)
I have written a fork to Anton Burnashev's "gspread".
This is my "Pull Request"
You should see that I alter almost nothing of Burnashev's code. I just provide the OAuth stuff, and just for "Installed Applications"
There are 6 different modalities :
Login
Web Server Applications
Client-side Applications
Installed Applications
Devices
Service Accounts
How certain are you that you are using the right one? It took me a lot of puzzling to realize that mine needed to be an "Installed App", but I'm now realizing I should also support "Devices"
The OAuth2 flow is slightly different now with the new Google Apps Marketplace experience. Since the admin installs the app, tokens are pre-appoved so you should have to prompt end-users. The are more details at https://developers.google.com/apps-marketplace/building#use_google_services_from_a_simple_web_server_app
Late to the game on migrating to the /v1 Fusion Table API but no holding off any longer.
I'm using Python on AppEngine and trying to connect to Google Fusion Tables with Google Service Accounts (the more complicated cousin of OAuth2 for server side apps that uses JSON Web Tokens)
I found another question that pointed me to some documentation for using Service Accounts with Google Prediction API.
Fusion Table and Google Service Accounts
So far I've got
import httplib2
from oauth2client.appengine import AppAssertionCredentials
from apiclient.discovery import build
credentials = AppAssertionCredentials(scope='https://www.googleapis.com/auth/fusiontables')
http = credentials.authorize(httplib2.Http(memcache)) #Http(memcache)
service = build("fusiontables", "v1", http=http)
# list the tables
tables = service.table().list().execute() # <-- ERROR 401 invalid credentials here
Does anyone have an example of connecting to Fusion Tables on AppEngine using Service Accounts they might be able to share? Or something nice online?
Thanks
This actually does work. The important parts are you have to give the app engine service account access to your fusion table. If you are writing then the account needs write access. For help see: https://developers.google.com/api-client-library/python/start/installation (look for Getting started: Quickstart)
Your app engine service account will be something like your-app-id#appspot.gserviceaccount.com
You must also make the app engine service account a team member in the api console and give it "can edit" privilege.
SCOPE='https://www.googleapis.com/auth/fusiontables'
PROJECT_NUMBER = 'XXXXXXXX' # REPLACE WITH YOUR Project ID
# Create a new API service for interacting with Fusion Tables
credentials = AppAssertionCredentials(scope=SCOPE)
http = credentials.authorize(httplib2.Http())
logging.info('QQQ: accountname: %s' % app_identity.get_service_account_name())
service = build('fusiontables', 'v1', http=http, developerKey='YOUR KEY HERE FROM API CONSOLE')
def log(value1,value2=None):
tableid='YOUR TABLE ID FROM FUSION TABLES'
now = strftime("%Y-%m-%d %H:%M:%S", gmtime())
service.query().sql(sql="INSERT INTO %s (Temperature,Date) values(%s,'%s')" % (tableid,value1,now)).execute()
to clarify Ralph Yozzo's answer: you need to add the value of 'client_email' from the json file you downloaded when you created your service_account credentials (the same file you load when using ServiceAccountCredentials.from_json_keyfile_name('service_acct.json') with the new oauth2client library), to your table's sharing dialog screen (click 1 then enter the email address in 2)
Since Fusion Tables' tables are owned by individual Gmail accounts rather than the service account associated with an API console project, the AppAssertionCredentials probably won't work. It would make for an interesting feature request, though:
http://code.google.com/p/fusion-tables/issues/list
The best online resource I have found for help connecting Python AppEngine to Fusion Tables API with Oauth2 is
Google APIs Client Library for Python
The slide presentation is helpful to understanding the online samples, why decorators are used.
Also useful for understanding whether to use the app's Service Acount or User Accounts to authenticate is:
Using OAuth 2.0 to Access Google APIs
Consider installing the Google APIs Client Library for Python
Apart from the scope, the Oauth2 is more or less common to all Google APIs not just fusion tables.
Once oauth2 is working, see the Google Fusion Tables API
In case you want it to work from another host than Google App Engine or Google Compute Engine (e.g. from localhost for testing) then you should use ServiceAccountCredentials created from a json key file that you can generate and download from your service account page.
scopes = ['https://www.googleapis.com/auth/fusiontables']
keyfile = 'PATH TO YOUR SERVICE ACCOUNT KEY FILE'
FTID = 'FUSION TABLE ID'
credentials = ServiceAccountCredentials.from_json_keyfile_name(keyfile, scopes)
http_auth = credentials.authorize(Http(memcache))
service = build('fusiontables', 'v2', http=http_auth)
def insert(title, description):
sqlInsert = "INSERT INTO {0} (Title,Description) values('{1}','{2}')".format(FTID, title, description)
service.query().sql(sql=sqlInsert).execute()
Refer to Google's page on service accounts for explanations.
Any tips on python oauth2 and facebook.
It seems there are little information since Facebook updated to OAuth2.
Is there anyway the existing Twitter library can be used to suite the facebook authentication?
import oauth2 as oauth
# Create your consumer with the proper key/secret.
consumer = oauth.Consumer(key="your-twitter-consumer-key",
secret="your-twitter-consumer-secret")
# Request token URL for Twitter.
request_token_url = "http://twitter.com/oauth/request_token"
# Create our client.
client = oauth.Client(consumer)
# The OAuth Client request works just like httplib2 for the most part.
resp, content = client.request(request_token_url, "GET")
print resp
print content
If your looking for readily available Django apps to integrate with your project, check out the authentication packages. Most of them that provide Facebook authentication have been updated to support the OAuth 2 protocol for some time already.
If, on the other hand, you'd like to work with a provider through an OAuth 2 library directly, take a look at python-oauth2--there's a lengthy example of how you can integrate it with Django's authentication immediately in the README.
There is an awesome project called Fandjango and Facepy. Simply, you don't even have to know or even worry about OAuth protocols anymore.
If you want all the user's details or are integrating more of Facebook's graph api, you should have a look at:
https://github.com/tschellenbach/Django-facebook
For a demo of how slick it is:
http://www.fashiolista.com/intro_wide/
Features (Copied from github)
Access the Facebook API, from:
Your website (Using javascript OAuth)
Facebook canvas pages (For building facebook applications)
Mobile (Or any other flow giving you a valid access token)
Django User Registration (Convert Facebook user data into a user model)
Use Facebook data to register a user with your Django app. Facebook connect using the open graph API.
Facebook FQL access
OAuth 2.0 compliant
Includes Open Facebook (stable and tested python client to the graph API)
Can anyone advice me on a good library or else how to go about having a Python appengine based application using OAuth to authenticate to another server?
I have an application on appengine that expects user input. I would like the user to be able to upload an image, which I would put in imgur.com and would be able to show to the user back on my page. To be able to do that, I need to be able to authenticate to api.imgur.com hence the question.
Have a look to python-oauth2 project.
A Client example:
import oauth2 as oauth
# Create your consumer with the proper key/secret.
consumer = oauth.Consumer(key="your-twitter-consumer-key",
secret="your-twitter-consumer-secret")
# Request token URL for Twitter.
request_token_url = "http://twitter.com/oauth/request_token"
# Create our client.
client = oauth.Client(consumer)
# The OAuth Client request works just like httplib2 for the most part.
resp, content = client.request(request_token_url, "GET")
print resp
print content
I believe the simplegeo oauth2 does not play well with GAE. Mike Knapp's library on GitHub is nice and simple, no install needed.
maybe you can use imgur-api, http://code.google.com/p/imgur-api/wiki/ImageUploading