mirror of
https://github.com/PaiGramTeam/PaiGram.git
synced 2024-11-29 02:57:22 +00:00
🔒️ Impore sign in group security
* 🔒️ 提高SIGN功能在群组使用的安全性
This commit is contained in:
parent
08f2e636ef
commit
53f30a8f85
@ -9,7 +9,7 @@ from genshin import Game, GenshinException, AlreadyClaimed, Client
|
||||
from httpx import AsyncClient, TimeoutException
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.constants import ChatAction
|
||||
from telegram.ext import CommandHandler, CallbackContext
|
||||
from telegram.ext import CommandHandler, CallbackContext, CallbackQueryHandler
|
||||
from telegram.ext import MessageHandler, filters
|
||||
|
||||
from core.admin.services import BotAdminService
|
||||
@ -36,12 +36,16 @@ class SignRedis:
|
||||
qname = "plugin:sign:"
|
||||
|
||||
@staticmethod
|
||||
async def get(uid: int) -> Optional[bytes]:
|
||||
return await SignRedis.client.get(f"{SignRedis.qname}{uid}")
|
||||
async def get(uid: int) -> Tuple[Optional[str], Optional[str]]:
|
||||
data = await SignRedis.client.get(f"{SignRedis.qname}{uid}")
|
||||
if not data:
|
||||
return None, None
|
||||
data = data.decode("utf-8").split("|")
|
||||
return data[0], data[1]
|
||||
|
||||
@staticmethod
|
||||
async def set(uid: int, challenge: str):
|
||||
await SignRedis.client.set(f"{SignRedis.qname}{uid}", challenge)
|
||||
async def set(uid: int, gt: str, challenge: str):
|
||||
await SignRedis.client.set(f"{SignRedis.qname}{uid}", f"{gt}|{challenge}")
|
||||
await SignRedis.client.expire(f"{SignRedis.qname}{uid}", 10 * 60)
|
||||
|
||||
|
||||
@ -170,25 +174,33 @@ class Sign(Plugin, BasePlugin):
|
||||
|
||||
@staticmethod
|
||||
async def gen_challenge_header(uid: int, validate: str) -> Optional[Dict]:
|
||||
challenge = await SignRedis.get(uid)
|
||||
_, challenge = await SignRedis.get(uid)
|
||||
if not challenge or not validate:
|
||||
return
|
||||
return {
|
||||
"x-rpc-challenge": challenge.decode("utf-8"),
|
||||
"x-rpc-challenge": challenge,
|
||||
"x-rpc-validate": validate,
|
||||
"x-rpc-seccode": f"{validate}|jordan",
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
async def gen_challenge_button(uid: int, gt: str, challenge: str):
|
||||
async def gen_challenge_button(uid: int, user_id: int, gt: str = None, challenge: str = None):
|
||||
if not config.pass_challenge_user_web:
|
||||
return None
|
||||
await SignRedis.set(uid, challenge)
|
||||
if gt and challenge:
|
||||
await SignRedis.set(uid, gt, challenge)
|
||||
data = f"sign|{user_id}|{uid}"
|
||||
return InlineKeyboardMarkup([[InlineKeyboardButton("请尽快点我进行手动验证", callback_data=data)]])
|
||||
gt, challenge = await SignRedis.get(uid)
|
||||
if not gt or not challenge:
|
||||
return
|
||||
url = f"{config.pass_challenge_user_web}?username={bot.app.bot.username}>={gt}&challenge={challenge}"
|
||||
return InlineKeyboardMarkup([[InlineKeyboardButton("请尽快点我进行手动验证", url=url)]])
|
||||
|
||||
@staticmethod
|
||||
async def start_sign(client: Client, headers: Dict = None) -> Tuple[str, Optional[InlineKeyboardMarkup]]:
|
||||
async def start_sign(
|
||||
client: Client, user_id: int, headers: Dict = None
|
||||
) -> Tuple[str, Optional[InlineKeyboardMarkup]]:
|
||||
try:
|
||||
rewards = await client.get_monthly_rewards(game=Game.GENSHIN, lang="zh-cn")
|
||||
except GenshinException as error:
|
||||
@ -223,6 +235,7 @@ class Sign(Plugin, BasePlugin):
|
||||
if request_daily_reward and request_daily_reward.get("success", 0) == 1:
|
||||
button = await Sign.gen_challenge_button(
|
||||
client.uid,
|
||||
user_id,
|
||||
request_daily_reward.get("gt", ""),
|
||||
request_daily_reward.get("challenge", ""),
|
||||
)
|
||||
@ -324,7 +337,7 @@ class Sign(Plugin, BasePlugin):
|
||||
client = await get_genshin_client(user.id)
|
||||
headers = await Sign.gen_challenge_header(client.uid, validate)
|
||||
await message.reply_chat_action(ChatAction.TYPING)
|
||||
sign_text, button = await self.start_sign(client, headers)
|
||||
sign_text, button = await self.start_sign(client, user.id, headers)
|
||||
reply_message = await message.reply_text(sign_text, allow_sending_without_reply=True, reply_markup=button)
|
||||
if filters.ChatType.GROUPS.filter(reply_message):
|
||||
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
|
||||
@ -339,3 +352,28 @@ class Sign(Plugin, BasePlugin):
|
||||
self._add_delete_message_job(context, message.chat_id, message.message_id, 30)
|
||||
else:
|
||||
await message.reply_text("未查询到您所绑定的账号信息,请先绑定账号", reply_markup=InlineKeyboardMarkup(buttons))
|
||||
|
||||
@handler(CallbackQueryHandler, pattern=r"^sign\|", block=False)
|
||||
@restricts(restricts_time_of_groups=20, without_overlapping=True)
|
||||
@error_callable
|
||||
async def sign_gen_link(self, update: Update, _: CallbackContext) -> None:
|
||||
callback_query = update.callback_query
|
||||
user = callback_query.from_user
|
||||
|
||||
async def get_sign_callback(callback_query_data: str) -> Tuple[int, int]:
|
||||
_data = callback_query_data.split("|")
|
||||
_user_id = int(_data[1])
|
||||
_uid = int(_data[2])
|
||||
logger.debug(f"callback_query_data 函数返回 user_id[{_user_id}] uid[{_uid}]")
|
||||
return _user_id, _uid
|
||||
|
||||
user_id, uid = await get_sign_callback(callback_query.data)
|
||||
if user.id != user_id:
|
||||
await callback_query.answer(text="这不是你的按钮!\n再乱点再按我叫西风骑士团、千岩军、天领奉行和教令院了!", show_alert=True)
|
||||
return
|
||||
challenge = await SignRedis.get(uid)
|
||||
if not challenge:
|
||||
await callback_query.answer(text="验证请求已经过期,请重新发起签到!", show_alert=True)
|
||||
return
|
||||
url = f"t.me/{bot.app.bot.username}?start=sign"
|
||||
await callback_query.answer(url=url)
|
||||
|
@ -36,6 +36,8 @@ class StartPlugin(Plugin):
|
||||
f"你好 {user.mention_markdown_v2()} {escape_markdown('!我是派蒙 !')}\n"
|
||||
f"{escape_markdown('发送 /setuid 或 /setcookie 命令进入绑定账号流程')}"
|
||||
)
|
||||
elif args[0] == "sign":
|
||||
await StartPlugin.gen_sign_button(update)
|
||||
elif args[0].startswith("challenge_"):
|
||||
await StartPlugin.process_sign_validate(update, args[0][10:])
|
||||
else:
|
||||
@ -43,6 +45,19 @@ class StartPlugin(Plugin):
|
||||
return
|
||||
await message.reply_markdown_v2(f"你好 {user.mention_markdown_v2()} {escape_markdown('!我是派蒙 !')}")
|
||||
|
||||
@staticmethod
|
||||
async def gen_sign_button(update: Update):
|
||||
with contextlib.suppress(UserNotFoundError, CookiesNotFoundError):
|
||||
client = await get_genshin_client(update.effective_user.id)
|
||||
await update.effective_message.reply_chat_action(ChatAction.TYPING)
|
||||
button = await Sign.gen_challenge_button(client.uid, update.effective_user.id)
|
||||
if not button:
|
||||
await update.effective_message.reply_text("验证请求已过期。", allow_sending_without_reply=True)
|
||||
return
|
||||
await update.effective_message.reply_text(
|
||||
"请尽快点击下方按钮进行验证。", allow_sending_without_reply=True, reply_markup=button
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
async def process_sign_validate(update: Update, validate: str):
|
||||
with contextlib.suppress(UserNotFoundError, CookiesNotFoundError):
|
||||
@ -52,7 +67,7 @@ class StartPlugin(Plugin):
|
||||
if not headers:
|
||||
await update.effective_message.reply_text("验证请求已过期。", allow_sending_without_reply=True)
|
||||
return
|
||||
sign_text, button = await Sign.start_sign(client, headers)
|
||||
sign_text, button = await Sign.start_sign(client, update.effective_user.id, headers)
|
||||
await update.effective_message.reply_text(sign_text, allow_sending_without_reply=True, reply_markup=button)
|
||||
|
||||
@staticmethod
|
||||
|
Loading…
Reference in New Issue
Block a user