mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-09-06 04:36:32 +00:00
Add nice error message for users trying to set uuid or isEditable
This commit is contained in:
@ -425,7 +425,9 @@ InvalidWebhooksUrl , InvalidRequest , BAD_REQU
|
|||||||
InvalidWebhooksHeaders , InvalidRequest , BAD_REQUEST ;
|
InvalidWebhooksHeaders , InvalidRequest , BAD_REQUEST ;
|
||||||
ReservedWebhook , InvalidRequest , BAD_REQUEST ;
|
ReservedWebhook , InvalidRequest , BAD_REQUEST ;
|
||||||
InvalidWebhookUuid , InvalidRequest , BAD_REQUEST ;
|
InvalidWebhookUuid , InvalidRequest , BAD_REQUEST ;
|
||||||
WebhookNotFound , InvalidRequest , NOT_FOUND
|
WebhookNotFound , InvalidRequest , NOT_FOUND ;
|
||||||
|
ImmutableWebhookUuid , InvalidRequest , BAD_REQUEST ;
|
||||||
|
ImmutableWebhookIsEditable , InvalidRequest , BAD_REQUEST
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorCode for JoinError {
|
impl ErrorCode for JoinError {
|
||||||
|
@ -7,12 +7,15 @@ use actix_http::header::{
|
|||||||
};
|
};
|
||||||
use actix_web::web::{self, Data, Path};
|
use actix_web::web::{self, Data, Path};
|
||||||
use actix_web::{HttpRequest, HttpResponse};
|
use actix_web::{HttpRequest, HttpResponse};
|
||||||
|
use core::convert::Infallible;
|
||||||
use deserr::actix_web::AwebJson;
|
use deserr::actix_web::AwebJson;
|
||||||
use deserr::Deserr;
|
use deserr::{DeserializeError, Deserr, ValuePointerRef};
|
||||||
use index_scheduler::IndexScheduler;
|
use index_scheduler::IndexScheduler;
|
||||||
use meilisearch_types::deserr::DeserrJsonError;
|
use meilisearch_types::deserr::{immutable_field_error, DeserrJsonError};
|
||||||
use meilisearch_types::error::deserr_codes::{InvalidWebhooksHeaders, InvalidWebhooksUrl};
|
use meilisearch_types::error::deserr_codes::{
|
||||||
use meilisearch_types::error::{ErrorCode, ResponseError};
|
BadRequest, InvalidWebhooksHeaders, InvalidWebhooksUrl,
|
||||||
|
};
|
||||||
|
use meilisearch_types::error::{Code, ErrorCode, ResponseError};
|
||||||
use meilisearch_types::keys::actions;
|
use meilisearch_types::keys::actions;
|
||||||
use meilisearch_types::milli::update::Setting;
|
use meilisearch_types::milli::update::Setting;
|
||||||
use meilisearch_types::webhooks::Webhook;
|
use meilisearch_types::webhooks::Webhook;
|
||||||
@ -54,7 +57,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserr, ToSchema)]
|
#[derive(Debug, Deserr, ToSchema)]
|
||||||
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
|
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields = deny_immutable_fields_webhook)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[schema(rename_all = "camelCase")]
|
#[schema(rename_all = "camelCase")]
|
||||||
pub(super) struct WebhookSettings {
|
pub(super) struct WebhookSettings {
|
||||||
@ -68,6 +71,22 @@ pub(super) struct WebhookSettings {
|
|||||||
headers: Setting<BTreeMap<String, Setting<String>>>,
|
headers: Setting<BTreeMap<String, Setting<String>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deny_immutable_fields_webhook(
|
||||||
|
field: &str,
|
||||||
|
accepted: &[&str],
|
||||||
|
location: ValuePointerRef,
|
||||||
|
) -> DeserrJsonError {
|
||||||
|
match field {
|
||||||
|
"uuid" => immutable_field_error(field, accepted, Code::ImmutableWebhookUuid),
|
||||||
|
"isEditable" => immutable_field_error(field, accepted, Code::ImmutableWebhookIsEditable),
|
||||||
|
_ => deserr::take_cf_content(DeserrJsonError::<BadRequest>::error::<Infallible>(
|
||||||
|
None,
|
||||||
|
deserr::ErrorKind::UnknownKey { key: field, accepted },
|
||||||
|
location,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, ToSchema)]
|
#[derive(Debug, Serialize, ToSchema)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[schema(rename_all = "camelCase")]
|
#[schema(rename_all = "camelCase")]
|
||||||
|
@ -273,7 +273,7 @@ async fn reserved_names() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Cannot edit webhook `[uuid]`. Webhooks prefixed with an underscore are reserved and may not be modified using the API.",
|
"message": "Cannot edit webhook `[uuid]`. The webhook defined from the command line cannot be modified using the API.",
|
||||||
"code": "reserved_webhook",
|
"code": "reserved_webhook",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#reserved_webhook"
|
"link": "https://docs.meilisearch.com/errors#reserved_webhook"
|
||||||
@ -284,7 +284,7 @@ async fn reserved_names() {
|
|||||||
snapshot!(code, @"400 Bad Request");
|
snapshot!(code, @"400 Bad Request");
|
||||||
snapshot!(value, @r#"
|
snapshot!(value, @r#"
|
||||||
{
|
{
|
||||||
"message": "Cannot edit webhook `[uuid]`. Webhooks prefixed with an underscore are reserved and may not be modified using the API.",
|
"message": "Cannot edit webhook `[uuid]`. The webhook defined from the command line cannot be modified using the API.",
|
||||||
"code": "reserved_webhook",
|
"code": "reserved_webhook",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#reserved_webhook"
|
"link": "https://docs.meilisearch.com/errors#reserved_webhook"
|
||||||
@ -562,3 +562,85 @@ async fn invalid_uuid() {
|
|||||||
}
|
}
|
||||||
"#);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_web::test]
|
||||||
|
async fn forbidden_fields() {
|
||||||
|
let server = Server::new().await;
|
||||||
|
|
||||||
|
// Test creating webhook with uuid field
|
||||||
|
let custom_uuid = Uuid::new_v4();
|
||||||
|
let (value, code) = server
|
||||||
|
.create_webhook(json!({
|
||||||
|
"url": "https://example.com/hook",
|
||||||
|
"uuid": custom_uuid.to_string(),
|
||||||
|
"headers": { "authorization": "TOKEN" }
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
snapshot!(code, @"400 Bad Request");
|
||||||
|
snapshot!(value, @r#"
|
||||||
|
{
|
||||||
|
"message": "Immutable field `uuid`: expected one of `url`, `headers`",
|
||||||
|
"code": "immutable_webhook_uuid",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#immutable_webhook_uuid"
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
|
// Test creating webhook with isEditable field
|
||||||
|
let (value, code) = server
|
||||||
|
.create_webhook(json!({
|
||||||
|
"url": "https://example.com/hook2",
|
||||||
|
"isEditable": false,
|
||||||
|
"headers": { "authorization": "TOKEN" }
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
snapshot!(code, @"400 Bad Request");
|
||||||
|
snapshot!(value, @r#"
|
||||||
|
{
|
||||||
|
"message": "Immutable field `isEditable`: expected one of `url`, `headers`",
|
||||||
|
"code": "immutable_webhook_is_editable",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#immutable_webhook_is_editable"
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
|
// Test patching webhook with uuid field
|
||||||
|
let (value, code) = server
|
||||||
|
.patch_webhook(
|
||||||
|
"uuid-whatever",
|
||||||
|
json!({
|
||||||
|
"uuid": Uuid::new_v4(),
|
||||||
|
"headers": { "new-header": "value" }
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
snapshot!(code, @"400 Bad Request");
|
||||||
|
snapshot!(value, @r#"
|
||||||
|
{
|
||||||
|
"message": "Immutable field `uuid`: expected one of `url`, `headers`",
|
||||||
|
"code": "immutable_webhook_uuid",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#immutable_webhook_uuid"
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
|
||||||
|
// Test patching webhook with isEditable field
|
||||||
|
let (value, code) = server
|
||||||
|
.patch_webhook(
|
||||||
|
"uuid-whatever",
|
||||||
|
json!({
|
||||||
|
"isEditable": false,
|
||||||
|
"headers": { "another-header": "value" }
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
snapshot!(code, @"400 Bad Request");
|
||||||
|
snapshot!(json_string!(value, { ".uuid" => "[uuid]" }), @r#"
|
||||||
|
{
|
||||||
|
"message": "Immutable field `isEditable`: expected one of `url`, `headers`",
|
||||||
|
"code": "immutable_webhook_is_editable",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#immutable_webhook_is_editable"
|
||||||
|
}
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user