Commit 4dd88a2a authored by Alex Kakiris's avatar Alex Kakiris
Browse files

list the user's invokers from Vault

parent ed1f949c
Loading
Loading
Loading
Loading
+19 −1
Changes for capif_backend/backoffice_service/controllers/me_controller.py: 19 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ from flask_jwt_extended import jwt_required

from ..core.operations import Operations
from ..utils.utils import get_capif_token, get_capif_urls, get_capif_uuid
from ..utils.vault import read_invoker, VaultError
from ..utils.vault import read_invoker, list_invokers, VaultError

me_routes = Blueprint("me_routes", __name__)
operations = Operations()   # create operations object -> operations.py
@@ -31,6 +31,24 @@ def onboard_invoker():
    )
    return jsonify(data), status

@me_routes.route("/invokers", methods=["GET"])
@jwt_required()
def list_my_invokers():
    if not get_capif_token():
        return jsonify({"error": "This account has no CAPIF credentials."}), 403

    user_uuid = get_capif_uuid()
    if not user_uuid:
        return jsonify({"error": "Could not determine the CAPIF user id for this account."}), 500

    try:
        invoker_ids = list_invokers(user_uuid)
    except VaultError as e:
        print(f"ERROR: {e}")
        return jsonify({"error": "Could not list invokers."}), 500

    return jsonify({"invokers": invoker_ids}), 200

@me_routes.route("/invokers/<api_invoker_id>/apis", methods=["GET"])
@jwt_required()
def discover_apis(api_invoker_id):
+29 −0
Changes for capif_backend/backoffice_service/utils/vault.py: 29 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -82,3 +82,32 @@ def read_invoker(user_uuid, invoker_id):
        return response.json()["data"]["data"]
    except (ValueError, KeyError, TypeError) as e:
        raise VaultError(f"Unexpected Vault response shape for invoker {invoker_id}") from e

def list_invokers(user_uuid):
    """Return the apiInvokerIds stored for a user."""

    path = f"secret/metadata/backoffice/users/{user_uuid}/invokers"
    try:
        response = requests.get(
           f"{vault_addr()}/v1/{path}",
           params={"list": "true"},
           headers=vault_headers(),
           verify=vault_verify(),
           timeout=10,
        )
    except requests.exceptions.RequestException as e:
        raise VaultError(f"Vault list of invokers failed: {e}") from e

    # Vault returns 404 when the path has no keys: this user has no invokers yet.
    if response.status_code == 404:
        return []
    if not response.ok:
        raise VaultError(f"Vault list of invokers failed: {response.status_code}")

    try:
        keys = response.json()["data"]["keys"]
    except (ValueError, KeyError, TypeError) as e:
        raise VaultError("Unexpected Vault list response shape") from e

    # Keys ending in "/" would be sub-folders, not invokers
    return [key for key in keys if not key.endswith("/")]
 No newline at end of file