from rest_framework.permissions import BasePermission
from .models import Menu


def get_all_menu_queryset(user):
    menus = Menu.objects.none()
    if user.is_superuser:
        menus = Menu.objects.all()
    else:
        menus = Menu.objects.none()
        roles = user.roles.all()
        if roles:
            for i in roles:
                menus = menus | i.menus.all()
    return menus
    

def get_permission_list(user):
    menus = get_all_menu_queryset(user)
    perms_list = menus.values_list('method',flat=True)
    perms_list = list(perms_list)
    if user.is_superuser:
        perms_list.append('admin')
    if perms_list:
        return list(perms_list)
    return ['basic']
    
class RbacPermission(BasePermission):
    """
    基于角色的认证系统的权限校验类
    """

    def has_permission(self, request, view):
        """
        权限校验逻辑
        :param request:
        :param view:
        :return:
        """
        perms = []
        if 'perms' in request.session:
            perms = request.session['perms']
        else:
            perms = get_permission_list(request.user)
        if perms:
            if 'admin' in perms:
                return True
            elif request.user.is_superuser:
                return True
            elif not hasattr(view, 'perms_map'):
                return True
            else:
                perms_map = view.perms_map
                _method = request._request.method.lower()
                for i in perms_map:
                    for method, alias in i.items():
                        if (_method == method or method == '*') and alias in perms:
                            return True




class RbacObjPermission(BasePermission):
    """
    对象级权限控制
    """

    def has_object_permission(self, request, view, obj):
        # if 'perms' in request.session:
        #     perms = request.session['perms']
        # else:
        #     perms = get_permission_list(request.user)
        # if 'admin' in perms:
        #     return True
        # else:
        #     return obj.owner == request.user
        return True