From f31239b08d56df1448c1a2aadfafa1a1558eeab4 Mon Sep 17 00:00:00 2001 From: Roger Curley Date: Tue, 1 Oct 2024 13:57:53 -0400 Subject: [PATCH] Add auth.py --- .gitignore | 2 +- src/auth.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/auth.py diff --git a/.gitignore b/.gitignore index ef72178..32f7606 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ __pycache__ *.epub -cookie +creds.json diff --git a/src/auth.py b/src/auth.py new file mode 100644 index 0000000..b12f11b --- /dev/null +++ b/src/auth.py @@ -0,0 +1,82 @@ +import aiohttp +import os +import asyncio +from getpass import getpass +from bs4 import BeautifulSoup +from urllib.parse import urljoin +import json + +# TODO: use this +# from .render import GLOWFIC_ROOT + +GLOWFIC_ROOT = "https://glowfic.com" +# TODO: import this +COOKIE_NAME = "_glowfic_constellation_production" + + +async def main(): + async with aiohttp.ClientSession() as session: + await login(session) + resp = await session.get("https://www.glowfic.com/api/v1/posts/6755") + text = await resp.text() + print(text) + + +def get_creds(): + if os.path.exists("creds.json"): + with open("creds.json", "r") as fin: + d = json.load(fin) + return (d["username"], d["password"]) + username = input("Username: ") + password = getpass() + save_str = input("Save credentials to file? [y/N]") + save = save_str.lower() in ["y", "yes", "true"] + if save: + print("Saving to creds.json") + d = {"username": username, "password": password} + with open("creds.json", "w") as f: + json.dump(d, f) + return (username, password) + + +async def login(session): + # Set cookie for non-API endpoints + authenticity_token = await get_authenticity_token(session) + (username, password) = get_creds() + payload = { + "username": username, + "password": password, + "authenticity_token": authenticity_token, + "commit": "Log+in", + } + url = urljoin(GLOWFIC_ROOT, "login") + resp = await session.post(url, data=payload) + found_cookie = False + for cookie in session.cookie_jar: + found_cookie |= cookie.key == COOKIE_NAME + if not found_cookie: + raise ValueError("Cookie not found after login") + api_login_url = urljoin(GLOWFIC_ROOT, "/api/v1/login") + payload = { + "username": username, + "password": password, + } + async with session.post(api_login_url, params=payload) as resp: + token_json = await resp.json() + try: + token = token_json["token"] + except KeyError: + print(token_json) + raise + session.headers["Authorization"] = "Bearer %s" % token + + +async def get_authenticity_token(session): + async with session.get(GLOWFIC_ROOT) as resp: + soup = BeautifulSoup(await resp.text(), "html.parser") + form = soup.find("form", id="header-form") + authenticity_token = form.find("input", attrs={"name": "authenticity_token"}) + return authenticity_token.attrs["value"] + + +asyncio.run(main())