refactor(config): .env in config.yaml integriert
- auth.secret_key und smtp.* direkt in config/config.yaml aufgenommen - config/env.example entfernt, config/config.example.yaml als Vorlage hinzugefügt - meshbot/auth.py: config.env() → config.get() für alle Auth/SMTP-Werte - meshbot/config.py: ENV_PATH, _load_env(), env() entfernt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4b9dd45f05
commit
261f0dac13
|
|
@ -74,7 +74,7 @@
|
|||
- Bot start: `/home/peter/meshdd-bot/venv/bin/python main.py`
|
||||
- Web port: 8081 (konfigurierbar via `web.port`)
|
||||
- Forgejo remote with token in URL
|
||||
- Current version: 0.08.15
|
||||
- Current version: 0.08.16
|
||||
- Protobuf objects converted via `google.protobuf.json_format.MessageToDict()`
|
||||
- Auth: bcrypt (12 rounds), aiohttp-session EncryptedCookieStorage, aiosmtplib for emails
|
||||
- SMTP fallback: if no smtp.host configured, verification links logged to console
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
# Changelog
|
||||
|
||||
## [0.08.17] - 2026-02-20
|
||||
|
||||
### Changed
|
||||
- **`.env`-Datei abgeschafft**: Alle Konfigurationswerte (`auth.secret_key`, `smtp.*`)
|
||||
sind jetzt direkt in `config/config.yaml` enthalten – keine separate `.env`-Datei mehr nötig.
|
||||
- **`meshbot/auth.py`**: `config.env()` durch `config.get()` ersetzt (liest jetzt aus YAML).
|
||||
- **`meshbot/config.py`**: `ENV_PATH`, `_load_env()` und `env()` entfernt.
|
||||
- **`config/env.example`** entfernt.
|
||||
|
||||
## [0.08.16] - 2026-02-20
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
35
config/config.example.yaml
Normal file
35
config/config.example.yaml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
version: "0.08.17"
|
||||
|
||||
bot:
|
||||
name: "MeshDD-Bot"
|
||||
command_prefix: "?"
|
||||
|
||||
meshtastic:
|
||||
host: "192.168.11.4"
|
||||
port: 4403
|
||||
|
||||
web:
|
||||
host: "0.0.0.0"
|
||||
port: 8081
|
||||
online_threshold: 900
|
||||
|
||||
database:
|
||||
path: "meshdd.db"
|
||||
|
||||
auth:
|
||||
session_max_age: 86400
|
||||
secret_key: "change-this-secret-key-32bytes!!"
|
||||
|
||||
smtp:
|
||||
host: ""
|
||||
port: 465
|
||||
user: ""
|
||||
password: ""
|
||||
from: "MeshDD-Bot <noreply@example.com>"
|
||||
app_url: "http://localhost:8081"
|
||||
|
||||
links:
|
||||
- url: "https://meshtastic.org"
|
||||
label: "Meshtastic"
|
||||
- url: "https://meshmap.net"
|
||||
label: "MeshMap"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
version: "0.08.16"
|
||||
version: "0.08.17"
|
||||
|
||||
bot:
|
||||
name: "MeshDD-Bot"
|
||||
|
|
@ -18,6 +18,15 @@ database:
|
|||
|
||||
auth:
|
||||
session_max_age: 86400
|
||||
secret_key: "4pY1h4S/pqpTojjPb7LV6TfaTZC8jas/DV3vixXIP8s="
|
||||
|
||||
smtp:
|
||||
host: "ssl0.ovh.net"
|
||||
port: 465
|
||||
user: "info@meshdresden.eu"
|
||||
password: "meshDresden"
|
||||
from: "MeshDD-Bot <info@meshdresden.eu>"
|
||||
app_url: "http://bot.home.pfeiffer-privat.de"
|
||||
|
||||
links:
|
||||
- url: "https://meshtastic.org"
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
AUTH_SECRET_KEY=change-this-secret-key-32bytes!!
|
||||
SMTP_HOST=
|
||||
SMTP_PORT=465
|
||||
SMTP_USER=
|
||||
SMTP_PASSWORD=
|
||||
SMTP_FROM=MeshDD-Bot <noreply@example.com>
|
||||
SMTP_APP_URL=http://localhost:8080
|
||||
|
|
@ -27,7 +27,7 @@ def check_password(password: str, hashed: str) -> bool:
|
|||
# ── Session setup ────────────────────────────────────
|
||||
|
||||
def setup_session(app: web.Application):
|
||||
secret_key = config.env("AUTH_SECRET_KEY", "change-this-secret-key-32bytes!!")
|
||||
secret_key = config.get("auth.secret_key", "change-this-secret-key-32bytes!!")
|
||||
# EncryptedCookieStorage accepts a Fernet object directly
|
||||
key_bytes = secret_key.encode("utf-8")[:32].ljust(32, b"\0")
|
||||
fernet_key = Fernet(base64.urlsafe_b64encode(key_bytes))
|
||||
|
|
@ -88,7 +88,7 @@ def require_admin_api(request: web.Request):
|
|||
# ── Email sending ────────────────────────────────────
|
||||
|
||||
async def _send_email(db, recipient: str, subject: str, html_body: str):
|
||||
smtp_host = config.env("SMTP_HOST")
|
||||
smtp_host = config.get("smtp.host", "")
|
||||
if not smtp_host:
|
||||
logger.info("SMTP not configured - email to %s not sent", recipient)
|
||||
await db.log_email(recipient, subject, "console", "SMTP not configured")
|
||||
|
|
@ -100,22 +100,21 @@ async def _send_email(db, recipient: str, subject: str, html_body: str):
|
|||
|
||||
msg = EmailMessage()
|
||||
msg["Subject"] = subject
|
||||
msg["From"] = config.env("SMTP_FROM", "MeshDD-Bot <noreply@example.com>")
|
||||
msg["From"] = config.get("smtp.from", "MeshDD-Bot <noreply@example.com>")
|
||||
msg["To"] = recipient
|
||||
|
||||
msg.set_content("Bitte HTML-fähigen E-Mail-Client verwenden.")
|
||||
msg.add_alternative(html_body, subtype="html")
|
||||
smtp_port = int(config.env("SMTP_PORT", "465"))
|
||||
smtp_client = aiosmtplib.SMTP(
|
||||
hostname=smtp_host,
|
||||
port=smtp_port,
|
||||
port=config.get("smtp.port", 465),
|
||||
use_tls=True,
|
||||
)
|
||||
|
||||
async with smtp_client:
|
||||
await smtp_client.login(
|
||||
config.env("SMTP_USER"),
|
||||
config.env("SMTP_PASSWORD"),
|
||||
config.get("smtp.user", ""),
|
||||
config.get("smtp.password", ""),
|
||||
)
|
||||
await smtp_client.send_message(msg)
|
||||
|
||||
|
|
@ -127,7 +126,7 @@ async def _send_email(db, recipient: str, subject: str, html_body: str):
|
|||
|
||||
|
||||
async def send_verification_email(db, email: str, token: str):
|
||||
app_url = config.env("SMTP_APP_URL", "http://localhost:8080")
|
||||
app_url = config.get("smtp.app_url", "http://localhost:8081")
|
||||
verify_url = f"{app_url}/auth/verify?token={token}"
|
||||
logger.info("Verification link for %s: %s", email, verify_url)
|
||||
subject = "MeshDD-Bot - E-Mail verifizieren"
|
||||
|
|
@ -142,7 +141,7 @@ async def send_verification_email(db, email: str, token: str):
|
|||
|
||||
|
||||
async def send_reset_email(db, email: str, token: str):
|
||||
app_url = config.env("SMTP_APP_URL", "http://localhost:8080")
|
||||
app_url = config.get("smtp.app_url", "http://localhost:8081")
|
||||
reset_url = f"{app_url}/auth/reset-password?token={token}"
|
||||
logger.info("Reset link for %s: %s", email, reset_url)
|
||||
subject = "MeshDD-Bot - Passwort zuruecksetzen"
|
||||
|
|
@ -157,7 +156,7 @@ async def send_reset_email(db, email: str, token: str):
|
|||
|
||||
|
||||
async def send_user_info_email(db, email: str, name: str, password: str = None):
|
||||
app_url = config.env("SMTP_APP_URL", "http://localhost:8080")
|
||||
app_url = config.get("smtp.app_url", "http://localhost:8081")
|
||||
login_url = f"{app_url}/login"
|
||||
subject = "MeshDD-Bot - Deine Zugangsdaten"
|
||||
pw_line = f"<p><strong>Passwort:</strong> {password}</p>" if password else "<p>Dein Passwort wurde nicht geaendert.</p>"
|
||||
|
|
|
|||
|
|
@ -7,26 +7,12 @@ import yaml
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_PATH = os.environ.get("CONFIG_PATH", os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", "config.yaml"))
|
||||
ENV_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", ".env")
|
||||
|
||||
_config = {}
|
||||
_mtime = 0.0
|
||||
_callbacks = []
|
||||
|
||||
|
||||
def _load_env():
|
||||
if not os.path.exists(ENV_PATH):
|
||||
return
|
||||
with open(ENV_PATH, "r") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
key, _, value = line.partition("=")
|
||||
os.environ.setdefault(key.strip(), value.strip())
|
||||
logger.info("Environment loaded from %s", ENV_PATH)
|
||||
|
||||
|
||||
def _load():
|
||||
global _config, _mtime
|
||||
with open(CONFIG_PATH, "r") as f:
|
||||
|
|
@ -75,10 +61,5 @@ def get(key: str, default=None):
|
|||
return val
|
||||
|
||||
|
||||
def env(key: str, default: str = "") -> str:
|
||||
return os.environ.get(key, default)
|
||||
|
||||
|
||||
# Load on import
|
||||
_load_env()
|
||||
_load()
|
||||
|
|
|
|||
Loading…
Reference in a new issue