1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
//! ArangoDB support for [bb8] based on the [arangors] crate.
//!
//! The library supports all authentication methods supported by `arangors`,
//! defined by `AuthenticationMethod`.
//!
//! [bb8]: https://crates.io/crates/bb8
//! [arangors]: https://crates.io/crates/arangors
//!
//! # Example
//!
//! Get all accessible databases using JWT authentication:
//!
//! ```
//! use bb8::Pool;
//! use bb8_arangodb::{ArangoConnectionManager, AuthenticationMethod};
//!
//! tokio_test::block_on(async {
//! let manager = ArangoConnectionManager::new(
//! "http://localhost:8529",
//! AuthenticationMethod::JWTAuth("root".to_string(), "openSesame".to_string())
//! );
//!
//! let pool = Pool::builder().max_size(5).build(manager).await.unwrap();
//!
//! let conn = pool.get().await.unwrap();
//! let dbs = conn.accessible_databases().await.unwrap();
//!
//! assert!(!dbs.is_empty());
//! });
//! ```
//!
//! Use basic authentication method:
//!
//! ```
//! use bb8::Pool;
//! use bb8_arangodb::{ArangoConnectionManager, AuthenticationMethod};
//!
//! tokio_test::block_on(async {
//! let manager = ArangoConnectionManager::new(
//! "http://localhost:8529",
//! AuthenticationMethod::BasicAuth("root".to_string(), "openSesame".to_string())
//! );
//!
//! let pool = Pool::builder().max_size(5).build(manager).await.unwrap();
//!
//! // ...
//! });
//! ```
//!
//! Using no authentication method (not recommended):
//!
//! ```no_run
//! use bb8::Pool;
//! use bb8_arangodb::{ArangoConnectionManager, AuthenticationMethod};
//!
//! tokio_test::block_on(async {
//! let manager =
//! ArangoConnectionManager::new("http://localhost:8529", AuthenticationMethod::NoAuth);
//!
//! let pool = Pool::builder().max_size(5).build(manager).await.unwrap();
//!
//! // ...
//! });
//! ```
#![deny(missing_docs, missing_debug_implementations)]
pub use arangors;
pub use bb8;
use arangors::{uclient, ClientError, Connection, GenericConnection};
use async_trait::async_trait;
/// Kind of the authentication method to use when establishing a connection.
#[derive(Debug)]
pub enum AuthenticationMethod {
/// Use basic authentication with a username and password for API calls.
BasicAuth(String, String),
/// Use JWT authentication with a token for API calls after authenticating
/// with username and password.
JWTAuth(String, String),
/// Use no authentication for API calls. This is only recommended for local
/// development.
NoAuth,
}
/// A connection manager for ArangoDB.
#[derive(Debug)]
pub struct ArangoConnectionManager {
url: String,
method: AuthenticationMethod,
}
impl ArangoConnectionManager {
/// Create a new ArangoConnectionManager..
pub fn new(url: &str, method: AuthenticationMethod) -> Self {
Self {
url: url.to_string(),
method,
}
}
}
#[async_trait]
impl bb8::ManageConnection for ArangoConnectionManager {
type Connection = GenericConnection<uclient::reqwest::ReqwestClient>;
type Error = ClientError;
async fn connect(&self) -> Result<Self::Connection, Self::Error> {
match &self.method {
AuthenticationMethod::BasicAuth(username, password) => {
Connection::establish_basic_auth(&self.url, username, password).await
}
AuthenticationMethod::JWTAuth(username, password) => {
Connection::establish_jwt(&self.url, username, password).await
}
AuthenticationMethod::NoAuth => Connection::establish_without_auth(&self.url).await,
}
}
async fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> {
match conn.accessible_databases().await {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
fn has_broken(&self, _conn: &mut Self::Connection) -> bool {
false
}
}