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:
@@ -223,4 +223,25 @@ def update_last_used(api_key):
|
||||
session.query(APIKey).filter_by(key=api_key.key).update(
|
||||
{APIKey.last_used_at: datetime.now(UTC)}
|
||||
)
|
||||
session.commit()
|
||||
session.commit()
|
||||
|
||||
|
||||
def get_actor():
|
||||
"""Identity string to record as author/last_modified_by.
|
||||
|
||||
- X-API-Key request -> the key's alias
|
||||
- Keycloak Bearer request -> the literal 'admin' (the backend does not
|
||||
track individual KC identities)
|
||||
- otherwise -> None
|
||||
Call only from endpoints already behind @require_auth.
|
||||
"""
|
||||
api_key_header = request.headers.get('X-API-Key')
|
||||
if api_key_header:
|
||||
api_key = get_api_key(api_key_header)
|
||||
if api_key:
|
||||
return api_key.alias
|
||||
return None
|
||||
auth_header = request.headers.get('Authorization')
|
||||
if auth_header and auth_header.startswith('Bearer'):
|
||||
return 'admin'
|
||||
return None
|
||||
Reference in New Issue
Block a user