feat: apikey alias/renewal + markdown/patch authorship
- APIKey.alias (unique, required). Creating with an existing alias renews that key: same key string kept, validity reset to 15d, reactivated, name/roles updated (response has renewed=true). - get_actor(): X-API-Key -> key alias, Bearer -> 'admin'. - markdown & patch create/update record author / created_at / updated_at / last_modified_by from the actor. - Idempotent run_migrations() (information_schema-guarded ALTERs + backfill) so existing tables/data gain the new columns on startup; create_all still covers fresh DBs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
11
api/patch.py
11
api/patch.py
@@ -1,5 +1,6 @@
|
||||
from datetime import datetime, UTC
|
||||
from flask import Blueprint, request, jsonify
|
||||
from api import limiter, require_auth, is_user_admin
|
||||
from api import limiter, require_auth, is_user_admin, get_actor
|
||||
from contexts.RequestContext import RequestContext
|
||||
from db import get_db
|
||||
from db.models.Markdown import Markdown
|
||||
@@ -65,11 +66,17 @@ def create_patch():
|
||||
if session.query(Markdown).get(markdown_id) is None:
|
||||
return jsonify({"error": "markdown not found"}), 404
|
||||
try:
|
||||
actor = get_actor()
|
||||
now = datetime.now(UTC)
|
||||
patch = MarkdownPatch(
|
||||
markdown_id=markdown_id,
|
||||
title=data.get('title'),
|
||||
content=content,
|
||||
order=data.get('order', 0),
|
||||
author=actor,
|
||||
last_modified_by=actor,
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
)
|
||||
session.add(patch)
|
||||
session.commit()
|
||||
@@ -104,6 +111,8 @@ def update_patch(patch_id):
|
||||
patch.content = data.get('content')
|
||||
if 'order' in data:
|
||||
patch.order = data.get('order')
|
||||
patch.updated_at = datetime.now(UTC)
|
||||
patch.last_modified_by = get_actor()
|
||||
session.commit()
|
||||
return jsonify(patch.to_dict()), 200
|
||||
|
||||
|
||||
Reference in New Issue
Block a user