modified: web/app.py

modified:   web/blueprints/group_admin.py
	modified:   web/panel_db.py
	modified:   web/templates/group_admin/privacy_policy.html
This commit is contained in:
simon
2026-04-17 12:04:00 +02:00
parent 2dbd5340a8
commit cd9a46b403
4 changed files with 59 additions and 18 deletions

View File

@@ -177,13 +177,22 @@ PANEL_MIGRATIONS = [
"Add users.consented_at for GDPR consent timestamp"),
(9,
"""CREATE TABLE IF NOT EXISTS group_privacy_policy (
group_id INT PRIMARY KEY,
policy_text LONGTEXT,
policy_url VARCHAR(500),
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
group_id INT PRIMARY KEY,
policy_text LONGTEXT,
policy_url VARCHAR(500),
public_token CHAR(36) NULL UNIQUE,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (group_id) REFERENCES user_groups(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4""",
"Add group_privacy_policy table for group-hosted privacy policies"),
(10,
"ALTER TABLE group_privacy_policy ADD COLUMN IF NOT EXISTS "
"public_token CHAR(36) NULL",
"Add group_privacy_policy.public_token for opaque public URL"),
(11,
"ALTER TABLE group_privacy_policy ADD CONSTRAINT IF NOT EXISTS "
"uq_gpp_public_token UNIQUE (public_token)",
"Unique index on group_privacy_policy.public_token"),
]
CREDS_SCHEMA = [
@@ -769,20 +778,39 @@ def set_user_consent(user_id: int, policy_version: str) -> None:
def get_group_policy(group_id: int):
"""Returns the group_privacy_policy row for *group_id*, or None if not set."""
rows = _panel_query(
"SELECT group_id, policy_text, policy_url, updated_at "
"SELECT group_id, policy_text, policy_url, public_token, updated_at "
"FROM group_privacy_policy WHERE group_id = %s",
(group_id,),
)
return rows[0] if rows else None
def get_group_policy_by_token(token: str):
"""Returns the policy row and group for the given opaque public_token, or None."""
rows = _panel_query(
"SELECT p.group_id, p.policy_text, p.policy_url, p.public_token, p.updated_at, "
"g.name AS group_name "
"FROM group_privacy_policy p "
"JOIN user_groups g ON g.id = p.group_id "
"WHERE p.public_token = %s",
(token,),
)
return rows[0] if rows else None
def set_group_policy(group_id: int, policy_text: str | None, policy_url: str | None) -> None:
"""Upserts the privacy policy for a group."""
"""Upserts the privacy policy for a group.
The *public_token* (opaque UUID) is generated once on first INSERT and
never changed on subsequent updates, so existing URLs stay valid.
"""
_panel_query(
"INSERT INTO group_privacy_policy (group_id, policy_text, policy_url) "
"VALUES (%s, %s, %s) "
"ON DUPLICATE KEY UPDATE policy_text = VALUES(policy_text), "
"policy_url = VALUES(policy_url), updated_at = UTC_TIMESTAMP()",
"INSERT INTO group_privacy_policy (group_id, policy_text, policy_url, public_token) "
"VALUES (%s, %s, %s, UUID()) "
"ON DUPLICATE KEY UPDATE "
"policy_text = VALUES(policy_text), "
"policy_url = VALUES(policy_url), "
"updated_at = UTC_TIMESTAMP()",
(group_id, policy_text, policy_url),
write=True,
)