Siste move før flytting

This commit is contained in:
Erol 2026-04-16 11:02:50 +02:00
parent c26f6e8f20
commit 1292fd0e20
3 changed files with 80 additions and 58 deletions

View file

@ -1,64 +1,82 @@
""" """
TEE OFF ADMIN GENERATOR v1.9 (DEBUG & BULLETPROOF) TEE OFF ADMIN GENERATOR
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
FUNKSJON: Genererer SQL-kommando for administrator. FUNKSJON: Oppretter eller erstatter administrator direkte i databasen uten
STATUS: Beholder TRUNCATE for feilsøking, men sikrer SQL-innsendingen. å skrive ut SQL, passordhash eller andre hemmeligheter.
STATUS: Nullstiller admins-tabellen og lager en ny 2FA-hemmelighet.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
""" """
import pyotp import asyncio
from passlib.hash import pbkdf2_sha256
import getpass import getpass
import sys import sys
def generate_admin(): import asyncpg
print("\n" + "="*50) import pyotp
print(" TEE OFF ADMIN GENERATOR v1.9 (DEBUG MODE)") from passlib.hash import pbkdf2_sha256
print("="*50)
from env_config import get_database_url
username = input("Brukernavn (f.eks Envide Webutvikling): ").strip()
DB_URL = get_database_url()
async def generate_admin() -> None:
print("\n" + "=" * 50)
print(" TEE OFF ADMIN GENERATOR")
print("=" * 50)
username = input("Brukernavn (f.eks Brukeren Leif): ").strip()
email = input("E-post: ").strip() email = input("E-post: ").strip()
# Sikre mot SQL-feil hvis navnet/eposten inneholder apostrof
safe_username = username.replace("'", "''")
safe_email = email.replace("'", "''")
# Passord-verifisering
while True: while True:
password = getpass.getpass("Skriv inn passord: ") password = getpass.getpass("Skriv inn passord: ")
password_confirm = getpass.getpass("Gjenta passord: ") password_confirm = getpass.getpass("Gjenta passord: ")
if password == password_confirm:
if len(password) < 8:
print("⚠️ Advarsel: Passordet bør være minst 8 tegn.")
print(f"\n[DEBUG] Passord akseptert. Lengde: {len(password)} tegn.")
break
else:
print("❌ Passordene er ikke like. Prøv igjen.\n")
otp_secret = pyotp.random_base32() if password != password_confirm:
print("❌ Passordene er ikke like. Prøv igjen.\n")
print("⏳ Genererer PBKDF2-hash...") continue
if len(password) < 8:
print("⚠️ Advarsel: Passordet bør være minst 8 tegn.")
break
password_hash = pbkdf2_sha256.hash(password) password_hash = pbkdf2_sha256.hash(password)
print(f"[DEBUG] Hash generert. Lengde: {len(password_hash)} tegn.") otp_secret = pyotp.random_base32()
print("\n✅ GENERERING VELLYKKET!") conn = None
try:
conn = await asyncpg.connect(DB_URL)
async with conn.transaction():
await conn.execute("TRUNCATE admins")
await conn.execute(
"""
INSERT INTO admins (username, email, password_hash, otp_secret)
VALUES ($1, $2, $3, $4)
""",
username,
email,
password_hash,
otp_secret,
)
except Exception as exc:
print(f"❌ Kunne ikke opprette admin-brukeren: {type(exc).__name__}")
sys.exit(1)
finally:
if conn is not None:
await conn.close()
print("\n✅ ADMIN BRUKER OPPRETTET")
print("-" * 50) print("-" * 50)
print("SLIK LEGGER DU INN BRUKEREN TRYGT:") print("Brukeren er lagret direkte i databasen.")
print("2FA-hemmeligheten vises nedenfor kun denne ene gangen.")
print("Lagre den i authenticator-appen din før du lukker terminalen.")
print("-" * 50) print("-" * 50)
print("1. Gå inn i databasen:") print(f"2FA-nøkkel: {otp_secret}")
print(" docker exec -it teeoff_db psql -U teeoff_admin -d teeoff")
print("\n2. Lim inn disse to linjene nøyaktig slik de står:")
print("TRUNCATE admins;")
print(f"INSERT INTO admins (username, email, password_hash, otp_secret) VALUES ('{safe_username}', '{safe_email}', '{password_hash}', '{otp_secret}');")
print("\n3. Skriv 'exit' for å gå ut.")
print("-" * 50)
print("4. KONFIGURER 2FA I GOOGLE AUTHENTICATOR:")
print(f"Bruk denne nøkkelen: {otp_secret}")
print("-" * 50 + "\n") print("-" * 50 + "\n")
if __name__ == "__main__": if __name__ == "__main__":
try: try:
generate_admin() asyncio.run(generate_admin())
except KeyboardInterrupt: except KeyboardInterrupt:
print("\nAvbrutt.") print("\nAvbrutt.")
sys.exit(0) sys.exit(0)

View file

@ -1,6 +1,7 @@
import asyncio import asyncio
import asyncpg import asyncpg
import os import os
import sys
from passlib.context import CryptContext from passlib.context import CryptContext
from env_config import get_database_url, get_required_env from env_config import get_database_url, get_required_env
@ -16,23 +17,23 @@ async def test_sannheten():
username = os.getenv("TEST_ADMIN_USERNAME", "Envide Webutvikling").strip() username = os.getenv("TEST_ADMIN_USERNAME", "Envide Webutvikling").strip()
test_password = get_required_env("TEST_ADMIN_PASSWORD") test_password = get_required_env("TEST_ADMIN_PASSWORD")
conn = None
try: try:
conn = await asyncpg.connect(DB_URL) conn = await asyncpg.connect(DB_URL)
row = await conn.fetchrow("SELECT password_hash FROM admins WHERE username = $1", username) row = await conn.fetchrow("SELECT password_hash FROM admins WHERE username = $1", username)
if not row: if not row:
print("❌ FEIL: Fant ikke brukeren i det hele tatt!") print("❌ FEIL: Fant ikke brukeren i det hele tatt!")
return return
db_hash = row['password_hash'] db_hash = row['password_hash']
print(f"1. Hash funnet i databasen: {db_hash[:30]}...") print("1. Hash funnet i databasen.")
print("2. Tester om oppgitt TEST_ADMIN_PASSWORD matcher.")
print(f"2. Tester mot passordet: '{test_password}'")
# Den magiske testen # Den magiske testen
is_valid = pwd_context.verify(test_password, db_hash) is_valid = pwd_context.verify(test_password, db_hash)
print("-" * 50) print("-" * 50)
if is_valid: if is_valid:
print("✅ SUKSESS! Passordet og hashen stemmer 100% overens.") print("✅ SUKSESS! Passordet og hashen stemmer 100% overens.")
@ -40,9 +41,12 @@ async def test_sannheten():
else: else:
print("❌ FEIL! Passordet stemmer IKKE med hashen i databasen.") print("❌ FEIL! Passordet stemmer IKKE med hashen i databasen.")
print("➡️ KONKLUSJON: Scriptet som oppdaterer passordet gjør en feil (f.eks. legger til usynlige tegn), eller lagringen i databasen blir korrupt.") print("➡️ KONKLUSJON: Scriptet som oppdaterer passordet gjør en feil (f.eks. legger til usynlige tegn), eller lagringen i databasen blir korrupt.")
except Exception as exc:
print(f"❌ Kunne ikke teste admin-login: {type(exc).__name__}")
sys.exit(1)
finally: finally:
await conn.close() if conn is not None:
await conn.close()
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(test_sannheten()) asyncio.run(test_sannheten())

View file

@ -8,7 +8,6 @@ STATUS: Påvirker IKKE tofaktor (2FA). Gjør jobben fra start til slutt.
""" """
import asyncio import asyncio
import asyncpg import asyncpg
import os
import sys import sys
import getpass import getpass
from passlib.hash import pbkdf2_sha256 from passlib.hash import pbkdf2_sha256
@ -23,10 +22,11 @@ async def update_admin_password():
print("="*50) print("="*50)
# Kobler til databasen på ekte backend-vis # Kobler til databasen på ekte backend-vis
conn = None
try: try:
conn = await asyncpg.connect(DB_URL) conn = await asyncpg.connect(DB_URL)
except Exception as e: except Exception as exc:
print(f"❌ Kunne ikke koble til databasen: {e}") print(f"❌ Kunne ikke koble til databasen: {type(exc).__name__}")
sys.exit(1) sys.exit(1)
try: try:
@ -55,7 +55,6 @@ async def update_admin_password():
if password == password_confirm: if password == password_confirm:
if len(password) < 8: if len(password) < 8:
print("⚠️ Advarsel: Passordet bør være minst 8 tegn.") print("⚠️ Advarsel: Passordet bør være minst 8 tegn.")
print(f"\n[DEBUG] Passord akseptert.")
break break
else: else:
print("❌ Passordene er ikke like. Prøv igjen.\n") print("❌ Passordene er ikke like. Prøv igjen.\n")
@ -75,7 +74,8 @@ async def update_admin_password():
finally: finally:
# Lukk tilkoblingen pent # Lukk tilkoblingen pent
await conn.close() if conn is not None:
await conn.close()
if __name__ == "__main__": if __name__ == "__main__":
try: try: