title: Python Decorator for GAE Web-Service Security Check
body: <p>In this post, Nick suggested a decoartor: </p>
  
  <p><a href="https://stackoverflow.com/questions/1499832/python-webapp-google-app-engine-testing-for-user-pass-in-the-headers/1500047#1500047">Python/WebApp Google App Engine - testing for user/pass in the headers</a></p>
  
  <p>I'm writing an API to expose potentially dozens of methods as web-services, so the decorator sounds like a great idea. </p>
  
  <p>I tried to start coding one based on this sample: 
  <a href="http://groups.google.com/group/google-appengine/browse_thread/thread/ac51cc32196d62f8/aa6ccd47f217cb9a?lnk=gst&amp;q=timeout#aa6ccd47f217cb9a" rel="nofollow noreferrer">http://groups.google.com/group/google-appengine/browse_thread/thread/ac51cc32196d62f8/aa6ccd47f217cb9a?lnk=gst&amp;q=timeout#aa6ccd47f217cb9a</a></p>
  
  <p>I need it compatible with Python 2.5 to run under Google App Engine (GAE). </p>
  
  <p>Here's my attempt.  Please just point the way to if I'm on the right track or not. 
  Currently getting an error "Invalid Syntax" on this line:
    class WSTest(webapp.RequestHandler):</p>
  
  <p>My idea is to pass an array of roles to the decorator.  These are the only roles (from my db that should have access to each various web service). </p>
  
  <pre><code>def BasicAuthentication(roles=[]):
    def _decorator(func):
      def _wrapper(*args, **kwds): 
          logging.info("\n\n BasicAuthentication:START:__call__ \n\n") 
          auth = None 
          if 'Authorization' in self.request.headers: 
             auth = self.request.headers['Authorization']
          if not auth:
             self.response.headers['WWW-Authenticate'] = 'Basic realm="MYREALM"'
             self.response.set_status(401)
             self.response.out.write("Authorization required")
             logging.info ("\n\n  Authorization required \n\n") 
             return 
  
          (username, password) = base64.b64decode(auth.split(' ')[1]).split(':')
          logging.info ("\n\n username = " + username + "  password=" + password + "\n\n")         
  
          isValidUserPass = False 
          usersSimulatedRole = "Admin" 
          #check against database here...  
          if user == "test12" and password == "test34":
             isValidUserPass = True  
          isValidRole = False 
          if usersSimulatedRole in roles:
             isValidRole = True 
          #next check that user has one of the roles 
          #  TODO 
  
          if not isValidUserPass:
             self.response.set_status(403)
             self.response.out.write("Forbidden: Userid/password combination failed")
  
          logging.info("\n\n BasicAuthentication:END:__call__ \n\n") 
          return func(*args, **kwds) 
      return _wrapper
    return _decorator 
  
  
  @BasicAuthentication(["Admin","Worker"])   #list of roles that can run this function 
  class WSTest(webapp.RequestHandler):
    def get(self):
       logging.info("\n\n\n WSTest \n\n") 
       ...etc...
  </code></pre>
  
  <p>Thanks,
  Neal Walters </p>