From c8da49eee77315dfaa28750e8d55f20e11168029 Mon Sep 17 00:00:00 2001 From: Anderson Toshiyuki Sasaki Date: Wed, 16 Oct 2024 18:01:51 +0200 Subject: [PATCH] agent_handler: Move the /agent scope configuration Move the /agent scope configuration from main to agent_handler. This is a preparation to support multiple API versions. Also, restrict the visibility of methods that are not required outside the module to private. Signed-off-by: Anderson Toshiyuki Sasaki --- keylime-agent/src/agent_handler.rs | 77 ++++++++++++++++++++++++++++- keylime-agent/src/errors_handler.rs | 36 -------------- keylime-agent/src/main.rs | 12 ++--- 3 files changed, 78 insertions(+), 47 deletions(-) diff --git a/keylime-agent/src/agent_handler.rs b/keylime-agent/src/agent_handler.rs index 11d02186..d75f3fa9 100644 --- a/keylime-agent/src/agent_handler.rs +++ b/keylime-agent/src/agent_handler.rs @@ -3,7 +3,7 @@ use crate::common::JsonWrapper; use crate::{tpm, Error as KeylimeError, QuoteData}; -use actix_web::{web, HttpRequest, HttpResponse, Responder}; +use actix_web::{http, web, HttpRequest, HttpResponse, Responder}; use base64::{engine::general_purpose, Engine as _}; use log::*; use serde::{Deserialize, Serialize}; @@ -19,7 +19,7 @@ pub(crate) struct AgentInfo { // This is an Info request which gets some information about this keylime agent // It should return a AgentInfo object as JSON -pub async fn info( +async fn info( req: HttpRequest, data: web::Data, ) -> impl Responder { @@ -38,12 +38,52 @@ pub async fn info( HttpResponse::Ok().json(response) } +/// Configure the endpoints for the /agent scope +async fn agent_default(req: HttpRequest) -> impl Responder { + let error; + let response; + let message; + + match req.head().method { + http::Method::GET => { + error = 400; + message = "URI not supported, only /info is supported for GET in /agent interface"; + response = HttpResponse::BadRequest() + .json(JsonWrapper::error(error, message)); + } + _ => { + error = 405; + message = "Method is not supported in /agent interface"; + response = HttpResponse::MethodNotAllowed() + .insert_header(http::header::Allow(vec![http::Method::GET])) + .json(JsonWrapper::error(error, message)); + } + }; + + warn!( + "{} returning {} response. {}", + req.head().method, + error, + message + ); + + response +} + +/// Configure the endpoints for the /agents scope +pub(crate) fn configure_agent_endpoints(cfg: &mut web::ServiceConfig) { + _ = cfg + .service(web::resource("/info").route(web::get().to(info))) + .default_service(web::to(agent_default)); +} + #[cfg(test)] #[cfg(feature = "testing")] mod tests { use super::*; use crate::common::API_VERSION; use actix_web::{test, web, App}; + use serde_json::{json, Value}; #[actix_rt::test] async fn test_agent_info() { @@ -73,4 +113,37 @@ mod tests { assert_eq!(result.results.tpm_enc_alg.as_str(), "rsa"); assert_eq!(result.results.tpm_sign_alg.as_str(), "rsassa"); } + + #[actix_rt::test] + async fn test_agents_default() { + let mut app = test::init_service( + App::new().service(web::resource("/").to(agent_default)), + ) + .await; + + let req = test::TestRequest::get().uri("/").to_request(); + + let resp = test::call_service(&app, req).await; + assert!(resp.status().is_client_error()); + + let result: JsonWrapper = test::read_body_json(resp).await; + + assert_eq!(result.results, json!({})); + assert_eq!(result.code, 400); + + let req = test::TestRequest::delete().uri("/").to_request(); + + let resp = test::call_service(&app, req).await; + assert!(resp.status().is_client_error()); + + let headers = resp.headers(); + + assert!(headers.contains_key("allow")); + assert_eq!(headers.get("allow").unwrap().to_str().unwrap(), "GET"); //#[allow_ci] + + let result: JsonWrapper = test::read_body_json(resp).await; + + assert_eq!(result.results, json!({})); + assert_eq!(result.code, 405); + } } diff --git a/keylime-agent/src/errors_handler.rs b/keylime-agent/src/errors_handler.rs index 96a3902a..6e20bf44 100644 --- a/keylime-agent/src/errors_handler.rs +++ b/keylime-agent/src/errors_handler.rs @@ -96,37 +96,6 @@ pub(crate) async fn api_default(req: HttpRequest) -> impl Responder { response } -pub(crate) async fn agent_default(req: HttpRequest) -> impl Responder { - let error; - let response; - let message; - - match req.head().method { - http::Method::GET => { - error = 400; - message = "URI not supported, only /info is supported for GET in /agent interface"; - response = HttpResponse::BadRequest() - .json(JsonWrapper::error(error, message)); - } - _ => { - error = 405; - message = "Method is not supported in /agent interface"; - response = HttpResponse::MethodNotAllowed() - .insert_header(http::header::Allow(vec![http::Method::GET])) - .json(JsonWrapper::error(error, message)); - } - }; - - warn!( - "{} returning {} response. {}", - req.head().method, - error, - message - ); - - response -} - pub(crate) async fn version_not_supported( req: HttpRequest, version: web::Path, @@ -255,11 +224,6 @@ mod tests { test_default(web::resource("/").to(api_default), "GET, POST").await } - #[actix_rt::test] - async fn test_agent_default() { - test_default(web::resource("/").to(agent_default), "GET").await - } - #[derive(Serialize, Deserialize)] struct DummyQuery { param: String, diff --git a/keylime-agent/src/main.rs b/keylime-agent/src/main.rs index 1bcc27f7..ca5c0c69 100644 --- a/keylime-agent/src/main.rs +++ b/keylime-agent/src/main.rs @@ -897,15 +897,9 @@ async fn main() -> Result<()> { ) .service( web::scope(&format!("/{API_VERSION}")) - .service( - web::scope("/agent") - .service(web::resource("/info").route( - web::get().to(agent_handler::info), - )) - .default_service(web::to( - errors_handler::agent_default, - )), - ) + .service(web::scope("/agent").configure( + agent_handler::configure_agent_endpoints, + )) .service(web::scope("/keys").configure( keys_handler::configure_keys_endpoints, ))