Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
180471e
Rename crates to trusted-server-core and trusted-server-adapter-fastly
prk-Jr Mar 18, 2026
f63e5b2
Add platform abstraction layer with traits and RuntimeServices
prk-Jr Mar 19, 2026
020e88c
Merge remote-tracking branch 'origin/main' into feature/edgezero-pr1-…
prk-Jr Mar 19, 2026
37c8fbf
Merge branch 'feature/edgezero-pr1-crate-rename' into feature/edgezer…
prk-Jr Mar 19, 2026
7495d96
Merge branch 'main' into feature/edgezero-pr2-platform-traits
prk-Jr Mar 20, 2026
2c40d58
Address platform layer review feedback
prk-Jr Mar 20, 2026
46e3360
Reject host strings containing control characters in BackendConfig
prk-Jr Mar 20, 2026
2f40b4c
Fix clippy error
prk-Jr Mar 20, 2026
8210a85
Validate scheme and host for control characters in BackendConfig
prk-Jr Mar 20, 2026
99d7bee
Address review findings on platform abstraction layer
prk-Jr Mar 22, 2026
a2597e5
Address review findings on platform abstraction layer
prk-Jr Mar 22, 2026
d7a35a1
Merge branch 'main' into feature/edgezero-pr2-platform-traits
prk-Jr Mar 22, 2026
d8b267b
Add config store read path and storage module split
prk-Jr Mar 23, 2026
591b9b3
Merge branch 'main' into feature/edgezero-pr2-platform-traits
aram356 Mar 23, 2026
ce456a9
Merge branch 'main' into feature/edgezero-pr3-config-store
prk-Jr Mar 23, 2026
ed57b14
Merge branch 'main' into feature/edgezero-pr3-config-store
prk-Jr Mar 24, 2026
a8c5648
Harden legacy config-store reads and align Fastly adapter stubs
prk-Jr Mar 24, 2026
14e54c4
Address storage review feedback
prk-Jr Mar 25, 2026
c682c6d
Resolved github-advanced-security bot problems
prk-Jr Mar 25, 2026
eec34fb
Address PR review feedback on platform abstraction layer
prk-Jr Mar 25, 2026
d6be0b2
Merge branch 'main' into feature/edgezero-pr2-platform-traits
prk-Jr Mar 25, 2026
b25bfd6
Add PR 4 design spec for secret store trait (read-only)
prk-Jr Mar 25, 2026
a641eb0
Clarify test scope and deferred branches in PR 4 spec
prk-Jr Mar 25, 2026
1ee695c
Add implementation plan for PR 4 secret store trait
prk-Jr Mar 25, 2026
5b205bb
Add test for get_secret_bytes open-failure path
prk-Jr Mar 25, 2026
df6bc60
Add NotImplemented tests for FastlyPlatformSecretStore write stubs
prk-Jr Mar 25, 2026
21ec187
Inline StoreId binding and add section comment in write-stub tests
prk-Jr Mar 25, 2026
e51a7d6
Remove plan
prk-Jr Mar 25, 2026
b4bda32
Add PR 6 design spec for backend and HTTP client traits
prk-Jr Mar 25, 2026
57d6bec
Address spec review findings on PR 6 design
prk-Jr Mar 25, 2026
571656c
Implement PlatformHttpClient and thread RuntimeServices through proxy…
prk-Jr Mar 26, 2026
e271dce
Merge branch 'main' into feature/edgezero-pr6-backend-http-client
prk-Jr Mar 26, 2026
7181a92
Merge branch 'main' into feature/edgezero-pr3-config-store
prk-Jr Mar 26, 2026
f4c4b57
Merge branch 'main' into feature/edgezero-pr2-platform-traits
prk-Jr Mar 26, 2026
b8c4daf
Merge branch 'main' into feature/edgezero-pr4-secret-store
prk-Jr Mar 26, 2026
2bc167e
Merge branch 'main' into feature/edgezero-pr2-platform-traits
prk-Jr Mar 30, 2026
b458d64
Address pr review findings
prk-Jr Mar 30, 2026
089a805
Merge branch 'feature/edgezero-pr2-platform-traits' into feature/edge…
prk-Jr Mar 30, 2026
882fd29
Merge branch 'feature/edgezero-pr3-config-store' into feature/edgezer…
prk-Jr Mar 30, 2026
291ad66
Merge branch 'feature/edgezero-pr4-secret-store' into feature/edgezer…
prk-Jr Mar 30, 2026
ebf129b
Resolve pr review findings
prk-Jr Mar 30, 2026
2ff0ce9
Add PR7 design spec for geo lookup + client info extract-once
prk-Jr Mar 30, 2026
ead539c
Fix spec review issues in PR7 design doc
prk-Jr Mar 30, 2026
8bbfc74
Update PR7 spec to address all five agent review findings
prk-Jr Mar 30, 2026
b39cd79
Add PR7 implementation plan and address plan review findings
prk-Jr Mar 30, 2026
d6a624a
Fix three plan review findings and two open questions
prk-Jr Mar 30, 2026
986a1b2
Broaden two low-severity doc cleanup steps in PR7 plan
prk-Jr Mar 30, 2026
86079c5
Fix two remaining low findings in PR7 plan
prk-Jr Mar 30, 2026
a03a765
Fix count drift in Step 7: four → five locations
prk-Jr Mar 30, 2026
ac79961
Add client_info field to AuctionContext and fix all construction sites
prk-Jr Mar 30, 2026
b96aec0
Change RequestInfo::from_request to take &ClientInfo, thread services…
prk-Jr Mar 30, 2026
661e3df
Add Task 2 follow-up coverage and README route fixes
prk-Jr Mar 30, 2026
774a07f
Add services param to generate_synthetic_id, remove Fastly IP/geo cal…
prk-Jr Mar 30, 2026
95ce45e
Revert premature publisher geo change from Task 3
prk-Jr Mar 30, 2026
b10dcec
Replace deprecated GeoInfo::from_request in publisher.rs with service…
prk-Jr Mar 30, 2026
888170d
Remove Fastly IP extraction from Didomi copy_headers, use ClientInfo …
prk-Jr Mar 30, 2026
f856b68
Move IpAddr import to test module level in didomi.rs
prk-Jr Mar 30, 2026
eb12522
Apply rustfmt formatting to didomi.rs, publisher.rs, and synthetic.rs
prk-Jr Mar 30, 2026
7fcb3b4
Add test coverage for generate_synthetic_id with concrete client IP
prk-Jr Mar 31, 2026
1844290
Align geo lookup warn log format with codebase convention ({e} not {e…
prk-Jr Mar 31, 2026
0132a36
Apply Prettier formatting to PR7 plan and spec docs
prk-Jr Mar 31, 2026
ffa1174
Document content rewriting as platform-agnostic in platform module
prk-Jr Mar 31, 2026
fbbf767
Document html_processor as platform-agnostic
prk-Jr Mar 31, 2026
b89a9e6
Document streaming_processor as platform-agnostic
prk-Jr Mar 31, 2026
6fa8b38
Fix unresolved doc link: replace EdgeRequest with edgezero_core::http…
prk-Jr Mar 31, 2026
e9ce63d
Add plan for content rewriting
prk-Jr Mar 31, 2026
794b66d
Add plan for PR9: wire signing to store primitives
prk-Jr Mar 31, 2026
e13537b
Add build_services_with_config_and_secret to test_support
prk-Jr Mar 31, 2026
b0c6571
Merge branch 'main' into feature/edgezero-pr6-backend-http-client
prk-Jr Apr 1, 2026
14f282b
Merge branch 'feature/edgezero-pr6-backend-http-client' into feature/…
prk-Jr Apr 1, 2026
34c44bd
Merge branch 'feature/edgezero-pr7-geo-client-info' into feature/edge…
prk-Jr Apr 1, 2026
04b9cda
Merge branch 'feature/edgezero-pr8-content-rewriting' into feature/ed…
prk-Jr Apr 1, 2026
2c0c4eb
Add FastlyManagementApiClient to adapter
prk-Jr Apr 1, 2026
f6b00c8
Implement FastlyPlatformConfigStore and FastlyPlatformSecretStore wri…
prk-Jr Apr 1, 2026
ec62970
Migrate KeyRotationManager from FastlyApiClient to RuntimeServices st…
prk-Jr Apr 1, 2026
27a0949
Migrate signing.rs from FastlyConfigStore/FastlySecretStore to Runtim…
prk-Jr Apr 1, 2026
5b6555f
Delete storage/api_client.rs from core; remove FastlyApiClient
prk-Jr Apr 1, 2026
0a8915c
Fix formatting after CI gate check
prk-Jr Apr 1, 2026
2f1cc97
Add services to AuctionContext; remove deprecated from_config shim
prk-Jr Apr 2, 2026
ba141fa
Fix prettier formatting in PR9 plan document
prk-Jr Apr 2, 2026
7310198
Add PR 10 logging initialization design
prk-Jr Apr 2, 2026
a05189e
Add PR 10 logging initialization plan
prk-Jr Apr 2, 2026
4617253
Fix PR 10 logging plan to avoid per-log allocation
prk-Jr Apr 2, 2026
236eecf
Extract Fastly logging initialization into adapter module
prk-Jr Apr 2, 2026
cd68357
Wire Fastly main.rs to adapter-local logging module
prk-Jr Apr 2, 2026
41cb0df
Remove log-fastly from core dependencies
prk-Jr Apr 2, 2026
e437454
Format Fastly logging module declaration
prk-Jr Apr 2, 2026
f9b4d62
format plan docs
prk-Jr Apr 2, 2026
1a0c0b6
Address PR findings
prk-Jr Apr 6, 2026
49e3f1d
Restore idiomatic fern logging and improve target label extraction
prk-Jr Apr 6, 2026
086b32c
Migrate utility layer to HTTP types
prk-Jr Apr 8, 2026
7365ec4
Address PR review findings
prk-Jr Apr 8, 2026
079a97f
Address review findings
prk-Jr Apr 9, 2026
3924a98
Address review findings
prk-Jr Apr 10, 2026
dd6929c
Resolve review findings
prk-Jr Apr 10, 2026
2817761
Resolve PR review findings
prk-Jr Apr 10, 2026
d5f5c0d
Fix rotate/delete atomicity, HTTP verb, idempotent deletes, and weak …
prk-Jr Apr 15, 2026
f9df8da
Merge branch 'main' into feature/edgezero-pr9-wire-signing-to-store-p…
prk-Jr Apr 15, 2026
1acbfa7
Resolve PR review feedback on logging module
prk-Jr Apr 15, 2026
ae402ff
Address review findings
prk-Jr Apr 15, 2026
1a2cb46
Address round-3 review findings
prk-Jr Apr 21, 2026
9a1fd41
Resolve PR review findings
prk-Jr Apr 23, 2026
cd9cda7
Resolve PR review findings
prk-Jr Apr 23, 2026
cf0df8e
Resolve PR review findings
prk-Jr Apr 25, 2026
dfa0386
Merge branch 'main' into feature/edgezero-pr9-wire-signing-to-store-p…
prk-Jr Apr 26, 2026
e0c9bb8
Merge branch 'feature/edgezero-pr9-wire-signing-to-store-primitives' …
prk-Jr Apr 26, 2026
5f5b067
Merge branch 'feature/edgezero-pr10-abstract-logging-initialization' …
prk-Jr Apr 26, 2026
1d22f8c
Route Fastly cookie calls through compat bridge after PR10 merge
prk-Jr Apr 26, 2026
8eb72ee
Remove unused Logger import
prk-Jr Apr 26, 2026
2986f33
Merge branch 'feature/edgezero-pr10-abstract-logging-initialization' …
prk-Jr Apr 26, 2026
76df6f8
Resolve PR review findings
prk-Jr Apr 30, 2026
2a908d4
Merge branch 'main' into feature/edgezero-pr11-utility-layer-migratio…
prk-Jr Apr 30, 2026
65d1e2d
Fix fmt lint
prk-Jr Apr 30, 2026
73734dd
Rename synthetic_id_cookie_value_is_safe → ec_cookie_value_is_safe
prk-Jr Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
763 changes: 433 additions & 330 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ log = "0.4.29"
log-fastly = "0.11.12"
lol_html = "2.7.2"
matchit = "0.9"
mime = "0.3"
rand = "0.8"
regex = "1.12.3"
serde = { version = "1.0", features = ["derive"] }
Expand Down
10 changes: 6 additions & 4 deletions crates/trusted-server-adapter-fastly/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ use fastly::{Request, Response};
use trusted_server_core::auction::endpoints::handle_auction;
use trusted_server_core::auction::{build_orchestrator, AuctionOrchestrator};
use trusted_server_core::auth::enforce_basic_auth;
use trusted_server_core::compat;
use trusted_server_core::constants::{
ENV_FASTLY_IS_STAGING, ENV_FASTLY_SERVICE_VERSION, HEADER_X_GEO_INFO_AVAILABLE,
HEADER_X_TS_ENV, HEADER_X_TS_VERSION,
};
use trusted_server_core::error::TrustedServerError;
use trusted_server_core::geo::GeoInfo;
use trusted_server_core::http_util::sanitize_forwarded_headers;
use trusted_server_core::integrations::IntegrationRegistry;
use trusted_server_core::platform::RuntimeServices;
use trusted_server_core::proxy::{
Expand Down Expand Up @@ -119,7 +119,7 @@ async fn route_request(
// Strip client-spoofable forwarded headers at the edge.
// On Fastly this service IS the first proxy — these headers from
// clients are untrusted and can hijack URL rewriting (see #409).
sanitize_forwarded_headers(&mut req);
compat::sanitize_fastly_forwarded_headers(&mut req);

// Look up geo info via the platform abstraction using the client IP
// already captured in RuntimeServices at the entry point.
Expand All @@ -134,8 +134,10 @@ async fn route_request(
// `get_settings()` should already have rejected invalid handler regexes.
// Keep this fallback so manually-constructed or otherwise unprepared
// settings still become an error response instead of panicking.
match enforce_basic_auth(settings, &req) {
Ok(Some(mut response)) => {
let auth_req = compat::from_fastly_headers_ref(&req);
match enforce_basic_auth(settings, &auth_req) {
Ok(Some(response)) => {
let mut response = compat::to_fastly_response(response);
finalize_response(settings, geo_info.as_ref(), &mut response);
return Some(response);
}
Expand Down
1 change: 1 addition & 0 deletions crates/trusted-server-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ http = { workspace = true }
iab_gpp = { workspace = true }
jose-jwk = { workspace = true }
log = { workspace = true }
mime = { workspace = true }
rand = { workspace = true }
lol_html = { workspace = true }
matchit = { workspace = true }
Expand Down
7 changes: 5 additions & 2 deletions crates/trusted-server-core/src/auction/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use error_stack::{Report, ResultExt};
use fastly::{Request, Response};

use crate::auction::formats::AdRequest;
use crate::compat;
use crate::consent;
use crate::cookies::handle_request_cookies;
use crate::edge_cookie::get_or_generate_ec_id;
Expand Down Expand Up @@ -46,6 +47,8 @@ pub async fn handle_auction(
body.ad_units.len()
);

let http_req = compat::from_fastly_headers_ref(&req);

// Generate EC ID early so the consent pipeline can use it for
// KV Store fallback/write operations.
let ec_id = get_or_generate_ec_id(settings, services, &req).change_context(
Expand All @@ -55,7 +58,7 @@ pub async fn handle_auction(
)?;

// Extract consent from request cookies, headers, and geo.
let cookie_jar = handle_request_cookies(&req)?;
let cookie_jar = handle_request_cookies(&http_req)?;
let geo = services
.geo()
.lookup(services.client_info.client_ip)
Expand All @@ -65,7 +68,7 @@ pub async fn handle_auction(
});
let consent_context = consent::build_consent_context(&consent::ConsentPipelineInput {
jar: cookie_jar.as_ref(),
req: &req,
req: &http_req,
config: &settings.consent,
geo: geo.as_ref(),
ec_id: Some(ec_id.as_str()),
Expand Down
98 changes: 59 additions & 39 deletions crates/trusted-server-core/src/auth.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use base64::{engine::general_purpose::STANDARD, Engine as _};
use edgezero_core::body::Body as EdgeBody;
use error_stack::Report;
use fastly::http::{header, StatusCode};
use fastly::{Request, Response};
use http::header;
use http::{Request, Response, StatusCode};
use sha2::{Digest as _, Sha256};
use subtle::ConstantTimeEq as _;

Expand All @@ -27,9 +28,9 @@ const BASIC_AUTH_REALM: &str = r#"Basic realm="Trusted Server""#;
/// un-compilable path regex.
pub fn enforce_basic_auth(
settings: &Settings,
req: &Request,
) -> Result<Option<Response>, Report<TrustedServerError>> {
let Some(handler) = settings.handler_for_path(req.get_path())? else {
req: &Request<EdgeBody>,
) -> Result<Option<Response<EdgeBody>>, Report<TrustedServerError>> {
let Some(handler) = settings.handler_for_path(req.uri().path())? else {
return Ok(None);
};

Expand All @@ -53,14 +54,15 @@ pub fn enforce_basic_auth(
if bool::from(username_match & password_match) {
Ok(None)
} else {
log::warn!("Basic auth failed for path: {}", req.get_path());
log::warn!("Basic auth failed for path: {}", req.uri().path());
Ok(Some(unauthorized_response()))
}
}

fn extract_credentials(req: &Request) -> Option<(String, String)> {
fn extract_credentials(req: &Request<EdgeBody>) -> Option<(String, String)> {
let header_value = req
.get_header(header::AUTHORIZATION)
.headers()
.get(header::AUTHORIZATION)
.and_then(|value| value.to_str().ok())?;

let mut parts = header_value.splitn(2, ' ');
Expand All @@ -84,25 +86,42 @@ fn extract_credentials(req: &Request) -> Option<(String, String)> {
Some((username, password))
}

fn unauthorized_response() -> Response {
Response::from_status(StatusCode::UNAUTHORIZED)
.with_header(header::WWW_AUTHENTICATE, BASIC_AUTH_REALM)
.with_header(header::CONTENT_TYPE, "text/plain; charset=utf-8")
.with_body_text_plain("Unauthorized")
fn unauthorized_response() -> Response<EdgeBody> {
Response::builder()
.status(StatusCode::UNAUTHORIZED)
.header(header::WWW_AUTHENTICATE, BASIC_AUTH_REALM)
.header(header::CONTENT_TYPE, "text/plain; charset=utf-8")
.body(EdgeBody::from(b"Unauthorized".as_ref()))
.expect("should build unauthorized response")
}

#[cfg(test)]
mod tests {
use super::*;
use base64::engine::general_purpose::STANDARD;
use fastly::http::{header, Method};
use http::{header, HeaderValue, Method};

use crate::test_support::tests::{crate_test_settings_str, create_test_settings};

fn build_request(method: Method, uri: &str) -> Request<EdgeBody> {
Request::builder()
.method(method)
.uri(uri)
.body(EdgeBody::empty())
.expect("should build request")
}

fn set_authorization(req: &mut Request<EdgeBody>, value: &str) {
req.headers_mut().insert(
header::AUTHORIZATION,
HeaderValue::from_str(value).expect("should build authorization header"),
);
}

#[test]
fn no_challenge_for_non_protected_path() {
let settings = create_test_settings();
let req = Request::new(Method::GET, "https://example.com/open");
let req = build_request(Method::GET, "https://example.com/open");

assert!(enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
Expand All @@ -112,24 +131,25 @@ mod tests {
#[test]
fn challenge_when_missing_credentials() {
let settings = create_test_settings();
let req = Request::new(Method::GET, "https://example.com/secure");
let req = build_request(Method::GET, "https://example.com/secure");

let response = enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
.expect("should challenge");
assert_eq!(response.get_status(), StatusCode::UNAUTHORIZED);
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
let realm = response
.get_header(header::WWW_AUTHENTICATE)
.headers()
.get(header::WWW_AUTHENTICATE)
.expect("should have WWW-Authenticate header");
assert_eq!(realm, BASIC_AUTH_REALM);
}

#[test]
fn allow_when_credentials_match() {
let settings = create_test_settings();
let mut req = Request::new(Method::GET, "https://example.com/secure/data");
let mut req = build_request(Method::GET, "https://example.com/secure/data");
let token = STANDARD.encode("user:pass");
req.set_header(header::AUTHORIZATION, format!("Basic {token}"));
set_authorization(&mut req, &format!("Basic {token}"));

assert!(enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
Expand All @@ -139,29 +159,29 @@ mod tests {
#[test]
fn challenge_when_both_credentials_wrong() {
let settings = create_test_settings();
let mut req = Request::new(Method::GET, "https://example.com/secure/data");
let mut req = build_request(Method::GET, "https://example.com/secure/data");
let token = STANDARD.encode("wrong:wrong");
req.set_header(header::AUTHORIZATION, format!("Basic {token}"));
set_authorization(&mut req, &format!("Basic {token}"));

let response = enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
.expect("should challenge");
assert_eq!(response.get_status(), StatusCode::UNAUTHORIZED);
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
}

#[test]
fn challenge_when_username_wrong_password_correct() {
// Validates that both fields are always evaluated — no short-circuit username oracle.
let settings = create_test_settings();
let mut req = Request::new(Method::GET, "https://example.com/secure/data");
let mut req = build_request(Method::GET, "https://example.com/secure/data");
let token = STANDARD.encode("wrong-user:pass");
req.set_header(header::AUTHORIZATION, format!("Basic {token}"));
set_authorization(&mut req, &format!("Basic {token}"));

let response = enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
.expect("should challenge");
assert_eq!(
response.get_status(),
response.status(),
StatusCode::UNAUTHORIZED,
"should reject wrong username even with correct password"
);
Expand All @@ -170,15 +190,15 @@ mod tests {
#[test]
fn challenge_when_username_correct_password_wrong() {
let settings = create_test_settings();
let mut req = Request::new(Method::GET, "https://example.com/secure/data");
let mut req = build_request(Method::GET, "https://example.com/secure/data");
let token = STANDARD.encode("user:wrong-pass");
req.set_header(header::AUTHORIZATION, format!("Basic {token}"));
set_authorization(&mut req, &format!("Basic {token}"));

let response = enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
.expect("should challenge");
assert_eq!(
response.get_status(),
response.status(),
StatusCode::UNAUTHORIZED,
"should reject correct username with wrong password"
);
Expand All @@ -187,13 +207,13 @@ mod tests {
#[test]
fn challenge_when_scheme_is_not_basic() {
let settings = create_test_settings();
let mut req = Request::new(Method::GET, "https://example.com/secure");
req.set_header(header::AUTHORIZATION, "Bearer token");
let mut req = build_request(Method::GET, "https://example.com/secure");
set_authorization(&mut req, "Bearer token");

let response = enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
.expect("should challenge");
assert_eq!(response.get_status(), StatusCode::UNAUTHORIZED);
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
}

#[test]
Expand All @@ -210,9 +230,9 @@ mod tests {
#[test]
fn allow_admin_path_with_valid_credentials() {
let settings = create_test_settings();
let mut req = Request::new(Method::POST, "https://example.com/admin/keys/rotate");
let mut req = build_request(Method::POST, "https://example.com/admin/keys/rotate");
let token = STANDARD.encode("admin:admin-pass");
req.set_header(header::AUTHORIZATION, format!("Basic {token}"));
set_authorization(&mut req, &format!("Basic {token}"));

assert!(
enforce_basic_auth(&settings, &req)
Expand All @@ -225,24 +245,24 @@ mod tests {
#[test]
fn challenge_admin_path_with_wrong_credentials() {
let settings = create_test_settings();
let mut req = Request::new(Method::POST, "https://example.com/admin/keys/rotate");
let mut req = build_request(Method::POST, "https://example.com/admin/keys/rotate");
let token = STANDARD.encode("admin:wrong");
req.set_header(header::AUTHORIZATION, format!("Basic {token}"));
set_authorization(&mut req, &format!("Basic {token}"));

let response = enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
.expect("should challenge admin path with wrong credentials");
assert_eq!(response.get_status(), StatusCode::UNAUTHORIZED);
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
}

#[test]
fn challenge_admin_path_with_missing_credentials() {
let settings = create_test_settings();
let req = Request::new(Method::POST, "https://example.com/admin/keys/rotate");
let req = build_request(Method::POST, "https://example.com/admin/keys/rotate");

let response = enforce_basic_auth(&settings, &req)
.expect("should evaluate auth")
.expect("should challenge admin path with missing credentials");
assert_eq!(response.get_status(), StatusCode::UNAUTHORIZED);
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
}
}
Loading
Loading