Skip to content

Commit

Permalink
Add basic auth.
Browse files Browse the repository at this point in the history
  • Loading branch information
glasser committed Jan 11, 2011
1 parent e438397 commit 0b1a11c
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions handler.py
@@ -1,5 +1,7 @@
#!/usr/bin/env python2.5

import base64
import logging
import os

from google.appengine.ext import webapp
Expand All @@ -17,10 +19,45 @@
else:
HOST_NAME = os.environ['SERVER_NAME']

# Inspired by mox's MoxMetaTestBase.
class RequestHandlerMetaClass(type):
"""Metaclass to do auth checks at the beginning of get and post methods."""

def __init__(cls, name, bases, d):
type.__init__(cls, name, bases, d)
# Also get all of the attributes from base classes to account for a case
# when the handler class is not the immediate child of RequestHandler.
for base in bases:
for attr_name in dir(base):
if attr_name not in d:
d[attr_name] = getattr(base, attr_name)

for func_name, func in d.items():
if callable(func) and (func_name == 'get' or func_name == 'post'):
setattr(cls, func_name, RequestHandlerMetaClass.wrap_with_auth(
cls, func))

@staticmethod
def wrap_with_auth(cls, func):
def new_method(self, *args, **kwargs):
if self.check_basic_auth():
func(self, *args, **kwargs)
new_method.__name__ = func.__name__
new_method.__doc__ = func.__doc__
new_method.__module__ = func.__module__
return new_method


class RequestHandler(webapp.RequestHandler):

__metaclass__ = RequestHandlerMetaClass

COOKIE_NAME = 'hq_username'
NOBODY = 'nobody'

BASIC_AUTH_USER = 'nugget'
BASIC_AUTH_PASSWORD = 'hotdog'

def initialize(self, *args, **kwds):
super(RequestHandler, self).initialize(*args, **kwds)

Expand All @@ -34,6 +71,30 @@ def set_username(self, username):
'%s=%s; path=/; expires=Fri, 31-Dec-2020 23:59:59 GMT' \
% (self.COOKIE_NAME, username.encode()))

def check_basic_auth(self):
auth_header = self.request.headers.get('Authorization')
if auth_header:
try:
(scheme, base64_raw) = auth_header.split(' ')
if scheme != 'Basic':
raise ValueError, 'scheme is not Basic!'
(username, password) = base64.b64decode(base64_raw).split(':')
except (ValueError, TypeError), err:
username = password = ''
logging.warn(type(err))
finally:
if (username == self.BASIC_AUTH_USER and
password == self.BASIC_AUTH_PASSWORD):
return True
else:
self.error(401)
self.response.headers['WWW-Authenticate'] = 'Basic realm="CIC"'
return False
else:
self.error(401)
self.response.headers['WWW-Authenticate'] = 'Basic realm="CIC"'
return False

def render_template(self, template_name, params, **kwds):
params['usernames'] = model.Username.all()
params['current_user'] = self.username
Expand Down

0 comments on commit 0b1a11c

Please sign in to comment.