|
from pathlib import Path
|
|
import os
|
|
from cryptography.fernet import Fernet # Import Fernet
|
|
import dotenv # Import dotenv to reload env vars
|
|
|
|
def ensure_env_file_exists(env_path: Path):
|
|
"""
|
|
Ensures that a .env file exists at the specified path.
|
|
If it doesn't exist, it creates one with default values (excluding SESSION_SECRET_KEY).
|
|
"""
|
|
if not env_path.exists():
|
|
default_env_content = """# .env - Environment variables for Retoor's Cloud Solutions
|
|
#
|
|
# This file is used to configure various aspects of the application,
|
|
# including pricing, email settings, and other sensitive information.
|
|
#
|
|
# For production, it is recommended to manage these variables through
|
|
# your hosting provider's environment variable management system
|
|
# rather than committing this file to version control.
|
|
|
|
# Pricing Configuration
|
|
# PRICE_PER_GB: Cost per gigabyte of storage.
|
|
PRICE_PER_GB=0.05
|
|
|
|
# SMTP (Email Sending) Configuration
|
|
# Used for sending transactional emails (e.g., welcome, password reset).
|
|
# SMTP_HOST: The hostname of your SMTP server.
|
|
# SMTP_PORT: The port of your SMTP server (e.g., 587 for TLS, 465 for SSL, 25 for unencrypted).
|
|
# SMTP_USERNAME: The username for authenticating with your SMTP server.
|
|
# SMTP_PASSWORD: The password for authenticating with your SMTP server.
|
|
# SMTP_USE_TLS: Set to True to enable STARTTLS encryption (recommended for most servers).
|
|
# SMTP_SENDER_EMAIL: The email address from which system emails will be sent.
|
|
SMTP_HOST=localhost
|
|
SMTP_PORT=1025
|
|
SMTP_USERNAME=
|
|
SMTP_PASSWORD=
|
|
SMTP_USE_TLS=False
|
|
SMTP_SENDER_EMAIL=no-reply@retoors.com
|
|
|
|
# IMAP (Email Receiving) Configuration (if applicable for future features)
|
|
# IMAP_HOST=
|
|
# IMAP_PORT=
|
|
# IMAP_USERNAME=
|
|
# IMAP_PASSWORD=
|
|
# IMAP_USE_SSL=True
|
|
"""
|
|
with open(env_path, "w") as f:
|
|
f.write(default_env_content)
|
|
print(f"Created default .env file at {env_path}")
|
|
else:
|
|
print(f".env file already exists at {env_path}")
|
|
|
|
def get_or_create_session_secret_key(env_path: Path) -> bytes:
|
|
"""
|
|
Retrieves the SESSION_SECRET_KEY from environment variables.
|
|
If not found or invalid, generates a new one, saves it to .env,
|
|
and reloads environment variables.
|
|
Returns the valid secret key as bytes.
|
|
"""
|
|
key_name = 'SESSION_SECRET_KEY'
|
|
|
|
# Try to get the key from already loaded environment variables
|
|
# This assumes dotenv.load_dotenv() has been called in main.py
|
|
secret_key_str = os.getenv(key_name)
|
|
|
|
# Variable to hold the key in bytes format
|
|
final_secret_key_bytes = None
|
|
|
|
if secret_key_str:
|
|
try:
|
|
# Fernet expects bytes, so encode the string from env var
|
|
final_secret_key_bytes = secret_key_str.encode('utf-8')
|
|
Fernet(final_secret_key_bytes) # Validate the key
|
|
print(f"Using existing valid {key_name} from environment.")
|
|
except ValueError:
|
|
print(f"Existing {key_name} in .env is invalid. Generating a new one.")
|
|
final_secret_key_bytes = None # Invalidate to trigger generation
|
|
|
|
if final_secret_key_bytes is None:
|
|
# Generate a new url-safe base64-encoded key
|
|
generated_key_bytes = Fernet.generate_key()
|
|
generated_key_str = generated_key_bytes.decode('utf-8')
|
|
|
|
# Append to .env file
|
|
with open(env_path, 'a') as f:
|
|
f.write(f'\n{key_name}={generated_key_str}\n')
|
|
|
|
print(f"Generated and added {key_name} to {env_path}")
|
|
|
|
# Reload environment variables to make the new key available for subsequent os.getenv calls
|
|
# This is important if other parts of the app might call os.getenv(key_name) later
|
|
dotenv.load_dotenv(dotenv_path=env_path)
|
|
|
|
final_secret_key_bytes = generated_key_bytes # Use the newly generated bytes directly
|
|
|
|
if final_secret_key_bytes is None:
|
|
raise RuntimeError(f"Failed to get or create {key_name}")
|
|
|
|
return final_secret_key_bytes
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Example usage:
|
|
project_root = Path(__file__).parent.parent.parent
|
|
env_file = project_root / ".env"
|
|
ensure_env_file_exists(env_file)
|
|
try:
|
|
key = get_or_create_session_secret_key(env_file)
|
|
print(f"Session key obtained: {key}")
|
|
except RuntimeError as e:
|
|
print(f"Error: {e}")
|