Skip to content

Commit 1d07156

Browse files
Implement automatic cookie refreshing
1 parent f87113a commit 1d07156

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
lines changed

css-reports/app.py

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
from flask import Flask, request, send_file, jsonify, redirect
2-
from report import get_product_customisations
2+
from typing import Final, LiteralString
3+
from report import get_product_customisations, check_or_refresh_cookie
34
from datetime import datetime
5+
from apscheduler.schedulers.background import BackgroundScheduler # type: ignore[import-untyped]
6+
7+
48
import os
59
import re
610

11+
712
app = Flask("css-reports")
813

914

15+
TRUE_VALUES: Final[set[LiteralString]] = {"true", "1", "t", "y", "yes", "on"}
16+
17+
18+
persistent_organisations: dict[str, tuple[str, str]] = {}
19+
20+
21+
async def refresh_persistent_cookies() -> None:
22+
for org_id, (auth_cookie, _) in persistent_organisations.items():
23+
persistent_organisations[org_id] = (auth_cookie, await check_or_refresh_cookie(org_id, auth_cookie))
24+
25+
1026
@app.route("/")
1127
def hello():
1228
return redirect("https://cssbham.com", code=302)
@@ -28,9 +44,7 @@ async def fetch_customisation_report():
2844
product_names: str | None = request.args.get("product_names")
2945
start_date: str | None = request.args.get("start_date")
3046
end_date: str | None = request.args.get("end_date")
31-
32-
print(f"Organisation ID: {organisation_id}")
33-
print(f"Product Name: {product_name}")
47+
persist: str | None = request.args.get("persist")
3448

3549
if not auth_cookie or not organisation_id:
3650
return jsonify({"error": "An auth token and organisation id are required."}), 400
@@ -59,13 +73,27 @@ async def fetch_customisation_report():
5973
name_or_id: str = product_name or product_names # type: ignore[assignment]
6074
name_or_id = re.sub(r"\W\s", "", name_or_id)
6175

76+
prod_cookie: str
77+
78+
if persist and persist.lower().strip() in TRUE_VALUES:
79+
if organisation_id in persistent_organisations.keys():
80+
if persistent_organisations[organisation_id][0] != auth_cookie:
81+
return jsonify({"error": "Persistent auth cookie does not match existing one for this organisation ID."}), 400
82+
else:
83+
prod_cookie = persistent_organisations[organisation_id][1]
84+
else:
85+
persistent_organisations[organisation_id] = (auth_cookie, auth_cookie)
86+
prod_cookie = auth_cookie
87+
else:
88+
prod_cookie = auth_cookie
89+
6290
csv_file_path: str | None = None
6391

6492
try:
6593
# Generate the CSV file
6694
csv_file_path = await get_product_customisations(
6795
product_id_or_name=name_or_id,
68-
auth_cookie=auth_cookie,
96+
auth_cookie=prod_cookie,
6997
org_id=organisation_id,
7098
from_date_input=start_date_dt,
7199
to_date_input=end_date_dt,
@@ -91,3 +119,7 @@ async def fetch_customisation_report():
91119
if __name__ == "__main__":
92120
# from waitress import serve
93121
app.run(host="0.0.0.0", port=8000, debug=True)
122+
123+
scheduler = BackgroundScheduler()
124+
scheduler.add_job(refresh_persistent_cookies, trigger="interval", minutes=5)
125+
scheduler.start()

css-reports/report.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@
2929
ssl_context: ssl.SSLContext = ssl.create_default_context(cafile=certifi.where())
3030

3131

32+
async def check_or_refresh_cookie(org_id: str, auth_cookie: str) -> str:
33+
"""Queries the org page and the cookie will either be returned if valid or a new cookie returned."""
34+
async with (
35+
aiohttp.ClientSession(headers=BASE_HEADERS, cookies={".AspNet.SharedCookie": auth_cookie}) as session,
36+
session.get(f"https://www.guildofstudents.com/organisation/admin/{org_id}") as response,
37+
):
38+
await response.text()
39+
40+
returned_asp_cookie: Morsel[str] | None = response.cookies.get(
41+
".AspNet.SharedCookie"
42+
)
43+
44+
return returned_asp_cookie.value if returned_asp_cookie else auth_cookie
45+
46+
3247
async def get_msl_context(
3348
url: str, auth_cookie: str
3449
) -> tuple[dict[str, str], dict[str, str]]:

css-reports/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ aiohttp
44
beautifulsoup4
55
python-dotenv
66
waitress
7-
certifi
7+
certifi
8+
APScheduler

0 commit comments

Comments
 (0)