URL-адрес входа с использованием аутентификационной информации в Django

Я работаю над платформой для регистрации онлайн-лабораторий для моего университета.

Вход в систему Просмотр [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))

URL-адреса

#========== 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),
)

Представление входа в систему в основном проверяет, является ли зарегистрированный пользователь is_teacher [атрибут UserProfile через get_profile ()], и перенаправляет пользователя в его профиль.

Лаборатория View [учителя 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))

Я использую декоратор @user_passes_test для проверки, есть ли у аутентифицированного пользователя разрешение на использование этого представления [представление лаборатории].

Проблема, с которой я столкнулся с текущей логикой, заключается в том, что как только Django аутентифицирует пользователя-учителя, он получает доступ ко всем профилям учителей, в основном путем ввода имени пользователя учителя в URL-адресе. Как только учитель находит имя пользователя коллеги, он получает прямой доступ к его данным.

Любые предложения будут высоко ценится.


person tsiokos    schedule 02.06.2010    source источник
comment
Вам действительно не нужно было публиковать весь этот код ... просто представления было бы достаточно.   -  person Daniel Roseman    schedule 02.06.2010
comment
Вы также можете сделать ссылку OneToOneField из вашей модели учителя на пользователя, чтобы вы могли просто сделать q2 = q1.teacher   -  person Steve Jalim    schedule 02.06.2010
comment
Прошу прощения, я думал, что что-то упустил в urls.py. Возможно, лучший способ передать имя пользователя, что могло бы предотвратить такую ​​проблему.   -  person tsiokos    schedule 02.06.2010


Ответы (3)


Простым способом было бы изменить представление, чтобы добавить дополнительную проверку:

@user_passes_test(user_is_teacher, login_url="/login/")
def labs(request, username):
    if username != request.user.username:
        return HttpResponseNotAllowed()
    ... and so on ...
person Daniel Roseman    schedule 02.06.2010
comment
Моя первая мысль, спасибо. Есть ли способ использовать вместо этого декоратор? - person tsiokos; 02.06.2010

Предполагая, что у вас есть переменная под названием «учитель», которая представляет профиль учителя, профиль которого вы просматриваете, просто сделайте что-то вроде этого в начале представления:

if request.user.get_profile() != teacher:
  ..redirect, throw 404, whatever you fancy 
person Steve Jalim    schedule 02.06.2010

Небольшая подсказка.

...

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

Мы использовали такие if утверждения, чтобы определить, совпадают ли фактический пользователь и запрошенное им действие. В приведенном выше примере только profile, создавший регистрацию, может удалить ее (или кто-то с staff привилегиями).

person miku    schedule 02.06.2010