Files
WOL-LY/app/config.py
2024-12-13 18:08:44 +02:00

138 lines
5.0 KiB
Python

import os
import re
from dotenv import load_dotenv
from werkzeug.security import generate_password_hash
# Create an empty .env file if it doesn't exist
env_file = '.env'
if not os.path.exists(env_file):
with open(env_file, 'w') as file:
file.write('# Environment variables\n')
# Function to manually read and parse the .env file for duplicates
def read_env_file(file_path):
with open(file_path, 'r') as file:
lines = file.readlines()
exact_mac_names_seen = set()
exact_iface_names_seen = set()
errors = []
for line in lines:
line = line.strip()
if not line or line.startswith('#'):
continue
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
if key.endswith('_MAC'):
if key in exact_mac_names_seen:
errors.append(f"Exact duplicate MAC entry: {key}")
exact_mac_names_seen.add(key)
elif key.endswith('_IFACE'):
if key in exact_iface_names_seen:
errors.append(f"Exact duplicate IFACE entry: {key}")
exact_iface_names_seen.add(key)
if errors:
for error in errors:
print(error)
raise SystemExit(1)
# Manually read and parse the .env file
read_env_file(env_file)
# Load environment variables
load_dotenv()
def validate_mac_address(mac):
# Regular expression pattern for a MAC address
mac_pattern = re.compile(r'^(?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]{2})$')
return mac_pattern.match(mac)
def validate_network_interface(iface):
# Regular expression pattern for a network interface
iface_pattern = re.compile(r'^(?:eth|wlan|eno|en)\d+$')
return iface_pattern.match(iface)
def validate_ip_or_domain(address):
# Regular expression pattern for an IP address or domain name
ip_domain_pattern = re.compile(r'^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$|^[a-zA-Z0-9-]{1,63}(?:\.[a-zA-Z]{2,})+$')
if ip_domain_pattern.match(address):
# If it's an IP address, verify that each octet is within the correct range
if re.match(r'^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$', address):
octets = address.split('.')
for octet in octets:
if int(octet) < 0 or int(octet) > 255:
return False
return True
return False
def validate_environment_variables():
errors = []
mac_names_seen = {}
iface_names_seen = {}
# List of required MAC address environment variables, interfaces and ips
mac_vars = {var: os.getenv(var) for var in os.environ if var.endswith('_MAC')}
iface_vars = {var: os.getenv(var) for var in os.environ if var.endswith('_IFACE')}
ip_vars = {var: os.getenv(var) for var in os.environ if var.endswith('_IP')}
# Check for duplicate MAC names (case-insensitive)
for var in mac_vars:
name_lower = var.rsplit('_', 1)[0].lower()
if name_lower in mac_names_seen:
errors.append(f"Duplicate MAC entries: {mac_names_seen[name_lower]} and {var}")
mac_names_seen[name_lower] = var
# Check for duplicate interface names (case-insensitive)
for var in iface_vars:
name_lower = var.rsplit('_', 1)[0].lower()
if name_lower in iface_names_seen:
errors.append(f"Duplicate IFACE entries: {iface_names_seen[name_lower]} and {var}")
iface_names_seen[name_lower] = var
# Validate MAC addresses (required)
for var, mac in mac_vars.items():
if not mac:
errors.append(f"Missing environment variable: {var}")
elif not validate_mac_address(mac):
errors.append(f"Invalid MAC address format: {var} = {mac}")
if not mac_vars:
errors.append("No MAC addresses found in environment variables.")
# Validate network interfaces (optional)
for var, iface in iface_vars.items():
if iface == "":
errors.append(f"Empty interface variable: {var}")
elif iface and not validate_network_interface(iface):
errors.append(f"Invalid network interface format: {var} = {iface}")
# Validate IP addresses or domain names (optional)
for var, address in ip_vars.items():
if address == "":
errors.append(f"Empty IP address or domain name variable: {var}")
elif address and not validate_ip_or_domain(address):
errors.append(f"Invalid IP address or domain name format: {var} = {address}")
if errors:
for error in errors:
print(error)
raise SystemExit(1)
# Validate environment variables
validate_environment_variables()
# Centralized configuration
class Config:
SECRET_KEY = os.getenv('WOL_SECRET_KEY', '28c93e98b2a87e47db16372bdb6e7593fb1addf9ccc10eae562827a7358cab3b')
USER_PASS = os.getenv('WOL_USER_PASS', '4acG2wHmp1-B')
USER_PASS_HASH = generate_password_hash(USER_PASS, method='pbkdf2:sha256', salt_length=16) # Hash the password once and store it
REDIS_URL = os.getenv('REDIS_URL', 'redis://localhost:6379/0')
RATE_LIMITS = ["200 per day", "50 per hour"]
LOG_FILE = 'app.log'
LOG_MAX_BYTES = 10000
LOG_BACKUP_COUNT = 1