Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit 04a4702d26d8a2783f1f82d1bddef0211f7de8be Andy Mroczkowski committed Feb 22, 2012
Showing with 158 additions and 0 deletions.
  1. +4 −0 .gitignore
  2. 0 README.md
  3. 0 moat/__init__.py
  4. +113 −0 moat/middleware.py
  5. +1 −0 requirements.txt
  6. +40 −0 setup.py
@@ -0,0 +1,4 @@
+*.db
+*.pyc
+*.DS_Store
+dist/*
No changes.
No changes.
@@ -0,0 +1,113 @@
+"""
+Mini-app to globally prevent access to site with Basic Auth. Emulates
+setting up HTTP Basic Auth in your webserver (Apache, nginx).
+
+If you provide a HTTP_AUTH_REALM in your settings, that will be used as
+the realm for the challenge.
+
+Adapted from:
+ - HTTP Authorization Middleware/Decorator
+ http://djangosnippets.org/snippets/1720/
+ - django-privatebetaa
+ https://github.com/pragmaticbadger/django-privatebeta
+"""
+
+from django.conf import settings
+from django.http import HttpResponse, iri_to_uri, get_host
+from django.contrib.auth import authenticate
+from django.core.urlresolvers import resolve
+
+import base64
+import logging
+
+class HttpResponseTemporaryRedirect(HttpResponse):
+ status_code = 307
+
+ def __init__(self, redirect_to):
+ HttpResponse.__init__(self)
+ self['Location'] = iri_to_uri(redirect_to)
+
+class MoatMiddleware(object):
+ """
+ Some middleware to authenticate all requests at this site.
+ """
+ def __init__(self):
+ self.always_allow_modules = getattr(settings, 'MOAT_ALWAYS_ALLOW_MODULES', [])
+ self.always_allow_views = getattr(settings, 'MOAT_ALWAYS_ALLOW_VIEWS', [])
+
+ def process_request(self, request):
+
+ # check if its globally disabled
+ try:
+ if not settings.MOAT_ENABLED:
+ return None
+ except AttributeError:
+ pass
+
+ # see if we already authenticated
+ if request.session.get('moat_username') != None:
+ logging.info("Already authenticated as: " + request.session.get('moat_username'))
+ return None
+ else:
+ logging.debug("Didn't find moat auth in session")
+
+ whitelisted_modules = []
+ if self.always_allow_modules:
+ whitelisted_modules += self.always_allow_modules
+
+ whitelisted_views = ['django.views.generic.simple.redirect_to']
+ if self.always_allow_views:
+ whitelisted_views += self.always_allow_views
+
+ view_func = resolve(request.META.get('PATH_INFO')).func
+ full_view_name = '%s.%s' % (view_func.__module__, view_func.__name__)
+ logging.debug("full_view_name = %s" % (full_view_name))
+
+ if full_view_name in whitelisted_views:
+ return None
+ if '%s' % view_func.__module__ in whitelisted_modules:
+ return None
+
+ # if not, redirect to secure
+ if not request.is_secure():
+ return self._redirect(request)
+
+ # finally check auth
+ return self._http_auth_helper(request)
+
+ def _redirect(self, request):
+ newurl = "https://%s%s" % (get_host(request),request.get_full_path())
+ if settings.DEBUG and request.method == 'POST':
+ raise RuntimeError, \
+ """Django can't perform a SSL redirect while maintaining POST data.
+ Please structure your views so that redirects only occur during GETs."""
+
+ return HttpResponseTemporaryRedirect(newurl)
+
+ def _http_auth_helper(self, request):
+ # At this point, the user is either not logged in, or must log in using
+ # http auth. If they have a header that indicates a login attempt, then
+ # use this to try to login.
+ if request.META.has_key('HTTP_AUTHORIZATION'):
+ auth = request.META['HTTP_AUTHORIZATION'].split()
+ if len(auth) == 2:
+ if auth[0].lower() == 'basic':
+ # Currently, only basic http auth is used.
+ uname, passwd = base64.b64decode(auth[1]).split(':')
+ user = authenticate(username=uname, password=passwd)
+ if user and user.is_staff:
+ request.session['moat_username'] = uname
+ return None
+
+ # The username/password combo was incorrect, or not provided.
+ # Challenge the user for a username/password.
+ resp = HttpResponse()
+ resp.status_code = 401
+ try:
+ # If we have a realm in our settings, use this for the challenge.
+ realm = settings.HTTP_AUTH_REALM
+ except AttributeError:
+ realm = ""
+
+ resp['WWW-Authenticate'] = 'Basic realm="%s"' % realm
+ return resp
@@ -0,0 +1 @@
+Django==1.3.1
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+import os
+import sys
+import codecs
+
+try:
+ from setuptools import setup, find_packages
+except ImportError:
+ from ez_setup import use_setuptools
+ use_setuptools()
+ from setuptools import setup, find_packages
+
+import moat as distmeta
+
+packages, data_files = find_packages(exclude=("example_project",)), []
+root_dir = os.path.dirname(__file__)
+if root_dir != '':
+ os.chdir(root_dir)
+src_dir = "moat"
+
+
+if os.path.exists("README.rst"):
+ long_description = codecs.open("README.rst", "r", "utf-8").read()
+else:
+ long_description = "See http://amrox.github.com/django-moat/"
+
+
+setup(
+ name='django-moat',
+ version=distmeta.__version__,
+ description=distmeta.__doc__,
+ author=distmeta.__author__,
+ author_email=distmeta.__contact__,
+ url=distmeta.__homepage__,
+ platforms=["any"],
+ # license="BSD",
+ packages=packages,
+ data_files=data_files,
+ long_description=long_description,
+)

0 comments on commit 04a4702

Please sign in to comment.