mirror of
				https://github.com/meilisearch/meilisearch.git
				synced 2025-10-31 07:56:28 +00:00 
			
		
		
		
	feat(auth): API keys
implements: https://github.com/meilisearch/specifications/blob/develop/text/0085-api-keys.md - Add tests on API keys management route (meilisearch-http/tests/auth/api_keys.rs) - Add tests checking authorizations on each meilisearch routes (meilisearch-http/tests/auth/authorization.rs) - Implement API keys management routes (meilisearch-http/src/routes/api_key.rs) - Create module to manage API keys and authorizations (meilisearch-auth) - Reimplement GuardedData to extend authorizations (meilisearch-http/src/extractors/authentication/mod.rs) - Change X-MEILI-API-KEY by Authorization Bearer (meilisearch-http/src/extractors/authentication/mod.rs) - Change meilisearch routes to fit to the new authorization feature (meilisearch-http/src/routes/) - close #1867
This commit is contained in:
		| @@ -2,6 +2,7 @@ use std::path::Path; | ||||
|  | ||||
| use actix_web::http::StatusCode; | ||||
| use byte_unit::{Byte, ByteUnit}; | ||||
| use meilisearch_auth::AuthController; | ||||
| use meilisearch_http::setup_meilisearch; | ||||
| use meilisearch_lib::options::{IndexerOpts, MaxMemory}; | ||||
| use once_cell::sync::Lazy; | ||||
| @@ -19,7 +20,7 @@ pub struct Server { | ||||
|     _dir: Option<TempDir>, | ||||
| } | ||||
|  | ||||
| static TEST_TEMP_DIR: Lazy<TempDir> = Lazy::new(|| TempDir::new().unwrap()); | ||||
| pub static TEST_TEMP_DIR: Lazy<TempDir> = Lazy::new(|| TempDir::new().unwrap()); | ||||
|  | ||||
| impl Server { | ||||
|     pub async fn new() -> Self { | ||||
| @@ -34,9 +35,12 @@ impl Server { | ||||
|         let options = default_settings(dir.path()); | ||||
|  | ||||
|         let meilisearch = setup_meilisearch(&options).unwrap(); | ||||
|         let auth = AuthController::new(&options.db_path, &options.master_key).unwrap(); | ||||
|         let service = Service { | ||||
|             meilisearch, | ||||
|             auth, | ||||
|             options, | ||||
|             api_key: None, | ||||
|         }; | ||||
|  | ||||
|         Server { | ||||
| @@ -47,9 +51,12 @@ impl Server { | ||||
|  | ||||
|     pub async fn new_with_options(options: Opt) -> Self { | ||||
|         let meilisearch = setup_meilisearch(&options).unwrap(); | ||||
|         let auth = AuthController::new(&options.db_path, &options.master_key).unwrap(); | ||||
|         let service = Service { | ||||
|             meilisearch, | ||||
|             auth, | ||||
|             options, | ||||
|             api_key: None, | ||||
|         }; | ||||
|  | ||||
|         Server { | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| use actix_web::{http::StatusCode, test}; | ||||
| use meilisearch_auth::AuthController; | ||||
| use meilisearch_lib::MeiliSearch; | ||||
| use serde_json::Value; | ||||
|  | ||||
| @@ -6,23 +7,27 @@ use meilisearch_http::{analytics, create_app, Opt}; | ||||
|  | ||||
| pub struct Service { | ||||
|     pub meilisearch: MeiliSearch, | ||||
|     pub auth: AuthController, | ||||
|     pub options: Opt, | ||||
|     pub api_key: Option<String>, | ||||
| } | ||||
|  | ||||
| impl Service { | ||||
|     pub async fn post(&self, url: impl AsRef<str>, body: Value) -> (Value, StatusCode) { | ||||
|         let app = test::init_service(create_app!( | ||||
|             &self.meilisearch, | ||||
|             &self.auth, | ||||
|             true, | ||||
|             &self.options, | ||||
|             analytics::MockAnalytics::new(&self.options).0 | ||||
|         )) | ||||
|         .await; | ||||
|  | ||||
|         let req = test::TestRequest::post() | ||||
|             .uri(url.as_ref()) | ||||
|             .set_json(&body) | ||||
|             .to_request(); | ||||
|         let mut req = test::TestRequest::post().uri(url.as_ref()).set_json(&body); | ||||
|         if let Some(api_key) = &self.api_key { | ||||
|             req = req.insert_header(("Authorization", ["Bearer ", api_key].concat())); | ||||
|         } | ||||
|         let req = req.to_request(); | ||||
|         let res = test::call_service(&app, req).await; | ||||
|         let status_code = res.status(); | ||||
|  | ||||
| @@ -39,17 +44,21 @@ impl Service { | ||||
|     ) -> (Value, StatusCode) { | ||||
|         let app = test::init_service(create_app!( | ||||
|             &self.meilisearch, | ||||
|             &self.auth, | ||||
|             true, | ||||
|             &self.options, | ||||
|             analytics::MockAnalytics::new(&self.options).0 | ||||
|         )) | ||||
|         .await; | ||||
|  | ||||
|         let req = test::TestRequest::post() | ||||
|         let mut req = test::TestRequest::post() | ||||
|             .uri(url.as_ref()) | ||||
|             .set_payload(body.as_ref().to_string()) | ||||
|             .insert_header(("content-type", "application/json")) | ||||
|             .to_request(); | ||||
|             .insert_header(("content-type", "application/json")); | ||||
|         if let Some(api_key) = &self.api_key { | ||||
|             req = req.insert_header(("Authorization", ["Bearer ", api_key].concat())); | ||||
|         } | ||||
|         let req = req.to_request(); | ||||
|         let res = test::call_service(&app, req).await; | ||||
|         let status_code = res.status(); | ||||
|  | ||||
| @@ -61,13 +70,18 @@ impl Service { | ||||
|     pub async fn get(&self, url: impl AsRef<str>) -> (Value, StatusCode) { | ||||
|         let app = test::init_service(create_app!( | ||||
|             &self.meilisearch, | ||||
|             &self.auth, | ||||
|             true, | ||||
|             &self.options, | ||||
|             analytics::MockAnalytics::new(&self.options).0 | ||||
|         )) | ||||
|         .await; | ||||
|  | ||||
|         let req = test::TestRequest::get().uri(url.as_ref()).to_request(); | ||||
|         let mut req = test::TestRequest::get().uri(url.as_ref()); | ||||
|         if let Some(api_key) = &self.api_key { | ||||
|             req = req.insert_header(("Authorization", ["Bearer ", api_key].concat())); | ||||
|         } | ||||
|         let req = req.to_request(); | ||||
|         let res = test::call_service(&app, req).await; | ||||
|         let status_code = res.status(); | ||||
|  | ||||
| @@ -79,16 +93,41 @@ impl Service { | ||||
|     pub async fn put(&self, url: impl AsRef<str>, body: Value) -> (Value, StatusCode) { | ||||
|         let app = test::init_service(create_app!( | ||||
|             &self.meilisearch, | ||||
|             &self.auth, | ||||
|             true, | ||||
|             &self.options, | ||||
|             analytics::MockAnalytics::new(&self.options).0 | ||||
|         )) | ||||
|         .await; | ||||
|  | ||||
|         let req = test::TestRequest::put() | ||||
|             .uri(url.as_ref()) | ||||
|             .set_json(&body) | ||||
|             .to_request(); | ||||
|         let mut req = test::TestRequest::put().uri(url.as_ref()).set_json(&body); | ||||
|         if let Some(api_key) = &self.api_key { | ||||
|             req = req.insert_header(("Authorization", ["Bearer ", api_key].concat())); | ||||
|         } | ||||
|         let req = req.to_request(); | ||||
|         let res = test::call_service(&app, req).await; | ||||
|         let status_code = res.status(); | ||||
|  | ||||
|         let body = test::read_body(res).await; | ||||
|         let response = serde_json::from_slice(&body).unwrap_or_default(); | ||||
|         (response, status_code) | ||||
|     } | ||||
|  | ||||
|     pub async fn patch(&self, url: impl AsRef<str>, body: Value) -> (Value, StatusCode) { | ||||
|         let app = test::init_service(create_app!( | ||||
|             &self.meilisearch, | ||||
|             &self.auth, | ||||
|             true, | ||||
|             &self.options, | ||||
|             analytics::MockAnalytics::new(&self.options).0 | ||||
|         )) | ||||
|         .await; | ||||
|  | ||||
|         let mut req = test::TestRequest::patch().uri(url.as_ref()).set_json(&body); | ||||
|         if let Some(api_key) = &self.api_key { | ||||
|             req = req.insert_header(("Authorization", ["Bearer ", api_key].concat())); | ||||
|         } | ||||
|         let req = req.to_request(); | ||||
|         let res = test::call_service(&app, req).await; | ||||
|         let status_code = res.status(); | ||||
|  | ||||
| @@ -100,13 +139,18 @@ impl Service { | ||||
|     pub async fn delete(&self, url: impl AsRef<str>) -> (Value, StatusCode) { | ||||
|         let app = test::init_service(create_app!( | ||||
|             &self.meilisearch, | ||||
|             &self.auth, | ||||
|             true, | ||||
|             &self.options, | ||||
|             analytics::MockAnalytics::new(&self.options).0 | ||||
|         )) | ||||
|         .await; | ||||
|  | ||||
|         let req = test::TestRequest::delete().uri(url.as_ref()).to_request(); | ||||
|         let mut req = test::TestRequest::delete().uri(url.as_ref()); | ||||
|         if let Some(api_key) = &self.api_key { | ||||
|             req = req.insert_header(("Authorization", ["Bearer ", api_key].concat())); | ||||
|         } | ||||
|         let req = req.to_request(); | ||||
|         let res = test::call_service(&app, req).await; | ||||
|         let status_code = res.status(); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user