Skip to content

Commit

Permalink
refactor(service/dropbox): Add DropboxConfig (#3961)
Browse files Browse the repository at this point in the history
* refactor(service/dropbox): Add DropboxConfig

Part of #3240

Signed-off-by: HowiieYu <[email protected]>

* chore(dropbox): apply fmt and clippy

Signed-off-by: HowiieYu <[email protected]>

* chore: apply fmt

Signed-off-by: HowiieYu <[email protected]>

* feat(dropbox): make DropboxConfig public

Signed-off-by: HowiieYu <[email protected]>

* doc(dropbox): add doc for DropboxConfig

Signed-off-by: HowiieYu <[email protected]>

---------

Signed-off-by: HowiieYu <[email protected]>
  • Loading branch information
howiieyu authored Jan 10, 2024
1 parent 039383b commit 56accd2
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 24 deletions.
71 changes: 47 additions & 24 deletions core/src/services/dropbox/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// specific language governing permissions and limitations
// under the License.

use serde::Deserialize;
use std::collections::HashMap;
use std::fmt::Debug;
use std::fmt::Formatter;
Expand All @@ -30,24 +31,45 @@ use super::core::DropboxSigner;
use crate::raw::*;
use crate::*;

/// Config for [Dropbox](https://www.dropbox.com/) backend support.
#[derive(Default, Deserialize, Clone)]
#[serde(default)]
#[non_exhaustive]
pub struct DropboxConfig {
/// root path for dropbox.
pub root: Option<String>,
/// access token for dropbox.
pub access_token: Option<String>,
/// refresh_token for dropbox.
pub refresh_token: Option<String>,
/// client_id for dropbox.
pub client_id: Option<String>,
/// client_secret for dropbox.
pub client_secret: Option<String>,
}

impl Debug for DropboxConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DropBoxConfig")
.field("root", &self.root)
.finish_non_exhaustive()
}
}

/// [Dropbox](https://www.dropbox.com/) backend support.
#[doc = include_str!("docs.md")]
#[derive(Default)]
pub struct DropboxBuilder {
root: Option<String>,

access_token: Option<String>,

refresh_token: Option<String>,
client_id: Option<String>,
client_secret: Option<String>,
config: DropboxConfig,

http_client: Option<HttpClient>,
}

impl Debug for DropboxBuilder {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Builder").field("root", &self.root).finish()
f.debug_struct("Builder")
.field("root", &self.config.root)
.finish()
}
}

Expand All @@ -56,7 +78,7 @@ impl DropboxBuilder {
///
/// Default to `/` if not set.
pub fn root(&mut self, root: &str) -> &mut Self {
self.root = Some(root.to_string());
self.config.root = Some(root.to_string());
self
}

Expand All @@ -67,7 +89,7 @@ impl DropboxBuilder {
/// NOTE: this token will be expired in 4 hours.
/// If you are trying to use the Dropbox service in a long time, please set a refresh_token instead.
pub fn access_token(&mut self, access_token: &str) -> &mut Self {
self.access_token = Some(access_token.to_string());
self.config.access_token = Some(access_token.to_string());
self
}

Expand All @@ -77,23 +99,23 @@ impl DropboxBuilder {
///
/// OpenDAL will use this refresh token to get a new access token when the old one is expired.
pub fn refresh_token(&mut self, refresh_token: &str) -> &mut Self {
self.refresh_token = Some(refresh_token.to_string());
self.config.refresh_token = Some(refresh_token.to_string());
self
}

/// Set the client id for Dropbox.
///
/// This is required for OAuth 2.0 Flow to refresh the access token.
pub fn client_id(&mut self, client_id: &str) -> &mut Self {
self.client_id = Some(client_id.to_string());
self.config.client_id = Some(client_id.to_string());
self
}

/// Set the client secret for Dropbox.
///
/// This is required for OAuth 2.0 Flow with refresh the access token.
pub fn client_secret(&mut self, client_secret: &str) -> &mut Self {
self.client_secret = Some(client_secret.to_string());
self.config.client_secret = Some(client_secret.to_string());
self
}

Expand All @@ -114,17 +136,15 @@ impl Builder for DropboxBuilder {
type Accessor = DropboxBackend;

fn from_map(map: HashMap<String, String>) -> Self {
let mut builder = Self::default();
map.get("root").map(|v| builder.root(v));
map.get("access_token").map(|v| builder.access_token(v));
map.get("refresh_token").map(|v| builder.refresh_token(v));
map.get("client_id").map(|v| builder.client_id(v));
map.get("client_secret").map(|v| builder.client_secret(v));
builder
Self {
config: DropboxConfig::deserialize(ConfigDeserializer::new(map))
.expect("config deserialize must succeed"),
..Default::default()
}
}

fn build(&mut self) -> Result<Self::Accessor> {
let root = normalize_root(&self.root.take().unwrap_or_default());
let root = normalize_root(&self.config.root.take().unwrap_or_default());
let client = if let Some(client) = self.http_client.take() {
client
} else {
Expand All @@ -134,22 +154,25 @@ impl Builder for DropboxBuilder {
})?
};

let signer = match (self.access_token.take(), self.refresh_token.take()) {
let signer = match (
self.config.access_token.take(),
self.config.refresh_token.take(),
) {
(Some(access_token), None) => DropboxSigner {
access_token,
// We will never expire user specified token.
expires_in: DateTime::<Utc>::MAX_UTC,
..Default::default()
},
(None, Some(refresh_token)) => {
let client_id = self.client_id.take().ok_or_else(|| {
let client_id = self.config.client_id.take().ok_or_else(|| {
Error::new(
ErrorKind::ConfigInvalid,
"client_id must be set when refresh_token is set",
)
.with_context("service", Scheme::Dropbox)
})?;
let client_secret = self.client_secret.take().ok_or_else(|| {
let client_secret = self.config.client_secret.take().ok_or_else(|| {
Error::new(
ErrorKind::ConfigInvalid,
"client_secret must be set when refresh_token is set",
Expand Down
1 change: 1 addition & 0 deletions core/src/services/dropbox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ mod error;
mod writer;

pub use builder::DropboxBuilder as Dropbox;
pub use builder::DropboxConfig;
3 changes: 3 additions & 0 deletions core/src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ pub use gdrive::Gdrive;
mod dropbox;
#[cfg(feature = "services-dropbox")]
pub use dropbox::Dropbox;
#[cfg(feature = "services-dropbox")]
pub use dropbox::DropboxConfig;

#[cfg(feature = "services-webhdfs")]
pub use webhdfs::Webhdfs;

Expand Down

0 comments on commit 56accd2

Please sign in to comment.