Different keys for session and csrf checking middleware, some comments in compose yml and .env

This commit is contained in:
DarkCat09 2023-03-24 19:00:31 +04:00
parent edbf0233ba
commit 3b588d2da5
4 changed files with 39 additions and 23 deletions

5
.env
View file

@ -2,7 +2,10 @@ APP_HOST=0.0.0.0
APP_PORT=8000 APP_PORT=8000
# Generate a strong secret key # Generate a strong secret key
# On Linux: openssl rand -hex 32 #
# On Linux: tr -dc A-Za-z0-9_- </dev/urandom | head -c 44
# With Python: import secrets; secrets.token_urlsafe(32)
#
# If this variable is not set, # If this variable is not set,
# the key is generated automatically # the key is generated automatically
#SECRET_KEY=secret #SECRET_KEY=secret

View file

@ -1,5 +1,6 @@
import secrets import secrets
from pathlib import Path from pathlib import Path
from typing import Literal
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from pydantic import BaseSettings from pydantic import BaseSettings
@ -14,12 +15,16 @@ static_dir = str(file_dir.parent / 'static')
# Main configuration # Main configuration
class Settings(BaseSettings): class Settings(BaseSettings):
debug: bool = False debug: bool = False
secret_key: str = 'secret' session_key: str = 'secret'
csrf_key: str = 'secret'
app_host: str = '127.0.0.1' app_host: str = '127.0.0.1'
app_port: int = 8000 app_port: int = 8000
# Instantiate Settings class # Type alias for secret keys settings fields
SecretKey = Literal['session_key', 'csrf_key']
# Settings class instantiating
settings = Settings() settings = Settings()
# Jinja templates handler # Jinja templates handler
@ -28,26 +33,30 @@ templates = Jinja2Templates(
) )
def secret_key_check() -> None: def secret_key_check(name: SecretKey) -> None:
"""Generates a secret key automatically """Generates a secret key automatically
if the env var `secret_key` is not set if an environment variable is not set
or contains text `secret`""" or contains text `secret`"""
if settings.secret_key == 'secret': settings_dict = settings.dict()
if settings_dict.get(name) != 'secret':
return
key_file = Path('/tmp/secret_key') key_file = Path(f'/tmp/{name}')
if key_file.exists(): if key_file.exists():
with key_file.open('rt') as f: with key_file.open('rt') as f:
secret_key = f.read() key = f.read()
else: else:
secret_key = secrets.token_hex(32) key = secrets.token_hex(32)
with key_file.open('wt') as f: with key_file.open('wt') as f:
f.write(secret_key) f.write(key)
settings.secret_key = secret_key settings_dict[name] = key
# Call the function # Calling the function
secret_key_check() # for session and CSRF keys
secret_key_check('session_key')
secret_key_check('csrf_key')

View file

@ -42,9 +42,9 @@ for p in paths:
# Add WTForms CSRF protection middlewares # Add WTForms CSRF protection middlewares
app.add_middleware( app.add_middleware(
SessionMiddleware, SessionMiddleware,
secret_key=common.settings.secret_key, secret_key=common.settings.session_key,
) )
app.add_middleware( app.add_middleware(
CSRFProtectMiddleware, CSRFProtectMiddleware,
csrf_secret=common.settings.secret_key, csrf_secret=common.settings.csrf_key,
) )

View file

@ -2,20 +2,20 @@ version: "3"
services: services:
${REPO_NAME_SNAKE}: app:
image: ${REPO_OWNER_LOWER}/${REPO_NAME_SNAKE}:latest image: ${REPO_OWNER_LOWER}/${REPO_NAME_SNAKE}:latest
container_name: ${REPO_NAME_SNAKE} container_name: ${REPO_NAME_SNAKE}
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8080:8000" - "8080:8000"
links: links:
- ${REPO_NAME_SNAKE}_db - database
env_file: .env env_file: .env
depends_on: depends_on:
${REPO_NAME_SNAKE}_db: database:
condition: service_healthy condition: service_healthy
${REPO_NAME_SNAKE}_db: database:
image: mariadb:latest image: mariadb:latest
container_name: ${REPO_NAME_SNAKE}_db container_name: ${REPO_NAME_SNAKE}_db
restart: unless-stopped restart: unless-stopped
@ -29,5 +29,9 @@ services:
timeout: 3s timeout: 3s
retries: 20 retries: 20
# Comment or remove these lines and
# edit `volumes` in services->database
# if you are going to store
# your DB in a directory
volumes: volumes:
db_data: db_data: