This commit is contained in:
Mateusz Gruszczyński committed 2026-10-08 11:27:18 +02:00
1 parent d940f9995f
commit 65e082b9d1
61 files changed
+1225 -581

No files matched your search

+69 -12
View File
@@ -185,6 +185,8 @@
"file-renewer",
&crate::auth::secret_hash(&api_token),
"external file renewal hook",
false,
&["manual-file".to_owned()],
"owner",
)
.await
@@ -223,7 +225,7 @@
.header("x-rustproxy-request", "1")
.header("x-csrf-token", &csrf)
.header("content-type", "application/json")
.body(Body::from(json!({"key_id":"x","token":token}).to_string()))
.body(Body::from(json!({"key_id":"x","token":token,"certificate_ids":["shared-cert"]}).to_string()))
.unwrap(),
)
.await
@@ -245,7 +247,13 @@
.header("x-csrf-token", &csrf)
.header("content-type", "application/json")
.body(Body::from(
json!({"key_id":key_id,"token":value,"comment":comment}).to_string(),
json!({
"key_id":key_id,
"token":value,
"comment":comment,
"certificate_ids":[if key_id == "certbot-main" { "shared-cert" } else { "deploy-cert" }],
"allow_deploy": key_id == "deploy-hook"
}).to_string(),
))
.unwrap(),
)
@@ -256,6 +264,8 @@
assert_eq!(rotated["configured"], true);
assert_eq!(rotated["credential"]["key_id"], key_id);
assert_eq!(rotated["credential"]["comment"], comment);
assert_eq!(rotated["credential"]["allow_deploy"], key_id == "deploy-hook");
assert_eq!(rotated["credential"]["certificate_ids"].as_array().unwrap().len(), 1);
assert_eq!(rotated["token"], value);
}
@@ -274,8 +284,8 @@
assert_eq!(status["credentials"].as_array().unwrap().len(), 2);
assert!(status.get("token").is_none());
let external = |key_id: &'static str, value: String| {
request("/api/certificates/reload")
let external = |path: &'static str, key_id: &'static str, value: String| {
request(path)
.method("POST")
.header("authorization", format!("Bearer {value}"))
.header("x-rustproxy-certificate-key", key_id)
@@ -283,18 +293,65 @@
.body(Body::from("{}"))
.unwrap()
};
// Certificate API credentials cannot trigger an all-certificate reload.
let response = router
.clone()
.oneshot(external("certbot-main", token.clone()))
.oneshot(external("/api/certificates/reload", "certbot-main", token.clone()))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
assert_eq!(response.status(), StatusCode::FORBIDDEN);
// The allowlisted ID passes the auth gate and reaches the handler; this
// fixture intentionally has no such configured certificate, so it is 404.
let response = router
.clone()
.oneshot(external("deploy-hook", token_two.clone()))
.oneshot(external("/api/certificates/shared-cert/reload", "certbot-main", token.clone()))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
assert_eq!(response.status(), StatusCode::NOT_FOUND);
// A reload-only token cannot use the deploy endpoint at all.
let response = router
.clone()
.oneshot(
request("/api/certificates/deploy")
.method("POST")
.header("authorization", format!("Bearer {token}"))
.header("x-rustproxy-certificate-key", "certbot-main")
.header("content-type", "application/json")
.body(Body::from("{}"))
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::FORBIDDEN);
// A different ID is rejected by the credential grant before the handler.
let response = router
.clone()
.oneshot(external("/api/certificates/deploy-cert/reload", "certbot-main", token.clone()))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::FORBIDDEN);
let response = router
.clone()
.oneshot(external("/api/certificates/deploy-cert/reload", "deploy-hook", token_two.clone()))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::NOT_FOUND);
let response = router
.clone()
.oneshot(
request("/api/certificates/deploy")
.method("POST")
.header("authorization", format!("Bearer {token_two}"))
.header("x-rustproxy-certificate-key", "deploy-hook")
.header("content-type", "application/json")
.body(Body::from(
json!({"certificate_id":"shared-cert","cert_pem":"bad","key_pem":"bad"}).to_string(),
))
.unwrap(),
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::FORBIDDEN);
let missing_key = router
.clone()
@@ -340,16 +397,16 @@
assert_eq!(revoked.status(), StatusCode::OK);
let response = router
.clone()
.oneshot(external("certbot-main", token.clone()))
.oneshot(external("/api/certificates/shared-cert/reload", "certbot-main", token.clone()))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
let response = router
.clone()
.oneshot(external("deploy-hook", token_two.clone()))
.oneshot(external("/api/certificates/deploy-cert/reload", "deploy-hook", token_two.clone()))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
assert_eq!(response.status(), StatusCode::NOT_FOUND);
let revoked_all = router
.clone()
@@ -367,7 +424,7 @@
.unwrap();
assert_eq!(revoked_all.status(), StatusCode::OK);
let response = router
.oneshot(external("deploy-hook", token_two))
.oneshot(external("/api/certificates/deploy-cert/reload", "deploy-hook", token_two))
.await
.unwrap();
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);