OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # |
| 3 # Copyright 2011 Google Inc. |
| 4 # |
| 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 # you may not use this file except in compliance with the License. |
| 7 # You may obtain a copy of the License at |
| 8 # |
| 9 # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 # |
| 11 # Unless required by applicable law or agreed to in writing, software |
| 12 # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 # See the License for the specific language governing permissions and |
| 15 # limitations under the License. |
| 16 |
| 17 import boto |
| 18 import pickle |
| 19 |
| 20 from google.appengine.api import memcache |
| 21 from google.appengine.api import users |
| 22 from google.appengine.ext import db |
| 23 from google.appengine.ext import webapp |
| 24 from google.appengine.ext.webapp import util |
| 25 from google.appengine.ext.webapp.util import login_required |
| 26 from oauth2_plugin import Credentials |
| 27 from oauth2client.appengine import StorageByKeyName |
| 28 from oauth2client.client import OAuth2WebServerFlow |
| 29 |
| 30 |
| 31 class MainHandler(webapp.RequestHandler): |
| 32 |
| 33 @login_required |
| 34 def get(self): |
| 35 user = users.get_current_user() |
| 36 credentials = StorageByKeyName( |
| 37 Credentials, user.user_id(), 'credentials').get() |
| 38 |
| 39 if not credentials or credentials.invalid: |
| 40 # Fill out the client ID and secret you created from the Developer |
| 41 # Console below. Also you need to edit the redirect URI into the Dev |
| 42 # Console, and that value needs to be updated when you move from |
| 43 # running this app locally to running on Google App Server (else you'll |
| 44 # get a 'redirect_uri_mismatch' error). |
| 45 flow = OAuth2WebServerFlow( |
| 46 client_id='<YOUR_CLIENT_ID>', |
| 47 client_secret='<YOUR_CLIENT_SECRET>', |
| 48 scope='https://www.googleapis.com/auth/devstorage.read_only', |
| 49 user_agent='cloudauth-sample', |
| 50 auth_uri='https://accounts.google.com/o/oauth2/auth', |
| 51 token_uri='https://accounts.google.com/o/oauth2/token') |
| 52 callback = self.request.relative_url('/auth_return') |
| 53 authorize_url = flow.step1_get_authorize_url(callback) |
| 54 memcache.set(user.user_id(), pickle.dumps(flow)) |
| 55 self.redirect(authorize_url) |
| 56 else: |
| 57 try: |
| 58 # List the user's buckets. This always requires auth, so will fail |
| 59 # if authorization didn't succeed. |
| 60 uri = boto.storage_uri('gs://') |
| 61 self.response.headers['Content-Type'] = 'text/plain' |
| 62 self.response.out.write(uri.get_all_buckets()) |
| 63 except boto.exception.GSResponseError, e: |
| 64 if e.error_code == 'AccessDenied': |
| 65 StorageByKeyName( |
| 66 Credentials, user.user_id(), 'credentials').put(None) |
| 67 self.redirect('/') |
| 68 else: |
| 69 self.response.out.write('Got error: %s' % str(e)) |
| 70 |
| 71 |
| 72 |
| 73 class AuthHandler(webapp.RequestHandler): |
| 74 |
| 75 @login_required |
| 76 def get(self): |
| 77 user = users.get_current_user() |
| 78 flow = pickle.loads(memcache.get(user.user_id())) |
| 79 # This code should be ammended with application specific error |
| 80 # handling. The following cases should be considered: |
| 81 # 1. What if the flow doesn't exist in memcache? Or is corrupt? |
| 82 # 2. What if the step2_exchange fails? |
| 83 if flow: |
| 84 credentials = flow.step2_exchange(self.request.params) |
| 85 StorageByKeyName( |
| 86 Credentials, user.user_id(), 'credentials').put(credentials) |
| 87 self.redirect('/') |
| 88 else: |
| 89 # Add application specific error handling here. |
| 90 pass |
| 91 |
| 92 |
| 93 def main(): |
| 94 application = webapp.WSGIApplication( |
| 95 [ |
| 96 ('/', MainHandler), |
| 97 ('/auth_return', AuthHandler) |
| 98 ], |
| 99 debug=True) |
| 100 util.run_wsgi_app(application) |
| 101 |
| 102 |
| 103 if __name__ == '__main__': |
| 104 main() |
OLD | NEW |