Added logging, handled secrets better

This commit is contained in:
Feiko Wielsma 2026-03-25 09:50:58 +01:00
parent 197ae8d75b
commit d8ceb50e9f
4 changed files with 69 additions and 29 deletions

6
.gitignore vendored
View file

@ -1 +1,5 @@
credentials.json
credentials.json
.venv/
*.pyc
__pycache__/
.env

34
app.py
View file

@ -2,11 +2,31 @@ import os
import yaml
import gspread
import secrets
import logging
import sys
from flask import Flask, render_template, request, redirect, url_for, abort, session
from datetime import datetime
# Configure logging for Docker/Portainer
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger(__name__)
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY', secrets.token_hex(32))
# Fail-fast secret requirement (allow bypass for pytest testing)
secret_key = os.environ.get('SECRET_KEY')
if not secret_key:
if os.environ.get('TESTING_NO_APPEND') or 'pytest' in sys.modules:
secret_key = 'test_secret_bypassed'
else:
logger.critical("No SECRET_KEY set! Exiting. Set it in .env or Portainer Stack secrets.")
sys.exit(1)
app.secret_key = secret_key
def generate_csrf_token():
if '_csrf_token' not in session:
@ -40,7 +60,7 @@ def get_google_sheet(sheet_id, tab_name=None):
# Default to first tab
return sh.sheet1
except Exception as e:
print(f"Error connecting to Google Sheet (ID: {sheet_id}, Tab: {tab_name}): {e}")
logger.error(f"Error connecting to Google Sheet (ID: {sheet_id}, Tab: {tab_name}): {e}")
return None
# NEW: Fetch and filter participants for public display
@ -82,7 +102,7 @@ def get_public_participants(sheet_id, tab_name=None):
return public_list
except Exception as e:
print(f"Error fetching participants: {e}")
logger.error(f"Error fetching participants: {e}")
return []
@app.route('/')
@ -146,9 +166,15 @@ def event_form(event_slug):
sheet = get_google_sheet(sheet_id, tab_name)
if sheet:
if not os.environ.get('TESTING_NO_APPEND'):
sheet.append_row(form_data)
try:
sheet.append_row(form_data)
logger.info(f"Successfully appended registration for {form_data[7]} to {tab_name}")
except Exception as e:
logger.error(f"Failed to append row to {tab_name}: {e}")
return f"Error appending data. Try again later."
return redirect(url_for('success', event_slug=event_slug))
else:
logger.error(f"Could not connect to tab '{tab_name}' during POST.")
return f"Error: Could not connect to Google Sheet Tab '{tab_name}'. Check server logs."
# GET Request: Fetch participants to show at bottom of form

View file

@ -4,6 +4,8 @@ services:
build: .
container_name: sailing_forms
restart: unless-stopped
env_file:
- .env
ports:
- "5000:5000"
volumes:

View file

@ -1,29 +1,37 @@
import os
import re
import pytest
from playwright.sync_api import Page, expect
from playwright.sync_api import sync_playwright, expect
def test_homepage_has_title(page: Page):
page.goto("http://localhost:5000/")
expect(page).to_have_title(re.compile("Zeilwedstrijden"))
def test_homepage_has_title():
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("http://localhost:5000/")
expect(page).to_have_title(re.compile("Zeilwedstrijden"))
browser.close()
def test_submission_flow(page: Page):
page.goto("http://localhost:5000/zomeravond")
# Fill required fields
page.select_option("select[name='klasse']", label="Kajuitklasse")
page.fill("input[name='zeilnummer']", "42")
page.fill("input[name='bootnaam']", "Vliegende Hollander")
page.fill("input[name='naam']", "Hendrik Test")
page.fill("input[name='telefoonmobiel']", "0612345678")
page.fill("input[name='email']", "hendrik@example.com")
# Accept terms
page.check("input#terms")
# Submit
page.click("button[type='submit']")
# Expect success redirect
expect(page).to_have_url(re.compile(r".*/zomeravond/success"))
expect(page.locator("h1")).to_have_text("Bedankt!")
def test_submission_flow():
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("http://localhost:5000/zomeravond")
# Fill required fields
page.select_option("select[name='klasse']", label="Kajuitklasse")
page.fill("input[name='zeilnummer']", "42")
page.fill("input[name='bootnaam']", "Vliegende Hollander")
page.fill("input[name='naam']", "Hendrik Test")
page.fill("input[name='telefoonmobiel']", "0612345678")
page.fill("input[name='email']", "hendrik@example.com")
# Accept terms
page.check("input#terms")
# Submit
page.click("button[type='submit']")
# Expect success redirect
expect(page).to_have_url(re.compile(r".*/zomeravond/success"))
expect(page.locator("h1")).to_have_text("Bedankt!")
browser.close()