diff --git a/Cargo.lock b/Cargo.lock index bc4b3c6a5..8e54e7599 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -290,6 +290,17 @@ dependencies = [ "syn", ] +[[package]] +name = "actix-web-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5ec7f5e4b361aeb648381a33cf81bd0e7a9d2cf9b49cf05fb4e161d8096bb25" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "adler32" version = "1.0.4" @@ -1507,6 +1518,7 @@ dependencies = [ "actix-rt", "actix-service", "actix-web", + "actix-web-macros", "assert-json-diff", "chrono", "crossbeam-channel", diff --git a/meilisearch-http/Cargo.toml b/meilisearch-http/Cargo.toml index ca7f3b256..c7331b871 100644 --- a/meilisearch-http/Cargo.toml +++ b/meilisearch-http/Cargo.toml @@ -46,6 +46,7 @@ actix-http = "1" actix-files = "0.2.1" actix-cors = "0.2.0" actix-service = "1.0.5" +actix-web-macros = "0.1.0" tokio = { version = "0.2.18", features = ["macros"] } [dev-dependencies] diff --git a/meilisearch-http/src/error.rs b/meilisearch-http/src/error.rs index e05853062..db0ce6c2d 100644 --- a/meilisearch-http/src/error.rs +++ b/meilisearch-http/src/error.rs @@ -17,14 +17,12 @@ pub enum ResponseError { InvalidToken(String), Maintenance, MissingAuthorizationHeader, - MissingFilterValue, MissingHeader(String), NotFound(String), OpenIndex(String), FilterParsing(String), RetrieveDocument(u64, String), SearchDocuments(String), - UnknownFilteredAttribute, } impl ResponseError { @@ -103,13 +101,11 @@ impl fmt::Display for ResponseError { Self::Maintenance => f.write_str("Server is in maintenance, please try again later"), Self::FilterParsing(err) => write!(f, "parsing error: {}", err), Self::MissingAuthorizationHeader => f.write_str("You must have an authorization token"), - Self::MissingFilterValue => f.write_str("a filter doesn't have a value to compare it with"), Self::MissingHeader(header) => write!(f, "Header {} is missing", header), Self::NotFound(err) => write!(f, "{} not found", err), Self::OpenIndex(err) => write!(f, "Impossible to open index; {}", err), Self::RetrieveDocument(id, err) => write!(f, "impossible to retrieve the document with id: {}; {}", id, err), Self::SearchDocuments(err) => write!(f, "impossible to search documents; {}", err), - Self::UnknownFilteredAttribute => f.write_str("a filter is specifying an unknown schema attribute"), } } } @@ -123,24 +119,22 @@ impl aweb::error::ResponseError for ResponseError { fn status_code(&self) -> StatusCode { match *self { - Self::BadParameter(_, _) => StatusCode::BAD_REQUEST, - Self::BadRequest(_) => StatusCode::BAD_REQUEST, - Self::CreateIndex(_) => StatusCode::BAD_REQUEST, - Self::DocumentNotFound(_) => StatusCode::NOT_FOUND, - Self::IndexNotFound(_) => StatusCode::NOT_FOUND, - Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, - Self::InvalidIndexUid => StatusCode::BAD_REQUEST, - Self::InvalidToken(_) => StatusCode::UNAUTHORIZED, - Self::Maintenance => StatusCode::SERVICE_UNAVAILABLE, - Self::FilterParsing(_) => StatusCode::BAD_REQUEST, + Self::BadParameter(_, _) + | Self::BadRequest(_) + | Self::CreateIndex(_) + | Self::InvalidIndexUid + | Self::OpenIndex(_) + | Self::RetrieveDocument(_, _) + | Self::SearchDocuments(_) + | Self::FilterParsing(_) => StatusCode::BAD_REQUEST, + Self::DocumentNotFound(_) + | Self::IndexNotFound(_) + | Self::NotFound(_) => StatusCode::NOT_FOUND, + Self::InvalidToken(_) + | Self::MissingHeader(_) => StatusCode::UNAUTHORIZED, Self::MissingAuthorizationHeader => StatusCode::FORBIDDEN, - Self::MissingFilterValue => StatusCode::BAD_REQUEST, - Self::MissingHeader(_) => StatusCode::UNAUTHORIZED, - Self::NotFound(_) => StatusCode::NOT_FOUND, - Self::OpenIndex(_) => StatusCode::BAD_REQUEST, - Self::RetrieveDocument(_, _) => StatusCode::BAD_REQUEST, - Self::SearchDocuments(_) => StatusCode::BAD_REQUEST, - Self::UnknownFilteredAttribute => StatusCode::BAD_REQUEST, + Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, + Self::Maintenance => StatusCode::SERVICE_UNAVAILABLE, } } } diff --git a/meilisearch-http/src/lib.rs b/meilisearch-http/src/lib.rs index 7ce65c5d9..d4f2822ad 100644 --- a/meilisearch-http/src/lib.rs +++ b/meilisearch-http/src/lib.rs @@ -29,57 +29,17 @@ pub fn create_app( App::new() .app_data(web::Data::new(data.clone())) .app_data(web::JsonConfig::default().limit(1024 * 1024 * 10)) // Json Limit of 10Mb - .wrap(helpers::Authentication::Public) .service(routes::load_html) .service(routes::load_css) - .service(routes::search::search_with_url_query) - .service(routes::document::get_document) - .service(routes::document::get_all_documents) - .wrap(helpers::Authentication::Private) - .service(routes::index::list_indexes) - .service(routes::index::get_index) - .service(routes::index::create_index) - .service(routes::index::update_index) - .service(routes::index::delete_index) - .service(routes::index::get_update_status) - .service(routes::index::get_all_updates_status) - .service(routes::document::delete_document) - .service(routes::document::add_documents) - .service(routes::document::update_documents) - .service(routes::document::delete_documents) - .service(routes::document::clear_all_documents) - .service(routes::setting::update_all) - .service(routes::setting::get_all) - .service(routes::setting::delete_all) - .service(routes::setting::get_rules) - .service(routes::setting::update_rules) - .service(routes::setting::delete_rules) - .service(routes::setting::get_distinct) - .service(routes::setting::update_distinct) - .service(routes::setting::delete_distinct) - .service(routes::setting::get_searchable) - .service(routes::setting::update_searchable) - .service(routes::setting::delete_searchable) - .service(routes::setting::get_displayed) - .service(routes::setting::update_displayed) - .service(routes::setting::delete_displayed) - .service(routes::setting::get_accept_new_fields) - .service(routes::setting::update_accept_new_fields) - .service(routes::stop_words::get) - .service(routes::stop_words::update) - .service(routes::stop_words::delete) - .service(routes::synonym::get) - .service(routes::synonym::update) - .service(routes::synonym::delete) - .service(routes::stats::index_stats) - .service(routes::stats::get_stats) - .service(routes::stats::get_version) - .service(routes::stats::get_sys_info) - .service(routes::stats::get_sys_info_pretty) - .service(routes::health::get_health) - .service(routes::health::change_healthyness) - .wrap(helpers::Authentication::Admin) - .service(routes::key::list) + .configure(routes::document::services) + .configure(routes::index::services) + .configure(routes::search::services) + .configure(routes::setting::services) + .configure(routes::stop_words::services) + .configure(routes::synonym::services) + .configure(routes::health::services) + .configure(routes::stats::services) + .configure(routes::key::services) } pub fn index_update_callback(index_uid: &str, data: &Data, status: ProcessedUpdateResult) { diff --git a/meilisearch-http/src/routes/document.rs b/meilisearch-http/src/routes/document.rs index 27407fa4d..eea5d760d 100644 --- a/meilisearch-http/src/routes/document.rs +++ b/meilisearch-http/src/routes/document.rs @@ -1,24 +1,39 @@ use std::collections::{BTreeSet, HashSet}; -use actix_web::{delete, get, post, put, web, HttpResponse}; +use actix_web::{web, HttpResponse}; +use actix_web_macros::{delete, get, post, put}; use indexmap::IndexMap; use serde::Deserialize; use serde_json::Value; use crate::error::ResponseError; +use crate::helpers::Authentication; use crate::routes::{IndexParam, IndexUpdateResponse}; use crate::Data; type Document = IndexMap; #[derive(Default, Deserialize)] -pub struct DocumentParam { +struct DocumentParam { index_uid: String, document_id: String, } -#[get("/indexes/{index_uid}/documents/{document_id}")] -pub async fn get_document( +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(get_document) + .service(delete_document) + .service(get_all_documents) + .service(add_documents) + .service(update_documents) + .service(delete_documents) + .service(clear_all_documents); +} + +#[get( + "/indexes/{index_uid}/documents/{document_id}", + wrap = "Authentication::Public" +)] +async fn get_document( data: web::Data, path: web::Path, ) -> Result { @@ -37,8 +52,11 @@ pub async fn get_document( Ok(HttpResponse::Ok().json(response)) } -#[delete("/indexes/{index_uid}/documents/{document_id}")] -pub async fn delete_document( +#[delete( + "/indexes/{index_uid}/documents/{document_id}", + wrap = "Authentication::Private" +)] +async fn delete_document( data: web::Data, path: web::Path, ) -> Result { @@ -62,14 +80,14 @@ pub async fn delete_document( #[derive(Default, Deserialize)] #[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct BrowseQuery { +struct BrowseQuery { offset: Option, limit: Option, attributes_to_retrieve: Option, } -#[get("/indexes/{index_uid}/documents")] -pub async fn get_all_documents( +#[get("/indexes/{index_uid}/documents", wrap = "Authentication::Public")] +async fn get_all_documents( data: web::Data, path: web::Path, params: web::Query, @@ -119,7 +137,7 @@ fn find_primary_key(document: &IndexMap) -> Option { #[derive(Default, Deserialize)] #[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct UpdateDocumentsQuery { +struct UpdateDocumentsQuery { primary_key: Option, } @@ -175,8 +193,8 @@ async fn update_multiple_documents( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[post("/indexes/{index_uid}/documents")] -pub async fn add_documents( +#[post("/indexes/{index_uid}/documents", wrap = "Authentication::Private")] +async fn add_documents( data: web::Data, path: web::Path, params: web::Query, @@ -185,8 +203,8 @@ pub async fn add_documents( update_multiple_documents(data, path, params, body, false).await } -#[put("/indexes/{index_uid}/documents")] -pub async fn update_documents( +#[put("/indexes/{index_uid}/documents", wrap = "Authentication::Private")] +async fn update_documents( data: web::Data, path: web::Path, params: web::Query, @@ -195,8 +213,11 @@ pub async fn update_documents( update_multiple_documents(data, path, params, body, true).await } -#[post("/indexes/{index_uid}/documents/delete-batch")] -pub async fn delete_documents( +#[post( + "/indexes/{index_uid}/documents/delete-batch", + wrap = "Authentication::Private" +)] +async fn delete_documents( data: web::Data, path: web::Path, body: web::Json>, @@ -224,8 +245,8 @@ pub async fn delete_documents( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[delete("/indexes/{index_uid}/documents")] -pub async fn clear_all_documents( +#[delete("/indexes/{index_uid}/documents", wrap = "Authentication::Private")] +async fn clear_all_documents( data: web::Data, path: web::Path, ) -> Result { diff --git a/meilisearch-http/src/routes/health.rs b/meilisearch-http/src/routes/health.rs index 825d79ef5..4f7795e48 100644 --- a/meilisearch-http/src/routes/health.rs +++ b/meilisearch-http/src/routes/health.rs @@ -1,13 +1,20 @@ -use crate::error::ResponseError; -use crate::Data; -use actix_web::{get, put, web, HttpResponse}; +use actix_web::{web, HttpResponse}; +use actix_web_macros::{get, put}; use heed::types::{Str, Unit}; use serde::Deserialize; +use crate::error::ResponseError; +use crate::helpers::Authentication; +use crate::Data; + const UNHEALTHY_KEY: &str = "_is_unhealthy"; -#[get("/health")] -pub async fn get_health(data: web::Data) -> Result { +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(get_health).service(change_healthyness); +} + +#[get("/health", wrap = "Authentication::Private")] +async fn get_health(data: web::Data) -> Result { let reader = data.db.main_read_txn()?; let common_store = data.db.common_store(); @@ -19,7 +26,7 @@ pub async fn get_health(data: web::Data) -> Result) -> Result { +async fn set_healthy(data: web::Data) -> Result { let mut writer = data.db.main_write_txn()?; let common_store = data.db.common_store(); common_store.delete::<_, Str>(&mut writer, UNHEALTHY_KEY)?; @@ -28,7 +35,7 @@ pub async fn set_healthy(data: web::Data) -> Result) -> Result { +async fn set_unhealthy(data: web::Data) -> Result { let mut writer = data.db.main_write_txn()?; let common_store = data.db.common_store(); common_store.put::<_, Str, Unit>(&mut writer, UNHEALTHY_KEY, &())?; @@ -38,12 +45,12 @@ pub async fn set_unhealthy(data: web::Data) -> Result, body: web::Json, ) -> Result { diff --git a/meilisearch-http/src/routes/index.rs b/meilisearch-http/src/routes/index.rs index d46160e76..b664d0121 100644 --- a/meilisearch-http/src/routes/index.rs +++ b/meilisearch-http/src/routes/index.rs @@ -1,13 +1,25 @@ -use actix_web::{delete, get, post, put, web, HttpResponse}; +use actix_web::{web, HttpResponse}; +use actix_web_macros::{delete, get, post, put}; use chrono::{DateTime, Utc}; use log::error; use rand::seq::SliceRandom; use serde::{Deserialize, Serialize}; use crate::error::ResponseError; +use crate::helpers::Authentication; use crate::routes::IndexParam; use crate::Data; +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(list_indexes) + .service(get_index) + .service(create_index) + .service(update_index) + .service(delete_index) + .service(get_update_status) + .service(get_all_updates_status); +} + fn generate_uid() -> String { let mut rng = rand::thread_rng(); let sample = b"abcdefghijklmnopqrstuvwxyz0123456789"; @@ -19,7 +31,7 @@ fn generate_uid() -> String { #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] -pub struct IndexResponse { +struct IndexResponse { name: String, uid: String, created_at: DateTime, @@ -27,8 +39,8 @@ pub struct IndexResponse { primary_key: Option, } -#[get("/indexes")] -pub async fn list_indexes(data: web::Data) -> Result { +#[get("/indexes", wrap = "Authentication::Private")] +async fn list_indexes(data: web::Data) -> Result { let reader = data.db.main_read_txn()?; let mut response = Vec::new(); @@ -81,8 +93,8 @@ pub async fn list_indexes(data: web::Data) -> Result, path: web::Path, ) -> Result { @@ -128,14 +140,14 @@ pub async fn get_index( #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct IndexCreateRequest { +struct IndexCreateRequest { name: Option, uid: Option, primary_key: Option, } -#[post("/indexes")] -pub async fn create_index( +#[post("/indexes", wrap = "Authentication::Private")] +async fn create_index( data: web::Data, body: web::Json, ) -> Result { @@ -206,14 +218,14 @@ pub async fn create_index( #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct UpdateIndexRequest { +struct UpdateIndexRequest { name: Option, primary_key: Option, } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] -pub struct UpdateIndexResponse { +struct UpdateIndexResponse { name: String, uid: String, created_at: DateTime, @@ -221,8 +233,8 @@ pub struct UpdateIndexResponse { primary_key: Option, } -#[put("/indexes/{index_uid}")] -pub async fn update_index( +#[put("/indexes/{index_uid}", wrap = "Authentication::Private")] +async fn update_index( data: web::Data, path: web::Path, body: web::Json, @@ -292,8 +304,8 @@ pub async fn update_index( })) } -#[delete("/indexes/{index_uid}")] -pub async fn delete_index( +#[delete("/indexes/{index_uid}", wrap = "Authentication::Private")] +async fn delete_index( data: web::Data, path: web::Path, ) -> Result { @@ -303,13 +315,16 @@ pub async fn delete_index( } #[derive(Default, Deserialize)] -pub struct UpdateParam { +struct UpdateParam { index_uid: String, update_id: u64, } -#[get("/indexes/{index_uid}/updates/{update_id}")] -pub async fn get_update_status( +#[get( + "/indexes/{index_uid}/updates/{update_id}", + wrap = "Authentication::Private" +)] +async fn get_update_status( data: web::Data, path: web::Path, ) -> Result { @@ -331,8 +346,8 @@ pub async fn get_update_status( } } -#[get("/indexes/{index_uid}/updates")] -pub async fn get_all_updates_status( +#[get("/indexes/{index_uid}/updates", wrap = "Authentication::Private")] +async fn get_all_updates_status( data: web::Data, path: web::Path, ) -> Result { diff --git a/meilisearch-http/src/routes/key.rs b/meilisearch-http/src/routes/key.rs index 76ab3a116..7cca1bbb1 100644 --- a/meilisearch-http/src/routes/key.rs +++ b/meilisearch-http/src/routes/key.rs @@ -1,15 +1,22 @@ -use crate::Data; -use actix_web::{get, web}; +use actix_web::web; +use actix_web_macros::get; use serde::Serialize; +use crate::helpers::Authentication; +use crate::Data; + +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(list); +} + #[derive(Default, Serialize)] -pub struct KeysResponse { +struct KeysResponse { private: Option, public: Option, } -#[get("/keys")] -pub async fn list(data: web::Data) -> web::Json { +#[get("/keys", wrap = "Authentication::Admin")] +async fn list(data: web::Data) -> web::Json { let api_keys = data.api_keys.clone(); web::Json(KeysResponse { private: api_keys.private, diff --git a/meilisearch-http/src/routes/search.rs b/meilisearch-http/src/routes/search.rs index 3dcfc2a93..f448553bf 100644 --- a/meilisearch-http/src/routes/search.rs +++ b/meilisearch-http/src/routes/search.rs @@ -2,17 +2,23 @@ use std::collections::{HashSet, HashMap}; use std::time::Duration; use log::warn; -use actix_web::{get, web}; +use actix_web::web; +use actix_web_macros::get; use serde::Deserialize; use crate::error::ResponseError; use crate::helpers::meilisearch::{IndexSearchExt, SearchResult}; +use crate::helpers::Authentication; use crate::routes::IndexParam; use crate::Data; +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(search_with_url_query); +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct SearchQuery { +struct SearchQuery { q: String, offset: Option, limit: Option, @@ -25,8 +31,8 @@ pub struct SearchQuery { matches: Option, } -#[get("/indexes/{index_uid}/search")] -pub async fn search_with_url_query( +#[get("/indexes/{index_uid}/search", wrap = "Authentication::Public")] +async fn search_with_url_query( data: web::Data, path: web::Path, params: web::Query, diff --git a/meilisearch-http/src/routes/setting.rs b/meilisearch-http/src/routes/setting.rs index 928736dd1..2af339931 100644 --- a/meilisearch-http/src/routes/setting.rs +++ b/meilisearch-http/src/routes/setting.rs @@ -1,13 +1,35 @@ -use actix_web::{delete, get, post, web, HttpResponse}; +use actix_web::{web, HttpResponse}; +use actix_web_macros::{delete, get, post}; use meilisearch_core::settings::{Settings, SettingsUpdate, UpdateState, DEFAULT_RANKING_RULES}; use std::collections::{BTreeMap, BTreeSet, HashSet}; use crate::error::ResponseError; +use crate::helpers::Authentication; use crate::routes::{IndexParam, IndexUpdateResponse}; use crate::Data; -#[post("/indexes/{index_uid}/settings")] -pub async fn update_all( +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(update_all) + .service(get_all) + .service(delete_all) + .service(get_rules) + .service(update_rules) + .service(delete_rules) + .service(get_distinct) + .service(update_distinct) + .service(delete_distinct) + .service(get_searchable) + .service(update_searchable) + .service(delete_searchable) + .service(get_displayed) + .service(update_displayed) + .service(delete_displayed) + .service(get_accept_new_fields) + .service(update_accept_new_fields); +} + +#[post("/indexes/{index_uid}/settings", wrap = "Authentication::Private")] +async fn update_all( data: web::Data, path: web::Path, body: web::Json, @@ -28,8 +50,8 @@ pub async fn update_all( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[get("/indexes/{index_uid}/settings")] -pub async fn get_all( +#[get("/indexes/{index_uid}/settings", wrap = "Authentication::Private")] +async fn get_all( data: web::Data, path: web::Path, ) -> Result { @@ -98,8 +120,8 @@ pub async fn get_all( Ok(HttpResponse::Ok().json(settings)) } -#[delete("/indexes/{index_uid}/settings")] -pub async fn delete_all( +#[delete("/indexes/{index_uid}/settings", wrap = "Authentication::Private")] +async fn delete_all( data: web::Data, path: web::Path, ) -> Result { @@ -126,8 +148,11 @@ pub async fn delete_all( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[get("/indexes/{index_uid}/settings/ranking-rules")] -pub async fn get_rules( +#[get( + "/indexes/{index_uid}/settings/ranking-rules", + wrap = "Authentication::Private" +)] +async fn get_rules( data: web::Data, path: web::Path, ) -> Result { @@ -148,8 +173,11 @@ pub async fn get_rules( Ok(HttpResponse::Ok().json(ranking_rules)) } -#[post("/indexes/{index_uid}/settings/ranking-rules")] -pub async fn update_rules( +#[post( + "/indexes/{index_uid}/settings/ranking-rules", + wrap = "Authentication::Private" +)] +async fn update_rules( data: web::Data, path: web::Path, body: web::Json>>, @@ -172,8 +200,11 @@ pub async fn update_rules( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[delete("/indexes/{index_uid}/settings/ranking-rules")] -pub async fn delete_rules( +#[delete( + "/indexes/{index_uid}/settings/ranking-rules", + wrap = "Authentication::Private" +)] +async fn delete_rules( data: web::Data, path: web::Path, ) -> Result { @@ -195,8 +226,11 @@ pub async fn delete_rules( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[get("/indexes/{index_uid}/settings/distinct-attribute")] -pub async fn get_distinct( +#[get( + "/indexes/{index_uid}/settings/distinct-attribute", + wrap = "Authentication::Private" +)] +async fn get_distinct( data: web::Data, path: web::Path, ) -> Result { @@ -210,8 +244,11 @@ pub async fn get_distinct( Ok(HttpResponse::Ok().json(distinct_attribute)) } -#[post("/indexes/{index_uid}/settings/distinct-attribute")] -pub async fn update_distinct( +#[post( + "/indexes/{index_uid}/settings/distinct-attribute", + wrap = "Authentication::Private" +)] +async fn update_distinct( data: web::Data, path: web::Path, body: web::Json>, @@ -234,8 +271,11 @@ pub async fn update_distinct( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[delete("/indexes/{index_uid}/settings/distinct-attribute")] -pub async fn delete_distinct( +#[delete( + "/indexes/{index_uid}/settings/distinct-attribute", + wrap = "Authentication::Private" +)] +async fn delete_distinct( data: web::Data, path: web::Path, ) -> Result { @@ -257,8 +297,11 @@ pub async fn delete_distinct( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[get("/indexes/{index_uid}/settings/searchable-attributes")] -pub async fn get_searchable( +#[get( + "/indexes/{index_uid}/settings/searchable-attributes", + wrap = "Authentication::Private" +)] +async fn get_searchable( data: web::Data, path: web::Path, ) -> Result { @@ -274,8 +317,11 @@ pub async fn get_searchable( Ok(HttpResponse::Ok().json(searchable_attributes)) } -#[post("/indexes/{index_uid}/settings/searchable-attributes")] -pub async fn update_searchable( +#[post( + "/indexes/{index_uid}/settings/searchable-attributes", + wrap = "Authentication::Private" +)] +async fn update_searchable( data: web::Data, path: web::Path, body: web::Json>>, @@ -298,8 +344,11 @@ pub async fn update_searchable( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[delete("/indexes/{index_uid}/settings/searchable-attributes")] -pub async fn delete_searchable( +#[delete( + "/indexes/{index_uid}/settings/searchable-attributes", + wrap = "Authentication::Private" +)] +async fn delete_searchable( data: web::Data, path: web::Path, ) -> Result { @@ -320,8 +369,11 @@ pub async fn delete_searchable( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[get("/indexes/{index_uid}/settings/displayed-attributes")] -pub async fn get_displayed( +#[get( + "/indexes/{index_uid}/settings/displayed-attributes", + wrap = "Authentication::Private" +)] +async fn get_displayed( data: web::Data, path: web::Path, ) -> Result { @@ -343,8 +395,11 @@ pub async fn get_displayed( Ok(HttpResponse::Ok().json(displayed_attributes)) } -#[post("/indexes/{index_uid}/settings/displayed-attributes")] -pub async fn update_displayed( +#[post( + "/indexes/{index_uid}/settings/displayed-attributes", + wrap = "Authentication::Private" +)] +async fn update_displayed( data: web::Data, path: web::Path, body: web::Json>>, @@ -367,8 +422,11 @@ pub async fn update_displayed( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[delete("/indexes/{index_uid}/settings/displayed-attributes")] -pub async fn delete_displayed( +#[delete( + "/indexes/{index_uid}/settings/displayed-attributes", + wrap = "Authentication::Private" +)] +async fn delete_displayed( data: web::Data, path: web::Path, ) -> Result { @@ -389,8 +447,11 @@ pub async fn delete_displayed( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[get("/indexes/{index_uid}/settings/accept-new-fields")] -pub async fn get_accept_new_fields( +#[get( + "/indexes/{index_uid}/settings/accept-new-fields", + wrap = "Authentication::Private" +)] +async fn get_accept_new_fields( data: web::Data, path: web::Path, ) -> Result { @@ -407,8 +468,11 @@ pub async fn get_accept_new_fields( Ok(HttpResponse::Ok().json(accept_new_fields)) } -#[post("/indexes/{index_uid}/settings/accept-new-fields")] -pub async fn update_accept_new_fields( +#[post( + "/indexes/{index_uid}/settings/accept-new-fields", + wrap = "Authentication::Private" +)] +async fn update_accept_new_fields( data: web::Data, path: web::Path, body: web::Json>, diff --git a/meilisearch-http/src/routes/stats.rs b/meilisearch-http/src/routes/stats.rs index 9f2449e65..8a793f9bb 100644 --- a/meilisearch-http/src/routes/stats.rs +++ b/meilisearch-http/src/routes/stats.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; -use actix_web::{get, web}; +use actix_web::web; +use actix_web_macros::get; use chrono::{DateTime, Utc}; use log::error; use pretty_bytes::converter::convert; @@ -9,19 +10,28 @@ use sysinfo::{NetworkExt, ProcessExt, ProcessorExt, System, SystemExt}; use walkdir::WalkDir; use crate::error::ResponseError; +use crate::helpers::Authentication; use crate::routes::IndexParam; use crate::Data; +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(index_stats) + .service(get_stats) + .service(get_version) + .service(get_sys_info) + .service(get_sys_info_pretty); +} + #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct IndexStatsResponse { +struct IndexStatsResponse { number_of_documents: u64, is_indexing: bool, fields_frequency: HashMap, } -#[get("/indexes/{index_uid}/stats")] -pub async fn index_stats( +#[get("/indexes/{index_uid}/stats", wrap = "Authentication::Private")] +async fn index_stats( data: web::Data, path: web::Path, ) -> Result, ResponseError> { @@ -51,14 +61,14 @@ pub async fn index_stats( #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct StatsResult { +struct StatsResult { database_size: u64, last_update: Option>, indexes: HashMap, } -#[get("/stats")] -pub async fn get_stats(data: web::Data) -> Result, ResponseError> { +#[get("/stats", wrap = "Authentication::Private")] +async fn get_stats(data: web::Data) -> Result, ResponseError> { let mut index_list = HashMap::new(); let reader = data.db.main_read_txn()?; @@ -109,14 +119,14 @@ pub async fn get_stats(data: web::Data) -> Result, #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct VersionResponse { +struct VersionResponse { commit_sha: String, build_date: String, pkg_version: String, } -#[get("/version")] -pub async fn get_version() -> web::Json { +#[get("/version", wrap = "Authentication::Private")] +async fn get_version() -> web::Json { web::Json(VersionResponse { commit_sha: env!("VERGEN_SHA").to_string(), build_date: env!("VERGEN_BUILD_TIMESTAMP").to_string(), @@ -126,7 +136,7 @@ pub async fn get_version() -> web::Json { #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct SysGlobal { +struct SysGlobal { total_memory: u64, used_memory: u64, total_swap: u64, @@ -150,7 +160,7 @@ impl SysGlobal { #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct SysProcess { +struct SysProcess { memory: u64, cpu: f32, } @@ -166,7 +176,7 @@ impl SysProcess { #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct SysInfo { +struct SysInfo { memory_usage: f64, processor_usage: Vec, global: SysGlobal, @@ -184,8 +194,8 @@ impl SysInfo { } } -#[get("/sys-info")] -pub async fn get_sys_info(data: web::Data) -> web::Json { +#[get("/sys-info", wrap = "Authentication::Private")] +async fn get_sys_info(data: web::Data) -> web::Json { let mut sys = System::new(); let mut info = SysInfo::new(); @@ -221,7 +231,7 @@ pub async fn get_sys_info(data: web::Data) -> web::Json { #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct SysGlobalPretty { +struct SysGlobalPretty { total_memory: String, used_memory: String, total_swap: String, @@ -245,7 +255,7 @@ impl SysGlobalPretty { #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct SysProcessPretty { +struct SysProcessPretty { memory: String, cpu: String, } @@ -261,7 +271,7 @@ impl SysProcessPretty { #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct SysInfoPretty { +struct SysInfoPretty { memory_usage: String, processor_usage: Vec, global: SysGlobalPretty, @@ -279,8 +289,8 @@ impl SysInfoPretty { } } -#[get("/sys-info/pretty")] -pub async fn get_sys_info_pretty(data: web::Data) -> web::Json { +#[get("/sys-info/pretty", wrap = "Authentication::Private")] +async fn get_sys_info_pretty(data: web::Data) -> web::Json { let mut sys = System::new(); let mut info = SysInfoPretty::new(); diff --git a/meilisearch-http/src/routes/stop_words.rs b/meilisearch-http/src/routes/stop_words.rs index fc498a363..21fc9281f 100644 --- a/meilisearch-http/src/routes/stop_words.rs +++ b/meilisearch-http/src/routes/stop_words.rs @@ -1,13 +1,22 @@ -use actix_web::{delete, get, post, web, HttpResponse}; +use actix_web::{web, HttpResponse}; +use actix_web_macros::{delete, get, post}; use meilisearch_core::settings::{SettingsUpdate, UpdateState}; use std::collections::BTreeSet; use crate::error::ResponseError; +use crate::helpers::Authentication; use crate::routes::{IndexParam, IndexUpdateResponse}; use crate::Data; -#[get("/indexes/{index_uid}/settings/stop-words")] -pub async fn get( +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(get).service(update).service(delete); +} + +#[get( + "/indexes/{index_uid}/settings/stop-words", + wrap = "Authentication::Private" +)] +async fn get( data: web::Data, path: web::Path, ) -> Result { @@ -22,8 +31,11 @@ pub async fn get( Ok(HttpResponse::Ok().json(stop_words)) } -#[post("/indexes/{index_uid}/settings/stop-words")] -pub async fn update( +#[post( + "/indexes/{index_uid}/settings/stop-words", + wrap = "Authentication::Private" +)] +async fn update( data: web::Data, path: web::Path, body: web::Json>, @@ -45,8 +57,11 @@ pub async fn update( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[delete("/indexes/{index_uid}/settings/stop-words")] -pub async fn delete( +#[delete( + "/indexes/{index_uid}/settings/stop-words", + wrap = "Authentication::Private" +)] +async fn delete( data: web::Data, path: web::Path, ) -> Result { diff --git a/meilisearch-http/src/routes/synonym.rs b/meilisearch-http/src/routes/synonym.rs index adf76ba99..973f591ab 100644 --- a/meilisearch-http/src/routes/synonym.rs +++ b/meilisearch-http/src/routes/synonym.rs @@ -1,15 +1,24 @@ use std::collections::BTreeMap; -use actix_web::{delete, get, post, web, HttpResponse}; +use actix_web::{web, HttpResponse}; +use actix_web_macros::{delete, get, post}; use indexmap::IndexMap; use meilisearch_core::settings::{SettingsUpdate, UpdateState}; use crate::error::ResponseError; +use crate::helpers::Authentication; use crate::routes::{IndexParam, IndexUpdateResponse}; use crate::Data; -#[get("/indexes/{index_uid}/settings/synonyms")] -pub async fn get( +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(get).service(update).service(delete); +} + +#[get( + "/indexes/{index_uid}/settings/synonyms", + wrap = "Authentication::Private" +)] +async fn get( data: web::Data, path: web::Path, ) -> Result { @@ -37,8 +46,11 @@ pub async fn get( Ok(HttpResponse::Ok().json(synonyms)) } -#[post("/indexes/{index_uid}/settings/synonyms")] -pub async fn update( +#[post( + "/indexes/{index_uid}/settings/synonyms", + wrap = "Authentication::Private" +)] +async fn update( data: web::Data, path: web::Path, body: web::Json>>, @@ -60,8 +72,11 @@ pub async fn update( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } -#[delete("/indexes/{index_uid}/settings/synonyms")] -pub async fn delete( +#[delete( + "/indexes/{index_uid}/settings/synonyms", + wrap = "Authentication::Private" +)] +async fn delete( data: web::Data, path: web::Path, ) -> Result {