Admin login pasword changes
This commit is contained in:
@@ -53,7 +53,7 @@ AUTH_LOCKOUT_SECONDS=300
|
||||
# convenience: it skips the password check entirely, so any username signs in
|
||||
# and `admin` gets the admin pages. On a host published to the internet it means
|
||||
# anyone who finds mcp.nearle.ai.in signs in as admin by typing anything at all.
|
||||
AUTH_ALLOW_ANY_LOGIN=true
|
||||
AUTH_ALLOW_ANY_LOGIN=false
|
||||
|
||||
# Machine consumers. Empty: MCP clients authenticate with a login token instead.
|
||||
API_KEYS=
|
||||
|
||||
@@ -127,6 +127,7 @@ def verify_password(password: str, encoded: str) -> bool:
|
||||
"""
|
||||
if not encoded:
|
||||
return False
|
||||
encoded = encoded.strip().strip("'\"")
|
||||
try:
|
||||
prefix, raw_iterations, raw_salt, raw_digest = encoded.split("$")
|
||||
if prefix != _PBKDF2_PREFIX:
|
||||
|
||||
@@ -290,20 +290,20 @@ AUTH_TOKEN_TTL_MINUTES = int(os.getenv("AUTH_TOKEN_TTL_MINUTES", "720"))
|
||||
# `make_auth_secrets.py` prints the lines ready to paste.
|
||||
#
|
||||
# `admin` is required whenever auth is on: without it nobody could sign in.
|
||||
AUTH_ADMIN_USERNAME = os.getenv("AUTH_ADMIN_USERNAME", "admin")
|
||||
AUTH_ADMIN_USERNAME = os.getenv("AUTH_ADMIN_USERNAME", "admin").strip().strip("'\"")
|
||||
AUTH_ADMIN_PASSWORD_HASH = (
|
||||
_require("AUTH_ADMIN_PASSWORD_HASH", feature_flag="AUTH_ENABLED")
|
||||
if AUTH_ENABLED
|
||||
else os.getenv("AUTH_ADMIN_PASSWORD_HASH", "")
|
||||
)
|
||||
).strip().strip("'\"")
|
||||
|
||||
# The second `user` account is OPTIONAL, and left unset in this deployment.
|
||||
# An empty hash is how the account is switched off: auth.py builds its account
|
||||
# table from these values and omits any entry whose hash is blank, so there is
|
||||
# nothing to sign in to. Setting the hash again re-enables it with no code
|
||||
# change - which is exactly what the test suite does in tests/conftest.py.
|
||||
AUTH_USER_USERNAME = os.getenv("AUTH_USER_USERNAME", "user")
|
||||
AUTH_USER_PASSWORD_HASH = os.getenv("AUTH_USER_PASSWORD_HASH", "")
|
||||
AUTH_USER_USERNAME = os.getenv("AUTH_USER_USERNAME", "user").strip().strip("'\"")
|
||||
AUTH_USER_PASSWORD_HASH = os.getenv("AUTH_USER_PASSWORD_HASH", "").strip().strip("'\"")
|
||||
|
||||
# Failed-login throttle, applied per username+client-IP. Prevents an exposed
|
||||
# login endpoint from being a free password oracle.
|
||||
|
||||
@@ -6,6 +6,9 @@ from dotenv import load_dotenv
|
||||
load_dotenv(Path(__file__).parent / ".env", override=True)
|
||||
|
||||
def verify_password(password, encoded):
|
||||
if not encoded:
|
||||
return False
|
||||
encoded = encoded.strip().strip("'\"")
|
||||
try:
|
||||
prefix, raw_iters, raw_salt, raw_digest = encoded.split("$")
|
||||
if prefix != "pbkdf2_sha256":
|
||||
@@ -18,20 +21,23 @@ def verify_password(password, encoded):
|
||||
candidate = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, iterations)
|
||||
return hmac.compare_digest(candidate, expected)
|
||||
|
||||
admin_hash = os.environ["AUTH_ADMIN_PASSWORD_HASH"]
|
||||
user_hash = os.environ["AUTH_USER_PASSWORD_HASH"]
|
||||
admin_hash = os.environ.get("AUTH_ADMIN_PASSWORD_HASH", "").strip().strip("'\"")
|
||||
user_hash = os.environ.get("AUTH_USER_PASSWORD_HASH", "").strip().strip("'\"")
|
||||
|
||||
print(f"Admin hash prefix: {admin_hash[:20]!r}")
|
||||
print(f"User hash prefix: {user_hash[:20]!r}")
|
||||
|
||||
ok1 = verify_password("DevAdmin!2026", admin_hash)
|
||||
ok2 = verify_password("DevUser!2026", user_hash)
|
||||
ok1 = verify_password("admin123", admin_hash)
|
||||
ok2 = verify_password("DevUser!2026", user_hash) if user_hash else True
|
||||
|
||||
print(f"Admin password verify: {ok1}")
|
||||
print(f"User password verify: {ok2}")
|
||||
print(f"Admin password ('admin123') verify: {ok1}")
|
||||
if user_hash:
|
||||
print(f"User password ('DevUser!2026') verify: {ok2}")
|
||||
else:
|
||||
print("User account is optional / unset.")
|
||||
|
||||
if ok1 and ok2:
|
||||
print("\nSUCCESS - both passwords verify. Login will work.")
|
||||
print("\nSUCCESS - admin password verifies cleanly. Login will work.")
|
||||
else:
|
||||
print("\nFAILURE - one or both passwords do NOT verify.")
|
||||
print("\nFAILURE - password verification failed.")
|
||||
exit(1)
|
||||
|
||||
@@ -70,6 +70,7 @@ os.environ["ACTIVE_BRANDS"] = ""
|
||||
# Auth is set unconditionally (not setdefault): the suite asserts on the real
|
||||
# guards, so it must never inherit a developer's AUTH_ENABLED=false.
|
||||
os.environ["AUTH_ENABLED"] = "true"
|
||||
os.environ["AUTH_ALLOW_ANY_LOGIN"] = "false"
|
||||
os.environ["AUTH_SECRET_KEY"] = "test-secret-key-not-for-production-use-at-all"
|
||||
os.environ["AUTH_ADMIN_USERNAME"] = "admin"
|
||||
os.environ["AUTH_ADMIN_PASSWORD_HASH"] = _hash(TEST_ADMIN_PASSWORD)
|
||||
|
||||
Reference in New Issue
Block a user