understanding commited on
Commit
8cbb291
·
verified ·
1 Parent(s): fa2ac4f

Create auth.py

Browse files
Files changed (1) hide show
  1. bot/integrations/auth.py +85 -0
bot/integrations/auth.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PATH: bot/integrations/auth.py
2
+ from __future__ import annotations
3
+
4
+ from typing import Any, Awaitable, Callable, Dict, Optional
5
+
6
+
7
+ # We KNOW cf_worker2 has is_allowed (your bot/core/auth.py already imports it),
8
+ # so we treat that as the primary source.
9
+ try:
10
+ from bot.integrations.cf_worker2 import is_allowed as _is_allowed # type: ignore
11
+ except Exception:
12
+ _is_allowed = None # type: ignore
13
+
14
+
15
+ # Optional admin helpers might exist in cf_worker2 (or cf_worker1 in some setups).
16
+ _allow_user: Optional[Callable[[int], Awaitable[Any]]] = None
17
+ _disallow_user: Optional[Callable[[int], Awaitable[Any]]] = None
18
+ _get_stats: Optional[Callable[[], Awaitable[Any]]] = None
19
+
20
+ for _modname in ("bot.integrations.cf_worker2", "bot.integrations.cf_worker1"):
21
+ try:
22
+ _mod = __import__(_modname, fromlist=["*"])
23
+ if _allow_user is None and hasattr(_mod, "allow_user"):
24
+ _allow_user = getattr(_mod, "allow_user")
25
+ if _disallow_user is None and hasattr(_mod, "disallow_user"):
26
+ _disallow_user = getattr(_mod, "disallow_user")
27
+ if _get_stats is None and hasattr(_mod, "get_stats"):
28
+ _get_stats = getattr(_mod, "get_stats")
29
+ except Exception:
30
+ continue
31
+
32
+
33
+ def _coerce_allowed(v: Any) -> bool:
34
+ if isinstance(v, bool):
35
+ return v
36
+ if isinstance(v, dict):
37
+ # common patterns from worker APIs
38
+ for k in ("allowed", "is_allowed", "result"):
39
+ if k in v:
40
+ return bool(v.get(k))
41
+ # sometimes {"ok": True} means allowed; sometimes not — be conservative
42
+ if "ok" in v and ("allowed" not in v and "is_allowed" not in v):
43
+ return bool(v.get("ok"))
44
+ return False
45
+ return bool(v)
46
+
47
+
48
+ async def is_allowed(uid: int) -> bool:
49
+ """Return True/False for allowlist check."""
50
+ if _is_allowed is None:
51
+ # If backend isn't available, default deny (owners/admins bypass in handlers anyway)
52
+ return False
53
+ out = await _is_allowed(uid) # may be bool or dict depending on your worker
54
+ return _coerce_allowed(out)
55
+
56
+
57
+ async def allow_user(uid: int) -> Dict[str, Any]:
58
+ """Admin: allow a user. Returns dict (ok/err)."""
59
+ if _allow_user is None:
60
+ return {"ok": False, "err": "allow_user_not_implemented"}
61
+ out = await _allow_user(uid)
62
+ return out if isinstance(out, dict) else {"ok": True}
63
+
64
+
65
+ async def disallow_user(uid: int) -> Dict[str, Any]:
66
+ """Admin: disallow a user. Returns dict (ok/err)."""
67
+ if _disallow_user is None:
68
+ return {"ok": False, "err": "disallow_user_not_implemented"}
69
+ out = await _disallow_user(uid)
70
+ return out if isinstance(out, dict) else {"ok": True}
71
+
72
+
73
+ async def get_stats() -> Dict[str, Any]:
74
+ """Admin: return stats dict used by /stats."""
75
+ if _get_stats is None:
76
+ # Keep handlers.py happy (it expects a dict)
77
+ return {
78
+ "ok": False,
79
+ "err": "stats_not_implemented",
80
+ "allowed_users": 0,
81
+ "profiles": 0,
82
+ "uploads_today": 0,
83
+ }
84
+ out = await _get_stats()
85
+ return out if isinstance(out, dict) else {"ok": True}