142 lines
4.8 KiB
Plaintext
142 lines
4.8 KiB
Plaintext
config.py.example# Configuration file. Each variable can be overridden by a
|
|
# corresponding environment variable
|
|
import os
|
|
import sys
|
|
import copy
|
|
import logging
|
|
import pathlib
|
|
|
|
from slowapi import Limiter
|
|
from slowapi.util import get_remote_address
|
|
from fastapi_login import LoginManager
|
|
|
|
|
|
# Authentication configuration
|
|
LOGIN_SECRET_KEY = (
|
|
os.getenv("LOGIN_SECRET_KEY") or "login-secret"
|
|
) # Recommended value: os.urandom(24).hex()
|
|
USE_BEARER_HEADER = True
|
|
USE_COOKIE = True
|
|
|
|
# Logging configuration
|
|
LOG_LEVEL = int(os.getenv("LOG_LEVEL") or 0) or 20
|
|
LOG_FILE = os.getenv("LOG_FILE") or "" # Empty to disable
|
|
LOG_FORMAT = os.getenv("LOG_FORMAT") or "[%(levelname)s - %(asctime)s] %(message)s"
|
|
LOG_DATE_FORMAT = os.getenv("LOG_DATE_FORMAT") or "%d/%m/%Y %p"
|
|
|
|
# Bcrypt configuration
|
|
BCRYPT_ROUNDS = (
|
|
os.getenv("BCRYPT_ROUNDS") or 10
|
|
) # How many rounds are used when salting
|
|
|
|
|
|
# Rate limit configuration
|
|
REDIS_URL = "" # Used for rate limits. Empty to fall back to memory
|
|
REDIS_OPTIONS = {} # Options for redis
|
|
RATELIMIT_ENABLED = False # False to disable rate limiting
|
|
RATELIMIT_STRATEGY = "moving-window" # Refer to https://flask-limiter.readthedocs.io/en/stable/strategies.html
|
|
|
|
# Session configuration
|
|
SESSION_EXPIRE_LIMIT = 3600 # Unit is in seconds
|
|
SESSION_COOKIE_NAME = "_social_media_session"
|
|
COOKIE_SAMESITE_POLICY = "none" # Options are "lax", "none", "strict"
|
|
COOKIE_DOMAIN = "localhost" # Empty to disable this
|
|
COOKIE_PATH = "/"
|
|
COOKIE_HTTPONLY = True
|
|
SECURE_COOKIE = False # Set to true in production, False during development (unless your local server has HTTPS)
|
|
|
|
# SMTP configuration
|
|
SMTP_HOST = "smtp.nocturn9x.space"
|
|
SMTP_USER = "info@example.com"
|
|
SMTP_PASSWORD = "password"
|
|
SMTP_PORT = 587
|
|
SMTP_USE_TLS = True
|
|
SMTP_FROM_USER = "info@example.com"
|
|
SMTP_TEMPLATES_DIRECTORY = pathlib.Path(__file__) / "templates" / "email"
|
|
SMTP_TIMEOUT = 10
|
|
|
|
# Miscellaneous
|
|
|
|
# Usernames containing these characters are not valid
|
|
INVALID_USERNAME_CHARACTERS = ["@", "\\", "/"] # Empty this to allow any character
|
|
# Empty this to disable username validation
|
|
VALIDATE_USERNAME_REGEX = (
|
|
rf"^([^{''.join(INVALID_USERNAME_CHARACTERS)}]|[a-z0-9A-Z]){{5,32}}$"
|
|
)
|
|
# Criteria:
|
|
# - Between 10 and 72 characters long
|
|
# - At least 2 uppercase letters
|
|
# - At least 3 lowercase letters
|
|
# - At least one special character (!, @, #, $, %, &, *, _, +, /, \, (, ), £, ", ?, ^
|
|
# - At least 2 numbers
|
|
# You can change the repetitions to enforce stricter/laxer rules or empty
|
|
# this field to disable weakness validation
|
|
VALIDATE_PASSWORD_REGEX = r"^(?=.*[A-Z]){2,}(?=.*[\"!@%#$&*_^\?\\\/(\)\+\-])+(?=.*[0-9]){2,}(?=.*[a-z]){3,}.{10,72}$"
|
|
FORCE_EMAIL_VERIFICATION = False
|
|
EMAIL_VERIFICATION_EXPIRATION = 3600 # In seconds
|
|
PLATFORM_NAME = "PySimpleSocial" # Used in emails
|
|
HAS_HTTPS = False
|
|
|
|
|
|
class NotAuthenticated(Exception):
|
|
pass
|
|
|
|
|
|
class AdminNotAuthenticated(Exception):
|
|
pass
|
|
|
|
|
|
if __name__ != "__main__":
|
|
LOGGER: logging.Logger = logging.getLogger("socialMedia")
|
|
LOGGER.setLevel(LOG_LEVEL)
|
|
handler = logging.StreamHandler(sys.stderr)
|
|
formatter = logging.Formatter(fmt=LOG_FORMAT, datefmt=LOG_DATE_FORMAT)
|
|
handler.setFormatter(formatter)
|
|
LOGGER.addHandler(handler)
|
|
handler.setLevel(LOG_LEVEL)
|
|
if LOG_FILE:
|
|
file_handler = logging.FileHandler(LOG_FILE, "a", "utf8")
|
|
file_handler.setFormatter(formatter)
|
|
LOGGER.addHandler(handler)
|
|
file_handler.setLevel(LOG_LEVEL)
|
|
logging.getLogger("uvicorn").addHandler(file_handler)
|
|
LIMITER = Limiter(
|
|
key_func=get_remote_address,
|
|
strategy=RATELIMIT_STRATEGY,
|
|
storage_uri=REDIS_URL or None,
|
|
in_memory_fallback_enabled=bool(REDIS_URL),
|
|
storage_options=REDIS_OPTIONS,
|
|
enabled=RATELIMIT_ENABLED,
|
|
)
|
|
MANAGER = LoginManager(
|
|
LOGIN_SECRET_KEY,
|
|
"/user",
|
|
use_cookie=True,
|
|
cookie_name=SESSION_COOKIE_NAME,
|
|
use_header=USE_BEARER_HEADER,
|
|
custom_exception=NotAuthenticated,
|
|
)
|
|
UNVERIFIED_MANAGER = copy.deepcopy(MANAGE
|
|
ADMIN_MANAGER = LoginManager(
|
|
LOGIN_SECRET_KEY,
|
|
"/admin",
|
|
use_cookie=True,
|
|
cookie_name=f"{SESSION_COOKIE_NAME}_admin",
|
|
use_header=USE_BEARER_HEADER,
|
|
custom_exception=AdminNotAuthenticated
|
|
)
|
|
|
|
# Uvicorn config
|
|
|
|
HOST = os.getenv("HOST") or "localhost"
|
|
PORT = int(os.getenv("PORT") or 0) or 8000
|
|
WORKERS = int(os.getenv("PORT") or 0) or 1
|
|
|
|
# Storage configuration
|
|
|
|
STORAGE_ENGINE = "database" # Stores media inside the database. Other options are "local" to use a local/remote folder
|
|
# or "url" for uploading to a CDN
|
|
STORAGE_FOLDER = "" # Only needed when STORAGE_ENGINE is set to local
|
|
MAX_MEDIA_SIZE = 5242880 # Max length of media allowed. Anything bigger raises a 415 HTTP Exception
|
|
ALLOWED_MEDIA_TYPES = ["gif", "png", "jpeg", "tiff"]
|
|
ZLIB_COMPRESSION_LEVEL = 9 |