feat: add network-level kill switch endpoint
This commit is contained in:
@@ -117,6 +117,10 @@ class KillSwitchSchema(Schema):
|
||||
network_ids = fields.List(fields.Str(), allow_none=True)
|
||||
|
||||
|
||||
class NetworkKillSwitchSchema(Schema):
|
||||
reason = fields.Str(allow_none=True, validate=validate.Length(max=500))
|
||||
|
||||
|
||||
# ── Networks ──────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -971,6 +975,36 @@ def admin_list_sessions(org_id):
|
||||
)
|
||||
|
||||
|
||||
@api_v1_bp.route("/organizations/<org_id>/admin/sessions/<session_id>/end", methods=["POST"])
|
||||
@login_required
|
||||
@require_admin
|
||||
@full_access_required
|
||||
def admin_end_session(org_id, session_id):
|
||||
"""End a specific activation session (admin only).
|
||||
|
||||
Terminates the active session for any user, deauthorizes the device
|
||||
in ZeroTier, and marks the membership as inactive. The user retains
|
||||
their approval and can re-authenticate without re-approval.
|
||||
"""
|
||||
org, err = _org_check(org_id)
|
||||
if err:
|
||||
return err
|
||||
|
||||
try:
|
||||
session = network_access_service.admin_end_session(
|
||||
session_id=session_id,
|
||||
admin_user_id=g.current_user.id,
|
||||
)
|
||||
return api_response(
|
||||
data={"session": _session_to_dict(session, include_user=True)},
|
||||
message="Session ended successfully by admin",
|
||||
)
|
||||
except ApprovalNotFoundError as e:
|
||||
return api_response(success=False, message=str(e), status=404, error_type="NOT_FOUND")
|
||||
except AppValidationError as e:
|
||||
return api_response(success=False, message=str(e.message), status=400, error_type=e.error_type)
|
||||
|
||||
|
||||
# ── Kill Switch ───────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -1005,6 +1039,30 @@ def trigger_kill_switch(org_id):
|
||||
return api_response(success=False, message=str(e.message), status=400, error_type=e.error_type)
|
||||
|
||||
|
||||
@api_v1_bp.route("/organizations/<org_id>/networks/<network_id>/kill-switch", methods=["POST"])
|
||||
@login_required
|
||||
@require_admin
|
||||
@full_access_required
|
||||
def trigger_network_kill_switch(org_id, network_id):
|
||||
"""Deactivate all active memberships on a network (admin only)."""
|
||||
org, err = _org_check(org_id)
|
||||
if err:
|
||||
return err
|
||||
|
||||
schema = NetworkKillSwitchSchema()
|
||||
data = schema.load(request.json or {})
|
||||
|
||||
count = network_access_service.kill_switch_network(
|
||||
portal_network_id=network_id,
|
||||
organization_id=org_id,
|
||||
admin_user_id=g.current_user.id,
|
||||
)
|
||||
return api_response(
|
||||
data={"affected_count": count},
|
||||
message="Network kill switch triggered successfully",
|
||||
)
|
||||
|
||||
|
||||
# ── Admin / ZeroTier Controller ───────────────────────────────────────────────
|
||||
|
||||
@api_v1_bp.route("/organizations/<org_id>/admin/memberships", methods=["GET"])
|
||||
|
||||
Reference in New Issue
Block a user