ResetToken.hash(phrase) added avoiding code duplication.

This commit is contained in:
2026-02-10 22:56:49 +00:00
parent d41cffc03e
commit aef0e0cb44
+15 -15
View File
@@ -10,13 +10,8 @@ import uuid7
from msgspec import field from msgspec import field
from paskia import db from paskia import db
from paskia.util.hostutil import normalize_host from paskia.util import hostutil
from paskia.util.passphrase import ( from paskia.util import passphrase as passphrase_util
generate as generate_passphrase,
)
from paskia.util.passphrase import (
is_well_formed as _is_passphrase,
)
# Sentinel for uuid fields before they are set by create() or DB post init # Sentinel for uuid fields before they are set by create() or DB post init
_UUID_UNSET = UUID(int=0) _UUID_UNSET = UUID(int=0)
@@ -462,16 +457,21 @@ class ResetToken(msgspec.Struct, dict=True):
"""Store this reset token in the database. Must be called inside a transaction.""" """Store this reset token in the database. Must be called inside a transaction."""
db.data().reset_tokens[self.key] = self db.data().reset_tokens[self.key] = self
@classmethod @staticmethod
def by_passphrase(cls, passphrase: str) -> ResetToken | None: def hash(passphrase: str) -> bytes:
"""Get a reset token by passphrase.""" """Hash a passphrase to bytes for reset token storage."""
if not _is_passphrase(passphrase): if not passphrase_util.is_well_formed(passphrase):
raise ValueError( raise ValueError(
"Trying to reset with a session token in place of a passphrase" "Trying to reset with a session token in place of a passphrase"
if len(passphrase) == 16 if len(passphrase) == 16
else "Invalid passphrase format" else "Invalid passphrase format"
) )
key = hashlib.sha512(passphrase.encode()).digest()[:9] return hashlib.sha512(passphrase.encode()).digest()[:9]
@classmethod
def by_passphrase(cls, passphrase: str) -> ResetToken | None:
"""Get a reset token by passphrase."""
key = cls.hash(passphrase)
return db.data().reset_tokens.get(key) return db.data().reset_tokens.get(key)
@classmethod @classmethod
@@ -495,8 +495,8 @@ class ResetToken(msgspec.Struct, dict=True):
code to give to the user. code to give to the user.
""" """
if passphrase is None: if passphrase is None:
passphrase = generate_passphrase() passphrase = passphrase_util.generate()
key = hashlib.sha512(passphrase.encode()).digest()[:9] key = cls.hash(passphrase)
user_uuid = user if isinstance(user, UUID) else user.uuid user_uuid = user if isinstance(user, UUID) else user.uuid
token = cls( token = cls(
user_uuid=user_uuid, user_uuid=user_uuid,
@@ -584,7 +584,7 @@ class DB(msgspec.Struct, dict=True, omit_defaults=False):
return None return None
# Normalize host for comparison (stored hosts are already normalized) # Normalize host for comparison (stored hosts are already normalized)
normalized_input = normalize_host(host) normalized_input = hostutil.normalize_host(host)
# Validate host matches (sessions are always created with a host) # Validate host matches (sessions are always created with a host)
if s.host != normalized_input: if s.host != normalized_input: