URL входа с использованием аутентификационной информации в Django - PullRequest
0 голосов
/ 02 июня 2010

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

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

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

Labs View [приложение для учителей 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 для проверки, имеет ли аутентифицированный пользователь разрешение на использование этого представления [представление labs].

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

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

Ответы [ 3 ]

2 голосов
/ 02 июня 2010

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

@user_passes_test(user_is_teacher, login_url="/login/")
def labs(request, username):
    if username != request.user.username:
        return HttpResponseNotAllowed()
    ... and so on ...
0 голосов
/ 02 июня 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 привилегиями).

0 голосов
/ 02 июня 2010

Предполагая, что у вас есть переменная с именем 'teacher', которая представляет профиль учителя, профиль которого вы просматриваете, просто сделайте что-то подобное в начале представления:

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