Авторизация Django - возврат перенаправления в вызове функции - PullRequest
0 голосов
/ 30 июня 2018

Я добавляю некоторую пользовательскую авторизацию для проверки того, что вошедшие в систему пользователи имеют доступ к определенным разделам моего приложения. Это не красиво, но работает:

view_permissions = {
    'admin_list': {
        'school':{'userrole':['S','A'], 'usertype':[]},
        'class':{'userrole':['S','A'], 'usertype':[]},
        ' ... '
    },
    'delete_object': { ... },
    'edit_object': { ... },
    }
}

def check_permissions(request, viewname, objecttype):
    if(request.user.userrole in view_permissions[viewname][objecttype]['userrole'] or 
       request.user.usertype in view_permissions[viewname][objecttype]['usertype']
    ):
        return True
    else:
        return False

def delete_object(request, objecttype, objectid):

    # Redirect to home page if not authorized
    if(not check_permissions(request, 'delete_object', objecttype)):
        return redirect('wakemeup:index')

    # Otherwise, continue processing
    myobject.delete()
    ...

    return admin_list(request, objecttype)

То, что я хочу сделать, это переместить redirect в функцию check_permissions, примерно так:

def check_permissions(request, viewname, objecttype):
    if( <check permissions are valid> ):
        pass # Authorized: Do nothing and continue with caller view logic
    else:
        return redirect('wakemeup:index') # Unauthorized: redirect to home

def delete_object(request, objecttype, objectid):

    # Redirect to home page if not authorized
    check_permissions(request, 'delete_object', objecttype))

Проблема в том, что перенаправление внутри функции check_permissions ничего не делает. Он только перенаправляет, если я добавлю return к логике вызова:

def delete_object(request, objecttype, objectid):

    # Redirect to home page if not authorized
    return check_permissions(request, 'delete_object', objecttype))

Я предполагаю, что это как-то связано с вызовом вложенной функции, возвращающей свой вывод полностью исходному вызывающему. Но есть ли простой способ заставить перенаправление работать из функции check_permissions?

Редактировать

Обновленная функция - мне нужно получить доступ к объекту request через args [0], но я могу получить доступ к другим моим переменным через kwargs. Я предполагаю, что это потому, что в формах объект запроса просто передается под прикрытием, а не в качестве аргумента.

def check_perm(view):
    viewname = view.__name__

    def view_wrapper(*args, **kwargs):

        objecttype = kwargs['objecttype']
        myuser = args[0].user

        if not (
            myuser.userrole in view_permissions[viewname][objecttype]['userrole'] or 
            myuser.usertype in view_permissions[viewname][objecttype]['usertype']
        ):
            # Invalid permission - redirect
            return redirect('wakemeup:index')

        # Valid permission - continue
        return view(*args, **kwargs)

    return view_wrapper

...

@check_perm
def delete_object(request, objecttype, objectid):
  ...

1 Ответ

0 голосов
/ 30 июня 2018

Я думаю, что функциональный декоратор - идеальное решение для этой проблемы. Следующее позволяет проверить условия (разрешения), перехватить ответ с помощью перенаправления, если необходимо, и если нет, продолжить с обычным ответом просмотра:

from django.shortcuts import redirect

def check_permissions(view):
    view_name = view.__name__

    def view_wrapper(*args, **kwargs):
        # Check permissions here.
        if False or False or True:
            # Hijack response with a redirect if conditions not met.
            return redirect('wakemeup:index')

        # Conditions met, continue with normal response.
        return view(*args, **kwargs)

    return view_wrapper

@check_permissions
def delete_object(request, object_type, object_id):
    # Your normal view...
    return

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

...