UPdate device tracking cookie
This commit is contained in:
parent
0cf8cf7fc0
commit
00f6c6576a
@ -364,3 +364,6 @@ For issues and questions:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -244,3 +244,6 @@ For issues and questions, please refer to the application documentation or creat
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -261,3 +261,6 @@ main "$@"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -70,3 +70,6 @@ Create the name of the service account to use
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -37,3 +37,6 @@ spec:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -23,3 +23,6 @@ spec:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -26,3 +26,6 @@ spec:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -17,3 +17,6 @@ metadata:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ importlib.reload(database)
|
|||||||
importlib.reload(db_config)
|
importlib.reload(db_config)
|
||||||
|
|
||||||
from app import app, randomUrlSuffix
|
from app import app, randomUrlSuffix
|
||||||
from flask import Flask, flash, render_template, request, redirect, url_for, jsonify
|
from flask import Flask, flash, render_template, request, redirect, url_for, jsonify, make_response
|
||||||
from sqlalchemy import text
|
from sqlalchemy import text
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_bootstrap import Bootstrap
|
from flask_bootstrap import Bootstrap
|
||||||
@ -36,6 +36,9 @@ from fixture_scraper import FixtureScraper, get_next_hkfc_c_fixture, get_opponen
|
|||||||
from club_scraper import ClubScraper, get_hk_hockey_clubs, expand_club_abbreviation
|
from club_scraper import ClubScraper, get_hk_hockey_clubs, expand_club_abbreviation
|
||||||
from s3_config import s3_config_manager, s3_asset_service
|
from s3_config import s3_config_manager, s3_asset_service
|
||||||
|
|
||||||
|
# Persistent device ID cookie name
|
||||||
|
DEVICE_COOKIE_NAME = 'motm_device_id'
|
||||||
|
|
||||||
# Custom authentication class that uses database
|
# Custom authentication class that uses database
|
||||||
class DatabaseBasicAuth(BasicAuth):
|
class DatabaseBasicAuth(BasicAuth):
|
||||||
def check_credentials(self, username, password):
|
def check_credentials(self, username, password):
|
||||||
@ -146,6 +149,23 @@ def generate_device_id(request):
|
|||||||
|
|
||||||
return device_id
|
return device_id
|
||||||
|
|
||||||
|
def get_or_create_device_id(request):
|
||||||
|
"""
|
||||||
|
Return a persistent device identifier using a long-lived cookie.
|
||||||
|
Falls back to a header/IP fingerprint only if absolutely necessary.
|
||||||
|
|
||||||
|
Returns a tuple of (device_id, created) where created indicates whether
|
||||||
|
a new cookie needs to be set on the response.
|
||||||
|
"""
|
||||||
|
# Prefer existing cookie to uniquely identify a device/browser
|
||||||
|
cookie_device_id = request.cookies.get(DEVICE_COOKIE_NAME)
|
||||||
|
if cookie_device_id:
|
||||||
|
return cookie_device_id, False
|
||||||
|
|
||||||
|
# Create a new random UUID (more stable than header/IP fingerprints)
|
||||||
|
new_device_id = uuid.uuid4().hex
|
||||||
|
return new_device_id, True
|
||||||
|
|
||||||
|
|
||||||
def is_admin_authenticated(request):
|
def is_admin_authenticated(request):
|
||||||
"""Check if the current request is authenticated as admin"""
|
"""Check if the current request is authenticated as admin"""
|
||||||
@ -490,8 +510,8 @@ def vote_thanks():
|
|||||||
update_player_totals(_motm)
|
update_player_totals(_motm)
|
||||||
update_player_totals(_dotd)
|
update_player_totals(_dotd)
|
||||||
|
|
||||||
# Generate device identifier and record vote for tracking
|
# Generate or retrieve persistent device identifier and record vote for tracking
|
||||||
device_id = generate_device_id(request)
|
device_id, device_created = get_or_create_device_id(request)
|
||||||
sql_device = text("""
|
sql_device = text("""
|
||||||
INSERT INTO device_votes (device_id, fixture_date, motm_player_number, dotd_player_number,
|
INSERT INTO device_votes (device_id, fixture_date, motm_player_number, dotd_player_number,
|
||||||
motm_player_name, dotd_player_name, ip_address, user_agent)
|
motm_player_name, dotd_player_name, ip_address, user_agent)
|
||||||
@ -531,7 +551,20 @@ def vote_thanks():
|
|||||||
# Fallback to static URL
|
# Fallback to static URL
|
||||||
simpsons_url = "/static/images/simpsons-monkeys.jpg"
|
simpsons_url = "/static/images/simpsons-monkeys.jpg"
|
||||||
|
|
||||||
return render_template('vote_thanks.html', simpsons_image_url=simpsons_url)
|
# Build response and set device ID cookie if newly created
|
||||||
|
response = make_response(render_template('vote_thanks.html', simpsons_image_url=simpsons_url))
|
||||||
|
if device_created:
|
||||||
|
# Two years in seconds
|
||||||
|
max_age_seconds = 60 * 60 * 24 * 730
|
||||||
|
response.set_cookie(
|
||||||
|
DEVICE_COOKIE_NAME,
|
||||||
|
device_id,
|
||||||
|
max_age=max_age_seconds,
|
||||||
|
httponly=True,
|
||||||
|
samesite='Lax',
|
||||||
|
secure=bool(request.is_secure)
|
||||||
|
)
|
||||||
|
return response
|
||||||
else:
|
else:
|
||||||
return 'Ouch ... something went wrong here'
|
return 'Ouch ... something went wrong here'
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user