62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from yuxi.channel.extensions.googlechat.api import send_message
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
_PARING_CODE_LENGTH = 6
|
|
|
|
_pairing_store: dict[str, dict] = {}
|
|
|
|
|
|
class GoogleChatPairingAdapter:
|
|
id_label = "Google Chat User ID"
|
|
|
|
def normalize_allow_entry(self, entry: str) -> str:
|
|
for prefix in ("googlechat:", "google-chat:", "gchat:"):
|
|
if entry.lower().startswith(prefix):
|
|
entry = entry[len(prefix):]
|
|
break
|
|
return entry.lower()
|
|
|
|
async def generate_code(self, peer_id: str) -> str:
|
|
import random
|
|
import string
|
|
|
|
code = "".join(random.choices(string.ascii_uppercase + string.digits, k=_PARING_CODE_LENGTH))
|
|
_pairing_store[peer_id] = {
|
|
"code": code,
|
|
"status": "pending",
|
|
}
|
|
return code
|
|
|
|
async def verify_code(self, peer_id: str, code: str) -> bool:
|
|
stored = _pairing_store.get(peer_id)
|
|
if stored and stored.get("code") == code:
|
|
stored["status"] = "verified"
|
|
return True
|
|
return False
|
|
|
|
async def notify_approval(
|
|
self, config: dict, peer_id: str, account_id: str | None = None
|
|
) -> None:
|
|
logger.info("Pairing approved for peer: %s (account: %s)", peer_id, account_id)
|
|
|
|
async def send_pairing_challenge(
|
|
self, account, space_name: str, peer_id: str
|
|
) -> str:
|
|
code = await self.generate_code(peer_id)
|
|
text = (
|
|
f"🔒 *Access Request*\n\n"
|
|
f"Your user ID: `{peer_id}`\n"
|
|
f"Pairing code: `{code}`\n\n"
|
|
f"An administrator must approve this pairing request before you can interact with this bot."
|
|
)
|
|
result = await send_message(account, space_name, text)
|
|
return result.get("name", "")
|
|
|
|
def is_paired(self, peer_id: str) -> bool:
|
|
stored = _pairing_store.get(peer_id)
|
|
return stored is not None and stored.get("status") == "verified" |