Skip to content
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

Add implementation of AppAuthClient for default (sync & async) clients. #162

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ The authentication type is designated by implementing a marker trait in
addition to the base `HttpClient` trait: one of `NoauthClient`,
`UserAuthClient`, `TeamAuthClient`, or `AppAuthClient`.

The default client has implementations of all of these (except for
`AppAuthClient` currently). They all share a common implementation and differ
only in which HTTP headers they add to the request.
The default client has implementations of all of these. They all share a common
implementation and differ only in which HTTP headers they add to the request.

[authentication types]: https://www.dropbox.com/developers/reference/auth-types

Expand Down
4 changes: 4 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v0.19.0-beta3
xxxx-yy-zz
* added implementations of AppAuthClient to default HTTP clients

# v0.19.0-beta2
2024-11-05
* renamed sync_routes_default feature to sync_routes_in_root
Expand Down
2 changes: 1 addition & 1 deletion src/async_client_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::future::{Future, ready};
use std::sync::Arc;
use bytes::Bytes;
use futures::AsyncRead;
use crate::client_trait_common::{HttpRequest, TeamSelect};
pub use crate::client_trait_common::{HttpRequest, TeamSelect};
use crate::Error;

/// The base HTTP asynchronous client trait.
Expand Down
2 changes: 1 addition & 1 deletion src/client_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use std::io::Read;
use std::sync::Arc;
use crate::client_trait_common::{HttpRequest, TeamSelect};
pub use crate::client_trait_common::{HttpRequest, TeamSelect};
use crate::Error;

/// The base HTTP synchronous client trait.
Expand Down
42 changes: 40 additions & 2 deletions src/default_async_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use std::str::FromStr;
use std::sync::Arc;
use bytes::Bytes;
use futures::{FutureExt, TryFutureExt, TryStreamExt};
use crate::async_client_trait::{HttpClient, HttpRequestResultRaw, NoauthClient, TeamAuthClient, UserAuthClient};
use crate::client_trait_common::{HttpRequest, TeamSelect};
use crate::async_client_trait::{AppAuthClient, HttpClient, HttpRequest, HttpRequestResultRaw,
NoauthClient, TeamAuthClient, TeamSelect, UserAuthClient};
use crate::default_client_common::impl_set_path_root;
use crate::Error;
use crate::oauth2::{Authorization, TokenCache};
Expand Down Expand Up @@ -156,6 +156,44 @@ impl HttpClient for TeamAuthDefaultClient {

impl TeamAuthClient for TeamAuthDefaultClient {}

/// Default HTTP client using App authorization.
#[derive(Debug)]
pub struct AppAuthDefaultClient {
inner: ReqwestClient,
path_root: Option<String>,
auth: String,
}

impl AppAuthDefaultClient {
/// Create a new App auth client using the given app key and secret, which can be found in the Dropbox app console.
pub fn new(app_key: &str, app_secret: &str) -> Self {
use base64::prelude::*;
let encoded = BASE64_STANDARD.encode(format!("{app_key}:{app_secret}"));
Self {
inner: ReqwestClient::default(),
path_root: None,
auth: format!("Basic {encoded}"),
}
}

impl_set_path_root!(self);
}

impl HttpClient for AppAuthDefaultClient {
type Request = ReqwestRequest;

fn execute(&self, request: Self::Request, body: Bytes) -> impl Future<Output=Result<HttpRequestResultRaw, Error>> + Send {
self.inner.execute(request, body)
}

fn new_request(&self, url: &str) -> Self::Request {
self.inner.new_request(url)
.set_header("Authorization", &self.auth)
}
}

impl AppAuthClient for AppAuthDefaultClient {}

/// Default HTTP client for unauthenticated API calls.
#[derive(Debug, Default)]
pub struct NoauthDefaultClient {
Expand Down
42 changes: 40 additions & 2 deletions src/default_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use std::fmt::Write;
use std::str::FromStr;
use std::sync::Arc;
use futures::FutureExt;
use crate::client_trait::{HttpClient, HttpRequestResultRaw, NoauthClient, TeamAuthClient, UserAuthClient};
use crate::client_trait_common::{HttpRequest, TeamSelect};
use crate::client_trait::{AppAuthClient, HttpClient, HttpRequest, HttpRequestResultRaw,
NoauthClient, TeamAuthClient, TeamSelect, UserAuthClient};
use crate::default_client_common::impl_set_path_root;

macro_rules! impl_update_token {
Expand Down Expand Up @@ -145,6 +145,44 @@ impl HttpClient for TeamAuthDefaultClient {

impl TeamAuthClient for TeamAuthDefaultClient {}

/// Default HTTP client using App authorization.
#[derive(Debug)]
pub struct AppAuthDefaultClient {
inner: UreqClient,
path_root: Option<String>,
auth: String,
}

impl AppAuthDefaultClient {
/// Create a new App auth client using the given app key and secret, which can be found in the Dropbox app console.
pub fn new(app_key: &str, app_secret: &str) -> Self {
use base64::prelude::*;
let encoded = BASE64_STANDARD.encode(format!("{app_key}:{app_secret}"));
Self {
inner: UreqClient::default(),
path_root: None,
auth: format!("Basic {encoded}"),
}
}

impl_set_path_root!(self);
}

impl HttpClient for AppAuthDefaultClient {
type Request = UreqRequest;

fn execute(&self, request: Self::Request, body: &[u8]) -> Result<HttpRequestResultRaw, Error> {
self.inner.execute(request, body)
}

fn new_request(&self, url: &str) -> Self::Request {
self.inner.new_request(url)
.set_header("Authorization", &self.auth)
}
}

impl AppAuthClient for AppAuthDefaultClient {}

/// Default HTTP client for unauthenticated API calls.
#[derive(Debug, Default)]
pub struct NoauthDefaultClient {
Expand Down
13 changes: 6 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,29 @@ if_feature! { "default_client",
if_feature! { "default_async_client", pub mod default_async_client; }

#[cfg(any(feature = "default_client", feature = "default_async_client"))]
pub(crate) mod default_client_common;
mod default_client_common;

pub mod client_trait_common;
mod client_trait_common;

pub mod client_trait;

pub mod async_client_trait;

pub(crate) mod client_helpers;
mod client_helpers;

pub mod oauth2;

mod generated;

// You need to run the Stone generator to create this module.
mod generated;
pub use generated::*;

#[cfg(feature = "async_routes")]
#[cfg(not(feature = "sync_routes_in_root"))]
pub use generated::async_routes::*;
pub use async_routes::*;

#[cfg(feature = "sync_routes")]
#[cfg(feature = "sync_routes_in_root")]
pub use generated::sync_routes::*;
pub use sync_routes::*;

mod error;
pub use error::{BoxedError, Error, NoError};
18 changes: 0 additions & 18 deletions tests/async_client_test.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::sync::Arc;
use bytes::Bytes;
use futures::io::Cursor;
use dropbox_sdk::async_routes::check;
use dropbox_sdk::async_client_trait::*;
use dropbox_sdk::client_trait_common::{HttpRequest, TeamSelect};
use dropbox_sdk::Error;

struct TestAsyncClient;
Expand Down Expand Up @@ -36,22 +34,6 @@ impl HttpClient for TestAsyncClient {
fn new_request(&self, url: &str) -> Self::Request {
TestRequest{ url: url.to_owned() }
}

async fn update_token(&self, _old_token: Arc<String>) -> Result<bool, Error> {
Ok(true)
}

fn token(&self) -> Option<Arc<String>> {
Some(Arc::new(String::new()))
}

fn path_root(&self) -> Option<&str> {
None
}

fn team_select(&self) -> Option<&TeamSelect> {
None
}
}

impl UserAuthClient for TestAsyncClient {}
Expand Down
1 change: 0 additions & 1 deletion tests/noop_client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::fmt::{Debug, Display, Formatter};
use dropbox_sdk::client_trait::*;
use dropbox_sdk::client_trait_common::HttpRequest;

macro_rules! noop_client {
($name:ident) => {
Expand Down
18 changes: 0 additions & 18 deletions tests/sync_client_test.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use std::io::Cursor;
use std::sync::Arc;
use dropbox_sdk::sync_routes::check;
use dropbox_sdk::client_trait::*;
use dropbox_sdk::client_trait_common::{HttpRequest, TeamSelect};
use dropbox_sdk::Error;

struct TestSyncClient;
Expand Down Expand Up @@ -31,22 +29,6 @@ impl HttpClient for TestSyncClient {
fn new_request(&self, url: &str) -> Self::Request {
TestRequest{ url: url.to_owned() }
}

fn update_token(&self, _old_token: Arc<String>) -> Result<bool, Error> {
Ok(true)
}

fn token(&self) -> Option<Arc<String>> {
Some(Arc::new(String::new()))
}

fn path_root(&self) -> Option<&str> {
None
}

fn team_select(&self) -> Option<&TeamSelect> {
None
}
}

impl UserAuthClient for TestSyncClient {}
Expand Down