mirror of
https://github.com/PaiGramTeam/PaiGram.git
synced 2024-11-25 09:37:30 +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 httpx import AsyncClient, TimeoutException
|
||||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||||
from telegram.constants import ChatAction
|
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 telegram.ext import MessageHandler, filters
|
||||||
|
|
||||||
from core.admin.services import BotAdminService
|
from core.admin.services import BotAdminService
|
||||||
@ -36,12 +36,16 @@ class SignRedis:
|
|||||||
qname = "plugin:sign:"
|
qname = "plugin:sign:"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get(uid: int) -> Optional[bytes]:
|
async def get(uid: int) -> Tuple[Optional[str], Optional[str]]:
|
||||||
return await SignRedis.client.get(f"{SignRedis.qname}{uid}")
|
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
|
@staticmethod
|
||||||
async def set(uid: int, challenge: str):
|
async def set(uid: int, gt: str, challenge: str):
|
||||||
await SignRedis.client.set(f"{SignRedis.qname}{uid}", challenge)
|
await SignRedis.client.set(f"{SignRedis.qname}{uid}", f"{gt}|{challenge}")
|
||||||
await SignRedis.client.expire(f"{SignRedis.qname}{uid}", 10 * 60)
|
await SignRedis.client.expire(f"{SignRedis.qname}{uid}", 10 * 60)
|
||||||
|
|
||||||
|
|
||||||
@ -170,25 +174,33 @@ class Sign(Plugin, BasePlugin):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def gen_challenge_header(uid: int, validate: str) -> Optional[Dict]:
|
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:
|
if not challenge or not validate:
|
||||||
return
|
return
|
||||||
return {
|
return {
|
||||||
"x-rpc-challenge": challenge.decode("utf-8"),
|
"x-rpc-challenge": challenge,
|
||||||
"x-rpc-validate": validate,
|
"x-rpc-validate": validate,
|
||||||
"x-rpc-seccode": f"{validate}|jordan",
|
"x-rpc-seccode": f"{validate}|jordan",
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@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:
|
if not config.pass_challenge_user_web:
|
||||||
return None
|
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}"
|
url = f"{config.pass_challenge_user_web}?username={bot.app.bot.username}>={gt}&challenge={challenge}"
|
||||||
return InlineKeyboardMarkup([[InlineKeyboardButton("请尽快点我进行手动验证", url=url)]])
|
return InlineKeyboardMarkup([[InlineKeyboardButton("请尽快点我进行手动验证", url=url)]])
|
||||||
|
|
||||||
@staticmethod
|
@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:
|
try:
|
||||||
rewards = await client.get_monthly_rewards(game=Game.GENSHIN, lang="zh-cn")
|
rewards = await client.get_monthly_rewards(game=Game.GENSHIN, lang="zh-cn")
|
||||||
except GenshinException as error:
|
except GenshinException as error:
|
||||||
@ -223,6 +235,7 @@ class Sign(Plugin, BasePlugin):
|
|||||||
if request_daily_reward and request_daily_reward.get("success", 0) == 1:
|
if request_daily_reward and request_daily_reward.get("success", 0) == 1:
|
||||||
button = await Sign.gen_challenge_button(
|
button = await Sign.gen_challenge_button(
|
||||||
client.uid,
|
client.uid,
|
||||||
|
user_id,
|
||||||
request_daily_reward.get("gt", ""),
|
request_daily_reward.get("gt", ""),
|
||||||
request_daily_reward.get("challenge", ""),
|
request_daily_reward.get("challenge", ""),
|
||||||
)
|
)
|
||||||
@ -324,7 +337,7 @@ class Sign(Plugin, BasePlugin):
|
|||||||
client = await get_genshin_client(user.id)
|
client = await get_genshin_client(user.id)
|
||||||
headers = await Sign.gen_challenge_header(client.uid, validate)
|
headers = await Sign.gen_challenge_header(client.uid, validate)
|
||||||
await message.reply_chat_action(ChatAction.TYPING)
|
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)
|
reply_message = await message.reply_text(sign_text, allow_sending_without_reply=True, reply_markup=button)
|
||||||
if filters.ChatType.GROUPS.filter(reply_message):
|
if filters.ChatType.GROUPS.filter(reply_message):
|
||||||
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
|
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)
|
self._add_delete_message_job(context, message.chat_id, message.message_id, 30)
|
||||||
else:
|
else:
|
||||||
await message.reply_text("未查询到您所绑定的账号信息,请先绑定账号", reply_markup=InlineKeyboardMarkup(buttons))
|
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"你好 {user.mention_markdown_v2()} {escape_markdown('!我是派蒙 !')}\n"
|
||||||
f"{escape_markdown('发送 /setuid 或 /setcookie 命令进入绑定账号流程')}"
|
f"{escape_markdown('发送 /setuid 或 /setcookie 命令进入绑定账号流程')}"
|
||||||
)
|
)
|
||||||
|
elif args[0] == "sign":
|
||||||
|
await StartPlugin.gen_sign_button(update)
|
||||||
elif args[0].startswith("challenge_"):
|
elif args[0].startswith("challenge_"):
|
||||||
await StartPlugin.process_sign_validate(update, args[0][10:])
|
await StartPlugin.process_sign_validate(update, args[0][10:])
|
||||||
else:
|
else:
|
||||||
@ -43,6 +45,19 @@ class StartPlugin(Plugin):
|
|||||||
return
|
return
|
||||||
await message.reply_markdown_v2(f"你好 {user.mention_markdown_v2()} {escape_markdown('!我是派蒙 !')}")
|
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
|
@staticmethod
|
||||||
async def process_sign_validate(update: Update, validate: str):
|
async def process_sign_validate(update: Update, validate: str):
|
||||||
with contextlib.suppress(UserNotFoundError, CookiesNotFoundError):
|
with contextlib.suppress(UserNotFoundError, CookiesNotFoundError):
|
||||||
@ -52,7 +67,7 @@ class StartPlugin(Plugin):
|
|||||||
if not headers:
|
if not headers:
|
||||||
await update.effective_message.reply_text("验证请求已过期。", allow_sending_without_reply=True)
|
await update.effective_message.reply_text("验证请求已过期。", allow_sending_without_reply=True)
|
||||||
return
|
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)
|
await update.effective_message.reply_text(sign_text, allow_sending_without_reply=True, reply_markup=button)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
Loading…
Reference in New Issue
Block a user