43 lines
1.5 KiB
Python
43 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Provision a password for Alfred's local admin pages (never in shell history)."""
|
|
import getpass
|
|
import json
|
|
import os
|
|
import secrets
|
|
from pathlib import Path
|
|
from werkzeug.security import generate_password_hash
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
AUTH_FILE = ROOT / 'config' / 'admin_auth.json'
|
|
SECRET_FILE = ROOT / 'config' / 'admin_secret.key'
|
|
|
|
|
|
def atomic_bytes(path, content):
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
temp = path.with_name(path.name + '.tmp')
|
|
fd = os.open(temp, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
|
try:
|
|
with os.fdopen(fd, 'wb') as stream:
|
|
stream.write(content)
|
|
stream.flush()
|
|
os.fsync(stream.fileno())
|
|
os.replace(temp, path)
|
|
os.chmod(path, 0o600)
|
|
finally:
|
|
temp.unlink(missing_ok=True)
|
|
|
|
|
|
def main():
|
|
if not SECRET_FILE.exists():
|
|
atomic_bytes(SECRET_FILE, secrets.token_bytes(32))
|
|
password = getpass.getpass('Nouveau mot de passe administrateur Alfred : ')
|
|
confirm = getpass.getpass('Confirmer le mot de passe : ')
|
|
if password != confirm or len(password) < 12:
|
|
raise SystemExit('Mot de passe non confirmé ou inférieur à 12 caractères.')
|
|
encoded = json.dumps({'password_hash': generate_password_hash(password, method='scrypt')}).encode('utf-8')
|
|
atomic_bytes(AUTH_FILE, encoded)
|
|
print('Mot de passe administrateur enregistré. Les anciennes sessions sont invalidées.')
|
|
|
|
if __name__ == '__main__':
|
|
main()
|