"""Customer authentication for the local bank pentesting lab.""" import psycopg from database import database_layer class AuthBank: """Verify a claimed customer identity without exposing password hashes.""" def __init__(self, database: database_layer | None = None): """Accept a database dependency or construct the default PostgreSQL layer.""" self._database = database if database is not None else database_layer() def authenticate_customer(self, email: str, password: str) -> bool: """Return whether ``password`` belongs to the claimed customer. PostgreSQL's ``crypt`` hashes the candidate using the salt and cost embedded in the stored bcrypt hash. Database errors fail closed. """ # Reject malformed inputs before opening a database connection. if not isinstance(email, str) or not isinstance(password, str): return False email = email.strip() if ( not email or len(email) > 320 or not password or len(password.encode("utf-8")) > 72 ): return False try: return self._database.verify_customer_credentials(email, password) except psycopg.Error: # Authentication fails closed when PostgreSQL is unavailable or errors. return False def authenticate_customer(email: str, password: str) -> bool: """Function-call-friendly wrapper returning only an approval boolean.""" return AuthBank().authenticate_customer(email, password)