def create_menu_strategy(event_code, dimension, menu_type, menu_op, strategy_name=None, strategy_desc=None): """ 新建名单型策略 :param str|unicode event_code: 项目uuid :param str|unicode dimension: 维度 user_id / ip / uid ... :param str|unicode menu_type: 名单类型 black, white, gray :param str|unicode menu_op: 操作码 在/不在(is/is_not) :param str|unicode strategy_name: 策略名称 :param str|unicode strategy_desc: 策略描述 """ strategy_name = strategy_name or get_sample_str() strategy_desc = strategy_desc or get_sample_str() data = { 'strategy_name': strategy_name, 'strategy_desc': strategy_desc, 'menu_op': menu_op, 'event': event_code, 'dimension': dimension, 'menu_type': menu_type } success, strategy_uuid = _create_new_strategy( MenuStrategyForm, strategy_conf=data ) assert success, 'create menu strategy fail.' return strategy_uuid
def create_bool_strategy(strategy_var, strategy_op, strategy_func, strategy_threshold, strategy_name=None, strategy_desc=None): """ 新建bool型策略 :param str|unicode strategy_var: 内置变量 :param str|unicode strategy_op: 操作码 :param str|unicode strategy_func: 内置函数 :param str|unicode strategy_threshold: 策略的阈值 :param str|unicode strategy_name: 策略名称 :param str|unicode strategy_desc: 策略描述 :return: """ strategy_name = strategy_name or get_sample_str() strategy_desc = strategy_desc or get_sample_str() data = { 'strategy_var': strategy_var, 'strategy_op': strategy_op, 'strategy_func': strategy_func, 'strategy_threshold': strategy_threshold, 'strategy_name': strategy_name, 'strategy_desc': strategy_desc } success, strategy_uuid = _create_new_strategy( BoolStrategyForm, strategy_conf=data ) assert success, 'create bool strategy fail.' return strategy_uuid
def create_freq_strategy(strategy_source, strategy_body, strategy_time, strategy_limit, strategy_name=None, strategy_desc=None): """ 新建时段频控型策略 :param str|unicode strategy_source: 上报数据源key :param str|unicode strategy_body: 限制主体 eg: ip, uid, user_id etc... :param int strategy_time: 时段(单位为秒) :param int strategy_limit: 限制个数 :param str|unicode strategy_name: 策略名称 :param str|unicode strategy_desc: 策略描述 :return: """ strategy_name = strategy_name or get_sample_str() strategy_desc = strategy_desc or get_sample_str() data = { 'strategy_source': strategy_source, 'strategy_body': strategy_body, 'strategy_time': strategy_time, 'strategy_limit': strategy_limit, 'strategy_name': strategy_name, 'strategy_desc': strategy_desc } success, strategy_uuid = _create_new_strategy(FreqStrategyForm, strategy_conf=data) assert success, 'create freq strategy fail.' return strategy_uuid
def create_user_strategy(strategy_source, strategy_body, strategy_day, strategy_limit, strategy_name=None, strategy_desc=None): """ 新建限用户数型策略 :param str|unicode strategy_source: 上报数据源key :param str|unicode strategy_body: 限制主体 eg: ip, uid, user_id etc... :param int strategy_day: 自然天数 :param int strategy_limit: 限制用户数 :param str|unicode strategy_name: 策略名称 :param str|unicode strategy_desc: 策略描述 :return: """ strategy_name = strategy_name or get_sample_str() strategy_desc = strategy_desc or get_sample_str() data = { 'strategy_source': strategy_source, 'strategy_body': strategy_body, 'strategy_day': strategy_day, 'strategy_limit': strategy_limit, 'strategy_name': strategy_name, 'strategy_desc': strategy_desc } success, strategy_uuid = _create_new_strategy( UserStrategyForm, strategy_conf=data ) assert success, 'create bool strategy fail.' return strategy_uuid
def create_rule(strategy_confs, end_time=None, title=None, describe=None, status='on', creator_name=None): creator_name = creator_name or get_sample_str() describe = describe or get_sample_str() title = title or get_sample_str() end_time = end_time or (datetime.now() + timedelta(days=10)) return RuleModel.create(creator_name, title, describe, status, end_time, strategy_confs)
def create_data_source(source_key=None, source_name=None, fields=None): source_key = source_key or get_sample_str(8) source_name = source_name or get_sample_str(8) fields = fields or ['user_id', 'uid'] # 目前仅仅用于测试中,为了简单,type暂不可配置 content = {field: 'string' for field in fields} content['name_show'] = source_name map_key = 'CONFIG_SOURCE_MAP' client = get_redis_client() client.hset(map_key, source_key, json.dumps(content)) return source_key
def _test_create(self): source_key = create_data_source() data = { 'strategy_source': source_key, 'strategy_desc': get_sample_str(8), 'strategy_body': 'uid', 'strategy_name': get_sample_str(8), 'strategy_time': random.randint(1000, 10000), 'strategy_limit': random.randint(1, 3) } response = self.client.post(reverse(self.create_uri), data=data) self.assertEquals(response.status_code, 200) resp_dict = json.loads(response.content) self.strategy_uuid = resp_dict['uuid'] self.assertIs(resp_dict['state'], True)
def _test_destroy(self): # 参数不全 resp = self.client.post(reverse(self.delete_uri)) self.assertEquals(resp.status_code, 200) self.assertEquals(json.loads(resp.content)['error'], u"id不合法") # ID格式错误 menu_element_id = get_sample_str(24) resp = self.client.post(reverse(self.delete_uri), data={'ids': menu_element_id}) self.assertEquals(resp.status_code, 200) self.assertEquals(json.loads(resp.content)['error'], u"id不合法") # 成功删除 menu_element_id = add_element_to_menu(self.event_code, 'black', self.dimension, 'test_value') resp = self.client.post(reverse(self.delete_uri), data={'ids': menu_element_id}) self.assertEquals(resp.status_code, 200) t = json.loads(resp.content) self.assertEquals(t['state'], True) # 删除不存在的记录 resp = self.client.post(reverse(self.delete_uri), data={'ids': menu_element_id}) self.assertEquals(resp.status_code, 200) t = json.loads(resp.content) self.assertEquals(t['error'], u"记录均不存在")
def setUp(self): super(TestRule, self).setUp() self.event_code = create_menu_event()['event_code'] self.menu_uuid = create_menu_strategy(event_code=self.event_code, dimension='user_id', menu_type='black', menu_op='is') self.bool_uuid = create_bool_strategy(strategy_var='user_id', strategy_op='is', strategy_func='is_abnormal', strategy_threshold='') strategy_confs = [ [get_sample_str(), self.menu_uuid, 'deny', get_sample_str(), '100'], [get_sample_str(), self.bool_uuid, 'log', get_sample_str(), '90'], ] self.rule_id, self.rule_uuid = create_rule(strategy_confs)
def _test_create(self): content = json.dumps({ "user_id": "string", "uid": "string", "ip": "string" }) name_show = get_sample_str(8) name_key = get_sample_str(8) response = self.client.post(reverse(self.create_uri), data={ 'content': content, 'name_show': name_show, 'name_key': name_key }) self.assertEquals(response.status_code, 200) resp_dict = json.loads(response.content) self.name_key = resp_dict['msg'] self.assertEquals(name_key, self.name_key) self.assertIs(resp_dict['state'], True)
def _test_create(self): data = {'event_name': get_sample_str(10)} response = self.client.post(reverse(self.create_uri), data=data) self.assertEquals(response.status_code, 200) t = json.loads(response.content) self.event_code = t['event_code'] self.assertEquals(t['state'], True) response = self.client.post(reverse(self.create_uri), data=data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], False)
def test_hit_detail_view(self): url = reverse('log_manage:hit_list_detail') # 普通 response = self.client.get(url) self.assertEquals(response.status_code, 200) # 带用户 data = {'user_id': 11} response = self.client.get(url, data) self.assertEquals(response.status_code, 200) # 表不存在 & 带时间 right = datetime.now() left = right - timedelta(days=1) data = { 'user_id': 11, 'start_day': left.strftime('%Y/%m/%d'), 'end_day': right.strftime('%Y/%m/%d') } response = self.client.get(url, data=data) self.assertEquals(response.status_code, 200) # 表存在 & 带时间 create_hit_table(left) response = self.client.get(url, data=data) self.assertEquals(response.status_code, 200) # 带错误的时间 data = { 'user_id': 11, 'start_day': get_sample_str(8), 'end_day': get_sample_str(8) } response = self.client.get(url, data=data) self.assertEquals(response.status_code, 200)
def add_element_to_menu(event_code, menu_type, dimension, element, end_time=None, menu_desc=None): """ 为名单中增加元素 :param str|unicode event_code: 名单项目code :param str|unicode menu_type: 名单类型 black white gray :param str|unicode dimension: 名单维度 user_id / ip / ... :param str|unicode element: 放入名单的元素 :param datetime end_time: 失效时间 :param str|unicode menu_desc: 备注 :return: """ end_time = (end_time or datetime.now() + timedelta(hours=1)) menu_desc = menu_desc or get_sample_str(15) payload = dict(end_time=end_time, menu_desc=menu_desc, menu_status=u"有效", create_time=datetime.now(), creator='test', value=element, event_code=event_code, dimension=dimension, menu_type=menu_type) db = get_mongo_client() insert_result = db['menus'].insert_one(payload) redis_client = get_redis_client() redis_key = build_redis_key(event_code, dimension=dimension, menu_type=menu_type) if redis_key: redis_client.sadd(redis_key, element) return str(insert_result.inserted_id)
def _test_change(self): change_url = reverse(self.change_url) valid_post_data = copy.deepcopy(self.valid_post_data) valid_post_data['id'] = self.rule_uuid # 正常请求 a = [[self.menu_strategy_uuid, [], get_sample_str()]] b = [[self.user_strategy_uuid, ["10", "10"], get_sample_str()]] c = [[self.bool_strategy_uuid, [], get_sample_str()]] d = [[self.freq_strategy_uuid, ["86400", "1"], get_sample_str()]] valid_post_data['strategys'] = '|'.join( [json.dumps(t) for t in (a, b, c, d)]) response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], True) # 状态不合法 status = valid_post_data.pop('status') valid_post_data['status'] = 'wrong_status' response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], False) # 仅修改阈值 valid_post_data['status'] = status end_time_str = valid_post_data.pop('end_time') response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], True) # 时间格式不合法 valid_post_data['end_time'] = 'xxxxx' response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], False) # 无规则名 valid_post_data['end_time'] = end_time_str title = valid_post_data.pop('title') response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], False) # 无描述 valid_post_data['title'] = title describe = valid_post_data.pop('describe') response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], False) # 表格数据留空/长度不匹配 valid_post_data['describe'] = describe names = valid_post_data.pop('names') response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], False) # 策略数据错误 valid_post_data['names'] = names strategys_str = valid_post_data.pop('strategys') valid_post_data['strategys'] = strategys_str[:-2] response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], False) # 权重非数字 valid_post_data['strategys'] = strategys_str weights = valid_post_data.pop('weights') valid_post_data['weights'] = weights + 'x' response = self.client.post(change_url, data=valid_post_data) self.assertEquals(response.status_code, 200) self.assertEquals(json.loads(response.content)['state'], False)
def _test_create(self): create_url = reverse(self.create_url) # 初始页面 response = self.client.get(create_url) self.assertEquals(response.status_code, 200) # 创建规则 # 无参数 response = self.client.post(create_url) self.assertEquals(response.status_code, 200) resp_json = json.loads(response.content) self.assertEquals(resp_json['state'], False) # 正常创建 event_code = create_menu_event()['event_code'] add_element_to_menu(event_code=event_code, menu_type='black', dimension='user_id', element='111111') # user_id 在 event_code 所代表的黑名单中 self.menu_strategy_uuid = create_menu_strategy(event_code=event_code, dimension='user_id', menu_type='black', menu_op='is') # 相同uid,当天限1个用户 data_source_key = create_data_source() self.user_strategy_uuid = create_user_strategy( strategy_source=data_source_key, strategy_body='uid', strategy_day=1, strategy_limit=1) # 用户是异常用户 self.bool_strategy_uuid = create_bool_strategy( strategy_var='user_id', strategy_op='is', strategy_func='is_abnormal', strategy_threshold='') # 相同uid,在最近86400s内,限1次 self.freq_strategy_uuid = create_freq_strategy( strategy_source=data_source_key, strategy_body='uid', strategy_time=24 * 60 * 60, strategy_limit=1) self.valid_post_data = { 'title': get_sample_str(10), 'describe': get_sample_str(8), 'status': 'on', 'end_time': (datetime.today() + timedelta(days=100)).strftime('%Y-%m-%d %H:%M:%S'), 'strategys': ','.join([ self.menu_strategy_uuid, self.user_strategy_uuid, self.bool_strategy_uuid, self.freq_strategy_uuid ]), 'controls': ','.join(['deny', 'log', 'number', 'pass']), 'customs': ':::'.join([get_sample_str()] * 4), 'names': ':::'.join([get_sample_str()] * 4), 'weights': ','.join(['100', '90', '80', '70']) } response = self.client.post(create_url, data=self.valid_post_data) self.assertEquals(response.status_code, 200) resp_json = json.loads(response.content) self.assertEquals(resp_json['state'], True) self.rule_uuid = resp_json['uuid']
class TestUserIDMenu(TestMenuMinix, BaseTestCase): dimension = 'user_id' test_cases = [(get_sample_str(10), True)] list_uri = 'menus:userid_list'
def create_menu_event(event_code=None, event_name=None): db = get_mongo_client() payload = dict(event_code=event_code or str(uuid.uuid4()), event_name=event_name or get_sample_str(length=8)) db['menu_event'].insert_one(payload) return payload
class TestPayMenu(TestMenuMinix, BaseTestCase): dimension = 'pay' test_cases = [(get_sample_str(10), True)] list_uri = 'menus:pay_list'
class TestIPMenu(TestMenuMinix, BaseTestCase): dimension = 'ip' test_cases = [(get_sample_str(7), False), ('1.1.1.1', True)] list_uri = 'menus:ip_list'
class TestPhoneMenu(TestMenuMinix, BaseTestCase): dimension = 'phone' test_cases = [(get_sample_str(10), False), ('11111111111', True)] list_uri = 'menus:phone_list'