0

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 belong 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.

3
  • 1
    You didn't really need to post all that code... just the view would have been sufficient. Commented Jun 2, 2010 at 14:29
  • You could also make a OneToOneField link from your Teacher model to User, so that you can just do q2 = q1.teacher Commented Jun 2, 2010 at 14:40
  • I apologise, i thought i was missing something in the urls.py. A better way to pass the username maybe, something that could prevent such a problem. Commented Jun 2, 2010 at 14:47

3 Answers 3

2

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 ...
Sign up to request clarification or add additional context in comments.

1 Comment

My first thought, thank you. Is there a way to use a decorator instead?
0

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 

Comments

0

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.