From 37fc100ff7821cf575110a2c28af69818d476ab1 Mon Sep 17 00:00:00 2001 From: Fang-Pen Lin Date: Thu, 6 Nov 2025 20:12:47 -0800 Subject: [PATCH] Add access control tests --- .../features/pki/acme/access-control.feature | 45 +++++++++++++++++++ backend/bdd/features/pki/acme/nonce.feature | 16 +++---- backend/bdd/features/pki/acme/order.feature | 4 +- backend/bdd/features/steps/pki_acme.py | 7 +++ 4 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 backend/bdd/features/pki/acme/access-control.feature diff --git a/backend/bdd/features/pki/acme/access-control.feature b/backend/bdd/features/pki/acme/access-control.feature new file mode 100644 index 000000000..24d2a379c --- /dev/null +++ b/backend/bdd/features/pki/acme/access-control.feature @@ -0,0 +1,45 @@ +Feature: Access Control + + Scenario Outline: Access across resources for a different account + Given I have an ACME cert profile as "acme_profile" + When I have an ACME client connecting to {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/directory + Then I register a new ACME account with email fangpen@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account0 + Then I memorize acme_account0.uri with jq "capture("/(?[^/]+)$") | .id" as account0_id + When I create certificate signing request as csr + Then I add names to certificate signing request csr + """ + { + "COMMON_NAME": "localhost" + } + """ + Then I create a RSA private key pair as cert_key + Then I sign the certificate signing request csr with private key cert_key and output it as csr_pem in PEM format + Then I submit the certificate signing request PEM csr_pem certificate order to the ACME server as order + And I put away current ACME client as client0 + + When I have an ACME client connecting to {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/directory + Then I register a new ACME account with email maidu@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account1 + Then I peak and memorize the next nonce as nonce + Then I memorize with jq "" as + When I send a raw ACME request to "" + """ + { + "protected": { + "alg": "RS256", + "nonce": "{nonce}", + "url": "", + "kid": "{acme_account1.uri}" + }, + "payload": {} + } + """ + Then the value response.status_code should be equal to 404 + + Examples: Endpoints + | src_var | jq | dest_var | url + | order | . | not_used | {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/accounts/{account0_id}/orders | + | order | . | not_used | {order.uri} | + | order | . | not_used | {order.uri}/finalize | + | order | . | not_used | {order.uri}/certificate | + | order | .authorizations[0].uri | auth_uri | {auth_uri} | + | order | .authorizations[0].body.challenges[0].url | challenge_uri | {challenge_uri} | diff --git a/backend/bdd/features/pki/acme/nonce.feature b/backend/bdd/features/pki/acme/nonce.feature index d92770d2e..673191e16 100644 --- a/backend/bdd/features/pki/acme/nonce.feature +++ b/backend/bdd/features/pki/acme/nonce.feature @@ -22,25 +22,25 @@ Feature: Nonce Then I sign the certificate signing request csr with private key cert_key and output it as csr_pem in PEM format Then I submit the certificate signing request PEM csr_pem certificate order to the ACME server as order Then I memorize with jq "" as - When I send a raw ACME request to "" + When I send a raw ACME request to "" """ { "protected": { "alg": "RS256", "nonce": "oFvnlFP1wIhRlYS2jTaXbA", - "url": "", + "url": "", "kid": "{acme_account.uri}" }, "payload": {} } """ Then the value response.status_code should be equal to 400 - Then the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:badNonce" Then the value response with jq ".status" should be equal to 400 + Then the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:badNonce" Then the value response with jq ".detail" should be equal to "Invalid nonce" Examples: Endpoints - | src_var | jq | dest_var | path | + | src_var | jq | dest_var | url | | order | . | not_used | {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/accounts/{account_id}/orders | | order | . | not_used | {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/new-order | | order | . | not_used | {order.uri} | @@ -79,25 +79,25 @@ Feature: Nonce """ Then the value response.status_code should be equal to 200 Then I memorize with jq "" as - When I send a raw ACME request to "" + When I send a raw ACME request to "" """ { "protected": { "alg": "RS256", "nonce": "{nonce_value}", - "url": "", + "url": "", "kid": "{acme_account.uri}" }, "payload": {} } """ Then the value response.status_code should be equal to 400 - Then the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:badNonce" Then the value response with jq ".status" should be equal to 400 + Then the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:badNonce" Then the value response with jq ".detail" should be equal to "Invalid nonce" Examples: Endpoints - | src_var | jq | dest_var | path | + | src_var | jq | dest_var | url | | order | . | not_used | {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/accounts/{account_id}/orders | | order | . | not_used | {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/new-order | | order | . | not_used | {order.uri} | diff --git a/backend/bdd/features/pki/acme/order.feature b/backend/bdd/features/pki/acme/order.feature index aed647e47..a4cf4f121 100644 --- a/backend/bdd/features/pki/acme/order.feature +++ b/backend/bdd/features/pki/acme/order.feature @@ -102,8 +102,8 @@ Feature: Order | email | Then the value response.status_code should be equal to 400 - Then the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:unsupportedIdentifier" Then the value response with jq ".status" should be equal to 400 + Then the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:unsupportedIdentifier" Then the value response with jq ".detail" should be equal to "Only DNS identifiers are supported" Scenario Outline: Create an order with invalid identifier values @@ -136,6 +136,6 @@ Feature: Order | ../../etc/passwd | Then the value response.status_code should be equal to 400 - Then the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:unsupportedIdentifier" Then the value response with jq ".status" should be equal to 400 + Then the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:unsupportedIdentifier" Then the value response with jq ".detail" should be equal to "Invalid DNS identifier" diff --git a/backend/bdd/features/steps/pki_acme.py b/backend/bdd/features/steps/pki_acme.py index f6e8a2636..52a234644 100644 --- a/backend/bdd/features/steps/pki_acme.py +++ b/backend/bdd/features/steps/pki_acme.py @@ -499,6 +499,13 @@ def step_impl(context: Context, var_name: str): context.vars[var_name] = json_util.encode_b64jose(list(acme_client.net._nonces)[0]) +@then("I put away current ACME client as {var_name}") +def step_impl(context: Context, var_name: str): + acme_client = context.acme_client + del context.acme_client + context.vars[var_name] = acme_client + + @then("I memorize {var_path} as {var_name}") def step_impl(context: Context, var_path: str, var_name: str): value = eval_var(context, var_path)