V1
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user