Remove project OAuth hardcodes
This commit is contained in:
+44
-13
@@ -43,7 +43,7 @@ VK_OAUTH_VERIFIER_COOKIE = "vk_oauth_verifier"
|
||||
VK_OAUTH_STATE_COOKIE = "vk_oauth_state"
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
PROJECT_ROOT = BASE_DIR.parents[1]
|
||||
FAVICON_PATH = PROJECT_ROOT / "favi.png"
|
||||
FAVICON_PATH = Path(settings.admin_favicon_path).resolve() if settings.admin_favicon_path.strip() else PROJECT_ROOT / "favi.png"
|
||||
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
|
||||
app = FastAPI(title=settings.display_site_title)
|
||||
LOCAL_TZ = ZoneInfo("Asia/Yekaterinburg")
|
||||
@@ -54,6 +54,22 @@ EDITOR_MEDIA_DIR.mkdir(parents=True, exist_ok=True)
|
||||
app.mount("/uploads", StaticFiles(directory=str(UPLOAD_ROOT)), name="uploads")
|
||||
|
||||
|
||||
def public_origin(request: Request) -> str:
|
||||
configured = settings.vk_oauth_origin.strip().rstrip("/")
|
||||
if configured:
|
||||
return configured
|
||||
proto = request.headers.get("x-forwarded-proto") or request.url.scheme
|
||||
host = request.headers.get("x-forwarded-host") or request.headers.get("host") or request.url.netloc
|
||||
return f"{proto}://{host}".rstrip("/")
|
||||
|
||||
|
||||
def oauth_redirect_uri(request: Request, path: str) -> str:
|
||||
configured = settings.vk_oauth_redirect_uri.strip()
|
||||
if configured and path == "/vk-oauth/callback":
|
||||
return configured
|
||||
return f"{public_origin(request)}{path}"
|
||||
|
||||
|
||||
@app.get("/favi.png")
|
||||
async def favicon_png():
|
||||
return FileResponse(FAVICON_PATH)
|
||||
@@ -882,7 +898,15 @@ def parse_source_line(line: str) -> dict[str, str]:
|
||||
if not raw:
|
||||
return {"name": "", "tag": "", "url": "", "error": "Пустая строка"}
|
||||
parts = re.split(r"\s+", raw)
|
||||
url_index = next((i for i, part in enumerate(parts) if "vk.com/" in part or part.startswith("club")), -1)
|
||||
url_index = next(
|
||||
(
|
||||
i
|
||||
for i, part in enumerate(parts)
|
||||
if any(domain in part for domain in ("vk.com/", "vk.ru/", "m.vk.com/"))
|
||||
or part.lower().startswith(("club", "public"))
|
||||
),
|
||||
-1,
|
||||
)
|
||||
if url_index < 0:
|
||||
if len(parts) == 1:
|
||||
value = parts[0].strip()
|
||||
@@ -900,8 +924,9 @@ def parse_source_line(line: str) -> dict[str, str]:
|
||||
else:
|
||||
name = ""
|
||||
tag = ""
|
||||
if url.startswith("vk.com/"):
|
||||
if url.startswith(("vk.com/", "vk.ru/", "m.vk.com/")):
|
||||
url = f"https://{url}"
|
||||
url = url.replace("https://vk.ru/", "https://vk.com/", 1).replace("https://m.vk.com/", "https://vk.com/", 1)
|
||||
return {"name": name, "tag": normalize_hash_tag(tag, ""), "url": url, "error": ""}
|
||||
|
||||
|
||||
@@ -1757,19 +1782,22 @@ async def vk_oauth_callback(request: Request, code: str = "", error: str = "", e
|
||||
|
||||
|
||||
@app.get("/vk/oauth/start")
|
||||
async def vk_oauth_start() -> RedirectResponse:
|
||||
async def vk_oauth_start(request: Request) -> RedirectResponse:
|
||||
client_id = settings.vk_oauth_client_id.strip() or str(await fetch_setting("vk_poster_app_id", "") or "").strip()
|
||||
if not client_id:
|
||||
return redirect("/workers")
|
||||
verifier = secrets.token_urlsafe(64)
|
||||
state = secrets.token_urlsafe(24)
|
||||
redirect_uri = "https://sw.exostring.xyz/vk/oauth/callback"
|
||||
redirect_uri = oauth_redirect_uri(request, "/vk/oauth/callback")
|
||||
params = {
|
||||
"client_id": "54635120",
|
||||
"client_id": client_id,
|
||||
"redirect_uri": redirect_uri,
|
||||
"response_type": "code",
|
||||
"scope": "wall photos video groups offline",
|
||||
"state": state,
|
||||
"code_challenge": pkce_challenge(verifier),
|
||||
"code_challenge_method": "s256",
|
||||
"origin": "https://sw.exostring.xyz",
|
||||
"origin": public_origin(request),
|
||||
"v": "5.199",
|
||||
}
|
||||
response = RedirectResponse(f"https://id.vk.ru/authorize?{urlencode(params)}")
|
||||
@@ -1779,13 +1807,16 @@ async def vk_oauth_start() -> RedirectResponse:
|
||||
|
||||
|
||||
@app.get("/vk/group-oauth/start")
|
||||
async def vk_group_oauth_start() -> RedirectResponse:
|
||||
async def vk_group_oauth_start(request: Request) -> RedirectResponse:
|
||||
client_id = settings.vk_oauth_client_id.strip() or str(await fetch_setting("vk_poster_app_id", "") or "").strip()
|
||||
if not client_id:
|
||||
return redirect("/workers")
|
||||
group_id = abs(int(settings.vk_storage_group_id))
|
||||
params = {
|
||||
"client_id": "54635120",
|
||||
"client_id": client_id,
|
||||
"group_ids": str(group_id),
|
||||
"display": "page",
|
||||
"redirect_uri": "https://sw.exostring.xyz/vk/oauth/callback",
|
||||
"redirect_uri": oauth_redirect_uri(request, "/vk/oauth/callback"),
|
||||
"scope": "manage,photos,docs",
|
||||
"response_type": "token",
|
||||
"state": secrets.token_urlsafe(24),
|
||||
@@ -1804,7 +1835,7 @@ async def vk_poster_oauth_start(request: Request) -> RedirectResponse:
|
||||
return redirect("/workers")
|
||||
verifier = secrets.token_urlsafe(64)
|
||||
state = secrets.token_urlsafe(24)
|
||||
redirect_uri = "https://sw.exostring.xyz/vk-oauth/callback"
|
||||
redirect_uri = oauth_redirect_uri(request, "/vk-oauth/callback")
|
||||
params = {
|
||||
"client_id": client_id,
|
||||
"redirect_uri": redirect_uri,
|
||||
@@ -1813,7 +1844,7 @@ async def vk_poster_oauth_start(request: Request) -> RedirectResponse:
|
||||
"state": state,
|
||||
"code_challenge": pkce_challenge(verifier),
|
||||
"code_challenge_method": "s256",
|
||||
"origin": "https://sw.exostring.xyz",
|
||||
"origin": public_origin(request),
|
||||
"v": "5.199",
|
||||
}
|
||||
response = RedirectResponse(f"https://id.vk.ru/authorize?{urlencode(params)}")
|
||||
@@ -1850,7 +1881,7 @@ async def vk_poster_oauth_callback(
|
||||
client_id = str(await fetch_setting("vk_poster_app_id", "") or "").strip()
|
||||
client_secret = str(await fetch_setting("vk_poster_client_secret", "") or "").strip()
|
||||
owner_id = int(await fetch_int_setting("vk_poster_owner_id", 0))
|
||||
redirect_uri = "https://sw.exostring.xyz/vk-oauth/callback"
|
||||
redirect_uri = oauth_redirect_uri(request, "/vk-oauth/callback")
|
||||
code_verifier = request.cookies.get(VK_OAUTH_VERIFIER_COOKIE, "")
|
||||
device_id = request.query_params.get("device_id", "")
|
||||
try:
|
||||
|
||||
@@ -8,6 +8,7 @@ class Settings(BaseSettings):
|
||||
app_secret_key: str = "change-me"
|
||||
admin_site_title: str = ""
|
||||
admin_app_title: str = "Редакторская"
|
||||
admin_favicon_path: str = ""
|
||||
admin_bootstrap_login: str = "admin"
|
||||
admin_bootstrap_password: str = ""
|
||||
|
||||
@@ -21,6 +22,9 @@ class Settings(BaseSettings):
|
||||
vk_group_access_token: str = ""
|
||||
vk_api_version: str = "5.199"
|
||||
vk_storage_group_id: int = 0
|
||||
vk_oauth_client_id: str = ""
|
||||
vk_oauth_redirect_uri: str = ""
|
||||
vk_oauth_origin: str = ""
|
||||
|
||||
tg_bot_token: str = ""
|
||||
tg_media_channel_id: str = ""
|
||||
|
||||
@@ -393,4 +393,22 @@
|
||||
</details>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<script>
|
||||
(() => {
|
||||
const scrollKey = "workers-scroll-y";
|
||||
const restoreY = sessionStorage.getItem(scrollKey);
|
||||
if (restoreY !== null) {
|
||||
sessionStorage.removeItem(scrollKey);
|
||||
requestAnimationFrame(() => window.scrollTo(0, Number(restoreY) || 0));
|
||||
}
|
||||
document.addEventListener("submit", (event) => {
|
||||
const form = event.target;
|
||||
if (!(form instanceof HTMLFormElement)) return;
|
||||
const action = form.getAttribute("action") || "";
|
||||
if (action.startsWith("/workers") || action.startsWith("/settings") || action.includes("-schedule/")) {
|
||||
sessionStorage.setItem(scrollKey, String(window.scrollY));
|
||||
}
|
||||
}, true);
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -192,8 +192,10 @@ def normalize_vk_source(value: str) -> str:
|
||||
raw = str(value or "").strip()
|
||||
if not raw:
|
||||
return ""
|
||||
if "vk.com" in raw:
|
||||
raw = raw.split("vk.com", 1)[1]
|
||||
for host in ("vk.com", "vk.ru", "m.vk.com"):
|
||||
if host in raw:
|
||||
raw = raw.split(host, 1)[1]
|
||||
break
|
||||
raw = raw.lstrip("/")
|
||||
raw = raw.split("?", 1)[0].split("#", 1)[0].strip()
|
||||
raw = re.sub(r"^(club|public)", "", raw, flags=re.IGNORECASE)
|
||||
|
||||
Reference in New Issue
Block a user