Index: chrome/common/extensions/docs/examples/apps/hello-python/main.py |
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/main.py b/chrome/common/extensions/docs/examples/apps/hello-python/main.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4e50f205cd80b034c8feb8c5f89cc6f6b078a40f |
--- /dev/null |
+++ b/chrome/common/extensions/docs/examples/apps/hello-python/main.py |
@@ -0,0 +1,149 @@ |
+#!/usr/bin/python |
+# Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+from google.appengine.ext import webapp |
+from google.appengine.ext.webapp import util |
+from google.appengine.api import users |
+from google.appengine.api import urlfetch |
+from google.appengine.ext.webapp import template |
+from google.appengine.api.urlfetch import DownloadError |
+import oauth2 |
+import urllib |
+import logging |
+import os |
+import time |
+from django.utils import simplejson |
+ |
+# Configuration |
+ |
+CONFIG = { |
+ 'oauth_consumer_key': 'anonymous', |
+ 'oauth_consumer_secret': 'anonymous', |
+ 'license_server': 'https://www.googleapis.com', |
+ 'license_path': '%(server)s/chromewebstore/v1/licenses/%(appid)s/%(userid)s', |
+ 'oauth_token': 'INSERT OAUTH TOKEN HERE', |
+ 'oauth_token_secret': 'INSERT OAUTH TOKEN SECRET HERE', |
+ 'app_id': 'INSERT APPLICATION ID HERE', |
+} |
+ |
+# Check to see if the server has been deployed. In the dev server, this |
+# env variable will start with 'Development', in production, it will start with |
+# 'Google App Engine' |
+IS_PRODUCTION = os.environ['SERVER_SOFTWARE'].startswith('Google App Engine') |
+ |
+# Valid access levels that may be returned by the license server. |
+VALID_ACCESS_LEVELS = ['FREE_TRIAL', 'FULL'] |
+ |
+def fetch_license_data(userid): |
+ """Fetches the license for a given user by making an OAuth signed request |
+ to the license server. |
+ |
+ Args: |
+ userid OpenID of the user you are checking access for. |
+ |
+ Returns: |
+ The server's response as text. |
+ """ |
+ url = CONFIG['license_path'] % { |
+ 'server': CONFIG['license_server'], |
+ 'appid': CONFIG['app_id'], |
+ 'userid': urllib.quote_plus(userid), |
+ } |
+ |
+ oauth_token = oauth2.Token(**{ |
+ 'key': CONFIG['oauth_token'], |
+ 'secret': CONFIG['oauth_token_secret'] |
+ }) |
+ |
+ oauth_consumer = oauth2.Consumer(**{ |
+ 'key': CONFIG['oauth_consumer_key'], |
+ 'secret': CONFIG['oauth_consumer_secret'] |
+ }) |
+ |
+ logging.debug('Requesting %s' % url) |
+ client = oauth2.Client(oauth_consumer, oauth_token) |
+ resp, content = client.request(url, 'GET') |
+ logging.debug('Got response code %s, content %s' % (resp, content)) |
+ return content |
+ |
+def parse_license_data(userid): |
+ """Returns the license for a given user as a structured object. |
+ |
+ Args: |
+ userid: The OpenID of the user to check. |
+ |
+ Returns: |
+ An object with the following parameters: |
+ error: True if something went wrong, False otherwise. |
+ message: A descriptive message if error is True. |
+ access: One of 'NO', 'FREE_TRIAL', or 'FULL' depending on the access. |
+ """ |
+ license = {'error': False, 'message': '', 'access': 'NO'} |
+ try: |
+ response_text = fetch_license_data(userid) |
+ try: |
+ logging.debug('Attempting to JSON parse: %s' % response_text) |
+ json = simplejson.loads(response_text) |
+ logging.debug('Got license server response: %s' % json) |
+ except ValueError: |
+ logging.exception('Could not parse response as JSON: %s' % response_text) |
+ license['error'] = True |
+ license['message'] = 'Could not parse the license server response' |
+ except DownloadError: |
+ logging.exception('Could not fetch license data') |
+ license['error'] = True |
+ license['message'] = 'Could not fetch license data' |
+ |
+ if json.has_key('error'): |
+ license['error'] = True |
+ license['message'] = json['error']['message'] |
+ elif json['result'] == 'YES' and json['accessLevel'] in VALID_ACCESS_LEVELS: |
+ license['access'] = json['accessLevel'] |
+ |
+ return license |
+ |
+class MainHandler(webapp.RequestHandler): |
+ """Request handler class.""" |
+ def get(self): |
+ """Handler for GET requests.""" |
+ user = users.get_current_user() |
+ if user: |
+ if IS_PRODUCTION: |
+ # We should use federated_identity in production, since the license |
+ # server requires an OpenID |
+ userid = user.federated_identity() |
+ else: |
+ # On the dev server, we won't have access to federated_identity, so |
+ # just use a default OpenID which will never return YES. |
+ # If you want to test different response values on the development |
+ # server, just change this default value (e.g. append '-yes' or |
+ # '-trial'). |
+ userid = ('https://www.google.com/accounts/o8/id?' |
+ 'id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') |
+ license_data = parse_license_data(userid) |
+ template_data = { |
+ 'license': license_data, |
+ 'user_name': user.nickname(), |
+ 'user_id': userid, |
+ 'user_logout': users.create_logout_url(self.request.uri), |
+ } |
+ else: |
+ # Force the OpenID login endpoint to be for Google accounts only, since |
+ # the license server doesn't support any other type of OpenID provider. |
+ login_url = users.create_login_url(dest_url='/', |
+ federated_identity='google.com/accounts/o8/id') |
+ template_data = { |
+ 'user_login': login_url, |
+ } |
+ |
+ # Render a simple template |
+ path = os.path.join(os.path.dirname(__file__), 'templates', 'index.html') |
+ self.response.out.write(template.render(path, template_data)) |
+ |
+if __name__ == '__main__': |
+ application = webapp.WSGIApplication([ |
+ ('/', MainHandler), |
+ ], debug=False) |
+ util.run_wsgi_app(application) |