Esempio n. 1
0
 def query_masking(self, db_name=None, sql='', resultset=None):
     """传入 sql语句, db名, 结果集,
     返回一个脱敏后的结果集"""
     # 解析语法树
     mask_tool = Masking()
     resultset_dict = resultset.__dict__
     inception_mask_result = mask_tool.data_masking(self.instance_name,
                                                    db_name, sql,
                                                    resultset_dict)
     # 传参进去之后, 就已经被处理
     resultset.rows = resultset_dict['rows']
     hit_rule = inception_mask_result['data']['hit_rule']
     if hit_rule == 1:
         resultset.is_masked = True
     if inception_mask_result['status'] != 0:
         resultset.is_critical = True
     return resultset
Esempio n. 2
0
def query_priv_check(user, instance_name, db_name, sql_content, limit_num):
    result = {
        'status': 0,
        'msg': 'ok',
        'data': {
            'priv_check': 1,
            'limit_num': 0
        }
    }
    instance = Instance.objects.get(instance_name=instance_name)
    table_ref = None  # 查询语句涉及的表信息
    # 检查用户是否有该数据库/表的查询权限
    if user.is_superuser:
        user_limit_num = int(SysConfig().get('admin_query_limit', 5000))
        limit_num = int(user_limit_num) if int(limit_num) == 0 else min(
            int(limit_num), int(user_limit_num))
        result['data']['limit_num'] = limit_num
        return result

    # 查看表结构的语句,inception语法树解析会报错,故单独处理,explain直接跳过不做校验
    elif re.match(r"^show\s+create\s+table", sql_content.lower()):
        tb_name = re.sub('^show\s+create\s+table',
                         '',
                         sql_content,
                         count=1,
                         flags=0).strip()
        # 先判断是否有整库权限
        db_privileges = QueryPrivileges.objects.filter(
            user_name=user.username,
            instance_name=instance_name,
            db_name=db_name,
            priv_type=1,
            valid_date__gte=datetime.datetime.now(),
            is_deleted=0)
        # 无整库权限再验证表权限
        if len(db_privileges) == 0:
            tb_privileges = QueryPrivileges.objects.filter(
                user_name=user.username,
                instance_name=instance_name,
                db_name=db_name,
                table_name=tb_name,
                priv_type=2,
                valid_date__gte=datetime.datetime.now(),
                is_deleted=0)
            if len(tb_privileges) == 0:
                result['status'] = 1
                result[
                    'msg'] = '你无' + db_name + '.' + tb_name + '表的查询权限!请先到查询权限管理进行申请'
                return result
    # sql查询, 可以校验到表级权限
    elif instance.db_type == 'mysql':
        # 首先使用inception的语法树打印获取查询涉及的的表
        table_ref_result = Masking().query_table_ref(sql_content + ';',
                                                     instance_name, db_name)

        # 正确解析拿到表数据,可以校验表权限
        if table_ref_result['status'] == 0:
            table_ref = table_ref_result['data']
            # 获取表信息,校验是否拥有全部表查询权限
            QueryPrivilegesOb = QueryPrivileges.objects.filter(
                user_name=user.username, instance_name=instance_name)
            # 先判断是否有整库权限
            for table in table_ref:
                db_privileges = QueryPrivilegesOb.filter(
                    db_name=table['db'],
                    priv_type=1,
                    valid_date__gte=datetime.datetime.now(),
                    is_deleted=0)
                # 无整库权限再验证表权限
                if len(db_privileges) == 0:
                    tb_privileges = QueryPrivilegesOb.filter(
                        db_name=table['db'],
                        table_name=table['table'],
                        valid_date__gte=datetime.datetime.now(),
                        is_deleted=0)
                    if len(tb_privileges) == 0:
                        result['status'] = 1
                        result['msg'] = '你无' + table['db'] + '.' + table[
                            'table'] + '表的查询权限!请先到查询权限管理进行申请'
                        return result

        # 获取表数据报错,检查配置文件是否允许继续执行,并进行库权限校验
        else:
            # 校验库权限,防止inception的语法树打印错误时连库权限也未做校验
            privileges = QueryPrivileges.objects.filter(
                user_name=user.username,
                instance_name=instance_name,
                db_name=db_name,
                valid_date__gte=datetime.datetime.now(),
                is_deleted=0)
            if len(privileges) == 0:
                result['status'] = 1
                result['msg'] = '你无' + db_name + '数据库的查询权限!请先到查询权限管理进行申请'
                return result
            if SysConfig().get('query_check'):
                return table_ref_result
            else:
                result['data']['priv_check'] = 2

    # 获取查询涉及表的最小limit限制
    if table_ref:
        db_list = [table_info['db'] for table_info in table_ref]
        table_list = [table_info['table'] for table_info in table_ref]
        user_limit_num = QueryPrivileges.objects.filter(
            user_name=user.username,
            instance_name=instance_name,
            db_name__in=db_list,
            table_name__in=table_list,
            valid_date__gte=datetime.datetime.now(),
            is_deleted=0).aggregate(Min('limit_num'))['limit_num__min']
        if user_limit_num is None:
            # 如果表没获取到则获取涉及库的最小limit限制
            user_limit_num = QueryPrivileges.objects.filter(
                user_name=user.username,
                instance_name=instance_name,
                db_name=db_name,
                valid_date__gte=datetime.datetime.now(),
                is_deleted=0).aggregate(Min('limit_num'))['limit_num__min']
    else:
        # 如果表没获取到则获取涉及库的最小limit限制
        user_limit_num = QueryPrivileges.objects.filter(
            user_name=user.username,
            instance_name=instance_name,
            db_name=db_name,
            valid_date__gte=datetime.datetime.now(),
            is_deleted=0).aggregate(Min('limit_num'))['limit_num__min']
    limit_num = int(user_limit_num) if int(limit_num) == 0 else min(
        int(limit_num), int(user_limit_num))
    result['data']['limit_num'] = limit_num
    return result
Esempio n. 3
0
import datetime
import time

from sql.utils.extend_json_encoder import ExtendJSONEncoder
from sql.utils.aes_decryptor import Prpcrypt
from sql.utils.dao import Dao
from .const import WorkflowDict
from .models import MasterConfig, SlaveConfig, QueryPrivilegesApply, QueryPrivileges, QueryLog, SqlGroup
from sql.utils.data_masking import Masking
from sql.utils.workflow import Workflow
from sql.utils.config import SysConfig
from sql.utils.group import user_slaves

dao = Dao()
prpCryptor = Prpcrypt()
datamasking = Masking()
workflowOb = Workflow()


# 查询权限申请用于工作流审核回调
def query_audit_call_back(workflow_id, workflow_status):
    # 更新业务表状态
    apply_info = QueryPrivilegesApply()
    apply_info.apply_id = workflow_id
    apply_info.status = workflow_status
    apply_info.save(update_fields=['status'])
    # 审核通过插入权限信息,批量插入,减少性能消耗
    if workflow_status == WorkflowDict.workflow_status['audit_success']:
        apply_queryset = QueryPrivilegesApply.objects.get(apply_id=workflow_id)
        # 库权限
        if apply_queryset.priv_type == 1: