aoc-2022/venv/Lib/site-packages/aocd/cookies.py

131 lines
4.6 KiB
Python
Raw Normal View History

import argparse
import glob
import json
import logging
import os
import sys
from termcolor import cprint
from aocd.exceptions import DeadTokenError
from aocd.models import AOCD_CONFIG_DIR
from aocd.utils import _ensure_intermediate_dirs
from aocd.utils import get_owner
log = logging.getLogger(__name__)
def get_working_tokens():
log.debug("checking for installation of browser-cookie3 package")
try:
import browser_cookie3 as bc3 # soft dependency
except ImportError:
sys.exit("To use this feature you must pip install browser-cookie3")
log.info("checking browser cookies storage for auth tokens, this might pop up an auth dialog!")
log.info("checking chrome cookie jar...")
cookie_files = glob.glob(os.path.expanduser("~/.config/google-chrome/*/Cookies")) + [None]
chrome_cookies = []
for cookie_file in cookie_files:
try:
chrome = bc3.chrome(cookie_file=cookie_file, domain_name=".adventofcode.com")
except Exception as err:
log.debug("Couldn't scrape chrome - %s: %s", type(err), err)
else:
chrome_cookies += [c for c in chrome if c.name == "session"]
log.info("%d candidates from chrome", len(chrome_cookies))
chrome = chrome_cookies
log.info("checking firefox cookie jar...")
try:
firefox = bc3.firefox(domain_name=".adventofcode.com")
except Exception as err:
log.debug("Couldn't scrape firefox - %s: %s", type(err), err)
firefox = []
else:
firefox = [c for c in firefox if c.name == "session"]
log.info("%d candidates from firefox", len(firefox))
# order preserving de-dupe
tokens = list({}.fromkeys([c.value for c in chrome + firefox]))
removed = len(chrome + firefox) - len(tokens)
if removed:
log.info("Removed %d duplicate%s", removed, "s"[:removed-1])
result = {} # map of {token: auth source}
for token in tokens:
try:
owner = get_owner(token)
except DeadTokenError:
pass
else:
result[token] = owner
return result
def scrape_session_tokens():
aocd_token_file = os.path.join(AOCD_CONFIG_DIR, "token")
aocd_tokens_file = os.path.join(AOCD_CONFIG_DIR, "tokens.json")
parser = argparse.ArgumentParser(description="Scrapes AoC session tokens from your browser's cookie storage")
parser.add_argument("-v", "--verbose", action="count", help="increased logging (may be specified multiple)")
parser.add_argument("-c", "--check", nargs="?", help="check existing token(s) and exit", const=True)
args = parser.parse_args()
if args.verbose is None:
log_level = logging.WARNING
elif args.verbose == 1:
log_level = logging.INFO
else:
log_level = logging.DEBUG
logging.basicConfig(level=log_level)
log.debug("called with %r", args)
if args.check is not None:
if args.check is True:
tokens = {}
if os.environ.get("AOC_SESSION"):
tokens["AOC_SESSION"] = os.environ["AOC_SESSION"]
if os.path.isfile(aocd_token_file):
with open(aocd_token_file) as f:
txt = f.read().strip()
if txt:
tokens[aocd_token_file] = txt.split()[0]
if os.path.isfile(aocd_tokens_file):
with open(aocd_tokens_file) as f:
tokens.update(json.load(f))
else:
tokens = {"CLI": args.check}
if not tokens:
sys.exit("no existing tokens found")
log.debug("%d tokens to check", len(tokens))
for name, token in tokens.items():
try:
owner = get_owner(token)
except DeadTokenError:
cprint("{} ({}) is dead".format(token, name), color="red")
else:
print("{} ({}) is alive".format(token, name))
if name != owner:
log.info("{} ({}) is owned by {}".format(token, name, owner))
sys.exit(0)
working = get_working_tokens()
if not working:
sys.exit("could not find any working tokens in browser cookies, sorry :(")
log.debug("found %d live tokens", len(working))
for cookie in working.items():
print("%s <- %s" % cookie)
if "AOC_SESSION" not in os.environ:
if not os.path.isfile(aocd_token_file):
if len(working) == 1:
[(token, auth_source)] = working.items()
_ensure_intermediate_dirs(aocd_token_file)
with open(aocd_token_file, "w") as f:
f.write(token)
log.info("wrote %s session to %s", auth_source, aocd_token_file)