From c9b6002921f528326fb929f874f195210bfc1fbb Mon Sep 17 00:00:00 2001 From: freeziyou <80776877@qq.com> Date: Mon, 26 Feb 2024 18:01:47 +0800 Subject: [PATCH] fix get_image --- server/routes/user.py | 48 +++++++++++++++++++++++--------------- server/tasks/lark/base.py | 7 +++++- server/tasks/lark/chat.py | 12 +++++----- server/tasks/lark/issue.py | 2 +- server/utils/utils.py | 9 ++++--- 5 files changed, 46 insertions(+), 32 deletions(-) diff --git a/server/routes/user.py b/server/routes/user.py index d631a507..0ed29e0a 100644 --- a/server/routes/user.py +++ b/server/routes/user.py @@ -1,12 +1,12 @@ from app import app -from flask import Blueprint, Response, jsonify, request, session +from flask import Blueprint, Response, abort, jsonify, request, session from model.team import ( get_application_info_by_team_id, get_team_list_by_user_id, is_team_admin, ) from model.user import get_user_by_id -from tasks.lark.base import get_bot_by_application_id +from tasks.lark.base import get_bot_by_application_id, get_repo_by_repo_id from utils.auth import authenticated from utils.utils import download_file @@ -62,27 +62,37 @@ def set_account(): return jsonify({"code": 0, "msg": "success"}) -@bp.route("///image/", methods=["GET"]) -# @authenticated -def get_image(team_id, message_id, img_key): +@bp.route("////image/", methods=["GET"]) +def get_image(team_id, message_id, repo_id, img_key): """ 1. 用 img_key 下载 image(cache) - 2. 这个链接需要用户登录信息 - 1. 公开仓库,不校验 - 3. 并且需要多加一层权限管理(只有这个team下面的人 ,才能查看这个图) - 4. 如果没有登录的时候,这个url返回一张403的图,点击的时候,告诉用户需要登录 - 1. 如果是github上面查看的时候,通过 判断,展示图片 - 2. 如果用户点击图片,直接浏览器打开 - 1. 这个时候rederer是空的,跳转github oauth登录 - 2. 然后跳转回到这个图片。可以正常查看图片内容 - 3. 这个时候如果刷新github的issue页面,应该是能正常查看图片的 + 2. """ - # 必须要登录,才能查看图片,不然ddos分分钟打爆db - _, im_application = get_application_info_by_team_id(team_id) - bot, _ = get_bot_by_application_id(im_application.id) - image_content = download_file(img_key, message_id, bot, "image") - return Response(image_content, mimetype="image/png") + def download_and_respond(): + _, im_application = get_application_info_by_team_id(team_id) + bot, _ = get_bot_by_application_id(im_application.id) + image_content = download_file(img_key, message_id, bot, "image") + return Response(image_content, mimetype="image/png") + + # GitHub调用 + user_agent = request.headers.get("User-Agent") + if user_agent and user_agent.startswith("github-camo"): + return download_and_respond() + + # TODO 用户调用(弱需求, 通常来讲此接口不会被暴露), 需要进一步校验权限 + referer = request.headers.get("Referer") + if not referer: + # 公开仓库不校验 + repo = get_repo_by_repo_id(repo_id) + is_private = repo.extra.get("private", False) + app.logger.debug(f"is_private: {is_private}") + + # 私有仓库校验,先登录 + if is_private: + return abort(403) + + return download_and_respond() app.register_blueprint(bp) diff --git a/server/tasks/lark/base.py b/server/tasks/lark/base.py index 47b05906..430cf657 100644 --- a/server/tasks/lark/base.py +++ b/server/tasks/lark/base.py @@ -24,6 +24,11 @@ def get_chat_group_by_chat_id(chat_id): def get_repo_name_by_repo_id(repo_id): + repo = get_repo_by_repo_id(repo_id) + return repo.name + + +def get_repo_by_repo_id(repo_id): repo = ( db.session.query(Repo) .filter( @@ -32,7 +37,7 @@ def get_repo_name_by_repo_id(repo_id): ) .first() ) - return repo.name + return repo def get_bot_by_application_id(app_id): diff --git a/server/tasks/lark/chat.py b/server/tasks/lark/chat.py index c5bb7fb7..cfc179c7 100644 --- a/server/tasks/lark/chat.py +++ b/server/tasks/lark/chat.py @@ -316,7 +316,7 @@ def create_issue( assignees = [code_users[openid][1] for openid in users if openid in code_users] # 处理 body - body = process_desc(app_id, message_id, body, data, team, *args, **kwargs) + body = process_desc(app_id, message_id, repo.id, body, data, team, *args, **kwargs) response = github_app.create_issue( team.name, repo.name, title, body, assignees, labels @@ -328,7 +328,7 @@ def create_issue( return response -def process_desc(app_id, message_id, desc, data, team, *args, **kwargs): +def process_desc(app_id, message_id, repo_id, desc, data, team, *args, **kwargs): """ 处理发给 github 的 desc, 转换@、处理图片、换行 """ @@ -340,16 +340,16 @@ def process_desc(app_id, message_id, desc, data, team, *args, **kwargs): ) # 2. 处理 body 中的图片 - desc = replace_images_keys_with_url(desc, team.id, message_id) + desc = replace_images_keys_with_url(desc, team.id, message_id, repo_id) # github 只支持 \r\n return desc.replace("\n", "\r\n") -def replace_images_keys_with_url(text, team_id, message_id): +def replace_images_keys_with_url(text, team_id, message_id, repo_id): """ replace image_key with image URL. - ![](image_key) -> ![](gitmaya.com/api///image/) + ![](image_key) -> ![](gitmaya.com/api////image/) Args: text (str): original text @@ -359,7 +359,7 @@ def replace_images_keys_with_url(text, team_id, message_id): host = os.environ.get("DOMAIN") replaced_text = re.sub( r"!\[.*?\]\((.*?)\)", - lambda match: f"![]({host}/api/{team_id}/{message_id}/image/{match.group(1)})", + lambda match: f"![]({host}/api/{team_id}/{message_id}/{repo_id}/image/{match.group(1)})", text, ) diff --git a/server/tasks/lark/issue.py b/server/tasks/lark/issue.py index 8dfc7602..39aff21f 100644 --- a/server/tasks/lark/issue.py +++ b/server/tasks/lark/issue.py @@ -605,7 +605,7 @@ def create_issue_comment(app_id, message_id, content, data, *args, **kwargs): # 处理 desc comment_text = process_desc( - app_id, message_id, comment_text, data, team, *args, **kwargs + app_id, message_id, repo.id, comment_text, data, team, *args, **kwargs ) response = github_app.create_issue_comment( diff --git a/server/utils/utils.py b/server/utils/utils.py index badc58d4..0f52b161 100644 --- a/server/utils/utils.py +++ b/server/utils/utils.py @@ -6,12 +6,11 @@ def process_image(url, bot): - if ( - not url - or not url.startswith("http") - or url.startswith(f"{os.environ.get('DOMAIN')}/api") - ): + if not url or not url.startswith("http"): return "" + + if url.startswith(f"{os.environ.get('DOMAIN')}/api"): + return url.split("/")[-1] return upload_image(url, bot)