1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| def get_pin_and_cookie_name( app: WSGIApplication, ) -> tuple[] | tuple[]: """Given an application object this returns a semi-stable 9 digit pin code and a random key. The hope is that this is stable between restarts to not make debugging particularly frustrating. If the pin was forcefully disabled this returns `None`.
Second item in the resulting tuple is the cookie name for remembering. """ pin = os.environ.get("WERKZEUG_DEBUG_PIN") rv = None num = None
# Pin was explicitly disabled if pin == "off": return None, None
# Pin was provided explicitly if pin is not None and pin.replace("-", "").isdecimal(): # If there are separators in the pin, return it directly if "-" in pin: rv = pin else: num = pin
modname = getattr(app, "__module__", t.cast(object, app).__class__.__module__) username: str | None
try: # getuser imports the pwd module, which does not exist in Google # App Engine. It may also raise a KeyError if the UID does not # have a username, such as in Docker. username = getpass.getuser() except (ImportError, KeyError): username = None
mod = sys.modules.get(modname)
# This information only exists to make the cookie unique on the # computer, not as a security feature. probably_public_bits = [ username, modname, getattr(app, "__name__", type(app).__name__), getattr(mod, "__file__", None), ]
# This information is here to make it harder for an attacker to # guess the cookie name. They are unlikely to be contained anywhere # within the unauthenticated debug page. private_bits = []
h = hashlib.sha1() for bit in chain(probably_public_bits, private_bits): if not bit: continue if isinstance(bit, str): bit = bit.encode() h.update(bit) h.update(b"cookiesalt")
cookie_name = f"__wzd{h.hexdigest()[]}"
# If we need to generate a pin we salt it a bit more so that we don't # end up with the same value and generate out 9 digits if num is None: h.update(b"pinsalt") num = f"{int(h.hexdigest(), 16):09d}"[]
# Format the pincode in groups of digits for easier remembering if # we don't have a result yet. if rv is None: for group_size in 5, 4, 3: if len(num) % group_size == 0: rv = "-".join( num[].rjust(group_size, "0") for x in range(0, len(num), group_size) ) break else: rv = num
return rv, cookie_name
|