Django closed sites w/ login
I am currently building an extranet for a large, North American book and audio book publisher. Currently, I have implemented our enternal stuff in Plone but I am hopeing to do the external stuff in Django. I like Plone. It has treated me well. But the CRUD thing is driving me crazy. I'm tired, loathely tired, of dealing w/ all the DB stuff. So, I have started the process of using Django. One of the requirements is, of course, no anonymous logins. Here is how I have implemented this function in Django and it is quite easy. Surprisingly so. I use a middleware class. I am guessing there is an innate, Django way to do it but I haven't seen hide nor hair of it.
First, create a directory titled 'middleware' in your python path. I placed mine in:
Within this directory is a file titled authenticate.py. You can find more about middleware at the djangoproject.com website. Within authenticate.py is a class which I have titled, 'CheckAuthenticationAndGroups'.
Middleware has three functions: process_request, process_view and process_response. You can read up on each at the link above but I only needed the one, process_request.
The first line after the state method statement causes anything with a '.' simply to be passed through. This has some serious security side-effects; however, I'll be revisiting that latter when I have time. The print statement is so when running under django-admin.py runserver I can see what is hitting my process_request method.
Here I place the groups the user belongs to into the GET object. I am sure there is a better way to go about this but it does mean that every request receives the groups of that user without having to request or take any other steps. I need to cache this and also find a better way to pass the groups. I don't use the groups for security but convienance in showing or not showing certain lengths. The actual locations are dealt with through permissions.
Now I believe I may have hacked the login function ;). I need to look and make sure. It seems like that it didn't take a redirect_to keyword and I changed it. Again, you may need to check that in views/auth/login.py to see if it will take the keyword variable and act accordingly. That aside, if the user is anonymous, they are redirect to login. The redirect is to wherever you want the user to wind up after they have logged in. I currently implement this to help run my household. We homeschool 6 children so it is used for chores, school assignments, weekly menu, calendar and other related stuff. The next control in the if statement is for a 'logout' link. Checking the request.session is there to cut off recursive and infinite looping through. The login function calls logout repeatedly until the session is deleted and no longer present. At that point login redirects to 'registration/login'. What I have done is created a directory called registration under my template directory and created a template within that directory called login.html. This template extends the base of my site so it is consistent with the rest of my site. I cut&pasted the login html and form from the admin.
registration/login.html
That is it. I don't think I missed anything that I did. If anyone knows better (like a developer) please let me know. Any comments as to a better way to make this work please let me know. Or any questions, feel free to ask.
Scott
PS. My next tutorial (loosely speaking) will be on inline editing of parent/child tables outside the admin (so that normal users can access it and it all still looks and acts like the rest of your public site) using templatetags and other elements not immediatly exposed outside the admin.
First, create a directory titled 'middleware' in your python path. I placed mine in:
->myproject
->apps
->middleware
Within this directory is a file titled authenticate.py. You can find more about middleware at the djangoproject.com website. Within authenticate.py is a class which I have titled, 'CheckAuthenticationAndGroups'.
from django.conf import settings
from django.utils import httpwrappers
from django.models.auth import users
from django.views.auth.login import *
class CheckAuthenticationAndGroups:
"""
do some authentication work
hey good lookin' be back to document you latter
"""
def process_request(self, request):
if '.' in request.path: return None
print "%s"%request.path
groups = [x.name for x in request.user.get_group_list()]
request.GET.update({'groups':groups})
if request.user.is_anonymous():
return login(request,redirect_to='/school/')
if 'logout' in request.get_full_path() and request.session:
return login(request,redirect_to='/school/')
else:
return None
Middleware has three functions: process_request, process_view and process_response. You can read up on each at the link above but I only needed the one, process_request.
def process_request(self, request):
if '.' in request.path: return None
print "%s"%request.path
The first line after the state method statement causes anything with a '.' simply to be passed through. This has some serious security side-effects; however, I'll be revisiting that latter when I have time. The print statement is so when running under django-admin.py runserver I can see what is hitting my process_request method.
groups = [x.name for x in request.user.get_group_list()]
request.GET.update({'groups':groups})
Here I place the groups the user belongs to into the GET object. I am sure there is a better way to go about this but it does mean that every request receives the groups of that user without having to request or take any other steps. I need to cache this and also find a better way to pass the groups. I don't use the groups for security but convienance in showing or not showing certain lengths. The actual locations are dealt with through permissions.
if request.user.is_anonymous():
return login(request,redirect_to='/school/')
if 'logout' in request.get_full_path() and request.session:
return login(request,redirect_to='/school/')
else:
return None
Now I believe I may have hacked the login function ;). I need to look and make sure. It seems like that it didn't take a redirect_to keyword and I changed it. Again, you may need to check that in views/auth/login.py to see if it will take the keyword variable and act accordingly. That aside, if the user is anonymous, they are redirect to login. The redirect is to wherever you want the user to wind up after they have logged in. I currently implement this to help run my household. We homeschool 6 children so it is used for chores, school assignments, weekly menu, calendar and other related stuff. The next control in the if statement is for a 'logout' link. Checking the request.session is there to cut off recursive and infinite looping through. The login function calls logout repeatedly until the session is deleted and no longer present. At that point login redirects to 'registration/login'. What I have done is created a directory called registration under my template directory and created a template within that directory called login.html. This template extends the base of my site so it is consistent with the rest of my site. I cut&pasted the login html and form from the admin.
registration/login.html
{% extends "base" %}
{% block navlinks %}
{% endblock %}
{% block maincolumn %}
{% if errors %}
{% for err in errors.username %}
username: {{ err }}
{% endfor %}
{% for err in errors.password %}
password: {{ err }}
{% endfor %}
{% endif %}
<form action="{{ app_path }}" method="post">
<input type="text" name="username" id="id_username" />
{% comment %} Have you forgotten your password?{% endcomment %}
<input type="submit" value="Log in" />
<script type="text/javascript">
document.getElementById('id_username').focus()
{% endblock %}
That is it. I don't think I missed anything that I did. If anyone knows better (like a developer) please let me know. Any comments as to a better way to make this work please let me know. Or any questions, feel free to ask.
Scott
PS. My next tutorial (loosely speaking) will be on inline editing of parent/child tables outside the admin (so that normal users can access it and it all still looks and acts like the rest of your public site) using templatetags and other elements not immediatly exposed outside the admin.

0 Comments:
Post a Comment
<< Home