示例#1
0
class ConsulService(object):
    """Consul服务, 接收服务名称, 返回域名"""
    def __init__(self):
        self.settings_value = GetSettingsValue()
        self.consul = self.settings_value.get_middleware_value('PERMISSION_MIDDLEWARE', 'CONSUL')
        self.run_env = self.settings_value.get_settings_value('RUN_ENV')

    def get_service_addr_consul(self, service, schema=""):
        """
        获取服务的consul地址
        优先环境变量,如未配置环境变量,从consul中找服务, 如果是("dev", "unit"), 则使用127.0.0.1
        """
        port = self.settings_value.get_middleware_service_value('PERMISSION_MIDDLEWARE', service, 'port')
        host = self.settings_value.get_middleware_value_not_validated('PERMISSION_MIDDLEWARE', service, 'host')
        service_name = self.settings_value.get_middleware_service_value('PERMISSION_MIDDLEWARE', service, 'name')
        consul_client = consul.Consul(host=self.consul['host'],
                                      port=self.consul['port'],
                                      scheme="http")
        if self.run_env in ("dev", "unit"):
            logger.info("run_env=%s, 使用本地地址")
            address = '127.0.0.1'
            domain = "{schema}{address}:{port}".format(schema=schema, address=address, port=port)
            return domain
        if host and port:
            domain = "{schema}{address}:{port}".format(schema=schema, address=host, port=port)
            logger.info("domain={domain}".format(domain=domain))
            return domain
        try:
            port = consul_client.catalog.service(service_name)[1][0]['ServicePort']
            address = consul_client.catalog.service(service_name)[1][0]['ServiceAddress']
            domain = "{schema}{address}:{port}".format(schema=schema, address=address, port=port)
            return domain
        except Exception:
            raise ImproperlyConfigured("请检查settings.py 的consul配置是否正确")
示例#2
0
class PermissionMiddleware(permissions.BasePermission):
    """
    权限中间件
    使用方法:
        1.导入此文件到项目中
        2.将此中间件放在 AuthenticationMiddleware 之后
    工作原理:
                                (url + method + user_id)
                                        |               / 有权限则允许通过
    request -> PermissionMiddleware ---https---> 权限模块
                                                        \ 无权限则返回HTTP 403错误

    """
    VERIFICATION_CONGIGURATION = VerificationConfiguration()
    VERIFICATION_CONGIGURATION.valid_permission_svc()
    SETTINGS_VALUE = GetSettingsValue()
    URL_JOIN = NormalizeUrl()
    FILTER_PATH = SETTINGS_VALUE.get_middleware_value(
        'PERMISSION_MIDDLEWARE', 'FILTER_PATH')
    SERVICE_NAME = SETTINGS_VALUE.get_middleware_service_value(
        'PERMISSION_MIDDLEWARE', 'PERMISSION_SERVICE', 'name')
    PERMISSION_ADDRESS = SETTINGS_VALUE.get_middleware_service_value(
        'PERMISSION_MIDDLEWARE', 'PERMISSION_SERVICE', 'address')
    HAS_PERMISSION = True

    def has_permission(self, request, view):
        # 验证中间件位置
        self.VERIFICATION_CONGIGURATION.verify_middleware_location(request)
        path = request.path
        method = request.method.upper()
        # 只校验有 不在 FILTER_PATH 中的url
        if path not in self.FILTER_PATH:
            if request.user.id:
                self.HAS_PERMISSION = self.valid_permission(path, method, request.user.id)
            if self.HAS_PERMISSION:
                return True
            return False

    def valid_permission(self, path, method, user_id):
        """ 验证权限, 目前使用的是http的方式验证,后面可能要改成rpc的方式"""
        if all([path, method, user_id]):
            domain = ConsulService().get_service_addr_consul(service='PERMISSION_SERVICE')
            url = self.URL_JOIN.normalize_url(
                domain=domain, path=self.PERMISSION_ADDRESS)
            post_data = {
                "path": path,
                "method": method,
                "user_id": user_id
            }
            response = requests.post(url, json=post_data)
            if response.status_code == 404:
                raise ImproperlyConfigured(
                    "请检查settings.py的permission_service配置的%s是否正确" % path)
            data = response.json()
            if response.status_code == 500:
                logger.error(data["message"])
                return True
            if 200 <= response.status_code < 300 and data['status']:
                return True
            return False
示例#3
0
class TestURLSplicing(unittest.TestCase):
    """测试url拼接"""
    def setUp(self):
        self.get_value = GetSettingsValue()
        self.get_value.get_settings_value = mock.Mock(
            return_value=PERMISSION_MIDDLEWARE)
        self.get_value.get_middleware_value = mock.Mock(
            return_value=PERMISSION_MIDDLEWARE['PERMISSION_SERVICE'])

    def test_get_middleware_value(self):
        service_value = self.get_value.get_settings_value(
            'PERMISSION_MIDDLEWARE')
        value = service_value.get('PERMISSION_SERVICE', None)
        self.assertEqual(value, PERMISSION_MIDDLEWARE['PERMISSION_SERVICE'])

    def test_get_middleware_service_value(self):
        middleware_value = self.get_value.get_middleware_value()
        value = middleware_value.get('name', None)
        self.assertEqual(value,
                         PERMISSION_MIDDLEWARE['PERMISSION_SERVICE']['name'])
示例#4
0
class DecodeJwt(object):
    """decode_jwt"""
    def __init__(self, ):
        self.settings_value = GetSettingsValue()
        self.secret = self.settings_value.get_middleware_value(
            'JWT_AUTHENTICATION_MIDDLEWARE', 'JWT_SECRET')

    def decode_jwt(self, token):
        secret = self.secret
        try:
            payload = jwt.decode(token, secret, algorithms='HS256')
        except Exception as ex:
            raise ex
        return payload
示例#5
0
from sparrow_django_common.utils.get_settings_value import GetSettingsValue
from sparrow_django_common.base_middlware.base_middleware import MiddlewareMixin


get_value = GetSettingsValue()
METHOD_MAP = get_value.get_middleware_value('METHOD_MIDDLEWARE', 'METHOD_MAP')
if not METHOD_MAP:
    METHOD_MAP = ('PUT', 'DELETE')


class MethodConvertMiddleware(MiddlewareMixin):
    """解决阿里云不支持put/delete 请求方式的问题"""
    def process_request(self, request):
        if 'HTTP_METHOD' in request.META:
            method = request.META['HTTP_METHOD'].upper()
            if method in METHOD_MAP:
                setattr(request, 'method', method)


示例#6
0
 def __init__(self, ):
     self.settings_value = GetSettingsValue()
     self.secret = self.settings_value.get_middleware_value(
         'JWT_AUTHENTICATION_MIDDLEWARE', 'JWT_SECRET')
 def __init__(self):
     self.settings_value = GetSettingsValue()
     self.run_env = self.settings_value.get_settings_value('RUN_ENV')
示例#8
0
def get_settings_value():
    """Get the data in settings and add value validation"""
    settings_value = GetSettingsValue()
    user_class_path = settings_value.get_middleware_value(
        JWT_AUTHENTICATION_MIDDLEWARE, USER_CLASS_PATH)
    return user_class_path
class PermissionMiddleware(permissions.BasePermission):
    """
    权限中间件
    使用方法:
        1.导入此文件到项目中
        2.将此中间件放在 AuthenticationMiddleware 之后
    工作原理:
                                (url + method + user_id)
                                        |               / 有权限则允许通过
    request -> PermissionMiddleware ---https---> 权限模块
                                                        \ 无权限则返回HTTP 403错误

    """
    VERIFICATION_CONGIGURATION = VerificationConfiguration()
    VERIFICATION_CONGIGURATION.valid_permission_svc()
    SETTINGS_VALUE = GetSettingsValue()
    URL_JOIN = NormalizeUrl()
    FILTER_PATH = SETTINGS_VALUE.get_middleware_value('PERMISSION_MIDDLEWARE',
                                                      'FILTER_PATH')
    SERVICE_NAME = SETTINGS_VALUE.get_middleware_service_value(
        'PERMISSION_MIDDLEWARE', 'PERMISSION_SERVICE', 'name')
    PERMISSION_ADDRESS = SETTINGS_VALUE.get_middleware_service_value(
        'PERMISSION_MIDDLEWARE', 'PERMISSION_SERVICE', 'address')
    HAS_PERMISSION = False

    def has_permission(self, request, view):
        # 验证中间件位置
        path = request.path
        method = request.method.upper()
        url = request.META.get('HTTP_REFERER', None)
        # 只校验有 不在 FILTER_PATH 中的url
        if path not in self.FILTER_PATH:
            if request.user:
                try:
                    if request.user.is_authenticated():
                        self.HAS_PERMISSION = self.valid_permission(
                            path, method, request.user.id)
                except:
                    if request.user.is_authenticated:
                        self.HAS_PERMISSION = self.valid_permission(
                            path, method, request.user.id)
            if self.HAS_PERMISSION:
                return True
            return False
        elif url is not None:
            if url.__contains__("login"):
                return True
            return False
        return True

    def valid_permission(self, path, method, user_id):
        """ 验证权限, 目前使用的是http的方式验证,后面可能要改成rpc的方式"""
        if all([path, method, user_id]):
            domain = ConsulService().get_service_addr_consul(
                service_dependencies='PERMISSION_MIDDLEWARE',
                service='PERMISSION_SERVICE')
            url_path = self.URL_JOIN.normalize_url(
                domain=domain, path=self.PERMISSION_ADDRESS)
            url = url_path + '?userid={0}&path={1}&method={2}'.format(
                user_id, path, method)
            try:
                response = requests.get(url)
            except Exception as ex:
                logger.error(ex)
                return True
            if response.status_code == 404:
                raise ImproperlyConfigured(
                    "请检查settings.py的permission_service配置的%s是否正确" %
                    self.PERMISSION_ADDRESS)
            data = response.json()
            if response.status_code == 500:
                logger.error(data["message"])
                return True
            if 200 <= response.status_code < 300 and data['status']:
                return True
            return False
示例#10
0
 def setUp(self):
     self.get_value = GetSettingsValue()
     self.get_value.get_settings_value = mock.Mock(
         return_value=PERMISSION_MIDDLEWARE)
     self.get_value.get_middleware_value = mock.Mock(
         return_value=PERMISSION_MIDDLEWARE['PERMISSION_SERVICE'])
示例#11
0
 def __init__(self):
     self.settings_value = GetSettingsValue()
     self.consul = self.settings_value.get_middleware_value('PERMISSION_MIDDLEWARE', 'CONSUL')
     self.run_env = self.settings_value.get_settings_value('RUN_ENV')
class PermissionMiddleware(MiddlewareMixin):
    """
    权限中间件
    使用方法:
        1.导入此文件到项目中
        2.将此中间件放在 AuthenticationMiddleware 之后
    工作原理:
                                (url + method + user_id)
                                        |               / 有权限则允许通过
    request -> PermissionMiddleware ---https---> 权限模块
                                                        \ 无权限则返回HTTP 403错误

    """
    VERIFICATION_CONGIGURATION = VerificationConfiguration()
    VERIFICATION_CONGIGURATION.valid_permission_svc()
    SETTINGS_VALUE = GetSettingsValue()
    URL_JOIN = NormalizeUrl()
    FILTER_PATH = SETTINGS_VALUE.get_middleware_value('PERMISSION_MIDDLEWARE',
                                                      'FILTER_PATH')
    SERVICE_NAME = SETTINGS_VALUE.get_middleware_service_value(
        'PERMISSION_MIDDLEWARE', 'PERMISSION_SERVICE', 'name')
    PERMISSION_ADDRESS = SETTINGS_VALUE.get_middleware_service_value(
        'PERMISSION_MIDDLEWARE', 'PERMISSION_SERVICE', 'address')
    HAS_PERMISSION = True
    SKIP_PERMISSION = SETTINGS_VALUE.get_value('PERMISSION_MIDDLEWARE',
                                               'SKIP_PERMISSION')

    def process_request(self, request):
        # 验证中间件位置
        path = request.path
        method = request.method.upper()
        # 只校验有 不在 FILTER_PATH 中的url
        if self.SKIP_PERMISSION is False or self.SKIP_PERMISSION == 'False':
            if path not in self.FILTER_PATH:
                if request.META['REMOTE_USER']:
                    self.HAS_PERMISSION = self.valid_permission(
                        path, method, request.META['REMOTE_USER'])
                if not self.HAS_PERMISSION:
                    return JsonResponse({"message": "无访问权限"}, status=403)

    def valid_permission(self, path, method, user_id):
        """ 验证权限, 目前使用的是http的方式验证,后面可能要改成rpc的方式"""
        if all([path, method, user_id]):
            domain = ConsulService().get_service_addr_consul(
                service_dependencies='PERMISSION_MIDDLEWARE',
                service='PERMISSION_SERVICE')
            url_path = self.URL_JOIN.normalize_url(
                domain=domain, path=self.PERMISSION_ADDRESS)
            url = url_path + '?userid={0}&path={1}&method={2}'.format(
                user_id, path, method)
            try:
                response = requests.get(url)
            except Exception as ex:
                logger.error(ex)
                return True
            if response.status_code == 404:
                raise ImproperlyConfigured(
                    "请检查settings.py的permission_service配置的%s是否正确" %
                    self.PERMISSION_ADDRESS)
            data = response.json()
            if response.status_code == 500:
                logger.error(data["message"])
                return True
            if 200 <= response.status_code < 300 and data['status']:
                return True
            return False