def post(self, args): draft_id = request.args.get('draft_id', type=int) doc = Post.query.get(draft_id) if doc: if doc.published == True: return api_abort(403, "该文章已发布") else: doc = Post() content = args["body"] soup = filter_html(content) doc.title = args["title"] doc.body = str(soup) doc.update_time = datetime.datetime.now() doc.category_id = args["category_id"] or 1 doc.author = g.user try: db.session.add(doc) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "数据保存失败") response = jsonify(post_schema(doc)) response.status_code = 201 return response
def post(self): try: task_id = request.json.get("task_id") if not task_id: return api_abort(400, "任务id不能为空") from manage import celery as celery_app celery_app.control.revoke(task_id, terminate=True) task_obj = AnsibleTasks.query.filter(AnsibleTasks.celery_id == task_id).first() if task_obj: task_obj.cancelled = True db.session.add(task_obj) db.session.commit() # 更改数据库任务状态,延迟10秒执行 celery_task = terminate_task.apply_async( (task_id,), countdown=6 ) return jsonify({ "code": 200, "msg": "任务终止成功", "cancelled": True }) except Exception as e: current_app.logger.error(e) return api_abort(403, "任务删除失败")
def forget_password(): """忘记密码接口""" try: domain = request.headers.get("Origin") if not domain: return api_abort(401, "请使用浏览器访问") capcha = request.json.get('capcha') capcha_id = request.json.get('capcha_id') if not capcha or not capcha_id: return api_abort(400, "请输入验证码") if not validate_capcha(capcha_id, capcha): return api_abort(400, "验证码错误") email = request.json["email"] user = User.query.filter_by(email=email).first() if not user: return api_abort(400, "邮箱未注册") token = gen_token(user=user, operation=Operations.RESET_PASSWORD, expire_in=3600) send_reset_password_email(user=user, token=token, domain=domain) return jsonify({"code": 20003, "message": "重置密码邮件已发送"}) except Exception as e: return api_abort(401, "数据有误")
def post(self, args): """创建playbook接口""" playbook_file = os.path.join(playbook_dir, args['name']) # 读取playbook内容 with open(playbook_file, encoding='utf8') as f: yml = f.read() playbook = PlayBook(name=args['name'], author=args['author'], information=args['information'], is_env=args['is_env'], upload=args['upload']) try: db.session.add(playbook) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "数据保存失败") play_content = PlayBookDetail() # commit提交后才能获取playbook的id play_content.playbook_id = playbook.id play_content.content = yml try: db.session.add(play_content) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "数据保存失败") response = jsonify(playbook_schema(playbook)) response.status_code = 201 return response
def put(self, args, post_id): """ 编辑文章接口 :param args: 请求数据 :param post_id: 文章ID :return: """ doc = Post.query.get_or_404(post_id) # 作者本人才可编辑 if g.user.id != doc.author.id: return api_abort(403, "您无法编辑此文章") content = args["body"] soup = filter_html(content) # 构建摘要数据,获取标签字符串的文本前150个符号 desc = soup.text[0:150] + "..." doc.title = args["title"] doc.category_id = args["category_id"] doc.desc = desc doc.body = str(soup) doc.update_time = datetime.datetime.now() doc.author = g.user # doc.author_id = 20 try: db.session.add(doc) db.session.commit() except Exception as e: current_app.logger.error(e) db.session.rollback() return api_abort(400, "数据保存失败") return jsonify(post_schema(doc))
def delete(self, draft_id): draft = Post.query.filter(Post.id == draft_id, Post.published == False).first() if not draft: return api_abort(404) # 文章作者有删除权限 if g.user.id != draft.author.id: return api_abort(403, "无法删除此文档") db.session.delete(draft) db.session.commit() return '', 204
def resend_confirm_email(): """重新发送确认邮箱邮件""" try: domain = request.headers.get("Origin") if not domain: return api_abort(401, "请使用浏览器访问") if g.user.confirmed: return jsonify({"code": 20001, "message": "邮箱已认证"}) token = gen_token(user=g.user, operation=Operations.CONFIRM, expire_in=3600) send_confirm_email(user=g.user, token=token, domain=domain) return jsonify({"code": 20005, "message": "验证邮件已发送"}) except Exception as e: return api_abort(401, "数据有误")
def wrapper(*args, **kwargs): stoken = request.args.get("stoken") if not stoken: return api_abort(403, "stoken缺失") stoken_key = str(g.user.username) + "_stoken" save_token = redis_conn.get(stoken_key) # print(save_token.decode(), stoken) if not save_token: return api_abort(403, "请勿重复操作") if stoken != save_token.decode(): return api_abort(403, "stoken校验失败") redis_conn.delete(stoken_key) return view(*args, **kwargs)
def post(self, args): """ 新建文章 :param args: :return: """ content = args["body"] soup = filter_html(content) # 构建摘要数据,获取标签字符串的文本前150个符号 desc = soup.text[0:150] + "..." doc = Post() doc.title = args["title"] doc.category_id = args["category_id"] or 1 doc.desc = desc doc.body = str(soup) doc.published = True doc.author = g.user # doc.author_id = 20 try: db.session.add(doc) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "数据保存失败") response = jsonify(post_schema(doc)) response.status_code = 201 return response
def post(self): """提交任务接口""" print(request.json) exec_hosts = [] payload = request.json try: host = payload["hosts"] playbook = payload["playbook"] extra_vars = payload["extra_vars"] option = payload['option'] is_upload = payload['is_upload'] if not option: option = None if not host or not playbook: return api_abort(400, "参数有误") except Exception as e: return api_abort(400, "参数有误") playbook = PlayBook.query.get_or_404(playbook) # # # 判断执行队列中是否有该任务 # # 1 正在执行 2 待执行 # if option: # option_obj = Options.query.get_or_404(option) # print(option_obj.name) # option_name = option_obj.name # task_state = redis_conn.get(option_name) # redis_conn.set(option_name, 1) # if task_state.decode() == '1': # return api_abort(403, "{} 任务正在发布中".format(option_name)) # 判断是否需要上传文件 if playbook.upload and not is_upload: return api_abort(403, "请先上传zip包") hosts = Host.query.filter(Host.id.in_(host)).all() if not hosts: return api_abort(400, "参数有误") for host in hosts: exec_hosts.append((host.ip, host.port)) # 获取playbook名称 playbook = playbook.name # 提交celery执行任务 ret = AnsibleOpt.ansible_playbook(exec_hosts, playbook, option, extra_vars=extra_vars) return jsonify(ret)
def delete(self, post_id): """删除文章接口""" doc = Post.query.get_or_404(post_id) # 文章作者有删除权限 if g.user.id != doc.author.id: return api_abort(403, "无法删除此文档") db.session.delete(doc) db.session.commit() return '', 204
def post(self): filename = request.json.get("name") filesize = request.json.get("size") if not filename or not filesize: return api_abort(400, "请选择文件") if filesize > 5 * 1024 * 1024: return api_abort(403, '单文件不能超过5M') if filesize + g.user.use_space > 100 * 1024 * 1024: return api_abort(403, '您的容量已不足,请升级套餐') # print(filename, filesize) token = get_sts_token() # print(token) token['region'] = current_app.config['OSS_REGION'] token['bucket'] = g.user.bucket return jsonify(token)
def batch_draft_del(): draft_list = request.json if not isinstance(draft_list, list): return api_abort(401, "请选择草稿") for item in draft_list: obj = Post.query.get_or_404(item) db.session.delete(obj) db.session.commit() drafts = Post.query.filter(Post.author == g.user, Post.published == False).order_by(text('-update_time')).all() return jsonify(drafts_schema(drafts))
def confirm(token): """邮箱验证""" domain = request.headers.get("Origin") if not domain: return api_abort(401, "请使用浏览器登录, 邮箱认证失败") if g.user.confirmed: return jsonify({"code": 20001, "message": "邮箱已认证"}) if validate_token(user=g.user, token=token, operation=Operations.CONFIRM): return jsonify({"code": 20002, "message": "邮箱认证成功"}) else: return jsonify({"code": 50001, "message": "邮箱认证失败"})
def add_bucket(): """创建bucket接口""" if g.user.bucket: return api_abort(403, 'bucket已存在,不可重复创建') bucket = '{}-{}'.format(g.user.username, str(int(time.time()))) # 创建用户桶 create_bucket(bucket) g.user.bucket = bucket db.session.commit() return jsonify({'bucket': bucket})
def put(self, args, fid): folder_obj = FileRepository.query.get_or_404(fid) folder_obj.name = args['name'] folder_obj.update_datetime = datetime.now() try: db.session.add(folder_obj) db.session.commit() except Exception as e: current_app.logger.error(e) db.session.rollback() return api_abort(400, "数据保存失败") return jsonify(file_schema(folder_obj))
def reset_password(args, token): """重置密码接口""" user = User.query.filter_by(email=args['email']).first() if not user: return api_abort(400, "邮箱错误") if validate_token(user=user, token=token, operation=Operations.RESET_PASSWORD, new_password=args['new_password']): return jsonify({"code": 20004, "message": "密码已更新, 请登录"}) else: return jsonify({"code": 50002, "message": "token认证失败"})
def put(self, category_id, name): """编辑分类""" category = Category.query.get_or_404(category_id) category.name = name try: db.session.add(category) db.session.commit() except Exception as e: current_app.logger.error(e) db.session.rollback() return api_abort(400, "数据保存失败") return jsonify(category_schema(category))
def post(self, args): """新建主机接口""" host = Host(hostname=args["hostname"], ip=args['ip'], port=args['port'], group_id=args['group_id']) try: db.session.add(host) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "数据保存失败") response = jsonify(host_schema(host)) response.status_code = 201 return response
def put(self, group_id, name, description): """编辑主机组""" group = HostGroup.query.get_or_404(group_id) group.name = name group.description = description try: db.session.add(group) db.session.commit() except Exception as e: current_app.logger.error(e) db.session.rollback() return api_abort(400, "数据保存失败") return jsonify(group_schema(group))
def post(self, args): key = args['key'] etag = args['etag'] # 向OSS校验etag值 from oss2.exceptions import NoSuchKey try: res = check_file(g.user.bucket, key) if etag != res.etag: return api_abort(403, "ETag错误") except NoSuchKey as e: return api_abort(403, "文件未上传成功") # user = User.query.filter_by(id=g.user.id).with_for_update(read=False).first() file_obj = FileRepository(name=args["filename"]) file_path = "http://{}.{}.aliyuncs.com/{}".format( g.user.bucket, current_app.config['OSS_REGION'], args['key']) file_obj.user = g.user file_obj.file_type = 1 file_obj.file_size = args['file_size'] file_obj.parent_id = args['parent_id'] if args['parent_id'] else None file_obj.key = key file_obj.file_path = file_path g.user.use_space += args['file_size'] db.session.commit() # print(g.user.use_space) try: db.session.add(file_obj) db.session.commit() except Exception as e: current_app.logger.error(e) db.session.rollback() return api_abort(400, "数据保存失败") return jsonify(file_schema(file_obj))
def login(): payload = request.json capcha = payload.get('capcha') capcha_id = payload.get('capcha_id') if not capcha or not capcha_id: return api_abort(400, "请输入验证码") if not validate_capcha(capcha_id, capcha): return api_abort(400, "验证码错误") try: email = payload["username"] password = payload["password"] user = User.query.filter_by(email=email).first() if not bcrypt.checkpw(password.encode(), user.password.encode()): return api_abort(401, "用户名或密码错误") # 验证通过,生成token token = gen_token(user, Operations.LOGIN) response = { 'code': 20000, 'user': { 'user_id': user.id, 'username': user.username, 'email': user.email }, 'token': token } current_app.logger.info("用户{}登录成功".format(user.username)) return jsonify(response) except AttributeError as e: current_app.logger.error("{}".format(e)) return api_abort(401, "用户名或密码错误") except Exception as e: current_app.logger.error("{}".format(e)) return api_abort(401, "登录失败")
def post(self): """上传dist压缩文件接口""" data = {"code": 2000, "msg": '', "is_upload": False} try: project = request.args.get('option') file_obj = request.files["file"] if not project: return api_abort(403, "请先选择参数") if not file_obj or file_obj.filename.split(".")[-1] != "zip": return api_abort(403, "请上传zip文件") upload_path = os.path.join(current_app.config["UPLOAD_PATH"], project) # 如果目录不存在,则创建 if not os.path.exists(upload_path): os.mkdir(upload_path) file_obj.save(os.path.join(upload_path, "dist.zip")) data["is_upload"] = True except Exception as e: current_app.logger.error(e) data["code"] = 5001 data["msg"] = "文件上传失败" return jsonify(data)
def post(self, args): """新建文件夹""" folder = FileRepository(user=g.user, name=args['name']) folder.file_type = 2 if args['folder_id']: folder.parent_id = args['folder_id'] try: db.session.add(folder) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "数据保存失败") response = jsonify(file_schema(folder)) response.status_code = 201 return response
def put(self, args, host_id): """编辑主机接口""" host = Host.query.get_or_404(host_id) host.hostname = args['hostname'] host.ip = args['ip'] host.port = args['port'] host.group_id = args['group_id'] try: db.session.add(host) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "保存数据失败") return jsonify(host_schema(host))
def post(self, args): """ 创建新分类 :param args: :return: """ category = Category(name=args['name']) try: db.session.add(category) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "数据保存失败") response = jsonify(category_schema(category)) response.status_code = 201 return response
def post(self, args): """ 创建新服务器组 :param args: :return: """ group = HostGroup(name=args['name'], description=args['description']) try: db.session.add(group) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "数据保存失败") response = jsonify(group_schema(group)) response.status_code = 201 return response
def put(self, args, option_id): """编辑playbook参数接口""" option = Options.query.get_or_404(option_id) option.name = args['name'] option.content = json.dumps(args['content']) option.playbook_id = args['playbook_id'] option.env_id = args.get('env_id') option.url = args.get('url') try: db.session.add(option) db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(e) return api_abort(400, "保存数据失败") return jsonify(option_schema(option))
def register(): payload = request.json domain = request.headers.get('Origin') if not domain: return api_abort(403, "请使用浏览器登录") capcha = payload.get('capcha') capcha_id = payload.get('capcha_id') if not capcha or not capcha_id: return api_abort(400, "请输入验证码") if not validate_capcha(capcha_id, capcha): return api_abort(400, "验证码错误") try: # 有任何异常,都返回400,如果保存数据出错,则向外抛出异常 email = payload['email'] username = payload['username'] if not isAlnum(username): return api_abort(400, '用户名只能为字母和数字组合') user = User.query.filter( or_(User.username == username, User.email == email)).first() if user: return api_abort(400, "用户已注册") password = payload['password'] bucket = '{}-{}'.format(username, str(int(time.time()))) # 创建用户桶 create_bucket(bucket) user = User(username=username, email=email) user.password = bcrypt.hashpw(password.encode(), bcrypt.gensalt()) user.bucket = bucket db.session.add(user) try: db.session.commit() token = gen_token(user=user, operation=Operations.CONFIRM, expire_in=3600) send_confirm_email(user=user, token=token, domain=domain) current_app.logger.info("用户{}注册成功".format(username)) return jsonify({"user_id": user.id}) except Exception as e: current_app.logger.error("%s" % e) db.session.rollback() raise except Exception as e: current_app.logger.error("%s" % e) return api_abort(400)
def file(): # query = FileRepository.query.filter( # FileRepository.user_id == 15, # FileRepository.id == 1 # ).first() import oss2 from backend.utils.aliyun.oss import delete_bucket try: delete_bucket("hepengfei-159086320") except oss2.exceptions.NoSuchBucket: return api_abort(404, "找不到指定的桶") # for b in part: # print(b.key) # print(query.file_type.value) # print(query.childs) return jsonify({"status": 200})