p@21: """ p@21: The MIT License p@21: p@21: Copyright (c) 2010 Justin Plock p@21: p@21: Permission is hereby granted, free of charge, to any person obtaining a copy p@21: of this software and associated documentation files (the "Software"), to deal p@21: in the Software without restriction, including without limitation the rights p@21: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell p@21: copies of the Software, and to permit persons to whom the Software is p@21: furnished to do so, subject to the following conditions: p@21: p@21: The above copyright notice and this permission notice shall be included in p@21: all copies or substantial portions of the Software. p@21: p@21: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR p@21: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, p@21: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE p@21: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER p@21: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, p@21: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN p@21: THE SOFTWARE. p@21: """ p@21: p@21: import os p@21: p@21: from google.appengine.ext import webapp p@21: from google.appengine.ext import db p@21: from google.appengine.ext.webapp import util p@21: import oauth2 as oauth # httplib2 is required for this to work on AppEngine p@21: p@21: class Client(db.Model): p@21: # oauth_key is the Model's key_name field p@21: oauth_secret = db.StringProperty() # str(uuid.uuid4()) works well for this p@21: first_name = db.StringProperty() p@21: last_name = db.StringProperty() p@21: email_address = db.EmailProperty(required=True) p@21: password = db.StringProperty(required=True) p@21: p@21: @property p@21: def secret(self): p@21: return self.oauth_secret p@21: p@21: class OAuthHandler(webapp.RequestHandler): p@21: p@21: def __init__(self): p@21: self._server = oauth.Server() p@21: self._server.add_signature_method(oauth.SignatureMethod_HMAC_SHA1()) p@21: self._server.add_signature_method(oauth.SignatureMethod_PLAINTEXT()) p@21: p@21: def get_oauth_request(self): p@21: """Return an OAuth Request object for the current request.""" p@21: p@21: try: p@21: method = os.environ['REQUEST_METHOD'] p@21: except: p@21: method = 'GET' p@21: p@21: postdata = None p@21: if method in ('POST', 'PUT'): p@21: postdata = self.request.body p@21: p@21: return oauth.Request.from_request(method, self.request.uri, p@21: headers=self.request.headers, query_string=postdata) p@21: p@21: def get_client(self, request=None): p@21: """Return the client from the OAuth parameters.""" p@21: p@21: if not isinstance(request, oauth.Request): p@21: request = self.get_oauth_request() p@21: client_key = request.get_parameter('oauth_consumer_key') p@21: if not client_key: p@21: raise Exception('Missing "oauth_consumer_key" parameter in ' \ p@21: 'OAuth "Authorization" header') p@21: p@21: client = models.Client.get_by_key_name(client_key) p@21: if not client: p@21: raise Exception('Client "%s" not found.' % client_key) p@21: p@21: return client p@21: p@21: def is_valid(self): p@21: """Returns a Client object if this is a valid OAuth request.""" p@21: p@21: try: p@21: request = self.get_oauth_request() p@21: client = self.get_client(request) p@21: params = self._server.verify_request(request, client, None) p@21: except Exception, e: p@21: raise e p@21: p@21: return client p@21: p@21: class SampleHandler(OAuthHandler): p@21: def get(self): p@21: try: p@21: client = self.is_valid() p@21: except Exception, e: p@21: self.error(500) p@21: self.response.out.write(e) p@21: p@21: def main(): p@21: application = webapp.WSGIApplication([(r'/sample', SampleHandler)], p@21: debug=False) p@21: util.run_wsgi_app(application) p@21: p@21: if __name__ == '__main__': p@21: main()