Skip to content

Update keys for v0.28.0 #313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 55 commits into from
Aug 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
a37ffd3
Update task api v0.28.0
bidoubiwa Jul 7, 2022
b9ffd60
Update tests to be relevant with the structures where they are ran
bidoubiwa Jul 11, 2022
c527312
Update types in code-samples
bidoubiwa Jul 11, 2022
17d6c19
Remove clearAll task type
bidoubiwa Jul 11, 2022
ff0d350
Add index_uid as an optional in the Tasks
bidoubiwa Jul 11, 2022
9241a7b
Add comments on best builder implementation
bidoubiwa Jul 19, 2022
eb38d18
Add execute function on get_tasks
bidoubiwa Aug 2, 2022
d37be56
Update code samples
bidoubiwa Aug 3, 2022
61be5a5
Remove out of context comment
bidoubiwa Aug 3, 2022
7aa409b
Merge
bidoubiwa Aug 3, 2022
c968df3
Fix tests
bidoubiwa Aug 3, 2022
c21b18f
Fix pagination tests
bidoubiwa Aug 3, 2022
012f939
Update HTTP methods for v0.28.0
bidoubiwa Aug 3, 2022
0cb9e93
Fix clippy
bidoubiwa Aug 3, 2022
a485ba5
Merge branch 'update_task_api_for_v0.28.0' of github.com:meilisearch/…
bidoubiwa Aug 3, 2022
f86bff4
Remove comment of task tests since the tests are now sucesful
bidoubiwa Aug 3, 2022
734fd13
Fix doc tests
bidoubiwa Aug 3, 2022
e5821c4
Merge branch 'update_task_api_for_v0.28.0' of github.com:meilisearch/…
bidoubiwa Aug 3, 2022
11bfb7e
Update keys for v0.28.0
bidoubiwa Aug 4, 2022
6b70f5a
Fix get tasks inside index structure
bidoubiwa Aug 4, 2022
604e08d
Make description and name optional in keys
bidoubiwa Aug 8, 2022
67637c2
Fix none doc tests with new get_tasks api
bidoubiwa Aug 8, 2022
c2dcd92
Add from and limit in tasks params
bidoubiwa Aug 8, 2022
efff813
Add warning on failing test
bidoubiwa Aug 8, 2022
f0020b6
Merge branch 'update_task_api_for_v0.28.0' of https://github.com/meil…
bidoubiwa Aug 8, 2022
e0762b1
Merge
bidoubiwa Aug 8, 2022
c1796a3
Update keys design
bidoubiwa Aug 9, 2022
abc0f7b
Update task API
bidoubiwa Aug 9, 2022
eaef1ea
Remove useless comment
bidoubiwa Aug 9, 2022
bdf4f13
Merge branch 'update_task_api_for_v0.28.0' of https://github.com/meil…
bidoubiwa Aug 9, 2022
2441da1
Merge branch 'update_http_methods_for_v0.28.0' of https://github.com/…
bidoubiwa Aug 9, 2022
d506eae
Remove client as mandatory parameter for the keyUpdater
bidoubiwa Aug 10, 2022
c803fd5
Add doc and tests on doc
bidoubiwa Aug 10, 2022
cdc2a41
Fix docs tests on keys in client
bidoubiwa Aug 10, 2022
b2ba741
Fix docs tests
bidoubiwa Aug 10, 2022
24ff749
Remove dbg
bidoubiwa Aug 10, 2022
1b41330
Add with_uid filter
bidoubiwa Aug 10, 2022
f6f821d
Add new actions on key creation
bidoubiwa Aug 10, 2022
710b2d6
Remove new line at the start of docs
bidoubiwa Aug 10, 2022
54d29eb
Fix clippy errors
bidoubiwa Aug 10, 2022
2439778
Merge branch 'update_keys_for_v0.28.0' of https://github.com/meilisea…
bidoubiwa Aug 10, 2022
3989758
Rename type in Task structure
bidoubiwa Aug 10, 2022
668ba13
Removed useless newlines
bidoubiwa Aug 10, 2022
ac95329
Fix typo in comment
bidoubiwa Aug 10, 2022
66bd1a5
Add missing semi-column
bidoubiwa Aug 10, 2022
3adc25e
t checkout uMerge branch 'update_task_api_for_v0.28.0' of https://git…
bidoubiwa Aug 10, 2022
17f1ecf
Merge
bidoubiwa Aug 10, 2022
7865c1f
Merge
bidoubiwa Aug 22, 2022
027181b
Improve doc comments
bidoubiwa Aug 22, 2022
b808156
Fix Keys actions
bidoubiwa Aug 24, 2022
de4be8f
Un hide assert in execute fonction of key
bidoubiwa Aug 24, 2022
a55739f
Remove useless comment
bidoubiwa Aug 24, 2022
7571d61
Remove flacky test
bidoubiwa Aug 24, 2022
05ec52a
Use name parameter instead of hardcoded name in key tests
bidoubiwa Aug 24, 2022
6e58840
Update src/key.rs
bidoubiwa Aug 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 97 additions & 134 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
errors::*,
indexes::*,
key::{Key, KeyBuilder},
key::{Key, KeyBuilder, KeyUpdater, KeysQuery, KeysResults},
request::*,
task_info::TaskInfo,
tasks::{Task, TasksQuery, TasksResults},
Expand Down Expand Up @@ -309,6 +309,40 @@ impl Client {
}
}

/// Get the API [Key]s from Meilisearch with parameters.
/// See the [meilisearch documentation](https://docs.meilisearch.com/reference/api/keys.html#get-all-keys).
///
/// See also [Client::create_key] and [Client::get_key].
///
/// # Example
///
/// ```
/// # use meilisearch_sdk::{client::*, errors::Error, key::KeysQuery};
/// #
/// # let MEILISEARCH_HOST = option_env!("MEILISEARCH_HOST").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
/// let mut query = KeysQuery::new();
/// query.with_limit(1);
/// let keys = client.get_keys_with(&query).await.unwrap();
///
/// assert_eq!(keys.results.len(), 1);
/// # });
/// ```
pub async fn get_keys_with(&self, keys_query: &KeysQuery) -> Result<KeysResults, Error> {
let keys = request::<&KeysQuery, KeysResults>(
&format!("{}/keys", self.host),
&self.api_key,
Method::Get(keys_query),
200,
)
.await?;

Ok(keys)
}

/// Get the API [Key]s from Meilisearch.
/// See the [meilisearch documentation](https://docs.meilisearch.com/reference/api/keys.html#get-all-keys).
///
Expand All @@ -325,26 +359,20 @@ impl Client {
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
/// let keys = client.get_keys().await.unwrap();
/// assert!(keys.len() >= 2);
///
/// assert_eq!(keys.results.len(), 2);
/// # });
/// ```
pub async fn get_keys(&self) -> Result<Vec<Key>, Error> {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Keys {
#[serde(rename = "results")]
pub inner: Vec<Key>,
}

let keys = request::<(), Keys>(
pub async fn get_keys(&self) -> Result<KeysResults, Error> {
let keys = request::<(), KeysResults>(
&format!("{}/keys", self.host),
&self.api_key,
Method::Get(()),
200,
)
.await?;

Ok(keys.inner)
Ok(keys)
}

/// Get one API [Key] from Meilisearch.
Expand All @@ -362,11 +390,12 @@ impl Client {
/// #
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
/// # let key = client.get_keys().await.unwrap().into_iter().find(|k| k.description.starts_with("Default Search API Key")).unwrap();
/// let key_id = // enter your API key here, for the example we'll say we entered our search API key.
/// # key.key;
/// # let key = client.get_keys().await.unwrap().results.into_iter()
/// .find(|k| k.name.as_ref().map_or(false, |name| name.starts_with("Default Search API Key")));
/// let key_id = key.unwrap().key // enter your API key here, for the example we use the search API key.
/// let key = client.get_key(key_id).await.unwrap();
/// assert_eq!(key.description, "Default Search API Key (Use it to search from the frontend)");
///
/// assert_eq!(key.name, Some("Default Search API Key".to_string()));
/// # });
/// ```
pub async fn get_key(&self, key: impl AsRef<str>) -> Result<Key, Error> {
Expand Down Expand Up @@ -394,14 +423,14 @@ impl Client {
/// #
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
/// let key = KeyBuilder::new("delete_key");
/// let key = KeyBuilder::new();
/// let key = client.create_key(key).await.unwrap();
/// let inner_key = key.key.clone();
///
/// client.delete_key(key).await.unwrap();
///
/// let keys = client.get_keys().await.unwrap();
/// assert!(keys.iter().all(|key| key.key != inner_key));
/// assert!(keys.results.iter().all(|key| key.key != inner_key));
/// # });
/// ```
pub async fn delete_key(&self, key: impl AsRef<str>) -> Result<(), Error> {
Expand Down Expand Up @@ -429,11 +458,12 @@ impl Client {
/// #
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
/// let mut key = KeyBuilder::new("create_key");
/// key.with_index("*").with_action(Action::DocumentsAdd);
/// let key = client.create_key(key).await.unwrap();
/// let name = "create_key".to_string();
/// let mut key = KeyBuilder::new();
/// key.with_name(&name);
///
/// assert_eq!(key.description, "create_key");
/// let key = client.create_key(key).await.unwrap();
/// assert_eq!(key.name, Some(name));
/// # client.delete_key(key).await.unwrap();
/// # });
/// ```
Expand All @@ -455,25 +485,26 @@ impl Client {
/// # Example
///
/// ```
/// # use meilisearch_sdk::{client::*, errors::Error, key::KeyBuilder};
/// # use meilisearch_sdk::{client::*, errors::Error, key::KeyBuilder, key::KeyUpdater};
/// #
/// # let MEILISEARCH_HOST = option_env!("MEILISEARCH_HOST").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
/// let key = KeyBuilder::new("update_key");
/// let mut key = client.create_key(key).await.unwrap();
/// assert!(key.indexes.is_empty());
/// let new_key = KeyBuilder::new();
/// let name = "my name".to_string();
/// let mut new_key = client.create_key(new_key).await.unwrap();
/// let mut key_update = KeyUpdater::new(new_key);
/// key_update.with_name(&name);
///
/// key.indexes = vec!["*".to_string()];
/// let key = client.update_key(key).await.unwrap();
/// assert_eq!(key.indexes, vec!["*"]);
/// let key = client.update_key(key_update).await.unwrap();
/// assert_eq!(key.name, Some(name));
/// # client.delete_key(key).await.unwrap();
/// # });
/// ```
pub async fn update_key(&self, key: impl AsRef<Key>) -> Result<Key, Error> {
request::<&Key, Key>(
pub async fn update_key(&self, key: impl AsRef<KeyUpdater>) -> Result<Key, Error> {
request::<&KeyUpdater, Key>(
&format!("{}/keys/{}", self.host, key.as_ref().key),
&self.api_key,
Method::Patch(key.as_ref()),
Expand Down Expand Up @@ -814,33 +845,35 @@ mod tests {
async fn test_get_tasks_with_params(client: Client) {
let query = TasksQuery::new(&client);
let tasks = client.get_tasks_with(&query).await.unwrap();

assert!(tasks.results.len() >= 2);
}

#[meilisearch_test]
async fn test_get_keys(client: Client) {
let keys = client.get_keys().await.unwrap();
assert!(keys.len() >= 2);
assert!(keys.iter().any(
|k| k.description != "Default Search API Key (Use it to search from the frontend)"
));
assert!(keys.iter().any(
|k| k.description != "Default Admin API Key (Use it for all other operations. Caution! Do not use it on a public frontend)"
));

assert!(keys.results.len() >= 2);
}

#[meilisearch_test]
async fn test_delete_key(client: Client, description: String) {
let key = KeyBuilder::new(description);
async fn test_delete_key(client: Client, name: String) {
let mut key = KeyBuilder::new();
key.with_name(&name);
let key = client.create_key(key).await.unwrap();

client.delete_key(&key).await.unwrap();
let keys = client.get_keys().await.unwrap();
assert!(keys.iter().all(|k| k.key != key.key));
let keys = KeysQuery::new()
.with_limit(10000)
.execute(&client)
.await
.unwrap();

assert!(keys.results.iter().all(|k| k.key != key.key));
}

#[meilisearch_test]
async fn test_error_delete_key(mut client: Client, description: String) {
async fn test_error_delete_key(mut client: Client, name: String) {
// ==> accessing a key that does not exist
let error = client.delete_key("invalid_key").await.unwrap_err();
assert!(matches!(
Expand All @@ -853,7 +886,8 @@ mod tests {
));

// ==> executing the action without enough right
let key = KeyBuilder::new(description);
let mut key = KeyBuilder::new();
key.with_name(&name);
let key = client.create_key(key).await.unwrap();

let master_key = client.api_key.clone();
Expand Down Expand Up @@ -886,44 +920,33 @@ mod tests {
}

#[meilisearch_test]
async fn test_create_key(client: Client, description: String) {
async fn test_create_key(client: Client, name: String) {
let expires_at = OffsetDateTime::now_utc() + time::Duration::HOUR;
let mut key = KeyBuilder::new(description.clone());
let mut key = KeyBuilder::new();
key.with_action(Action::DocumentsAdd)
.with_name(&name)
.with_expires_at(expires_at.clone())
.with_description("a description")
.with_index("*");
let key = client.create_key(key).await.unwrap();

assert_eq!(key.actions, vec![Action::DocumentsAdd]);
assert_eq!(key.description, description);
assert_eq!(&key.name, &Some(name));
// We can't compare the two timestamp directly because of some nanoseconds imprecision with the floats
assert_eq!(
key.expires_at.unwrap().unix_timestamp(),
expires_at.unix_timestamp()
);
assert_eq!(key.indexes, vec!["*".to_string()]);

let keys = client.get_keys().await.unwrap();

let remote_key = keys.iter().find(|k| k.key == key.key).unwrap();

assert_eq!(remote_key.actions, vec![Action::DocumentsAdd]);
assert_eq!(remote_key.description, description);
// We can't compare the two timestamp directly because of some nanoseconds imprecision with the floats
assert_eq!(
remote_key.expires_at.unwrap().unix_timestamp(),
expires_at.unix_timestamp()
);
assert_eq!(remote_key.indexes, vec!["*".to_string()]);

client.delete_key(key).await.unwrap();
}

#[meilisearch_test]
async fn test_error_create_key(mut client: Client, description: String) {
async fn test_error_create_key(mut client: Client, name: String) {
// ==> Invalid index name
/* TODO: uncomment once meilisearch fix this bug: https://github.com/meilisearch/meilisearch/issues/2158
let mut key = KeyBuilder::new(&description);
let mut key = KeyBuilder::new();
key.with_index("invalid index # / \\name with spaces");
let error = client.create_key(key).await.unwrap_err();

Expand All @@ -938,14 +961,16 @@ mod tests {
*/

// ==> executing the action without enough right
let no_right_key = KeyBuilder::new(&description);
let mut no_right_key = KeyBuilder::new();
no_right_key.with_name(&format!("{name}_1"));
let no_right_key = client.create_key(no_right_key).await.unwrap();

// backup the master key for cleanup at the end of the test
let master_client = client.clone();
client.api_key = Arc::new(no_right_key.key.clone());

let key = KeyBuilder::new(&description);
let mut key = KeyBuilder::new();
key.with_name(format!("{name}_2"));
let error = client.create_key(key).await.unwrap_err();

assert!(matches!(
Expand All @@ -963,84 +988,22 @@ mod tests {

#[meilisearch_test]
async fn test_update_key(client: Client, description: String) {
let expires_at = OffsetDateTime::now_utc() + time::Duration::HOUR;
let key = KeyBuilder::new(description.clone());
let mut key = KeyBuilder::new();
key.with_name("test_update_key");
let mut key = client.create_key(key).await.unwrap();

key.actions = vec![Action::DocumentsAdd];
key.expires_at = Some(expires_at);
key.indexes = vec!["*".to_string()];

let key = client.update_key(key).await.unwrap();

assert_eq!(key.actions, vec![Action::DocumentsAdd]);
assert_eq!(key.description, description);
// We can't compare the two timestamp directly because of some nanoseconds imprecision with the floats
assert_eq!(
key.expires_at.unwrap().unix_timestamp(),
expires_at.unix_timestamp()
);
assert_eq!(key.indexes, vec!["*".to_string()]);
let name = "new name".to_string();
key.with_description(&description);
key.with_name(&name);

let keys = client.get_keys().await.unwrap();

let remote_key = keys.iter().find(|k| k.key == key.key).unwrap();
let key = key.update(&client).await.unwrap();

assert_eq!(remote_key.actions, vec![Action::DocumentsAdd]);
assert_eq!(remote_key.description, description);
// We can't compare the two timestamp directly because of some nanoseconds imprecision with the floats
assert_eq!(
remote_key.expires_at.unwrap().unix_timestamp(),
expires_at.unix_timestamp()
);
assert_eq!(remote_key.indexes, vec!["*".to_string()]);
assert_eq!(key.description, Some(description));
assert_eq!(key.name, Some(name));

client.delete_key(key).await.unwrap();
}

#[meilisearch_test]
async fn test_error_update_key(mut client: Client, description: String) {
let key = KeyBuilder::new(description.clone());
let key = client.create_key(key).await.unwrap();

// ==> Invalid index name
/* TODO: uncomment once meilisearch fix this bug: https://github.com/meilisearch/meilisearch/issues/2158
key.indexes = vec!["invalid index # / \\name with spaces".to_string()];
let error = client.update_key(key).await.unwrap_err();

assert!(matches!(
error,
Error::MeilisearchError {
error_code: ErrorCode::InvalidApiKeyIndexes,
error_type: ErrorType::InvalidRequest,
..
}
));
*/

// ==> executing the action without enough right
let no_right_key = KeyBuilder::new(&description);
let no_right_key = client.create_key(no_right_key).await.unwrap();

// backup the master key for cleanup at the end of the test
let master_client = client.clone();
client.api_key = Arc::new(no_right_key.key.clone());

let error = client.update_key(key).await.unwrap_err();

assert!(matches!(
error,
Error::Meilisearch(MeilisearchError {
error_code: ErrorCode::InvalidApiKey,
error_type: ErrorType::Auth,
..
})
));

// cleanup
master_client.delete_key(&*client.api_key).await.unwrap();
}

#[meilisearch_test]
async fn test_get_index(client: Client, index_uid: String) -> Result<(), Error> {
let task = client.create_index(&index_uid, None).await?;
Expand Down
Loading