views:

491

answers:

6

I'm about to put a beta version of the site I'm working on up on the web. It needs to have a beta code to restrict access. The site is written in django.

I don't want to change the fundamental Auth system to accommodate a beta code, and I don't care particularly that the security of the beta code is iron-clad, just that it's a significant stumbling block.

How should I do this? It's a fairly large project so adding code to every view is far from ideal.


That solution works well. The Middleware Class I ended up with this this:

from django.http import HttpResponseRedirect

class BetaMiddleware(object):
    """
    Require beta code session key in order to view any page.
    """
    def process_request(self, request):
        if request.path != '/beta/' and not request.session.get('in_beta'):
            return HttpResponseRedirect('%s?next=%s' % ('/beta/', request.path))
A: 

You should be able to add @login_required decorators across the board and be done with it. Unless you have a boat-load of view functions, it shouldn't be too horrible.

S.Lott
The problem with this is that then whoever is trying to get access is taken to the login page, rather then to a page for entering a beta code. The login page has all the menus and ui around it. I'd like to keep that stuff private for now.
defrex
@defrex, make your own login_required decorator that wraps Django's built-in version. When you go live, just replace it with Django's entirely.
John Millikin
+3  A: 

You can probably restrict access to the entire site via apache with htaccess, taking the problem out of the django's project space entirely.

rcreswick
A: 

Do what StackOverflow did.

They had a simple email/password form. It had a single hard-coded password (falkensmaze). When the user gets the password right set a cookie. eg. auth=1

Don't worry about it being unsecure. Who care's if someone hacks into the beta?

Apache/htaccess is also a nice and simple solution.

andyuk
This implies that I have to check for the existence of a cookie in every view. I'd rather avoid adding code to every view. Is there a way to check for a cookie globally in django?
defrex
+14  A: 

Start with this Django snippet, but modify it to check request.session['has_beta_access']. If they don't have it, then have it return a redirect to a "enter beta code" page that, when posted to with the right code, sets that session variable to True.

Making it a public beta then just consists of removing that middleware from your MIDDLEWARE_CLASSES setting.

AdamKG
A: 

I'm not sure what version of the Pinax code you're using, but they've built in the ability to close the site off for a private beta so you don't need to do much work yourself.

The link to the specific project template for a private beta site is here: http://github.com/pinax/pinax/tree/3ad73d1ba44f37365333bae17b507668b0eb7e16/pinax/projects/private_beta_project although I think they might have since added that functionality to all the project templates.

John Debs
A really old version of pinax. The question was asked in Sept, 08. It's a good point though, so I removed the reference to pinax out of the question so people don't get misled.
defrex
A: 

Great snippet but it resulted lots of problems for me related OpenId sessions. So I end up relying on Cookies instead of the Session:

class BetaMiddleware(object):
    """
    Require beta code cookie key in order to view any page.
    """
    set_beta = False
    def process_request(self, request):
        referer = request.META.get('HTTP_REFERER', '')

        if request.method == 'GET' and not 'is_in_beta' in request.COOKIES:
            return HttpResponseRedirect('%s?next=%s' % ('/beta/', request.path))

        if request.method == 'POST' and 'pass' in request.POST:
            code = request.POST['pass']

            if code=='beta':
                self.set_beta = True
                return HttpResponseRedirect('%s' % '/')

    def process_response(self, request, response):        

        if self.set_beta is True:
            response.set_cookie('is_in_beta', '1')
        return response

It's not secure but that's enough for me. This also works with just a beta html page.

ercu