mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-07-04 04:17:10 +02:00
Merge #2414
2414: Improve index uid validation upon API key creation r=Kerollmops a=pierre-l - ~Use an IndexUid newtype to enforce stronger constraints~ - ~`cargo update -p vergen`~ (`rustup update` was the proper fix for this) - Add a new `meilisearch_types` crate - Move `meilisearch_error` to `meilisearch_types::error` - Move `meilisearch_lib::index_resolver::IndexUid` to `meilisearch_types::index_uid` - Add a new `InvalidIndexUid` error in `meilisearch_types::index_uid` - Move `meilisearch_http::routes::StarOr` to `meilisearch_types::star_or` - Use the `IndexUid` and `StarOr` in `meilisearch_auth::Key` Fixes #2158 Co-authored-by: pierre-l <pierre.larger@gmail.com>
This commit is contained in:
commit
de356061db
51 changed files with 362 additions and 193 deletions
|
@ -29,7 +29,7 @@ itertools = "0.10.3"
|
|||
lazy_static = "1.4.0"
|
||||
log = "0.4.14"
|
||||
meilisearch-auth = { path = "../meilisearch-auth" }
|
||||
meilisearch-error = { path = "../meilisearch-error" }
|
||||
meilisearch-types = { path = "../meilisearch-types" }
|
||||
milli = { git = "https://github.com/meilisearch/milli.git", tag = "v0.29.2" }
|
||||
mime = "0.3.16"
|
||||
num_cpus = "1.13.1"
|
||||
|
@ -59,7 +59,7 @@ whoami = { version = "1.2.1", optional = true }
|
|||
|
||||
[dev-dependencies]
|
||||
actix-rt = "2.7.0"
|
||||
meilisearch-error = { path = "../meilisearch-error", features = ["test-traits"] }
|
||||
meilisearch-types = { path = "../meilisearch-types", features = ["test-traits"] }
|
||||
mockall = "0.11.0"
|
||||
nelson = { git = "https://github.com/meilisearch/nelson.git", rev = "675f13885548fb415ead8fbb447e9e6d9314000a"}
|
||||
paste = "1.0.6"
|
||||
|
|
|
@ -2,7 +2,8 @@ use std::borrow::Borrow;
|
|||
use std::fmt::{self, Debug, Display};
|
||||
use std::io::{self, BufRead, BufReader, BufWriter, Cursor, Read, Seek, Write};
|
||||
|
||||
use meilisearch_error::{internal_error, Code, ErrorCode};
|
||||
use meilisearch_types::error::{Code, ErrorCode};
|
||||
use meilisearch_types::internal_error;
|
||||
use milli::documents::DocumentBatchBuilder;
|
||||
|
||||
type Result<T> = std::result::Result<T, DocumentFormatError>;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use anyhow::bail;
|
||||
use meilisearch_error::Code;
|
||||
use meilisearch_types::error::Code;
|
||||
use milli::update::IndexDocumentsMethod;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use meilisearch_error::{Code, ResponseError};
|
||||
use meilisearch_types::error::{Code, ResponseError};
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use milli::update::IndexDocumentsMethod;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
|
@ -6,7 +7,6 @@ use uuid::Uuid;
|
|||
|
||||
use super::v4::{Task, TaskContent, TaskEvent};
|
||||
use crate::index::{Settings, Unchecked};
|
||||
use crate::index_resolver::IndexUid;
|
||||
use crate::tasks::task::{DocumentDeletion, TaskId, TaskResult};
|
||||
|
||||
use super::v2;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use meilisearch_error::ResponseError;
|
||||
use meilisearch_types::error::ResponseError;
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use milli::update::IndexDocumentsMethod;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
|
@ -9,7 +10,6 @@ use crate::tasks::batch::BatchId;
|
|||
use crate::tasks::task::{
|
||||
DocumentDeletion, TaskContent as NewTaskContent, TaskEvent as NewTaskEvent, TaskId, TaskResult,
|
||||
};
|
||||
use crate::IndexUid;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Task {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use meilisearch_auth::error::AuthControllerError;
|
||||
use meilisearch_error::{internal_error, Code, ErrorCode};
|
||||
use meilisearch_types::error::{Code, ErrorCode};
|
||||
use meilisearch_types::internal_error;
|
||||
|
||||
use crate::{index_resolver::error::IndexResolverError, tasks::error::TaskError};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
use meilisearch_error::{Code, ErrorCode};
|
||||
use meilisearch_types::error::{Code, ErrorCode};
|
||||
use milli::UserError;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::error::Error;
|
||||
|
||||
use meilisearch_error::{internal_error, Code, ErrorCode};
|
||||
use meilisearch_types::error::{Code, ErrorCode};
|
||||
use meilisearch_types::internal_error;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::{error::MilliError, update_file_store};
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use std::error::Error;
|
||||
|
||||
use meilisearch_error::Code;
|
||||
use meilisearch_error::{internal_error, ErrorCode};
|
||||
use meilisearch_types::error::{Code, ErrorCode};
|
||||
use meilisearch_types::index_uid::IndexUidFormatError;
|
||||
use meilisearch_types::internal_error;
|
||||
use tokio::task::JoinError;
|
||||
|
||||
use super::DocumentAdditionFormat;
|
||||
|
@ -63,3 +64,9 @@ impl ErrorCode for IndexControllerError {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IndexUidFormatError> for IndexControllerError {
|
||||
fn from(err: IndexUidFormatError) -> Self {
|
||||
IndexResolverError::from(err).into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use actix_web::error::PayloadError;
|
|||
use bytes::Bytes;
|
||||
use futures::Stream;
|
||||
use futures::StreamExt;
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use milli::update::IndexDocumentsMethod;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
|
@ -37,7 +38,6 @@ use error::Result;
|
|||
use self::error::IndexControllerError;
|
||||
use crate::index_resolver::index_store::{IndexStore, MapIndexStore};
|
||||
use crate::index_resolver::meta_store::{HeedMetaStore, IndexMetaStore};
|
||||
pub use crate::index_resolver::IndexUid;
|
||||
use crate::index_resolver::{create_index_resolver, IndexResolver};
|
||||
use crate::update_file_store::UpdateFileStore;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
use meilisearch_error::{internal_error, Code, ErrorCode};
|
||||
use meilisearch_types::{internal_error, Code, ErrorCode};
|
||||
|
||||
use crate::{
|
||||
document_formats::DocumentFormatError,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::fmt;
|
||||
|
||||
use meilisearch_error::{internal_error, Code, ErrorCode};
|
||||
use meilisearch_types::error::{Code, ErrorCode};
|
||||
use meilisearch_types::index_uid::IndexUidFormatError;
|
||||
use meilisearch_types::internal_error;
|
||||
use tokio::sync::mpsc::error::SendError as MpscSendError;
|
||||
use tokio::sync::oneshot::error::RecvError as OneshotRecvError;
|
||||
use uuid::Uuid;
|
||||
|
@ -25,8 +27,8 @@ pub enum IndexResolverError {
|
|||
UuidAlreadyExists(Uuid),
|
||||
#[error("{0}")]
|
||||
Milli(#[from] milli::Error),
|
||||
#[error("`{0}` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_).")]
|
||||
BadlyFormatted(String),
|
||||
#[error("{0}")]
|
||||
BadlyFormatted(#[from] IndexUidFormatError),
|
||||
}
|
||||
|
||||
impl<T> From<MpscSendError<T>> for IndexResolverError
|
||||
|
|
|
@ -2,20 +2,17 @@ pub mod error;
|
|||
pub mod index_store;
|
||||
pub mod meta_store;
|
||||
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::convert::TryFrom;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use error::{IndexResolverError, Result};
|
||||
use index_store::{IndexStore, MapIndexStore};
|
||||
use meilisearch_error::ResponseError;
|
||||
use meilisearch_types::error::ResponseError;
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use meta_store::{HeedMetaStore, IndexMetaStore};
|
||||
use milli::heed::Env;
|
||||
use milli::update::{DocumentDeletionResult, IndexerConfig};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
use tokio::task::spawn_blocking;
|
||||
use uuid::Uuid;
|
||||
|
@ -35,12 +32,6 @@ pub use real::IndexResolver;
|
|||
#[cfg(test)]
|
||||
pub use test::MockIndexResolver as IndexResolver;
|
||||
|
||||
/// An index uid is composed of only ascii alphanumeric characters, - and _, between 1 and 400
|
||||
/// bytes long
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||
pub struct IndexUid(#[cfg_attr(test, proptest(regex("[a-zA-Z0-9_-]{1,400}")))] String);
|
||||
|
||||
pub fn create_index_resolver(
|
||||
path: impl AsRef<Path>,
|
||||
index_size: usize,
|
||||
|
@ -53,81 +44,6 @@ pub fn create_index_resolver(
|
|||
Ok(IndexResolver::new(uuid_store, index_store, file_store))
|
||||
}
|
||||
|
||||
impl IndexUid {
|
||||
pub fn new_unchecked(s: impl AsRef<str>) -> Self {
|
||||
Self(s.as_ref().to_string())
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> String {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Return a reference over the inner str.
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for IndexUid {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<IndexUid> for String {
|
||||
type Error = IndexUidFormatError;
|
||||
|
||||
fn try_into(self) -> std::result::Result<IndexUid, IndexUidFormatError> {
|
||||
IndexUid::from_str(&self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IndexUidFormatError {
|
||||
invalid_uid: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for IndexUidFormatError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"invalid index uid `{}`, the uid must be an integer \
|
||||
or a string containing only alphanumeric characters \
|
||||
a-z A-Z 0-9, hyphens - and underscores _.",
|
||||
self.invalid_uid,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for IndexUidFormatError {}
|
||||
|
||||
impl From<IndexUidFormatError> for IndexResolverError {
|
||||
fn from(error: IndexUidFormatError) -> Self {
|
||||
Self::BadlyFormatted(error.invalid_uid)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for IndexUid {
|
||||
type Err = IndexUidFormatError;
|
||||
|
||||
fn from_str(uid: &str) -> std::result::Result<IndexUid, IndexUidFormatError> {
|
||||
if !uid
|
||||
.chars()
|
||||
.all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
|
||||
|| uid.is_empty()
|
||||
|| uid.len() > 400
|
||||
{
|
||||
Err(IndexUidFormatError {
|
||||
invalid_uid: uid.to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok(IndexUid(uid.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod real {
|
||||
use super::*;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ mod update_file_store;
|
|||
|
||||
use std::path::Path;
|
||||
|
||||
pub use index_controller::{IndexUid, MeiliSearch};
|
||||
pub use index_controller::MeiliSearch;
|
||||
pub use milli;
|
||||
pub use milli::heed;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use meilisearch_error::{internal_error, Code, ErrorCode};
|
||||
use meilisearch_types::error::{Code, ErrorCode};
|
||||
use meilisearch_types::internal_error;
|
||||
use tokio::task::JoinError;
|
||||
|
||||
use crate::update_file_store::UpdateFileStoreError;
|
||||
|
|
|
@ -55,9 +55,9 @@ mod test {
|
|||
task::{Task, TaskContent},
|
||||
};
|
||||
use crate::update_file_store::{Result as FileStoreResult, UpdateFileStore};
|
||||
use crate::IndexUid;
|
||||
|
||||
use super::*;
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use milli::update::IndexDocumentsMethod;
|
||||
use nelson::Mocker;
|
||||
use proptest::prelude::*;
|
||||
|
|
|
@ -534,10 +534,11 @@ fn make_batch(tasks: &mut TaskQueue, config: &SchedulerConfig) -> Processing {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use milli::update::IndexDocumentsMethod;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{index_resolver::IndexUid, tasks::task::TaskContent};
|
||||
use crate::tasks::task::TaskContent;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use meilisearch_error::ResponseError;
|
||||
use meilisearch_types::error::ResponseError;
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use milli::update::{DocumentAdditionResult, IndexDocumentsMethod};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
|
@ -6,7 +7,6 @@ use uuid::Uuid;
|
|||
|
||||
use super::batch::BatchId;
|
||||
use crate::index::{Settings, Unchecked};
|
||||
use crate::index_resolver::IndexUid;
|
||||
|
||||
pub type TaskId = u32;
|
||||
|
||||
|
|
|
@ -267,13 +267,11 @@ impl TaskStore {
|
|||
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use crate::{
|
||||
tasks::{scheduler::Processing, task_store::store::test::tmp_env},
|
||||
IndexUid,
|
||||
};
|
||||
use crate::tasks::{scheduler::Processing, task_store::store::test::tmp_env};
|
||||
|
||||
use super::*;
|
||||
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use nelson::Mocker;
|
||||
use proptest::{
|
||||
strategy::Strategy,
|
||||
|
|
|
@ -179,11 +179,11 @@ impl Store {
|
|||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use itertools::Itertools;
|
||||
use meilisearch_types::index_uid::IndexUid;
|
||||
use milli::heed::EnvOpenOptions;
|
||||
use nelson::Mocker;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::index_resolver::IndexUid;
|
||||
use crate::tasks::task::TaskContent;
|
||||
|
||||
use super::*;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue