Added logging, handled secrets better
This commit is contained in:
parent
197ae8d75b
commit
d8ceb50e9f
4 changed files with 69 additions and 29 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1 +1,5 @@
|
|||
credentials.json
|
||||
credentials.json
|
||||
.venv/
|
||||
*.pyc
|
||||
__pycache__/
|
||||
.env
|
||||
34
app.py
34
app.py
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ services:
|
|||
build: .
|
||||
container_name: sailing_forms
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "5000:5000"
|
||||
volumes:
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue