update parsing logic and add tests

This commit is contained in:
ppc
2026-01-09 20:09:44 +00:00
parent 6630496280
commit 59d1a8bd3e
4 changed files with 339 additions and 73 deletions
+23 -20
View File
@@ -24,6 +24,14 @@ pub fn build_server() -> Router {
.layer(services)
}
fn build_error_response(status: StatusCode, message: &str) -> Response {
let error = crate::webapi::ServerError {
error: message.to_string(),
};
(status, Json(error)).into_response()
}
async fn server_state_handler() -> Json<crate::webapi::ServerState> {
let config = Config::instance();
let metrics = SystemMetrics::instance();
@@ -49,23 +57,26 @@ async fn card_submission_handler(
return build_error_response(StatusCode::BAD_REQUEST, "Access code is required");
}
if !utils::is_valid_access_code(&payload.access_code) {
let Some(access_code) = utils::parse_access_code(&payload.access_code) else {
return build_error_response(StatusCode::UNPROCESSABLE_ENTITY, "Invalid access code provided");
}
};
if payload.card_idm_hex.as_ref().is_some_and(|idm| idm.chars().any(|c| !c.is_ascii_hexdigit())) {
return build_error_response(StatusCode::UNPROCESSABLE_ENTITY, "Invalid IDm provided");
}
let card_idm_bytes = if let Some(idm_hex) = payload.card_idm_hex.as_ref() {
if idm_hex.len() != 16 {
return build_error_response(StatusCode::BAD_REQUEST, "IDm must be a 16-char hex string");
}
let presenter = CardPresenter::instance().present_card(
&payload.access_code,
payload.card_idm_hex.as_ref(),
Duration::from_secs(5),
);
let Some(idm_bytes) = utils::parse_idm_hex(idm_hex) else {
return build_error_response(StatusCode::UNPROCESSABLE_ENTITY, "Invalid IDm provided");
};
match presenter {
Some(idm_bytes)
} else {
None
};
match CardPresenter::instance().present_card(access_code, card_idm_bytes, Duration::from_secs(5)) {
CardPresentResult::Accepted => StatusCode::ACCEPTED.into_response(),
CardPresentResult::Rejected(message) => build_error_response(StatusCode::FORBIDDEN, format!("Card rejected: {}", message).as_str()),
CardPresentResult::SlotUnavailable(release_time) => {
let now = Instant::now();
let wait_secs = if release_time > now {
@@ -86,11 +97,3 @@ async fn card_submission_handler(
}
}
}
fn build_error_response(status: StatusCode, message: &str) -> Response {
let error = crate::webapi::ServerError {
error: message.to_string(),
};
(status, Json(error)).into_response()
}