Initial release of the oVirt/RHV Engine API simulator.
Stateful FastAPI lab with contract packs, Compose/Helm, Docker Hub release targets, and Pulumi coverage across all Engine series (GET/POST/PUT/DELETE/HEAD).
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
"""Password hashing helpers for lab users."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import secrets
|
||||
|
||||
|
||||
def _b64(value: bytes) -> str:
|
||||
return base64.urlsafe_b64encode(value).rstrip(b"=").decode()
|
||||
|
||||
|
||||
def _unb64(value: str) -> bytes:
|
||||
return base64.urlsafe_b64decode(value + "=" * (-len(value) % 4))
|
||||
|
||||
|
||||
def hash_secret(secret: str, *, salt: bytes | None = None) -> str:
|
||||
actual_salt = salt or secrets.token_bytes(16)
|
||||
digest = hashlib.scrypt(secret.encode(), salt=actual_salt, n=2**14, r=8, p=1, dklen=32)
|
||||
return f"scrypt$16384$8$1${_b64(actual_salt)}${_b64(digest)}"
|
||||
|
||||
|
||||
def verify_secret(secret: str, encoded: str) -> bool:
|
||||
try:
|
||||
algorithm, n, r, p, salt, expected = encoded.split("$")
|
||||
if algorithm != "scrypt":
|
||||
return False
|
||||
actual = hashlib.scrypt(
|
||||
secret.encode(), salt=_unb64(salt), n=int(n), r=int(r), p=int(p), dklen=32
|
||||
)
|
||||
return hmac.compare_digest(actual, _unb64(expected))
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
Reference in New Issue
Block a user