mirror of
https://github.com/zvx-echo6/recon.git
synced 2026-05-20 22:54:46 +02:00
Add contacts/phone book system with per-user scoping
New files: - lib/auth.py: Authentik forward-auth helpers (get_user_id, @require_auth) - lib/contacts.py: ContactsDB with CRUD, soft delete, restore, purge, find_nearby - lib/contacts_api.py: Flask Blueprint with 9 API endpoints at /api/contacts - templates/knowledge/deleted_contacts.html: Dashboard recovery page Modified: - lib/api.py: Register contacts_bp, add KNOWLEDGE_SUBNAV entry, /deleted-contacts route - config/profiles: has_contacts feature flag (true for home, false for pi profiles) Separate SQLite DB at data/contacts.db. Per-user isolation via X-Authentik-Username. Home/Work labels enforced unique per user. Haversine proximity queries (75m default). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
095bf8c2af
commit
a4288c0cd8
8 changed files with 423 additions and 0 deletions
22
lib/auth.py
Normal file
22
lib/auth.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
RECON Auth Helper — extract user identity from Authentik forward-auth headers.
|
||||
"""
|
||||
from functools import wraps
|
||||
from flask import request, jsonify
|
||||
|
||||
|
||||
def get_user_id():
|
||||
"""Return X-Authentik-Username or None."""
|
||||
return request.headers.get('X-Authentik-Username')
|
||||
|
||||
|
||||
def require_auth(f):
|
||||
"""Decorator: 401 if no Authentik auth header."""
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
user_id = get_user_id()
|
||||
if not user_id:
|
||||
return jsonify({'error': 'Authentication required'}), 401
|
||||
request.user_id = user_id
|
||||
return f(*args, **kwargs)
|
||||
return wrapper
|
||||
Loading…
Add table
Add a link
Reference in a new issue