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

131 lines
4.6 KiB
Python

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)