diff --git a/crates/defguard_core/src/appstate.rs b/crates/defguard_core/src/appstate.rs index 27722d50a6..326b74ab4b 100644 --- a/crates/defguard_core/src/appstate.rs +++ b/crates/defguard_core/src/appstate.rs @@ -63,7 +63,7 @@ impl AppState { AppEvent::UserCreated(user) => (json!(user), "user_created"), AppEvent::UserModified(user) => (json!(user), "user_modified"), AppEvent::UserDeleted(username) => { - (json!({ "username": username }), "user_deleted") + (json!({"username": username}), "user_deleted") } AppEvent::HWKeyProvision(data) => (json!(data), "user_keys"), }; diff --git a/crates/defguard_core/src/enterprise/db/models/acl.rs b/crates/defguard_core/src/enterprise/db/models/acl.rs index 63b20c0b5b..3a9db0bbdb 100644 --- a/crates/defguard_core/src/enterprise/db/models/acl.rs +++ b/crates/defguard_core/src/enterprise/db/models/acl.rs @@ -1900,7 +1900,7 @@ pub(crate) struct AclAliasDestinationRange { pub end: IpAddr, } -impl AclAliasDestinationRange { +impl AclAliasDestinationRange { pub async fn save<'e, E>(self, executor: E) -> Result, SqlxError> where E: PgExecutor<'e>, diff --git a/crates/defguard_core/src/enterprise/handlers/acl.rs b/crates/defguard_core/src/enterprise/handlers/acl.rs index 59e3e6e229..c13d36a71f 100644 --- a/crates/defguard_core/src/enterprise/handlers/acl.rs +++ b/crates/defguard_core/src/enterprise/handlers/acl.rs @@ -199,10 +199,7 @@ pub(crate) async fn list_acl_rules( api_rules.push(info.into()); } info!("User {} listed ACL rules", session.user.username); - Ok(ApiResponse { - json: json!(api_rules), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(api_rules, StatusCode::OK)) } /// Get ACL rule. @@ -275,10 +272,7 @@ pub(crate) async fn create_acl_rule( "User {} created ACL rule {}", session.user.username, rule.id ); - Ok(ApiResponse { - json: json!(rule), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(rule, StatusCode::CREATED)) } /// Update ACL rule. @@ -314,10 +308,7 @@ pub(crate) async fn update_acl_rule( err })?; info!("User {} updated ACL rule", session.user.username); - Ok(ApiResponse { - json: json!(rule), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(rule, StatusCode::OK)) } /// Delete ACL rule. diff --git a/crates/defguard_core/src/enterprise/handlers/acl/alias.rs b/crates/defguard_core/src/enterprise/handlers/acl/alias.rs index a5201a6a44..7e42138b6e 100644 --- a/crates/defguard_core/src/enterprise/handlers/acl/alias.rs +++ b/crates/defguard_core/src/enterprise/handlers/acl/alias.rs @@ -203,10 +203,7 @@ pub(crate) async fn list_acl_aliases( api_aliases.push(info.into()); } info!("User {} listed ACL aliases", session.user.username); - Ok(ApiResponse { - json: json!(api_aliases), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(api_aliases, StatusCode::OK)) } /// Get ACL alias. @@ -243,10 +240,7 @@ pub(crate) async fn get_acl_alias( }; info!("User {} retrieved ACL alias {id}", session.user.username); - Ok(ApiResponse { - json: alias, - status, - }) + Ok(ApiResponse::new(alias, status)) } /// Create ACL alias. @@ -277,10 +271,7 @@ pub(crate) async fn create_acl_alias( "User {} created ACL alias {}", session.user.username, alias.id ); - Ok(ApiResponse { - json: json!(alias), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(alias, StatusCode::CREATED)) } /// Update ACL alias. @@ -312,10 +303,7 @@ pub(crate) async fn update_acl_alias( err })?; info!("User {} updated ACL alias", session.user.username); - Ok(ApiResponse { - json: json!(alias), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(alias, StatusCode::OK)) } /// Delete ACL alias. diff --git a/crates/defguard_core/src/enterprise/handlers/acl/destination.rs b/crates/defguard_core/src/enterprise/handlers/acl/destination.rs index 844ce1e5c7..5b4d2ad793 100644 --- a/crates/defguard_core/src/enterprise/handlers/acl/destination.rs +++ b/crates/defguard_core/src/enterprise/handlers/acl/destination.rs @@ -212,10 +212,7 @@ pub(crate) async fn list_acl_destinations( api_aliases.push(info.into()); } info!("User {} listed ACL destinations", session.user.username); - Ok(ApiResponse { - json: json!(api_aliases), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(api_aliases, StatusCode::OK)) } /// Get ACL destination. @@ -258,10 +255,7 @@ pub(crate) async fn get_acl_destination( "User {} retrieved ACL destination {id}", session.user.username ); - Ok(ApiResponse { - json: alias, - status, - }) + Ok(ApiResponse::new(alias, status)) } /// Create ACL destination. @@ -295,10 +289,7 @@ pub(crate) async fn create_acl_destination( "User {} created ACL destination {}", session.user.username, alias.id ); - Ok(ApiResponse { - json: json!(alias), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(alias, StatusCode::CREATED)) } /// Update ACL destination. @@ -332,10 +323,7 @@ pub(crate) async fn update_acl_destination( err })?; info!("User {} updated ACL destination", session.user.username); - Ok(ApiResponse { - json: json!(alias), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(alias, StatusCode::OK)) } /// Delete ACL destination. diff --git a/crates/defguard_core/src/enterprise/handlers/activity_log_stream.rs b/crates/defguard_core/src/enterprise/handlers/activity_log_stream.rs index e8bbe7573a..96cf905970 100644 --- a/crates/defguard_core/src/enterprise/handlers/activity_log_stream.rs +++ b/crates/defguard_core/src/enterprise/handlers/activity_log_stream.rs @@ -4,7 +4,6 @@ use axum::{ }; use defguard_common::db::{Id, NoId}; use reqwest::StatusCode; -use serde_json::json; use super::LicenseInfo; use crate::{ @@ -32,10 +31,7 @@ pub async fn get_activity_log_stream( "User {} retrieved activity log streams", session.user.username ); - Ok(ApiResponse { - json: json!(streams), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(streams, StatusCode::OK)) } #[derive(Debug, Deserialize)] @@ -70,10 +66,7 @@ pub async fn create_activity_log_stream( event: Box::new(ApiEventType::ActivityLogStreamCreated { stream }), })?; debug!("ActivityLogStreamCreated api event sent"); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::with_status(StatusCode::CREATED)) } pub async fn modify_activity_log_stream( diff --git a/crates/defguard_core/src/enterprise/handlers/api_tokens.rs b/crates/defguard_core/src/enterprise/handlers/api_tokens.rs index 5a1d5923c7..d0842acc01 100644 --- a/crates/defguard_core/src/enterprise/handlers/api_tokens.rs +++ b/crates/defguard_core/src/enterprise/handlers/api_tokens.rs @@ -71,10 +71,10 @@ pub async fn add_api_token( event: Box::new(ApiEventType::ApiTokenAdded { owner, token }), })?; } - Ok(ApiResponse { - json: json!({"token": token_string}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::new( + json!({"token": token_string}), + StatusCode::CREATED, + )) } // GET on user, returns ApiTokenInfo vector in JSON @@ -92,10 +92,7 @@ pub async fn fetch_api_tokens( .map(Into::into) .collect(); - Ok(ApiResponse { - json: json!(tokens_info), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(tokens_info, StatusCode::OK)) } pub async fn delete_api_token( @@ -131,10 +128,7 @@ pub async fn delete_api_token( return Err(WebError::BadRequest("Key not found".into())); } - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } #[derive(Debug, Deserialize, Serialize, Clone)] @@ -181,8 +175,5 @@ pub async fn rename_api_token( return Err(WebError::ObjectNotFound(String::new())); } - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } diff --git a/crates/defguard_core/src/enterprise/handlers/enterprise_settings.rs b/crates/defguard_core/src/enterprise/handlers/enterprise_settings.rs index 437c2c3e7a..e52811806e 100644 --- a/crates/defguard_core/src/enterprise/handlers/enterprise_settings.rs +++ b/crates/defguard_core/src/enterprise/handlers/enterprise_settings.rs @@ -1,5 +1,4 @@ use axum::{Json, extract::State, http::StatusCode}; -use serde_json::json; use struct_patch::Patch; use super::LicenseInfo; @@ -23,10 +22,7 @@ pub async fn get_enterprise_settings( "User {} retrieved enterprise settings", session.user.username ); - Ok(ApiResponse { - json: json!(settings), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(settings, StatusCode::OK)) } pub async fn patch_enterprise_settings( diff --git a/crates/defguard_core/src/enterprise/handlers/mod.rs b/crates/defguard_core/src/enterprise/handlers/mod.rs index 781eded1b3..042d0f9d9e 100644 --- a/crates/defguard_core/src/enterprise/handlers/mod.rs +++ b/crates/defguard_core/src/enterprise/handlers/mod.rs @@ -98,26 +98,21 @@ pub async fn check_enterprise_info(_admin: AdminRole, _session: SessionInfo) -> }), }); - serde_json::json!( - { - "free": is_enterprise_free(), - "valid_until": license.valid_until, - "subscription": license.subscription, - "expired": license.is_max_overdue(), - "limits_exceeded": counts.is_over_license_limits(license), - "tier": license.tier, - "limits": limits_info, - } - ) + serde_json::json!({ + "free": is_enterprise_free(), + "valid_until": license.valid_until, + "subscription": license.subscription, + "expired": license.is_max_overdue(), + "limits_exceeded": counts.is_over_license_limits(license), + "tier": license.tier, + "limits": limits_info, + + }) }); - Ok(ApiResponse { - json: serde_json::json!( - { - "license_info": license_info, - } - ), - status: StatusCode::OK, - }) + Ok(ApiResponse::json( + serde_json::json!({"license_info": license_info}), + StatusCode::OK, + )) } impl FromRequestParts for CanManageDevices diff --git a/crates/defguard_core/src/enterprise/handlers/openid_login.rs b/crates/defguard_core/src/enterprise/handlers/openid_login.rs index e894f426f0..28c82888cc 100644 --- a/crates/defguard_core/src/enterprise/handlers/openid_login.rs +++ b/crates/defguard_core/src/enterprise/handlers/openid_login.rs @@ -518,12 +518,10 @@ pub(crate) async fn get_auth_info( Ok(( private_cookies, - ApiResponse { - json: json!( - {"url": authorize_url, "button_display_name": provider.display_name} - ), - status: StatusCode::OK, - }, + ApiResponse::new( + json!({"url": authorize_url, "button_display_name": provider.display_name}), + StatusCode::OK, + ), )) } @@ -617,10 +615,7 @@ pub(crate) async fn auth_callback( return Ok(( cookies, private_cookies, - ApiResponse { - json: json!(mfa_info), - status: StatusCode::CREATED, - }, + ApiResponse::json(mfa_info, StatusCode::CREATED), )); } @@ -638,13 +633,13 @@ pub(crate) async fn auth_callback( Ok(( cookies, private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, - url - }), - status: StatusCode::OK, - }, + url, + }, + StatusCode::OK, + ), )) } else { unimplemented!("Impossible to get here"); diff --git a/crates/defguard_core/src/enterprise/handlers/openid_providers.rs b/crates/defguard_core/src/enterprise/handlers/openid_providers.rs index 60ae0b0132..e9590885ab 100644 --- a/crates/defguard_core/src/enterprise/handlers/openid_providers.rs +++ b/crates/defguard_core/src/enterprise/handlers/openid_providers.rs @@ -191,10 +191,7 @@ pub(crate) async fn add_openid_provider( }), })?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::with_status(StatusCode::CREATED)) } /// Get OpenID provider by name. @@ -226,21 +223,15 @@ pub(crate) async fn get_openid_provider( // Get rid of it, it should stay on the backend only. provider.google_service_account_key = None; provider.okta_private_jwk = None; - Ok(ApiResponse { - json: json!({ - "provider": json!(provider), - "settings": settings_json, - }), - status: StatusCode::OK, - }) + Ok(ApiResponse::new( + json!({"provider": provider, "settings": settings_json}), + StatusCode::OK, + )) } - None => Ok(ApiResponse { - json: json!({ - "provider": null, - "settings": settings_json, - }), - status: StatusCode::NO_CONTENT, - }), + None => Ok(ApiResponse::new( + json!({"provider": null, "settings": settings_json}), + StatusCode::NO_CONTENT, + )), } } @@ -298,19 +289,13 @@ pub(crate) async fn delete_openid_provider( context, event: Box::new(ApiEventType::OpenIdProviderRemoved { provider }), })?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } else { warn!( "User {} failed to delete OpenID provider {name}. Such provider does not exist.", session.user.username, ); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::NOT_FOUND, - }) + Ok(ApiResponse::with_status(StatusCode::NOT_FOUND)) } } @@ -358,19 +343,13 @@ pub(crate) async fn modify_openid_provider( event: Box::new(ApiEventType::OpenIdProviderModified { provider }), })?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } else { warn!( "User {} failed to modify OpenID client {}. Such client does not exist.", session.user.username, provider_data.name ); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::NOT_FOUND, - }) + Ok(ApiResponse::with_status(StatusCode::NOT_FOUND)) } } @@ -392,10 +371,7 @@ pub(crate) async fn list_openid_providers( State(appstate): State, ) -> ApiResult { let providers = OpenIdProvider::all(&appstate.pool).await?; - Ok(ApiResponse { - json: json!(providers), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(providers, StatusCode::OK)) } pub(crate) async fn test_dirsync_connection( @@ -414,17 +390,17 @@ pub(crate) async fn test_dirsync_connection( "User {} tested directory sync connection, the connection failed: {err}", session.user.username, ); - return Ok(ApiResponse { - json: json!({"message": err.to_string(), "success": false}), - status: StatusCode::OK, - }); + return Ok(ApiResponse::new( + json!({"message": err.to_string(), "success": false}), + StatusCode::OK, + )); } debug!( "User {} tested directory sync connection, the connection was successful", session.user.username ); - Ok(ApiResponse { - json: json!({"message": "Connection successful", "success": true}), - status: StatusCode::OK, - }) + Ok(ApiResponse::new( + json!({"message": "Connection successful", "success": true}), + StatusCode::OK, + )) } diff --git a/crates/defguard_core/src/enterprise/snat/handlers.rs b/crates/defguard_core/src/enterprise/snat/handlers.rs index 40558cb4cf..790a02e8cf 100644 --- a/crates/defguard_core/src/enterprise/snat/handlers.rs +++ b/crates/defguard_core/src/enterprise/snat/handlers.rs @@ -10,7 +10,6 @@ use defguard_common::db::{ }; use reqwest::StatusCode; use serde::{Deserialize, Serialize}; -use serde_json::json; use utoipa::ToSchema; use crate::{ @@ -69,10 +68,7 @@ pub async fn list_snat_bindings( let bindings = UserSnatBinding::all_for_location(&appstate.pool, location.id).await?; - Ok(ApiResponse { - json: json!(bindings), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(bindings, StatusCode::OK)) } #[derive(Debug, Deserialize, Serialize, ToSchema)] @@ -170,10 +166,7 @@ pub async fn create_snat_binding( } } - Ok(ApiResponse { - json: json!(binding), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(binding, StatusCode::CREATED)) } #[derive(Debug, Deserialize, Serialize, ToSchema)] @@ -274,10 +267,7 @@ pub async fn modify_snat_binding( } } - Ok(ApiResponse { - json: json!(snat_binding), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(snat_binding, StatusCode::OK)) } /// Delete an existing SNAT binding for a user in a WireGuard location diff --git a/crates/defguard_core/src/handlers/app_info.rs b/crates/defguard_core/src/handlers/app_info.rs index c92add185a..678e82ca4d 100644 --- a/crates/defguard_core/src/handlers/app_info.rs +++ b/crates/defguard_core/src/handlers/app_info.rs @@ -3,7 +3,6 @@ use defguard_common::{ VERSION, db::models::{Settings, WireguardNetwork}, }; -use serde_json::json; use super::{ApiResponse, ApiResult}; use crate::{ @@ -84,5 +83,5 @@ pub(crate) async fn get_app_info( external_openid_enabled, }; - Ok(ApiResponse::new(json!(res), StatusCode::OK)) + Ok(ApiResponse::json(res, StatusCode::OK)) } diff --git a/crates/defguard_core/src/handlers/auth.rs b/crates/defguard_core/src/handlers/auth.rs index 9e01c18243..e81d13aef8 100644 --- a/crates/defguard_core/src/handlers/auth.rs +++ b/crates/defguard_core/src/handlers/auth.rs @@ -21,7 +21,6 @@ use defguard_common::{ types::user_info::UserInfo, }; use defguard_mail::Mail; -use serde_json::json; use sqlx::{PgPool, types::Uuid}; use time::Duration; use tokio::sync::mpsc::UnboundedSender; @@ -263,10 +262,7 @@ pub(crate) async fn authenticate( return Ok(( cookies, private_cookies, - ApiResponse { - json: json!(mfa_info), - status: StatusCode::CREATED, - }, + ApiResponse::json(mfa_info, StatusCode::CREATED), )); } @@ -294,13 +290,13 @@ pub(crate) async fn authenticate( Ok(( cookies, private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, - url - }), - status: StatusCode::OK, - }, + url, + }, + StatusCode::OK, + ), )) } else { unimplemented!("Impossible to get here"); @@ -433,10 +429,7 @@ pub async fn webauthn_init( "Initialized WebAuthn registration for user {}", user.username ); - Ok(ApiResponse { - json: json!(ccr), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(ccr, StatusCode::OK)) } Err(err) => Err(WebError::WebauthnRegistration(err.to_string())), } @@ -478,7 +471,7 @@ pub async fn webauthn_finish( .get_allowed_origins() .iter() .map(ToString::to_string) - .collect::>() + .collect::>() ); let passkey = appstate @@ -509,10 +502,7 @@ pub async fn webauthn_finish( event: Box::new(ApiEventType::MfaSecurityKeyAdded { key: webauthn }), })?; - Ok(ApiResponse { - json: json!(recovery_codes), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(recovery_codes, StatusCode::OK)) } /// Start WebAuthn authentication @@ -527,10 +517,7 @@ pub async fn webauthn_start( session .set_passkey_authentication(&appstate.pool, &passkey_reg) .await?; - Ok(ApiResponse { - json: json!(rcr), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(rcr, StatusCode::OK)) } Err(_err) => Err(WebError::Http(StatusCode::BAD_REQUEST)), } @@ -590,24 +577,24 @@ pub async fn webauthn_end( let private_cookies = private_cookies.remove(openid_cookie); Ok(( private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, url: Some(redirect_url), - }), - status: StatusCode::OK, - }, + }, + StatusCode::OK, + ), )) } else { Ok(( private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, url: None, - }), - status: StatusCode::OK, - }, + }, + StatusCode::OK, + ), )) } } else { @@ -646,10 +633,7 @@ pub async fn totp_secret(session: SessionInfo, State(appstate): State) let secret = user.new_totp_secret(&appstate.pool).await?; info!("Generated new TOTP secret for user {}", user.username); - Ok(ApiResponse { - json: json!(AuthTotp::new(secret)), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(AuthTotp::new(secret), StatusCode::OK)) } /// Enable TOTP @@ -680,10 +664,7 @@ pub async fn totp_enable( context, event: Box::new(ApiEventType::MfaTotpEnabled), })?; - Ok(ApiResponse { - json: json!(recovery_codes), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(recovery_codes, StatusCode::OK)) } else { Err(WebError::ObjectNotFound("Invalid TOTP code".into())) } @@ -748,24 +729,24 @@ pub async fn totp_code( let private_cookies = private_cookies.remove(openid_cookie); Ok(( private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, url: Some(redirect_url), - }), - status: StatusCode::OK, - }, + }, + StatusCode::OK, + ), )) } else { Ok(( private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, url: None, - }), - status: StatusCode::OK, - }, + }, + StatusCode::OK, + ), )) } } else { @@ -848,10 +829,7 @@ pub async fn email_mfa_enable( context, event: Box::new(ApiEventType::MfaEmailEnabled), })?; - Ok(ApiResponse { - json: json!(recovery_codes), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(recovery_codes, StatusCode::OK)) } else { Err(WebError::ObjectNotFound("Invalid email code".into())) } @@ -936,24 +914,24 @@ pub async fn email_mfa_code( let private_cookies = private_cookies.remove(openid_cookie); Ok(( private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, url: Some(redirect_url), - }), - status: StatusCode::OK, - }, + }, + StatusCode::OK, + ), )) } else { Ok(( private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, url: None, - }), - status: StatusCode::OK, - }, + }, + StatusCode::OK, + ), )) } } else { @@ -1026,25 +1004,25 @@ pub async fn recovery_code( let private_cookies = private_cookies.remove(openid_cookie); return Ok(( private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, url: Some(redirect_url), - }), - status: StatusCode::OK, - }, + }, + StatusCode::OK, + ), )); } return Ok(( private_cookies, - ApiResponse { - json: json!(AuthResponse { + ApiResponse::json( + AuthResponse { user: user_info, url: None, - }), - status: StatusCode::OK, - }, + }, + StatusCode::OK, + ), )); } } diff --git a/crates/defguard_core/src/handlers/ca.rs b/crates/defguard_core/src/handlers/ca.rs index 7e82f1b6af..59b79c8683 100644 --- a/crates/defguard_core/src/handlers/ca.rs +++ b/crates/defguard_core/src/handlers/ca.rs @@ -1,7 +1,6 @@ use axum::{Json, extract::State}; use defguard_common::db::models::{Settings, settings::update_current_settings}; use reqwest::StatusCode; -use serde_json::json; use crate::{ appstate::AppState, @@ -36,8 +35,5 @@ pub async fn create_ca( update_current_settings(&appstate.pool, settings).await?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::with_status(StatusCode::CREATED)) } diff --git a/crates/defguard_core/src/handlers/group.rs b/crates/defguard_core/src/handlers/group.rs index f35f6eaaa8..e0027a7ac1 100644 --- a/crates/defguard_core/src/handlers/group.rs +++ b/crates/defguard_core/src/handlers/group.rs @@ -11,7 +11,6 @@ use defguard_common::db::{ group::{Group, Permission}, }, }; -use serde_json::json; use sqlx::query_as; use utoipa::ToSchema; @@ -141,10 +140,7 @@ pub(crate) async fn bulk_assign_to_groups( event: Box::new(ApiEventType::GroupsBulkAssigned { users, groups }), })?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } /// Retrieve all groups info @@ -198,10 +194,7 @@ pub(crate) async fn list_groups_info( ) .fetch_all(&appstate.pool) .await?; - Ok(ApiResponse { - json: json!(q_result), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(q_result, StatusCode::OK)) } /// Retrieve all groups. @@ -237,10 +230,7 @@ pub(crate) async fn list_groups( .map(|group| group.name) .collect(); info!("User {} listed groups", &session.user.username); - Ok(ApiResponse { - json: json!(Groups::new(groups)), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(Groups::new(groups), StatusCode::OK)) } /// Retrieve group with name @@ -287,16 +277,10 @@ pub(crate) async fn get_group( .has_permission(&appstate.pool, Permission::IsAdmin) .await?; info!("Retrieved group {name}"); - Ok(ApiResponse { - json: json!(GroupInfo::new( - group.id, - name, - members, - vpn_locations, - is_admin - )), - status: StatusCode::OK, - }) + Ok(ApiResponse::json( + GroupInfo::new(group.id, name, members, vpn_locations, is_admin), + StatusCode::OK, + )) } else { let msg = format!("Group {name} not found"); error!(msg); @@ -391,10 +375,7 @@ pub(crate) async fn create_group( event: Box::new(ApiEventType::GroupAdded { group }), })?; - Ok(ApiResponse { - json: json!(group_info), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(group_info, StatusCode::CREATED)) } /// Modify group @@ -460,10 +441,7 @@ pub(crate) async fn modify_group( "Can't remove admin permissions from the last admin group: {}", name ); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } } @@ -597,10 +575,7 @@ pub(crate) async fn delete_group( .len(); if admin_group_count == 1 { error!("Cannot delete the last admin group: {name}"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } } group.clone().delete(&appstate.pool).await?; @@ -731,10 +706,7 @@ pub(crate) async fn remove_group_member( context, event: Box::new(ApiEventType::GroupMemberRemoved { group, user }), })?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } else { let msg = format!("User {username} not found"); error!(msg); diff --git a/crates/defguard_core/src/handlers/mail.rs b/crates/defguard_core/src/handlers/mail.rs index 922d1642c4..129c9ec8ba 100644 --- a/crates/defguard_core/src/handlers/mail.rs +++ b/crates/defguard_core/src/handlers/mail.rs @@ -56,12 +56,10 @@ pub struct TestMail { /// Handles logging the error and returns ApiResponse that contains it fn internal_error(to: &str, subject: &str, error: &impl Display) -> ApiResponse { error!("Error sending mail to {to}, subject: {subject}, error: {error}"); - ApiResponse { - json: json!({ - "error": error.to_string(), - }), - status: StatusCode::INTERNAL_SERVER_ERROR, - } + ApiResponse::new( + json!({"error": error.to_string()}), + StatusCode::INTERNAL_SERVER_ERROR, + ) } pub async fn test_mail( @@ -91,10 +89,7 @@ pub async fn test_mail( "User {} sent test mail to {}", session.user.username, data.to ); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } Some(Err(err)) => Ok(internal_error(&to, &subject, &err)), None => Ok(internal_error( @@ -194,10 +189,7 @@ pub async fn send_support_data( "User {} sent support mail to {SUPPORT_EMAIL_ADDRESS}", session.user.username ); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } Some(Err(err)) => Ok(internal_error(&to, &subject, &err)), None => Ok(internal_error( diff --git a/crates/defguard_core/src/handlers/mod.rs b/crates/defguard_core/src/handlers/mod.rs index f9c1d197f7..79e337a54a 100644 --- a/crates/defguard_core/src/handlers/mod.rs +++ b/crates/defguard_core/src/handlers/mod.rs @@ -55,35 +55,52 @@ pub(crate) const DEFAULT_API_PAGE_SIZE: u32 = 50; #[derive(Default, ToSchema)] pub struct ApiResponse { - pub json: Value, + json: Value, #[schema(value_type = u16)] - pub status: StatusCode, + status: StatusCode, } impl ApiResponse { + /// Build a new [`ApiResponse`]. #[must_use] pub fn new(json: Value, status: StatusCode) -> Self { Self { json, status } } + + /// Response with `json` set to "{}", and a status code. + #[must_use] + pub fn with_status(status: StatusCode) -> Self { + Self { + json: Value::Object(serde_json::Map::new()), + status, + } + } + + /// Response with serializable value for JSON, and a status code. + #[must_use] + pub fn json(value: T, status: StatusCode) -> Self { + let json = serde_json::to_value(value).expect("Failed to convert value to JSON"); + Self { json, status } + } } impl From for ApiResponse { fn from(web_error: WebError) -> ApiResponse { match web_error { WebError::ObjectNotFound(msg) => { - ApiResponse::new(json!({ "msg": msg }), StatusCode::NOT_FOUND) + ApiResponse::new(json!({"msg": msg}), StatusCode::NOT_FOUND) } WebError::ObjectAlreadyExists(msg) => { - ApiResponse::new(json!({ "msg": msg }), StatusCode::CONFLICT) + ApiResponse::new(json!({"msg": msg}), StatusCode::CONFLICT) } WebError::Authorization(msg) => { error!(msg); - ApiResponse::new(json!({ "msg": msg }), StatusCode::UNAUTHORIZED) + ApiResponse::new(json!({"msg": msg}), StatusCode::UNAUTHORIZED) } - WebError::Authentication => ApiResponse::new(json!({}), StatusCode::UNAUTHORIZED), + WebError::Authentication => ApiResponse::with_status(StatusCode::UNAUTHORIZED), WebError::Forbidden(msg) => { error!(msg); - ApiResponse::new(json!({ "msg": msg }), StatusCode::FORBIDDEN) + ApiResponse::new(json!({"msg": msg}), StatusCode::FORBIDDEN) } WebError::DbError(_) | WebError::Grpc(_) @@ -154,19 +171,19 @@ impl From for ApiResponse { WebError::Http(status) => { error!("{status}"); ApiResponse::new( - json!({ "msg": status.canonical_reason().unwrap_or_default() }), + json!({"msg": status.canonical_reason().unwrap_or_default()}), status, ) } WebError::TooManyLoginAttempts(_) => ApiResponse::new( - json!({ "msg": "Too many login attempts" }), + json!({"msg": "Too many login attempts"}), StatusCode::TOO_MANY_REQUESTS, ), WebError::PubkeyValidation(msg) | WebError::PubkeyExists(msg) | WebError::BadRequest(msg) => { error!(msg); - ApiResponse::new(json!({ "msg": msg }), StatusCode::BAD_REQUEST) + ApiResponse::new(json!({"msg": msg}), StatusCode::BAD_REQUEST) } WebError::TemplateError(err) => { error!("Template error: {err}"); @@ -178,22 +195,22 @@ impl From for ApiResponse { WebError::LicenseError(err) => match err { LicenseError::DecodeError(msg) | LicenseError::InvalidLicense(msg) => { warn!(msg); - ApiResponse::new(json!({ "msg": msg }), StatusCode::BAD_REQUEST) + ApiResponse::new(json!({"msg": msg}), StatusCode::BAD_REQUEST) } LicenseError::SignatureMismatch => { let msg = "License signature doesn't match its content"; warn!(msg); - ApiResponse::new(json!({ "msg": msg }), StatusCode::BAD_REQUEST) + ApiResponse::new(json!({"msg": msg}), StatusCode::BAD_REQUEST) } LicenseError::InvalidSignature => { let msg = "License signature is malformed and couldn't be read"; warn!(msg); - ApiResponse::new(json!({ "msg": msg }), StatusCode::BAD_REQUEST) + ApiResponse::new(json!({"msg": msg}), StatusCode::BAD_REQUEST) } LicenseError::LicenseNotFound => { let msg = "License not found"; warn!(msg); - ApiResponse::new(json!({ "msg": msg }), StatusCode::NOT_FOUND) + ApiResponse::new(json!({"msg": msg}), StatusCode::NOT_FOUND) } _ => { error!("License error: {err}"); @@ -209,8 +226,7 @@ impl From for ApiResponse { impl IntoResponse for WebError { fn into_response(self) -> Response { - let api_response = ApiResponse::from(self); - api_response.into_response() + ApiResponse::from(self).into_response() } } diff --git a/crates/defguard_core/src/handlers/network_devices.rs b/crates/defguard_core/src/handlers/network_devices.rs index 27353b632b..59ddf4bca4 100644 --- a/crates/defguard_core/src/handlers/network_devices.rs +++ b/crates/defguard_core/src/handlers/network_devices.rs @@ -162,10 +162,7 @@ pub async fn get_network_device( let network_device_info = NetworkDeviceInfo::from_device(device, &mut transaction).await?; transaction.commit().await?; - return Ok(ApiResponse { - json: json!(network_device_info), - status: StatusCode::OK, - }); + return Ok(ApiResponse::json(network_device_info, StatusCode::OK)); } } error!( @@ -200,10 +197,7 @@ pub(crate) async fn list_network_devices( transaction.commit().await?; info!("Listed {} network devices", devices_response.len()); - Ok(ApiResponse { - json: json!(devices_response), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(devices_response, StatusCode::OK)) } #[derive(Serialize, Deserialize, Debug)] @@ -312,10 +306,7 @@ pub(crate) async fn check_ip_availability( } } - Ok(ApiResponse { - json: json!(validation_results), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(validation_results, StatusCode::OK)) } pub(crate) async fn find_available_ips( @@ -361,19 +352,13 @@ pub(crate) async fn find_available_ips( "Found addresses {:?} for new device i network {} ({:?})", split_ips, network.name, network.address ); - Ok(ApiResponse { - json: json!(split_ips), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(split_ips, StatusCode::OK)) } else { warn!( "Failed to find available IPs for new device in network {} ({:?})", network.name, network.address ); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::NOT_FOUND, - }) + Ok(ApiResponse::with_status(StatusCode::NOT_FOUND)) } } @@ -487,10 +472,10 @@ pub(crate) async fn start_network_device_setup( transaction.commit().await?; - Ok(ApiResponse { - json: json!({"enrollment_token": configuration_token, "enrollment_url": config.enrollment_url.to_string()}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::new( + json!({"enrollment_token": configuration_token, "enrollment_url": config.enrollment_url.to_string()}), + StatusCode::CREATED, + )) } // Make a new CLI configuration token for an already added network device @@ -550,13 +535,13 @@ pub(crate) async fn start_network_device_setup_for_device( device {} with ID {}: {configuration_token}", device.name, device.id ); - Ok(ApiResponse { - json: json!({ + Ok(ApiResponse::new( + json!({ "enrollment_token": configuration_token, "enrollment_url": config.enrollment_url.to_string() }), - status: StatusCode::CREATED, - }) + StatusCode::CREATED, + )) } pub(crate) async fn add_network_device( @@ -677,10 +662,7 @@ pub(crate) async fn add_network_device( }), })?; - Ok(ApiResponse { - json: json!(result), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(result, StatusCode::CREATED)) } #[derive(Debug, Deserialize)] @@ -771,10 +753,7 @@ pub async fn modify_network_device( after: device, }), })?; - Ok(ApiResponse { - json: json!(network_device_info), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(network_device_info, StatusCode::OK)) } #[derive(Debug, Serialize)] diff --git a/crates/defguard_core/src/handlers/openid_clients.rs b/crates/defguard_core/src/handlers/openid_clients.rs index 767c5b16a1..ed9a74194f 100644 --- a/crates/defguard_core/src/handlers/openid_clients.rs +++ b/crates/defguard_core/src/handlers/openid_clients.rs @@ -58,10 +58,10 @@ pub async fn add_openid_client( "User {} attempted to create openid client with name containing HTML: {}", session.user.username, data.name ); - return Ok(ApiResponse { - json: json!({"msg": "invalid name"}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::new( + json!({"msg": "invalid name"}), + StatusCode::BAD_REQUEST, + )); } let client: OAuth2Client = data.into(); let client = client.save(&appstate.pool).await?; @@ -75,18 +75,12 @@ pub async fn add_openid_client( app: client.clone(), }), })?; - Ok(ApiResponse { - json: json!(client), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(client, StatusCode::CREATED)) } pub async fn list_openid_clients(_admin: AdminRole, State(appstate): State) -> ApiResult { let clients = OAuth2Client::all(&appstate.pool).await?; - Ok(ApiResponse { - json: json!(clients), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(clients, StatusCode::OK)) } pub async fn get_openid_client( @@ -97,21 +91,15 @@ pub async fn get_openid_client( match OAuth2Client::find_by_client_id(&appstate.pool, &client_id).await? { Some(client) => { if session.is_admin { - Ok(ApiResponse { - json: json!(client), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(client, StatusCode::OK)) } else { - Ok(ApiResponse { - json: json!(OAuth2ClientSafe::from(client)), - status: StatusCode::OK, - }) + Ok(ApiResponse::json( + OAuth2ClientSafe::from(client), + StatusCode::OK, + )) } } - None => Ok(ApiResponse { - json: json!({}), - status: StatusCode::NOT_FOUND, - }), + None => Ok(ApiResponse::with_status(StatusCode::NOT_FOUND)), } } @@ -132,10 +120,10 @@ pub async fn change_openid_client( "User {} attempted to edit openid client with name containing HTML: {}", session.user.username, data.name ); - return Ok(ApiResponse { - json: json!({"msg": "invalid name"}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::new( + json!({"msg": "invalid name"}), + StatusCode::BAD_REQUEST, + )); } let mut transaction = appstate.pool.begin().await?; let status = match OAuth2Client::find_by_client_id(&mut *transaction, &client_id).await? { @@ -166,10 +154,7 @@ pub async fn change_openid_client( } None => StatusCode::NOT_FOUND, }; - Ok(ApiResponse { - json: json!({}), - status, - }) + Ok(ApiResponse::with_status(status)) } pub async fn change_openid_client_state( @@ -203,10 +188,7 @@ pub async fn change_openid_client_state( } None => StatusCode::NOT_FOUND, }; - Ok(ApiResponse { - json: json!({}), - status, - }) + Ok(ApiResponse::with_status(status)) } pub async fn delete_openid_client( @@ -235,8 +217,5 @@ pub async fn delete_openid_client( } None => StatusCode::NOT_FOUND, }; - Ok(ApiResponse { - json: json!({}), - status, - }) + Ok(ApiResponse::with_status(status)) } diff --git a/crates/defguard_core/src/handlers/openid_flow.rs b/crates/defguard_core/src/handlers/openid_flow.rs index 2f12e57fcc..19e5e303b3 100644 --- a/crates/defguard_core/src/handlers/openid_flow.rs +++ b/crates/defguard_core/src/handlers/openid_flow.rs @@ -41,7 +41,6 @@ use serde::{ de::{Deserialize, Deserializer, Error as DeError, Unexpected, Visitor}, ser::{Serialize, Serializer}, }; -use serde_json::json; use sqlx::PgPool; use time::Duration; @@ -99,10 +98,10 @@ pub async fn discovery_keys() -> ApiResult { keys.push(openid_key.as_verification_key()); } - Ok(ApiResponse { - json: json!(CoreJsonWebKeySet::new(keys)), - status: StatusCode::OK, - }) + Ok(ApiResponse::json( + CoreJsonWebKeySet::new(keys), + StatusCode::OK, + )) } pub type DefguardIdTokenFields = IdTokenFields< GroupClaims, @@ -829,10 +828,7 @@ pub async fn token( None, None, ); - return Ok(ApiResponse { - json: json!(response), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::json(response, StatusCode::BAD_REQUEST)); } if let Some(user) = @@ -886,10 +882,7 @@ pub async fn token( "Issued new token for user {} client {}", user.username, client.name ); - return Ok(ApiResponse { - json: json!(response), - status: StatusCode::OK, - }); + return Ok(ApiResponse::json(response, StatusCode::OK)); } Err(err) => { error!( @@ -900,10 +893,10 @@ pub async fn token( StandardErrorResponse::::new( err, None, None, ); - return Ok(ApiResponse { - json: json!(response), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::json( + response, + StatusCode::BAD_REQUEST, + )); } } } @@ -937,10 +930,7 @@ pub async fn token( let err = CoreErrorResponseType::InvalidClient; let response = StandardErrorResponse::::new(err, None, None); - return Ok(ApiResponse { - json: json!(response), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::json(response, StatusCode::BAD_REQUEST)); }; if !client.enabled { @@ -950,19 +940,13 @@ pub async fn token( None, None, ); - return Ok(ApiResponse { - json: json!(response), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::json(response, StatusCode::BAD_REQUEST)); } token.refresh_and_save(&appstate.pool).await?; let response = TokenRequest::refresh_token_flow(&token); token.save(&appstate.pool).await?; - return Ok(ApiResponse { - json: json!(response), - status: StatusCode::OK, - }); + return Ok(ApiResponse::json(response, StatusCode::OK)); } } } @@ -970,10 +954,7 @@ pub async fn token( } let err = CoreErrorResponseType::UnsupportedGrantType; let response = StandardErrorResponse::::new(err, None, None); - Ok(ApiResponse { - json: json!(response), - status: StatusCode::BAD_REQUEST, - }) + Ok(ApiResponse::json(response, StatusCode::BAD_REQUEST)) } /// https://openid.net/specs/openid-connect-core-1_0.html#UserInfo @@ -1018,10 +999,10 @@ pub async fn userinfo(State(appstate): State, headers: HeaderMap) -> A let user_claims = UserClaims::from_user(&user, &client, &oauth2token); - Ok(ApiResponse { - json: json!(StandardClaims::::from(&user_claims)), - status: StatusCode::OK, - }) + Ok(ApiResponse::json( + StandardClaims::::from(&user_claims), + StatusCode::OK, + )) } // Must be served under /.well-known/openid-configuration @@ -1070,8 +1051,5 @@ pub async fn openid_configuration() -> ApiResult { config.url.join("api/v1/oauth/userinfo").unwrap(), ))); - Ok(ApiResponse { - json: json!(provider_metadata), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(provider_metadata, StatusCode::OK)) } diff --git a/crates/defguard_core/src/handlers/settings.rs b/crates/defguard_core/src/handlers/settings.rs index 6d4b3df06e..2bc26f9232 100644 --- a/crates/defguard_core/src/handlers/settings.rs +++ b/crates/defguard_core/src/handlers/settings.rs @@ -6,7 +6,6 @@ use defguard_common::db::models::{ Settings, SettingsEssentials, settings::{LdapSyncStatus, SettingsPatch, update_current_settings}, }; -use serde_json::json; use struct_patch::Patch; use super::{ApiResponse, ApiResult}; @@ -30,10 +29,7 @@ pub async fn get_settings(_admin: AdminRole, State(appstate): State) - if settings.main_logo_url.is_empty() { settings.main_logo_url = DEFAULT_MAIN_LOGO_URL.into(); } - return Ok(ApiResponse { - json: json!(settings), - status: StatusCode::OK, - }); + return Ok(ApiResponse::json(settings, StatusCode::OK)); } debug!("Retrieved settings"); Ok(ApiResponse::default()) @@ -80,10 +76,7 @@ pub async fn get_settings_essentials(State(appstate): State) -> ApiRes info!("Retrieved essential settings"); - Ok(ApiResponse { - json: json!(settings), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(settings, StatusCode::OK)) } pub async fn set_default_branding( @@ -112,10 +105,7 @@ pub async fn set_default_branding( context, event: Box::new(ApiEventType::SettingsDefaultBrandingRestored), })?; - Ok(ApiResponse { - json: json!(settings), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(settings, StatusCode::OK)) } None => Err(WebError::DbError("Cannot restore settings".into())), } @@ -176,17 +166,11 @@ pub async fn test_ldap_settings(_admin: AdminRole) -> ApiResult { match LDAPConnection::create().await { Ok(_) => { debug!("LDAP connected successfully"); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } Err(err) => { debug!("LDAP connection rejected: {err}"); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }) + Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)) } } } diff --git a/crates/defguard_core/src/handlers/ssh_authorized_keys.rs b/crates/defguard_core/src/handlers/ssh_authorized_keys.rs index 6d1b7c96d6..efdb7f83fe 100644 --- a/crates/defguard_core/src/handlers/ssh_authorized_keys.rs +++ b/crates/defguard_core/src/handlers/ssh_authorized_keys.rs @@ -7,7 +7,6 @@ use defguard_common::db::{ Id, models::{AuthenticationKey, AuthenticationKeyType, User, group::Group}, }; -use serde_json::json; use sqlx::{Error as SqlxError, PgExecutor, PgPool, query}; use ssh_key::PublicKey; @@ -216,10 +215,7 @@ pub async fn add_authentication_key( event: Box::new(ApiEventType::AuthenticationKeyAdded { key }), })?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::with_status(StatusCode::CREATED)) } // GET on user, returns AuthenticationKeyInfo vector in JSON @@ -231,10 +227,7 @@ pub async fn fetch_authentication_keys( let user = user_for_admin_or_self(&appstate.pool, &session, &username).await?; let keys_info = AuthenticationKeyInfo::find_by_user_id(&appstate.pool, user.id).await?; - Ok(ApiResponse { - json: json!(keys_info), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(keys_info, StatusCode::OK)) } pub async fn delete_authentication_key( @@ -262,10 +255,7 @@ pub async fn delete_authentication_key( return Err(WebError::BadRequest("Key not found".into())); } - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } #[derive(Debug, Deserialize, Clone)] @@ -319,8 +309,5 @@ pub async fn rename_authentication_key( return Err(WebError::ObjectNotFound(String::new())); } - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } diff --git a/crates/defguard_core/src/handlers/support.rs b/crates/defguard_core/src/handlers/support.rs index 83b79ceed0..64e370113f 100644 --- a/crates/defguard_core/src/handlers/support.rs +++ b/crates/defguard_core/src/handlers/support.rs @@ -17,10 +17,7 @@ pub async fn configuration( debug!("User {} dumping app configuration", session.user.username); let config = dump_config(&appstate.pool).await; info!("User {} dumped app configuration", session.user.username); - Ok(ApiResponse { - json: config, - status: StatusCode::OK, - }) + Ok(ApiResponse::new(config, StatusCode::OK)) } pub async fn logs(_admin: AdminRole, session: SessionInfo) -> Result { diff --git a/crates/defguard_core/src/handlers/updates.rs b/crates/defguard_core/src/handlers/updates.rs index 07a5fa43c6..23ea76a828 100644 --- a/crates/defguard_core/src/handlers/updates.rs +++ b/crates/defguard_core/src/handlers/updates.rs @@ -22,10 +22,7 @@ pub(crate) async fn check_new_version(_admin: AdminRole, session: SessionInfo) - // Front-end expects empty JSON. Value::Null }; - Ok(ApiResponse { - json, - status: StatusCode::OK, - }) + Ok(ApiResponse::new(json, StatusCode::OK)) } // FIXME: Switch to SSE and generally make it better. @@ -39,8 +36,5 @@ pub(crate) async fn outdated_components( .read() .expect("Failed to lock appstate.incompatible_components")) .clone(); - Ok(ApiResponse::new( - json!(incompatible_components), - StatusCode::OK, - )) + Ok(ApiResponse::json(incompatible_components, StatusCode::OK)) } diff --git a/crates/defguard_core/src/handlers/user.rs b/crates/defguard_core/src/handlers/user.rs index d2eda7df6c..5007397b6d 100644 --- a/crates/defguard_core/src/handlers/user.rs +++ b/crates/defguard_core/src/handlers/user.rs @@ -200,10 +200,7 @@ pub async fn list_users(_role: AdminRole, State(appstate): State) -> A for user in all_users { users.push(UserInfo::from_user(&appstate.pool, &user).await?); } - Ok(ApiResponse { - json: json!(users), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(users, StatusCode::OK)) } /// Get user @@ -262,10 +259,7 @@ pub async fn get_user( ) -> ApiResult { let user = user_for_admin_or_self(&appstate.pool, &session, &username).await?; let user_details = UserDetails::from_user(&appstate.pool, &user).await?; - Ok(ApiResponse { - json: json!(user_details), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(user_details, StatusCode::OK)) } /// Add user @@ -324,10 +318,7 @@ pub async fn add_user( // check username if let Err(err) = check_username(&username) { debug!("Username {username} rejected: {err}"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } // check if email doesn't already exist @@ -336,20 +327,14 @@ pub async fn add_user( .is_some() { debug!("User with email {} already exists", user_data.email); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } // check phone number if let Some(ref phone) = user_data.phone { if !is_valid_phone_number(phone) { debug!("Invalid phone number for new user {username}: {phone}"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } } @@ -358,10 +343,7 @@ pub async fn add_user( // check password strength if let Err(err) = check_password_strength(password) { debug!("Password not strong enough: {err}"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } Some(password.as_str()) } @@ -395,10 +377,7 @@ pub async fn add_user( context, event: Box::new(ApiEventType::UserAdded { user }), })?; - Ok(ApiResponse { - json: json!(&user_info), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(&user_info, StatusCode::CREATED)) } /// Trigger enrollment process manually @@ -514,10 +493,10 @@ pub async fn start_enrollment( event: Box::new(ApiEventType::EnrollmentTokenAdded { user }), })?; - Ok(ApiResponse { - json: json!({"enrollment_token": enrollment_token, "enrollment_url": config.enrollment_url.to_string()}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::new( + json!({"enrollment_token": enrollment_token, "enrollment_url": config.enrollment_url.to_string()}), + StatusCode::CREATED, + )) } /// Start remote desktop configuration @@ -618,10 +597,10 @@ pub async fn start_remote_desktop_configuration( event: Box::new(ApiEventType::ClientConfigurationTokenAdded { user }), })?; - Ok(ApiResponse { - json: json!({"enrollment_token": desktop_configuration_token, "enrollment_url": config.enrollment_url.to_string()}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::new( + json!({"enrollment_token": desktop_configuration_token, "enrollment_url": config.enrollment_url.to_string()}), + StatusCode::CREATED, + )) } /// Verify if the user is available @@ -658,10 +637,7 @@ pub async fn username_available( ) -> ApiResult { if let Err(err) = check_username(&data.username) { debug!("Username {} rejected: {err}", data.username); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } let status = match User::find_by_username(&appstate.pool, &data.username).await? { Some(_) => { @@ -670,10 +646,7 @@ pub async fn username_available( } None => StatusCode::OK, }; - Ok(ApiResponse { - json: json!({}), - status, - }) + Ok(ApiResponse::with_status(status)) } /// Modify user @@ -723,20 +696,14 @@ pub async fn modify_user( let old_username = user.username.clone(); if let Err(err) = check_username(&user_info.username) { debug!("Username {} rejected: {err}", user_info.username); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } // check phone number if let Some(ref phone) = user_info.phone { if !is_valid_phone_number(phone) { debug!("Invalid phone number for user {username}: {phone}"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } } @@ -766,10 +733,7 @@ pub async fn modify_user( // prevent admin from disabling himself if session.user.username == username && !user_info.is_active { debug!("Admin {username} attempted to disable himself"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } // update VPN gateway config if user status or groups have changed @@ -904,10 +868,7 @@ pub async fn delete_user( debug!("User {} deleting user {username}", session.user.username); if session.user.username == username { debug!("User {username} attempted to delete himself"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } if let Some(user) = User::find_by_username(&appstate.pool, &username).await? { // Get rid of all devices of the deleted user from networks first @@ -977,18 +938,12 @@ pub async fn change_self_password( debug!("User {} is changing his password.", session.user.username); let mut user = session.user; if user.verify_password(&data.old_password).is_err() { - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } if let Err(err) = check_password_strength(&data.new_password) { debug!("User {} password change failed: {err}", user.username); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } user.set_password(&data.new_password); @@ -1002,10 +957,7 @@ pub async fn change_self_password( event: Box::new(ApiEventType::PasswordChanged), })?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } /// Change user password @@ -1053,25 +1005,16 @@ pub async fn change_password( if session.user.username == username { debug!("Cannot change own ({username}) password with this endpoint."); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } if let Err(err) = check_password_strength(&data.new_password) { debug!("Password for user {username} not strong enough: {err}"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } if let Err(err) = check_username(&username) { debug!("Invalid username ({username}): {err}"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } let user = User::find_by_username(&appstate.pool, &username).await?; @@ -1091,10 +1034,7 @@ pub async fn change_password( Ok(ApiResponse::default()) } else { debug!("Can't change password for user {username}, user not found"); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::NOT_FOUND, - }) + Ok(ApiResponse::with_status(StatusCode::NOT_FOUND)) } } @@ -1139,10 +1079,7 @@ pub async fn reset_password( if session.user.username == username { debug!("Cannot reset own ({username}) password with this endpoint."); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } let user = User::find_by_username(&appstate.pool, &username).await?; @@ -1205,10 +1142,7 @@ pub async fn reset_password( Ok(ApiResponse::default()) } else { debug!("Can't reset password for user {username}, user not found"); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::NOT_FOUND, - }) + Ok(ApiResponse::with_status(StatusCode::NOT_FOUND)) } } @@ -1321,10 +1255,7 @@ pub async fn delete_security_key( )] pub async fn me(session: SessionInfo, State(appstate): State) -> ApiResult { let user_info = UserInfo::from_user(&appstate.pool, &session.user).await?; - Ok(ApiResponse { - json: json!(user_info), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(user_info, StatusCode::OK)) } /// Delete OAuth token. diff --git a/crates/defguard_core/src/handlers/webhooks.rs b/crates/defguard_core/src/handlers/webhooks.rs index d30374f399..c13f28ccb1 100644 --- a/crates/defguard_core/src/handlers/webhooks.rs +++ b/crates/defguard_core/src/handlers/webhooks.rs @@ -2,7 +2,6 @@ use axum::{ extract::{Json, Path, State}, http::StatusCode, }; -use serde_json::json; use super::{ApiResponse, ApiResult, WebHookData}; use crate::{ @@ -34,20 +33,14 @@ pub async fn add_webhook( Err(_) => StatusCode::BAD_REQUEST, }; - Ok(ApiResponse { - json: json!({}), - status, - }) + Ok(ApiResponse::with_status(status)) } // TODO: paginate pub async fn list_webhooks(_admin: AdminRole, State(appstate): State) -> ApiResult { let webhooks = WebHook::all(&appstate.pool).await?; - Ok(ApiResponse { - json: json!(webhooks), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(webhooks, StatusCode::OK)) } pub async fn get_webhook( @@ -56,14 +49,8 @@ pub async fn get_webhook( Path(id): Path, ) -> ApiResult { match WebHook::find_by_id(&appstate.pool, id).await? { - Some(webhook) => Ok(ApiResponse { - json: json!(webhook), - status: StatusCode::OK, - }), - None => Ok(ApiResponse { - json: json!({}), - status: StatusCode::NOT_FOUND, - }), + Some(webhook) => Ok(ApiResponse::json(webhook, StatusCode::OK)), + None => Ok(ApiResponse::with_status(StatusCode::NOT_FOUND)), } } @@ -102,10 +89,7 @@ pub async fn change_webhook( None => StatusCode::NOT_FOUND, }; - Ok(ApiResponse { - json: json!({}), - status, - }) + Ok(ApiResponse::with_status(status)) } pub async fn delete_webhook( @@ -128,10 +112,7 @@ pub async fn delete_webhook( } None => StatusCode::NOT_FOUND, }; - Ok(ApiResponse { - json: json!({}), - status, - }) + Ok(ApiResponse::with_status(status)) } #[derive(Deserialize)] @@ -170,8 +151,5 @@ pub async fn change_enabled( } None => StatusCode::NOT_FOUND, }; - Ok(ApiResponse { - json: json!({}), - status, - }) + Ok(ApiResponse::with_status(status)) } diff --git a/crates/defguard_core/src/handlers/wireguard.rs b/crates/defguard_core/src/handlers/wireguard.rs index 01e7d2171e..760edb65bc 100644 --- a/crates/defguard_core/src/handlers/wireguard.rs +++ b/crates/defguard_core/src/handlers/wireguard.rs @@ -271,10 +271,7 @@ pub(crate) async fn create_network( })?; update_counts(&appstate.pool).await?; - Ok(ApiResponse { - json: json!(network), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(network, StatusCode::CREATED)) } async fn find_network(id: Id, pool: &PgPool) -> Result, WebError> { @@ -382,10 +379,7 @@ pub(crate) async fn modify_network( after: network.clone(), }), })?; - Ok(ApiResponse { - json: json!(network), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(network, StatusCode::OK)) } /// Delete network @@ -484,10 +478,7 @@ pub(crate) async fn list_networks(_role: AdminRole, State(appstate): State ApiResponse { - json: Value::Null, - status: StatusCode::NOT_FOUND, - }, + None => ApiResponse::new(Value::Null, StatusCode::NOT_FOUND), }; debug!("Displayed network details for network {network_id}"); @@ -564,10 +549,7 @@ pub(crate) async fn gateway_status( debug!("Displayed gateway status for network {network_id}"); - Ok(ApiResponse { - json: json!(gateways), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(gateways, StatusCode::OK)) } /// Returns state of gateways for all networks @@ -587,10 +569,7 @@ pub(crate) async fn all_gateways_status( entry.push(gateway.into()); } - Ok(ApiResponse { - json: json!(map), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(map, StatusCode::OK)) } #[derive(Deserialize)] @@ -612,19 +591,16 @@ pub(crate) async fn change_gateway( gateway.url = data.url; gateway.save(&appstate.pool).await?; info!("Changed gateway"); - return Ok(ApiResponse { - json: json!(GatewayInfo::from(gateway)), - status: StatusCode::OK, - }); + return Ok(ApiResponse::json( + GatewayInfo::from(gateway), + StatusCode::OK, + )); } } info!("Changed gateway {gateway_id} in network {network_id}"); - Ok(ApiResponse { - json: Value::Null, - status: StatusCode::NOT_FOUND, - }) + Ok(ApiResponse::new(Value::Null, StatusCode::NOT_FOUND)) } /// Remove gateway (DELETE). @@ -639,10 +615,7 @@ pub(crate) async fn remove_gateway( info!("Removed gateway {gateway_id} in network {network_id}"); - Ok(ApiResponse { - json: Value::Null, - status: StatusCode::OK, - }) + Ok(ApiResponse::new(Value::Null, StatusCode::OK)) } pub(crate) async fn import_network( @@ -695,10 +668,10 @@ pub(crate) async fn import_network( })?; update_counts(&appstate.pool).await?; - Ok(ApiResponse { - json: json!(ImportedNetworkData { network, devices }), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json( + ImportedNetworkData { network, devices }, + StatusCode::CREATED, + )) } // This is used exclusively for the wizard to map imported devices to users. @@ -721,10 +694,7 @@ pub(crate) async fn add_user_devices( // finish early if no devices were provided in request if mapped_devices.is_empty() { debug!("No devices provided in request, skipping mapping"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::NO_CONTENT, - }); + return Ok(ApiResponse::with_status(StatusCode::NO_CONTENT)); } if let Some(network) = WireguardNetwork::find_by_id(&appstate.pool, network_id).await? { @@ -740,10 +710,7 @@ pub(crate) async fn add_user_devices( ); update_counts(&appstate.pool).await?; - Ok(ApiResponse { - json: json!({}), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::with_status(StatusCode::CREATED)) } else { error!("Failed to map devices, network {network_id} not found"); Err(WebError::ObjectNotFound(format!( @@ -860,10 +827,7 @@ pub(crate) async fn add_device( let networks = WireguardNetwork::all(&appstate.pool).await?; if networks.is_empty() { error!("Failed to add device {device_name}, no networks found"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } Device::validate_pubkey(&add_device.wireguard_pubkey).map_err(WebError::PubkeyValidation)?; @@ -979,10 +943,7 @@ pub(crate) async fn add_device( }), })?; - Ok(ApiResponse { - json: json!(result), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::json(result, StatusCode::CREATED)) } /// Modify device @@ -1052,10 +1013,7 @@ pub(crate) async fn modify_device( if networks.is_empty() { error!("Failed to update device {device_id}, no networks found"); - return Ok(ApiResponse { - json: json!({}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::with_status(StatusCode::BAD_REQUEST)); } // check pubkeys @@ -1064,10 +1022,10 @@ pub(crate) async fn modify_device( error!( "Failed to update device {device_id}, device's pubkey must be different from server's pubkey" ); - return Ok(ApiResponse { - json: json!({"msg": "device's pubkey must be different from server's pubkey"}), - status: StatusCode::BAD_REQUEST, - }); + return Ok(ApiResponse::new( + json!({"msg": "device's pubkey must be different from server's pubkey"}), + StatusCode::BAD_REQUEST, + )); } } @@ -1110,10 +1068,7 @@ pub(crate) async fn modify_device( }), })?; - Ok(ApiResponse { - json: json!(device), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(device, StatusCode::OK)) } /// Get device @@ -1157,10 +1112,7 @@ pub(crate) async fn get_device( debug!("Retrieving device with id: {device_id}"); let device = device_for_admin_or_self(&appstate.pool, &session, device_id).await?; debug!("Retrieved device with id: {device_id}"); - Ok(ApiResponse { - json: json!(device), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(device, StatusCode::OK)) } /// Delete device @@ -1311,10 +1263,7 @@ pub(crate) async fn list_devices(_role: AdminRole, State(appstate): State Api ) .to_jwt() .map_err(|_| WebError::Authorization("Failed to create bridge token".into()))?; - Ok(ApiResponse { - json: json!({ "token": token }), - status: StatusCode::CREATED, - }) + Ok(ApiResponse::new( + json!({ "token": token }), + StatusCode::CREATED, + )) } pub async fn list_workers( @@ -107,10 +104,7 @@ pub async fn list_workers( let state = worker_state.lock().unwrap(); let workers = state.list_workers(); debug!("Listed workers"); - Ok(ApiResponse { - json: json!(workers), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(workers, StatusCode::OK)) } pub async fn remove_worker( @@ -156,27 +150,21 @@ pub async fn job_status( } if response.success { debug!("Fetched job status for job {id}"); - Ok(ApiResponse { - json: json!(job_response), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(job_response, StatusCode::OK)) } else { error!( "Failed to fetch job status for job {id}: {}", response.error ); - Ok(ApiResponse { - json: json!(JobResponseError { - message: response.error.clone() - }), - status: StatusCode::NOT_FOUND, - }) + Ok(ApiResponse::json( + JobResponseError { + message: response.error.clone(), + }, + StatusCode::NOT_FOUND, + )) } } else { debug!("Fetched job status for job {id}"); - Ok(ApiResponse { - json: json!(job_response), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(job_response, StatusCode::OK)) } } diff --git a/crates/defguard_core/src/handlers/yubikey.rs b/crates/defguard_core/src/handlers/yubikey.rs index 23a1d65ce6..1ff73ba9f2 100644 --- a/crates/defguard_core/src/handlers/yubikey.rs +++ b/crates/defguard_core/src/handlers/yubikey.rs @@ -4,7 +4,6 @@ use axum::{ http::StatusCode, }; use defguard_common::db::{Id, models::YubiKey}; -use serde_json::json; use super::{ApiResponse, ApiResult, user_for_admin_or_self}; use crate::{appstate::AppState, auth::SessionInfo, error::WebError}; @@ -29,10 +28,7 @@ pub(crate) async fn delete_yubikey( } yubikey.delete(&appstate.pool).await?; info!("Yubikey {key_id} deleted by user {}", user.id); - Ok(ApiResponse { - json: json!({}), - status: StatusCode::OK, - }) + Ok(ApiResponse::with_status(StatusCode::OK)) } #[derive(Deserialize)] @@ -62,8 +58,5 @@ pub(crate) async fn rename_yubikey( yubikey.name = data.name; yubikey.save(&appstate.pool).await?; info!("Yubikey {} renamed by user {}", yubikey.id, user.id); - Ok(ApiResponse { - json: json!(yubikey), - status: StatusCode::OK, - }) + Ok(ApiResponse::json(yubikey, StatusCode::OK)) } diff --git a/crates/defguard_core/tests/integration/api/acl.rs b/crates/defguard_core/tests/integration/api/acl.rs index c85f9603c7..36fc67de09 100644 --- a/crates/defguard_core/tests/integration/api/acl.rs +++ b/crates/defguard_core/tests/integration/api/acl.rs @@ -888,7 +888,7 @@ async fn test_rule_application(_: PgPoolOptions, options: PgConnectOptions) { // apply rule let response = client .put("/api/v1/acl/rule/apply") - .json(&json!({ "rules": vec![1] })) + .json(&json!({ "rules": [1] })) .send() .await; assert_eq!(response.status(), StatusCode::OK); @@ -900,7 +900,7 @@ async fn test_rule_application(_: PgPoolOptions, options: PgConnectOptions) { // cannot apply the same rule again let response = client .put("/api/v1/acl/rule/apply") - .json(&json!({ "rules": vec![1] })) + .json(&json!({ "rules": [1] })) .send() .await; assert_eq!(response.status(), StatusCode::BAD_REQUEST); @@ -914,7 +914,7 @@ async fn test_rule_application(_: PgPoolOptions, options: PgConnectOptions) { // still cannot apply the same rule again let response = client .put("/api/v1/acl/rule/apply") - .json(&json!({ "rules": vec![1] })) + .json(&json!({ "rules": [1] })) .send() .await; assert_eq!(response.status(), StatusCode::BAD_REQUEST); @@ -922,7 +922,7 @@ async fn test_rule_application(_: PgPoolOptions, options: PgConnectOptions) { // apply modification let response = client .put("/api/v1/acl/rule/apply") - .json(&json!({ "rules": vec![2] })) + .json(&json!({ "rules": [2] })) .send() .await; assert_eq!(response.status(), StatusCode::OK); @@ -950,7 +950,7 @@ async fn test_rule_application(_: PgPoolOptions, options: PgConnectOptions) { // apply modification let response = client .put("/api/v1/acl/rule/apply") - .json(&json!({ "rules": vec![3] })) + .json(&json!({ "rules": [3] })) .send() .await; assert_eq!(response.status(), StatusCode::OK); @@ -982,7 +982,7 @@ async fn test_multiple_rules_application(_: PgPoolOptions, options: PgConnectOpt // apply multiple rules let response = client .put("/api/v1/acl/rule/apply") - .json(&json!({ "rules": vec![1, 3] })) + .json(&json!({ "rules": [1, 3] })) .send() .await; assert_eq!(response.status(), StatusCode::OK); @@ -1165,7 +1165,7 @@ async fn test_alias_application(_: PgPoolOptions, options: PgConnectOptions) { // cannot apply already applied alias let response = client .put("/api/v1/acl/alias/apply") - .json(&json!({ "aliases": vec![1] })) + .json(&json!({ "aliases": [1] })) .send() .await; assert_eq!(response.status(), StatusCode::BAD_REQUEST); @@ -1173,7 +1173,7 @@ async fn test_alias_application(_: PgPoolOptions, options: PgConnectOptions) { // apply modification let response = client .put("/api/v1/acl/alias/apply") - .json(&json!({ "aliases": vec![2] })) + .json(&json!({ "aliases": [2] })) .send() .await; assert_eq!(response.status(), StatusCode::OK); @@ -1240,7 +1240,7 @@ async fn test_multiple_aliases_application(_: PgPoolOptions, options: PgConnectO // apply multiple aliases let response = client .put("/api/v1/acl/alias/apply") - .json(&json!({ "aliases": vec![4, 6] })) + .json(&json!({ "aliases": [4, 6] })) .send() .await; assert_eq!(response.status(), StatusCode::OK);