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