TDD: 1, Me: 0
This commit is contained in:
137
app/config.py
Normal file
137
app/config.py
Normal file
@@ -0,0 +1,137 @@
|
||||
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
|
||||
Reference in New Issue
Block a user