diff --git a/app/src/api.rs b/app/src/api.rs index 3ebb113..fc8102d 100644 --- a/app/src/api.rs +++ b/app/src/api.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Error}; +use anyhow::Result; use lldap_model::*; use yew::callback::Callback; @@ -9,21 +9,32 @@ use yew::services::fetch::{FetchService, FetchTask, Request, Response}; pub struct HostService {} impl HostService { - pub fn list_users(&mut self, request: ListUsersRequest, callback: Callback, Error>>) -> Result { + pub fn list_users( + &mut self, + request: ListUsersRequest, + callback: Callback>>, + ) -> Result { let url = format!("/api/users"); - let handler = move |response: Response, Error>>>| { - let (meta, Json(data)) = response.into_parts(); - if meta.status.is_success() { - callback.emit(data) - } else { - callback.emit(Err(anyhow!( - "{}: error getting users from /api/users", - meta.status - ))) - } - }; - let request = Request::post(url.as_str()).header("Content-Type", "application/json").body(Json(&request)).unwrap(); + let handler = + move |response: Response>| { + let (meta, maybe_data) = response.into_parts(); + match maybe_data { + Ok(data) => { + if meta.status.is_success() { + callback.emit(serde_json::from_str(&data).map_err(|e| { + anyhow::format_err!("Could not parse response: {}", e) + })) + } else { + callback.emit(Err(anyhow::anyhow!("[{}]: {}", meta.status, data))) + } + } + Err(e) => callback.emit(Err(anyhow::anyhow!("Could not fetch: {}", e))), + } + }; + let request = Request::post(url.as_str()) + .header("Content-Type", "application/json") + .body(Json(&request)) + .unwrap(); FetchService::fetch(request, handler.into()) } } - diff --git a/app/src/app.rs b/app/src/app.rs index a4372d6..225b201 100644 --- a/app/src/app.rs +++ b/app/src/app.rs @@ -41,9 +41,7 @@ impl Component for App { Ok(task) => self.task = Some(task), Err(e) => { self.task = None; - ConsoleService::log( - format!("Error trying to fetch users: {:?}", e).as_str(), - ) + ConsoleService::log(format!("Error trying to fetch users: {}", e).as_str()) } } } @@ -53,7 +51,7 @@ impl Component for App { } Msg::ListUsersResponse(Err(e)) => { self.task = None; - ConsoleService::log(format!("Error listing users: {:?}", e).as_str()) + ConsoleService::log(format!("Error listing users: {}", e).as_str()) } } true diff --git a/model/src/lib.rs b/model/src/lib.rs index df7aa16..b66b30b 100644 --- a/model/src/lib.rs +++ b/model/src/lib.rs @@ -1,4 +1,4 @@ -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; #[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] pub struct BindRequest { diff --git a/src/infra/ldap_handler.rs b/src/infra/ldap_handler.rs index 46d714f..47cd13f 100644 --- a/src/infra/ldap_handler.rs +++ b/src/infra/ldap_handler.rs @@ -100,16 +100,10 @@ fn map_field(field: &str) -> Result { fn convert_filter(filter: &LdapFilter) -> Result { match filter { LdapFilter::And(filters) => Ok(RequestFilter::And( - filters - .iter() - .map(convert_filter) - .collect::>()?, + filters.iter().map(convert_filter).collect::>()?, )), LdapFilter::Or(filters) => Ok(RequestFilter::Or( - filters - .iter() - .map(convert_filter) - .collect::>()?, + filters.iter().map(convert_filter).collect::>()?, )), LdapFilter::Not(filter) => Ok(RequestFilter::Not(Box::new(convert_filter(&*filter)?))), LdapFilter::Equality(field, value) => { diff --git a/src/infra/tcp_server.rs b/src/infra/tcp_server.rs index 64829d2..9aeb53a 100644 --- a/src/infra/tcp_server.rs +++ b/src/infra/tcp_server.rs @@ -1,4 +1,4 @@ -use crate::domain::handler::*; +use crate::domain::{error::Error, handler::*}; use crate::infra::configuration::Configuration; use actix_files::{Files, NamedFile}; use actix_http::HttpServiceBuilder; @@ -16,6 +16,16 @@ async fn index(req: HttpRequest) -> actix_web::Result { Ok(NamedFile::open(path)?) } +fn error_to_http_response(error: Error) -> ApiResult { + ApiResult::Right( + match error { + Error::AuthenticationError(_) => HttpResponse::Unauthorized(), + Error::DatabaseError(_) => HttpResponse::InternalServerError(), + } + .body(error.to_string()), + ) +} + type ApiResult = actix_web::Either, HttpResponse>; async fn user_list_handler( @@ -26,10 +36,11 @@ where Backend: BackendHandler + 'static, { let req: ListUsersRequest = info.clone(); - match data.backend_handler.list_users(req).await { - Ok(res) => ApiResult::Left(web::Json(res)), - Err(_) => ApiResult::Right(HttpResponse::InternalServerError().finish()), - } + data.backend_handler + .list_users(req) + .await + .map(|res| ApiResult::Left(web::Json(res))) + .unwrap_or_else(error_to_http_response) } fn api_config(cfg: &mut web::ServiceConfig) @@ -41,9 +52,10 @@ where .error_handler(|err, _req| { // create custom error response log::error!("API error: {}", err); + let msg = err.to_string(); actix_web::error::InternalError::from_response( err, - HttpResponse::Conflict().finish().into(), + HttpResponse::BadRequest().body(msg).into(), ) .into() });