Loading capif_backend/backoffice_service/controllers/me_controller.py +12 −3 Changes for capif_backend/backoffice_service/controllers/me_controller.py: 12 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -80,14 +80,23 @@ def onboard_provider(user_uuid): @jwt_required() @capif_user_required def list_my_providers(user_uuid): # No user input reaches the Vault path here: the uuid comes from the JWT. # No user input reaches the Vault paths here: the uuid comes from the JWT, and the ids come # from Vault's own listing. try: provider_ids = list_providers(user_uuid) providers = [] for prov_dom_id in list_providers(user_uuid): secret = read_provider(user_uuid, prov_dom_id) if secret is None: continue # deleted between the list and the read providers.append({ "apiProvDomId": prov_dom_id, "onboardedAt": provider_ops.onboarded_at(secret), }) except VaultError as e: print(f"ERROR: {e}") return jsonify({"error": "Could not list providers."}), 500 return jsonify({"providers": provider_ids}), 200 return jsonify({"providers": providers}), 200 @me_routes.route("/providers/<api_prov_dom_id>/apis", methods=["POST"]) @jwt_required() Loading capif_backend/backoffice_service/core/provider_ops.py +18 −0 Changes for capif_backend/backoffice_service/core/provider_ops.py: 18 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import os import requests from cryptography import x509 from ..utils.certs import generate_keypair_and_csr, mtls_files, SecureTempUnavailable from ..utils.vault import store_provider Loading Loading @@ -266,3 +267,20 @@ def publish(publish_url_template, functions, api): if not api_id: print("WARNING: CCF publish returned 201 without an apiId") return {"apiId": api_id}, 201 def onboarded_at(provider_secret): """Return when a provider was onboarded, as an ISO 8601 UTC string, or None if unknown. Taken from the APF certificate's not-before date: all three certificates are issued in the same onboarding, and the secret stores no date of its own. Vault backdates not-before by about 30 seconds, which is close enough for display. """ certificate = ((provider_secret.get("functions") or {}).get("apf") or {}).get("certificate") if not certificate: return None try: cert = x509.load_pem_x509_certificate(certificate.encode("utf-8")) except ValueError: print("WARNING: could not parse a stored APF certificate") return None return cert.not_valid_before_utc.isoformat() No newline at end of file Loading
capif_backend/backoffice_service/controllers/me_controller.py +12 −3 Changes for capif_backend/backoffice_service/controllers/me_controller.py: 12 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -80,14 +80,23 @@ def onboard_provider(user_uuid): @jwt_required() @capif_user_required def list_my_providers(user_uuid): # No user input reaches the Vault path here: the uuid comes from the JWT. # No user input reaches the Vault paths here: the uuid comes from the JWT, and the ids come # from Vault's own listing. try: provider_ids = list_providers(user_uuid) providers = [] for prov_dom_id in list_providers(user_uuid): secret = read_provider(user_uuid, prov_dom_id) if secret is None: continue # deleted between the list and the read providers.append({ "apiProvDomId": prov_dom_id, "onboardedAt": provider_ops.onboarded_at(secret), }) except VaultError as e: print(f"ERROR: {e}") return jsonify({"error": "Could not list providers."}), 500 return jsonify({"providers": provider_ids}), 200 return jsonify({"providers": providers}), 200 @me_routes.route("/providers/<api_prov_dom_id>/apis", methods=["POST"]) @jwt_required() Loading
capif_backend/backoffice_service/core/provider_ops.py +18 −0 Changes for capif_backend/backoffice_service/core/provider_ops.py: 18 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import os import requests from cryptography import x509 from ..utils.certs import generate_keypair_and_csr, mtls_files, SecureTempUnavailable from ..utils.vault import store_provider Loading Loading @@ -266,3 +267,20 @@ def publish(publish_url_template, functions, api): if not api_id: print("WARNING: CCF publish returned 201 without an apiId") return {"apiId": api_id}, 201 def onboarded_at(provider_secret): """Return when a provider was onboarded, as an ISO 8601 UTC string, or None if unknown. Taken from the APF certificate's not-before date: all three certificates are issued in the same onboarding, and the secret stores no date of its own. Vault backdates not-before by about 30 seconds, which is close enough for display. """ certificate = ((provider_secret.get("functions") or {}).get("apf") or {}).get("certificate") if not certificate: return None try: cert = x509.load_pem_x509_certificate(certificate.encode("utf-8")) except ValueError: print("WARNING: could not parse a stored APF certificate") return None return cert.not_valid_before_utc.isoformat() No newline at end of file