Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » добавить дополнительную проверку при логине в админку [RSS Feed]

#1 Фев. 24, 2014 13:44:47

botinag
Зарегистрирован: 2014-02-20
Сообщения: 179
Репутация: +  35  -
Профиль   Отправить e-mail  

добавить дополнительную проверку при логине в админку

накидал следующую мидлварь…

from django.conf import settings
from django import http
class SuperUserIpRestrictMiddleware(object):
    """
    Разрешает доступ суперпользователям только с определенных ip
    список разрешенных ip = settings.SUPERUSER_ALLOWED_IP
    """
    def process_request(self, request):
        if (request.user.is_superuser and request.path != u'/logout/' and 
                request.META['REMOTE_ADDR'] not in 
                settings.SUPERUSER_ALLOWED_IP):
            html_str = u'''
                <h1>Доступ запрещен</h1>Вход с ip {ip} для 
                пользователя <b>{user}</b> запрещен.</br>
                <a href="/logout/">Вернуться</a>
                '''.format(ip=request.META['REMOTE_ADDR'], user=request.user)
            return http.HttpResponseForbidden(html_str)
        return None
теперь вот думаю, что выглядит не слишком красиво.
а красиво бы выглядело, если как при несовпадении логина/пароля выскакивал соответствыющий ValidationError.
я думал сделать следующим образом:
сделать кастомную форму, унаследованную от AuthenticationForm и переопределить там clean()…
но как мне в clean передавать вещи, начинающиеся с request?
чтобы реализовать что-то типа:
def clean(self):
...
if request.user.is_superuser and request.META['REMOTE_ADDR'] != u'127.0.0.1':
    raise ValidationError(u'доступ запрещен')

Офлайн

#2 Фев. 24, 2014 14:40:06

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

добавить дополнительную проверку при логине в админку

botinag
накидал следующую мидлварь…
Вы определитесь сначала вам надо чтобы работало на каждый запрос(middleware) или только на форме входа(Form)

Офлайн

#3 Фев. 24, 2014 19:46:42

botinag
Зарегистрирован: 2014-02-20
Сообщения: 179
Репутация: +  35  -
Профиль   Отправить e-mail  

добавить дополнительную проверку при логине в админку

PanovSergey
Вы определитесь сначала вам надо чтобы работало на каждый запрос(middleware) или только на форме входа(Form)
как я себе вижу ситуацию:
все стандартные вещи в админке доступны только после логина и все мои собственные вьюхи требуют логина => мне достаточно, чтобы ip проверялся только на форме входа.
был бы признателен за пример кода для моего случая.

Офлайн

#4 Фев. 25, 2014 04:08:46

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

добавить дополнительную проверку при логине в админку

botinag
как я себе вижу ситуацию:
все стандартные вещи в админке доступны только после логина и все мои собственные вьюхи требуют логина => мне достаточно, чтобы ip проверялся только на форме входа.
был бы признателен за пример кода для моего случая.
Значит вам надо для каждой въюхи требовать вход. Обычно делается декоратором login_required
Дальше во вью login пишете обработку. Миддлваре тут не нужен.
Если для какой то вью нужны доп проверки есть еще декоратор user_passes_test

Отредактировано PanovSergey (Фев. 25, 2014 04:09:15)

Офлайн

#5 Фев. 25, 2014 08:59:08

botinag
Зарегистрирован: 2014-02-20
Сообщения: 179
Репутация: +  35  -
Профиль   Отправить e-mail  

добавить дополнительную проверку при логине в админку

PanovSergey
Значит вам надо для каждой въюхи требовать вход. Обычно делается декоратором login_required
мои самописные вьюхи снабжены декоратором.
PanovSergey
Дальше во вью login пишете обработку. Миддлваре тут не нужен.
я как раз хочу отказаться от миддлварь. вот я не совсем понимаю как во вьюхе сделать, чтобы при попытке логина с ip не из моего списка выскакивал ValidationError для формы логина.
—–
например при несовпадении логина и пароля на странице входа в админку, выскакивает следующее оповещение (я использую django-grappelli):

я хочу, чтобы выскакивало подобное сообщение с моим текстом, но для суперюзеров, пытающихся залогинится с ip, не входящих в мой список.

Отредактировано botinag (Фев. 25, 2014 09:02:52)

Офлайн

#6 Фев. 25, 2014 11:50:31

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

добавить дополнительную проверку при логине в админку

вот я не совсем понимаю как во вьюхе сделать, чтобы при попытке логина с ip не из моего списка выскакивал ValidationError для формы логина.
Отнаследуйтесь от формы логина, передавайте ей параметр
current_ip=request.META['REMOTE_ADDR']
. В методе clean сделайте проверку.
Типа этого

Отредактировано PanovSergey (Фев. 25, 2014 11:52:20)

Офлайн

#7 Фев. 26, 2014 07:54:07

botinag
Зарегистрирован: 2014-02-20
Сообщения: 179
Репутация: +  35  -
Профиль   Отправить e-mail  

добавить дополнительную проверку при логине в админку

накидал следующего кадавра:
urls.py:

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.views.generic import TemplateView
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
from accounts.forms import MyAuthenticationForm
urlpatterns = patterns('',
...
    url(r'^login/',
        'accounts.views.custom_login',
        {'authentication_form': MyAuthenticationForm},
        name='auth_login'),
)
urlpatterns += staticfiles_urlpatterns()

accounts/views.py:
from accounts.forms import MyAuthenticationForm
from django.core.exceptions import ValidationError
from django.contrib.auth.views import login
from django import forms
from django.shortcuts import redirect
from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login
from django.utils.http import base36_to_int, is_safe_url
from django.shortcuts import resolve_url
from django.http import HttpResponseRedirect, QueryDict
def custom_login(request, template_name='login.html',
                 redirect_field_name=REDIRECT_FIELD_NAME,
                 authentication_form=MyAuthenticationForm,
                 current_app=None, extra_context=None):
                 
    redirect_to = request.REQUEST.get(redirect_field_name, '')
    if request.method == 'POST':
        form = MyAuthenticationForm(
            data=request.POST, current_ip=request.META['REMOTE_ADDR'], 
            user=request.user, request=request
        )
        if form.is_valid():
            # Ensure the user-originating redirection url is safe.
            if not is_safe_url(url=redirect_to, host=request.get_host()):
                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
            # Okay, security check complete. Log the user in.
            auth_login(request, form.get_user())
            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()
            return HttpResponseRedirect(redirect_to)
    else:
        form = MyAuthenticationForm(current_ip=request.META['REMOTE_ADDR'], 
                                    user=request.user, request=request)
    request.session.set_test_cookie()
    current_site = get_current_site(request)
    context = {
        'form': form,
        redirect_field_name: redirect_to,
        'site': current_site,
        'site_name': current_site.name,
    }
    if extra_context is not None:
        context.update(extra_context)
    return TemplateResponse(request, template_name, context,
                            current_app=current_app)

accounts/forms.py:
from django.contrib.auth.forms import AuthenticationForm
from django import forms
class MyAuthenticationForm(AuthenticationForm):
    current_ip = forms.IPAddressField()
    
    def __init__(self, current_ip=None, user=None, request=None, *args, **kwargs):
        self.current_ip = current_ip
        self.request = request
        self.user_cache = None
        self.user = user
        super(MyAuthenticationForm, self).__init__(*args, **kwargs)
        UserModel = get_user_model()
        self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
        if not self.fields['username'].label:
            self.fields['username'].label = capfirst(self.username_field.verbose_name)
    def clean_current_ip(self):
        current_ip = self.cleaned_data.get('current_ip')
        if self.user.is_superuser() and current_ip != u'127.0.0.1':
            raise forms.ValidationError(u'try from another ip!')
        return current_ip

пока при попытке зайти на страницу логина выдает 404 ошибку.
login.html лежит в папке templates

как сие исправить?

Офлайн

  • Начало
  • » Django
  • » добавить дополнительную проверку при логине в админку[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version