开发者

Login URL using authentication information in Django

I'm working on a platform for online labs registration for my university.

Login View [project views.py]

from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response

from django.template import RequestContext
from django.contrib import auth

def index(request):
    return render_to_response('index.html', {}, context_instance = RequestContext(request))

def login(request):
    if request.method == "POST":
        post = request.POST.copy()
        if post.has_key('username') and post.has_key('password'):
            usr = post['username']
            pwd = post['password']
            user = auth.authenticate(username=usr, password=pwd)
            if user is not None and user.is_active:
                auth.login(request, user)
                if user.get_profile().is_teacher:
                    return HttpResponseRedirect('/teachers/'+user.username+'/')
                else:
                    return HttpResponseRedirect('/students/'+user.username+'/')
            else:
                return render_to_response('index.html', {'msg': 'You don\'t bel开发者_运维百科ong here.'}, context_instance = RequestContext(request)

    return render_to_response('login.html', {}, context_instance = RequestContext(request))


def logout(request):
    auth.logout(request)

    return render_to_response('index.html', {}, context_instance = RequestContext(request))

URLS

#========== PROJECT URLS ==========#

urlpatterns = patterns('',
    (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT }),
    (r'^admin/', include(admin.site.urls)),

    (r'^teachers/', include('diogenis.teachers.urls')),
    (r'^students/', include('diogenis.students.urls')),
    (r'^login/', login),
    (r'^logout/', logout),
    (r'^$', index),
)

#========== TEACHERS APP URLS ==========#

urlpatterns = patterns('',
    (r'^(?P<username>\w{0,50})/', labs),
)

The login view basically checks whether the logged in user is_teacher [UserProfile attribute via get_profile()] and redirects the user to his profile.

Labs View [teachers app views.py]

from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response

from django.template import RequestContext
from django.contrib.auth.decorators import user_passes_test

from django.contrib.auth.models import User
from accounts.models import *
from labs.models import *

def user_is_teacher(user):
    return user.is_authenticated() and user.get_profile().is_teacher

@user_passes_test(user_is_teacher, login_url="/login/")
def labs(request, username):
    q1 = User.objects.get(username=username)
    q2 = u'%s %s' % (q1.last_name, q1.first_name)
    q2 = Teacher.objects.get(name=q2)
    results = TeacherToLab.objects.filter(teacher=q2)

    return render_to_response('teachers/labs.html', {'results': results}, context_instance = RequestContext(request))

I'm using @user_passes_test decorator for checking whether the authenticated user has the permission to use this view [labs view].

The problem I'm having with the current logic is that once Django authenticates a teacher user he has access to all teachers profiles basically by typing the teachers username in the url. Once a teacher finds a co-worker's username he has direct access to his data.

Any suggestions would be much appreciated.


A simple way would be to modify the view to add an extra check:

@user_passes_test(user_is_teacher, login_url="/login/")
def labs(request, username):
    if username != request.user.username:
        return HttpResponseNotAllowed()
    ... and so on ...


Assuming you have a variable called 'teacher' that represents the profile of the teacher whose profile you're viewing, just do something like this early in the view:

if request.user.get_profile() != teacher:
  ..redirect, throw 404, whatever you fancy 


Just a short hint.

...

user = request.user
enrollment = get_object_or_404(Enrollment, id=enrollment_id)
profile = get_object_or_404(Profile, user=user)

if not (enrollment.profile == profile or user.is_staff):
    raise Http404

...

enrollment.delete()

We used such if statements to determine, whether the actual user and the action he requested match. In the example above, only the profile who create an enrollment is allowed to delete it (or someone with staff priviledges).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜