🔒 Repository is read-only – file editing is disabled.

PaganLinux/pagan-web-v2/auth.py main

69 linii Raw ← Powrót
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
import hashlib, secrets, functools, os
from datetime import datetime, timedelta
from flask import request, redirect, session

def hash_password(password: str) -> str:
    """Bezpieczne hashowanie: PBKDF2-SHA256 z solą."""
    salt = secrets.token_hex(32)
    dk = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 600000)
    return f"pbkdf2:sha256:600000${salt}${dk.hex()}"

def verify_password(password: str, hash_: str) -> bool:
    if hash_.startswith("pbkdf2:sha256:"):
        # Format: pbkdf2:sha256:600000$SALT$DK_HEX
        try:
            meta, salt, stored = hash_.split("$", 2)
            _, _, iters_str = meta.split(":", 2)
            iters = int(iters_str)
            dk = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), iters)
            return secrets.compare_digest(dk.hex(), stored)
        except Exception:
            return False
    # Stary format (SHA256 plain) – automatyczna migracja przy logowaniu
    old = hashlib.sha256(password.encode()).hexdigest()
    if secrets.compare_digest(old, hash_):
        # Migruj do nowego formatu (tylko jeśli hash w DB to stary format)
        try:
            from database import get_db
            db = get_db()
            new_hash = hash_password(password)
            db.execute("UPDATE users SET password_hash=? WHERE password_hash=?", (new_hash, hash_))
            db.commit()
            db.close()
        except Exception:
            pass
        return True
    return False

def login_required(f):
    @functools.wraps(f)
    def wrap(*a, **kw):
        if not session.get("username"):
            return redirect("/login?next=" + request.path)
        return f(*a, **kw)
    return wrap

def build_auth_required(f):
    @functools.wraps(f)
    def wrap(*a, **kw):
        from config.settings import BUILD_PASSWORD
        if request.cookies.get("build_auth") != BUILD_PASSWORD:
            return redirect("/build/login")
        return f(*a, **kw)
    return wrap

def can_edit_repo(username, repo_name):
    if not username:
        return False
    from database import get_db
    db = get_db()
    row = db.execute("SELECT role FROM repo_permissions WHERE repo_name=? AND username=?",
                     (repo_name, username)).fetchone()
    db.close()
    return row is not None

def get_section():
    """Wykrywa aktywną sekcję na podstawie domeny."""
    host = request.host.split(":")[0]
    from config.settings import DOMAINS
    return DOMAINS.get(host, "main")