def create_task(): """ 创建任务,可以由浏览器插件或者直接在平台上创建,redis缓存查询用户信息 :return: """ try: post_data = request.get_json(force=True) if json_utils.has_dict_value_blank( post_data, ['hook_rule', 'read_agreement', 'task_name']): return jsonify(status=400, message="创建任务失败", data={"extra_info": "新建任务时没有设置网址正则或任务名称"}) if not post_data.get("read_agreement"): return jsonify(status=400, message="创建任务失败", data={"extra_info": "请阅读用户协议并点击同意"}) current_user_name = session["user_name"] post_hook_rule = post_data.get("hook_rule") post_task_name = post_data.get("task_name") current_user = RedisService.get_user(user_name=current_user_name) receivers_email = current_user[ "email"] if "email" in current_user else None task = TaskService.save(create_user_id=current_user["id"], task_name=post_task_name, receivers_email=receivers_email, hook_rule=post_hook_rule) #if UserTaskService.count(where=(UserTask.task_id == task.id, UserTask.user_id == current_user["id"])) == 0: UserTaskService.save(task_id=task.id, user_id=current_user["id"]) RedisService.create_task(task.id, post_hook_rule, current_user_name, TaskStatus.WORKING) RedisService.update_user_field(current_user_name, "current_task_id", task.id) UserService.update(fields=({ User.recent_operation_time: datetime.datetime.now() }), where=(User.user_name == current_user_name)) task_access_key = generate_access_key( task.id, current_user_name).decode("utf-8") TaskService.update(fields=({ Task.access_key: task_access_key }), where=(Task.id == task.id)) scan_celery.delay(post_data, task.id, current_user_name, TaskStatus.WORKING) return jsonify(status=200, message="创建任务成功", data={ "task_id": task.id, "full_name": current_user["full_name"], "create_time": get_current_time(), "task_access_key": task_access_key }) except Exception as e: logger.exception("create_task exception") return jsonify(status=500, message="未知异常", data={"extra_info": "创建任务时出现未知异常,请联系管理员查看异常日志"})
def testGetUsersScanCount(self): from model.user import UserService import logging logger = logging.getLogger('peewee') logger.addHandler(logging.StreamHandler()) logger.setLevel(logging.DEBUG) UserService.get_users_scan_count()
def testGetCreateUser(self): """ 测试执行SQL :return: """ from model.user import UserService import logging logger = logging.getLogger('peewee') logger.addHandler(logging.StreamHandler()) logger.setLevel(logging.DEBUG) UserService.get_create_user(task_id=1)
def update_user_role(openid): """ 更改用户权限 :return: """ put_data = request.get_json(force=True) role = put_data.get("role") if role == Role.ADMIN or role == Role.USER: UserService.update_role(openid, role) return jsonify(status=200, message="更新权限成功", data={}) else: return jsonify(status=400, message="更新权限失败", data={"extra_info": "role不合法"})
def list_users(): """ 获取系统中的用户列表 :return: """ user_list = [] try: users = UserService.get_fields_by_where() user_list.reverse() response_data = jsonify(status=200, message="查询成功", data={ 'users': user_list, 'num': len(users) }) except UsersDataNotExistException: logger.exception("list_users raise error") response_data = jsonify(status=200, message="查询成功", data={ 'users': user_list, 'num': 0 }) return response_data
def login(): """ 请求如下 POST /api/v1/user {"username": "", "password": ""} 登录成功并设置SESSION :return: """ post_data = request.get_json(force=True) username = post_data["username"] password = post_data["password"] count = UserService.count(where=(User.username == username, User.password == password)) if count > 0: session["username"] = username session["password"] = password session["ok"] = True response_data = jsonify(status=200, message="授权成功", data={ "extra_info": "跳转到后台", "site": "/" }) else: response_data = jsonify(status=403, message="未能授权成功", data={ "extra_info": "跳转到登录页面", "site": "/login" }) return response_data
def check_initialization_success(): """ 检测初始化是否成功 :return: """ user = UserService.get_fields_by_where()[0] print("username:{},passwor:{},token:{}".format(user.username, user.password, user.token)) """
def create_admin_user(): """ 新建管理账户 :return: """ if UserService.count(where=(User.user_name == "hunter")) <= 0: User.create(user_name="hunter", pass_word="hunter", full_name="hunter管理员", role=4)
def modify_user(user_id): """ 更新用户资料,主要包含权限,部门等等 data: {department: "信息安全部", emails: "", mobilephone: "18324742048", role: "管理员"} :return: """ try: put_data = request.get_json(force=True) param_list = ["email", "mobile_phone", "role", "depart_ment"] if has_dict_value_blank(put_data, param_list): return jsonify( status=400, message="更新失败", data={"extra_info": "请保证%s任一参数值不为空" % ','.join(param_list)}) email = put_data.get("email") mobile_phone = put_data.get("mobile_phone") role = put_data.get("role") depart_ment = put_data.get("depart_ment") UserService.update(fields=({ User.email: email, User.mobile_phone: mobile_phone, User.role: role, User.dept_name: depart_ment }), where=(User.id == user_id)) user = UserService.get_fields_by_where(where=(User.id == user_id))[0] RedisService.update_user( user.user_name, { "dept_name": depart_ment, "role": role, "mobile_phone": mobile_phone, "email": email }) return jsonify(status=200, message="更新用户成功", data={}) except Exception as e: logger.exception("update_user error") return jsonify(status=500, message="未知异常", data={"extra_info": "发生未知异常,请联系管理员查看异常日志"})
def get_tokens(refresh=False): """ 从数据库中获取token,单例模式 :param refresh: :return: """ global TOKENS if not TOKENS or refresh: TOKENS = list() users = UserService.get_fields_by_where(fields=(User.token)) for user in users: TOKENS.append(user.token) return TOKENS
def authorize_route(): """ 基础账号密码认证体系 :return: """ try: post_data = request.get_json(force=True) post_user_name = post_data.get("user_name") post_pass_word = post_data.get("pass_word") if UserService.count( where=(User.user_name == post_user_name, User.pass_word == post_pass_word)) <= 0: return jsonify(status=403, message="认证出错", data={ "extra_info": "账号密码登录出错", "site": "/login" }) db_user = UserService.get_fields_by_where( where=(User.user_name == post_user_name, User.pass_word == post_pass_word))[0] BaseAuthModule.modify_user_info_cache_session( user_name=db_user.user_name, db_user=db_user) return jsonify(status=200, message="认证成功", data={ "extra_info": "稍后自动跳转首页,请耐心等待", "site": get_system_config()['front_end']['index'] }) except Exception as e: logger.exception("auth_account raise error") return jsonify(status=500, message="未知异常", data={"extra_info": "发生未知异常,请联系管理员查看异常日志"})
def testGetAllUser(self): """ 列出所有用户 :return: """ from model.user import UserService, User import logging logger = logging.getLogger('peewee') logger.addHandler(logging.StreamHandler()) logger.setLevel(logging.DEBUG) user = UserService.get_fields_by_where() logger.info("1121") User.select().execute() logger.info(user)
def generate_report(self, task_id): """ 生成邮件发送报告 :param cls: :param task_id: :return: """ current_task = TaskService.get_fields_by_where(where=(Task.id == task_id))[0] vulns_info = VulnerabilityService.get_fields_by_where(where=(Vulnerability.task_id == task_id)) users = UserService.get_users(task_id=task_id) if len(vulns_info) <= 0: content = """<br>你好,欢迎使用Hunter,本次扫描结束,扫描到你有0个漏洞。详情请可登录{}查看<br>""".format( get_system_config()['front_end']['index']) else: content = """<br>你好,欢迎使用Hunter,本次扫描结束,扫描到你有{}个漏洞。任务预览如下,详情请登录{}查看<br>""".format(len(vulns_info), get_system_config()[ 'front_end'][ 'index']) content += """ <table frame='border' cellpadding='15' cellspacing='0' align='center' style='border: 1px solid #d6d3d3;'> <tr style='background: #e6e6e6;'> <th style="border-right: 1px solid #bfbfbf;">序号</th> <th style="border-right: 1px solid #bfbfbf;">漏洞等级</th> <th style="border-right: 1px solid #bfbfbf;">漏洞类型</th> <th style="border-right: 1px solid #bfbfbf;">漏洞详情</th> </tr> """ index = 0 for vuln_info in vulns_info: index += 1 vuln_detail_url = '<a href="{}">{}</a>'.format( get_system_config()['front_end']['vuln_route'] + str(task_id), vuln_info.info) content += """ <tr> <td style="border-right: 1px solid #bfbfbf;">{}</td> <td style="border-right: 1px solid #bfbfbf;">{}</td> <td style="border-right: 1px solid #bfbfbf;">{}</td> <td style="border-right: 1px solid #bfbfbf;">{}</td> </tr> """.format(index, vuln_info.level, vuln_info.chinese_type, vuln_detail_url) content += """</table>""" return content, ",".join([user.email for user in users if user.email])
def testGetFieldsByWhere(self): """ :return: """ import logging from model.user import UserService from model.user import User from model.user_task import UserTask from model.hunter_model import OrmModelJsonSerializer logger = logging.getLogger('peewee') logger.addHandler(logging.StreamHandler()) logger.setLevel(logging.DEBUG) user_services = UserService.get_fields_by_where(fields=( UserTask.select(fn.COUNT(UserTask.id)).alias('scan_count').where( UserTask.user_id == User.id), User.full_name))
def list_tasks_by_num(): """ 获取系统中的任务列表,用于数据大盘展示用户使用最新动态,需要跨表连接获取数据 SELECT * FROM user INNER JOIN usertask ON usertask.user_id = user.id where usertask.task_id = 2333 :return: """ try: num = int(request.args.get("num")) tasks_cursor_wrapper = TaskService.get_fields_by_where( fields=(Task.created_time, Task.killed_time, Task.task_name, Task.id)) tasks_list = OrmModelJsonSerializer.serializer(tasks_cursor_wrapper) tasks_list.reverse() if len(tasks_list) > num: tasks_result = tasks_list[0:num] else: tasks_result = tasks_list result = list() for task_result in tasks_result: user = UserService.get_users(task_id=task_result["id"])[0] task_result["dept_name"] = user.dept_name task_result["full_name"] = user.full_name task_result["user_name"] = user.user_name result.append(task_result) response_data = jsonify(status=200, message="查询成功", data={ 'tasks': result, 'num': len(result) }) except Exception as e: logger.exception("list_tasks raise error") return jsonify(status=200, message="查询成功", data={ 'tasks': [], 'num': 0 }) return response_data
def addUser2dbAndRedis(self): """ 同步一个账号到数据库和redis :return: """ from api.service.redis_service import RedisService from model.default_value import Role from model.user import User, UserService user_name = "b5mali4" full_name = "小明" email = "*****@*****.**" dept_name = "信息安全部" role = Role.USER mobile_phone = "131xxxx9871" if UserService.count(where=(User.user_name == user_name)) <= 0: UserService.save(user_name=user_name, full_name=full_name, email=email, dept_name=dept_name, role=role, mobile_phone=mobile_phone) else: UserService.update(fields=({ User.user_name: user_name, User.full_name: full_name, User.email: email, User.dept_name: dept_name, User.role: role, User.mobile_phone: mobile_phone })) user = UserService.get_fields_by_where( where=(User.user_name == user_name))[0] user_info = { "user_name": "b5mali4", "full_name": "小明", "email": "*****@*****.**", "dept_name": "信息安全部", "role": Role.USER, "mobile_phone": "131xxxx9871", "id": user.id } RedisService.update_user(user_name="b5mali4", user_info=user_info)
def stop_task(): """ 关闭任务,关闭任务之后将用户任务信息进行持久化到数据库,包括结束任务时间 :return: """ post_data = request.get_json(force=True) if json_utils.has_dict_value_blank(post_data, ["task_id"]): return jsonify(status=400, message="结束任务失败", data={"extra_info": "task_id缺失,无法结束任务"}) post_task_id = int(post_data.get("task_id")) current_user_name = session["user_name"] try: user = RedisService.get_user(current_user_name) if UserTaskService.count( where=(UserTask.user_id == user["id"], UserTask.task_id == post_task_id)) == 0: return jsonify(status=403, message="结束任务失败", data={"extra_info": "请勿尝试非法关闭非自己权限任务"}) task = TaskService.get_fields_by_where( fields=(Task.task_status), where=(Task.id == post_task_id))[0] if task.task_status in [TaskStatus.DONE, TaskStatus.KILLED]: return jsonify(status=200, message="结束任务成功", data={ "fullname": user["full_name"], "extra_info": "该任务早已经结束,请登录后台查看扫描结果", "stop_time": get_current_time() }) TaskService.update(fields=({ Task.task_status: TaskStatus.KILLED, Task.killed_time: datetime.datetime.now() }), where=(Task.id == post_task_id)) UserService.update(fields=({ User.recent_operation_time: datetime.datetime.now() }), where=(User.user_name == current_user_name)) scan_celery.delay(post_data, post_task_id, current_user_name, TaskStatus.KILLED) RedisService.stop_task(post_task_id) RedisService.clean_urlclassifications(post_task_id) return jsonify(status=200, message="结束任务成功", data={ "full_name": user["full_name"], "extra_info": "请登录后台查看扫描结果", "stop_time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M") }) except Exception as e: logger.exception("stop_task exception") if isinstance(e, UserNotFoundInRedisException): return jsonify(status=403, message="结束任务失败", data={ "extra_info": "认证失败,请重新登录进行授权", "auth_site": "" }) return jsonify(status=500, message="未知异常", data={"extra_info": "创建任务时出现未知异常,请联系管理员查看异常日志"})
def authorize_route(): """ ldap认证账号体系 :return: """ try: post_data = request.get_json(force=True) post_user_name = post_data.get("user_name") post_pass_word = post_data.get("pass_word") ldap_config = LdapConfigService.get_single_instance() if ldap_config.ldap_switch is False: return jsonify(status=500, message="登录失败", data={"extra_info": "不支持ldap认证,请后台配置并开启ldap模块"}) status, result_dict = ldap_auth(post_user_name, post_pass_word) if status: user_name = result_dict["user_name"] # 保存更新数据库和Redis if UserService.count(where=(User.user_name == user_name)) <= 0: UserService.save(user_name=result_dict["user_name"], full_name=result_dict["full_name"], dept_name=result_dict["dept_name"], email=result_dict["email"], mobile_phone=result_dict["mobile"]) else: UserService.update(fields=({ User.full_name: result_dict["full_name"], User.dept_name: result_dict["dept_name"], User.email: result_dict["email"], User.mobile_phone: result_dict["mobile"] }), where=(User.user_name == user_name)) db_user = UserService.get_fields_by_where( where=(User.user_name == user_name))[0] BaseAuthModule.modify_user_info_cache_session( user_name=db_user.user_name, db_user=db_user) return jsonify(status=200, message="认证成功", data={ "extra_info": "稍后自动跳转首页,请耐心等待", "site": get_system_config()['front_end']['index'] }) return jsonify(status=403, message="认证出错", data={ "extra_info": "账号密码登录出错", "site": "/login" }) except Exception as e: logger.exception("auth_account raise error") return jsonify(status=500, message="未知异常", data={"extra_info": "发生未知异常,请联系管理员查看异常日志"})
def list_users(): """ 显示用户列表 一个用户包含 用户名,扫描次数,最新扫描时间,扫描记录 动作包含是否加入管理员等等 v2.5 可条件查询 路由请求格式 fullname=XX&department=&role= 参数值为''表示所有 fullname=XX 参数名也表示所有,例如这里表示只查询fullname :return: """ def change_user_dic(user): """ 将user转换成DIC :param user: :return: """ # from model.user_task import UserTask, UserTaskService # scan_count = UserTaskService.count(where=(UserTask.user_id == user.id)) recent_operation_time = user.recent_operation_time.strftime( "%Y-%m-%d %H:%M") if user.recent_operation_time else "" return { "id": user.id, "user_name": user.user_name, "full_name": user.full_name, "mobile_phone": user.mobile_phone, "email": user.email, "depart_ment": user.dept_name, "role": user.role, "scan_count": user.scan_count, "recent_operation_time": recent_operation_time, "user_info": user.user_info } def generate_search_query(full_name, depart_ment, role, id): result = list() if full_name is not None and full_name != "": result.append(User.full_name == full_name) if depart_ment is not None and depart_ment != "": result.append(User.dept_name == depart_ment) if role is not None and role != "": result.append(User.role == role) if id is not None and id != "": result.append(User.id == id) return result try: full_name = request.args.get("full_name") depart_ment = request.args.get('depart_ment') role = request.args.get("role") id = request.args.get("id") # 构造条件查询元组 query = generate_search_query(full_name, depart_ment, role, id) if len(query) > 0: users = [ change_user_dic(user) for user in UserService.get_users_scan_count( where=tuple(query)) ] else: users = [ change_user_dic(user) for user in UserService.get_users_scan_count() ] return jsonify(status=200, message="查询成功", data=users) except Exception as e: logger.exception("list_user raise error") return jsonify(status=500, message="未知异常", data={"extra_info": "发生未知异常,请联系管理员查看异常日志"})