diff --git a/.gitignore b/.gitignore index 7ef72bb..d81eac6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +appengine/credentials.py *.pyc .DS_Store docs/_build diff --git a/appengine/auth.py b/appengine/auth.py new file mode 100644 index 0000000..c28bc37 --- /dev/null +++ b/appengine/auth.py @@ -0,0 +1,45 @@ +import rest +import logging +import base64 +import credentials + +AUTHENTICATE_HEADER = "WWW-Authenticate" +AUTHORIZATION_HEADER = "Authorization" +AUTHENTICATE_TYPE = 'Basic realm="Secure Area"' +CONTENT_TYPE_HEADER = "Content-Type" +HTML_CONTENT_TYPE = "text/html" + +class BasicAuthenticator(rest.Authenticator): + """Example implementation of HTTP Basic Auth.""" + + def __init__(self): + super(BasicAuthenticator, self).__init__() + + def authenticate(self, dispatcher): + + user_arg = None + pass_arg = None + try: + # Parse the header to extract a user/password combo. + # We're expecting something like "Basic XZxgZRTpbjpvcGVuIHYlc4FkZQ==" + auth_header = dispatcher.request.headers[AUTHORIZATION_HEADER] + + # Isolate the encoded user/passwd and decode it + auth_parts = auth_header.split(' ') + user_pass_parts = base64.b64decode(auth_parts[1]).split(':') + user_arg = user_pass_parts[0] + pass_arg = user_pass_parts[1] + + except Exception: + # set the headers requesting the browser to prompt for a user/password: + dispatcher.response.set_status(401, message="Authentication Required") + dispatcher.response.headers[AUTHENTICATE_HEADER] = AUTHENTICATE_TYPE + dispatcher.response.headers[CONTENT_TYPE_HEADER] = HTML_CONTENT_TYPE + + dispatcher.response.out.write("401 Authentication Required") + raise rest.DispatcherException() + + if user_arg==credentials.USER and pass_arg==credentials.PASS: + return + + dispatcher.forbidden() \ No newline at end of file diff --git a/appengine/index.py b/appengine/index.py index 1e9b7c4..5eb17d8 100644 --- a/appengine/index.py +++ b/appengine/index.py @@ -4,6 +4,7 @@ from google.appengine.ext.webapp.util import run_wsgi_app import models +import auth from django.utils import simplejson @@ -12,12 +13,13 @@ class JSONDispatcher(rest.Dispatcher): content_type_order = [rest.JSON_CONTENT_TYPE] base_url="/rest/v1/json" + authenticator = auth.BasicAuthenticator() class XMLDispatcher(rest.Dispatcher): content_type_order = [rest.XML_CONTENT_TYPE] base_url="/rest/v1/xml" + authenticator = auth.BasicAuthenticator() - application = webapp.WSGIApplication([ ('/rest/v1/json/.*', JSONDispatcher),