Skip to content

Commit

Permalink
Add ClientBuilder to allow for root ca adding
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaspustina committed Apr 8, 2020
1 parent 6569d32 commit 738c262
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 23 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

## [Unreleased]

## [0.5.0] - 2020-04-08

### Breaking Change
* `Client` changed to allow for externally defined, reqwest based HTTP clients

### Add
* `ClientBuilder` added that supports adding an self-maintained Root CA -- cf. `examples/root_ca.rs`.

## [0.4.1] - 2020-03-11

Expand Down Expand Up @@ -131,7 +138,8 @@ Initial release supports
* delete
* download

[Unreleased]: https:/lukaspustina/ceres/compare/v0.4.1...HEAD
[Unreleased]: https:/lukaspustina/ceres/compare/v0.5.0...HEAD
[0.5.0]: https:/lukaspustina/ceres/compare/v0.4.1...0.5.0
[0.4.1]: https:/lukaspustina/ceres/compare/v0.4.0...0.4.1
[0.4.0]: https:/lukaspustina/ceres/compare/v0.3.12...0.4.0
[0.3.12]: https:/lukaspustina/ceres/compare/v0.3.10...0.3.12
Expand Down
4 changes: 2 additions & 2 deletions examples/collections.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use centerdevice::{client::collections::CollectionsQuery, CenterDevice, Client, ClientCredentials, Token};
use centerdevice::{client::collections::CollectionsQuery, CenterDevice, ClientBuilder, ClientCredentials, Token};

use std::env;

Expand All @@ -23,7 +23,7 @@ fn main() {
let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);

let client = Client::with_token("centerdevice.de", client_credentials, token);
let client = ClientBuilder::new("centerdevice.de", client_credentials).build_with_token(token);
let query = CollectionsQuery::new().include_public();

let collections = client.search_collections(query).expect("Search failed.");
Expand Down
4 changes: 2 additions & 2 deletions examples/delete.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use centerdevice::{CenterDevice, Client, ClientCredentials, Token};
use centerdevice::{CenterDevice, ClientBuilder, ClientCredentials, Token};

use std::env;

Expand Down Expand Up @@ -28,7 +28,7 @@ fn main() {

let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);
let client = Client::with_token("centerdevice.de", client_credentials, token);
let client = ClientBuilder::new("centerdevice.de", client_credentials).build_with_token(token);

client.delete_documents(&ids).expect("Download failed");

Expand Down
4 changes: 2 additions & 2 deletions examples/download.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use centerdevice::{client::download::Download, CenterDevice, Client, ClientCredentials, Token};
use centerdevice::{client::download::Download, CenterDevice, ClientBuilder, ClientCredentials, Token};

use std::{env, path::Path};

Expand Down Expand Up @@ -26,7 +26,7 @@ fn main() {

let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);
let client = Client::with_token("centerdevice.de", client_credentials, token);
let client = ClientBuilder::new("centerdevice.de", client_credentials).build_with_token(token);

let download_dir_path = "/tmp";
let path = Path::new(download_dir_path);
Expand Down
4 changes: 2 additions & 2 deletions examples/download_with_progress.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use centerdevice::{client::download::Download, CenterDevice, Client, ClientCredentials, Token, WithProgress};
use centerdevice::{client::download::Download, CenterDevice, ClientBuilder, ClientCredentials, Token, WithProgress};

use std::{
env,
Expand Down Expand Up @@ -63,7 +63,7 @@ fn main() {

let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);
let client = Client::with_token("centerdevice.de", client_credentials, token);
let client = ClientBuilder::new("centerdevice.de", client_credentials).build_with_token(token);

let download_dir_path = "/tmp";
let path = Path::new(download_dir_path);
Expand Down
5 changes: 3 additions & 2 deletions examples/get_tokens.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use centerdevice::{
client::auth::{Code, CodeProvider},
errors::Result,
Client,
ClientBuilder,
ClientCredentials,
};

Expand Down Expand Up @@ -51,7 +51,8 @@ fn main() {
let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let code_provider = MyCodeProvider {};

let client = Client::new("centerdevice.de", client_credentials)
let client = ClientBuilder::new("centerdevice.de", client_credentials)
.build()
.authorize_with_code_flow(&redirect_uri, &code_provider)
.expect("API call failed.");

Expand Down
5 changes: 2 additions & 3 deletions examples/refresh_access_token.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use centerdevice::{CenterDevice, Client, ClientCredentials, Token};
use centerdevice::{CenterDevice, ClientBuilder, ClientCredentials, Token};

use std::env;

Expand All @@ -23,8 +23,7 @@ fn main() {
let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);

let client = Client::with_token("centerdevice.de", client_credentials, token);

let client = ClientBuilder::new("centerdevice.de", client_credentials).build_with_token(token);
let token = client.refresh_access_token().expect("Search failed.");

println!("Refreshed Access Token: '{:#?}'", token);
Expand Down
44 changes: 44 additions & 0 deletions examples/root_ca.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use centerdevice::{CenterDevice, Certificate, ClientBuilder, ClientCredentials, Token};

use std::env;

fn main() {
let client_id = env::var_os("CENTERDEVICE_CLIENT_ID")
.expect("Environment variable 'CENTERDEVICE_CLIENT_ID' is not set.")
.to_string_lossy()
.to_string();
let client_secret = env::var_os("CENTERDEVICE_CLIENT_SECRET")
.expect("Environment variable 'CENTERDEVICE_CLIENT_SECRET' is not set.")
.to_string_lossy()
.to_string();
let access_token = env::var_os("CENTERDEVICE_ACCESS_TOKEN")
.expect("Environment variable 'CENTERDEVICE_ACCESS_TOKEN' is not set.")
.to_string_lossy()
.to_string();
let refresh_token = env::var_os("CENTERDEVICE_REFRESH_TOKEN")
.expect("Environment variable 'CENTERDEVICE_REFRESH_TOKEN' is not set.")
.to_string_lossy()
.to_string();
let base_url = env::var_os("CENTERDEVICE_BASE_URL")
.expect("Environment variable 'CENTERDEVICE_BASE_URL' is not set.")
.to_string_lossy()
.to_string();
let root_ca_file = env::var_os("CENTERDEVICE_ROOT_CA_FILE")
.expect("Environment variable 'CENTERDEVICE_ROOT_CA_FILE' is not set.")
.to_string_lossy()
.to_string();

let pem = std::fs::read(root_ca_file).expect("Failed to read Root CA pem file");
let certificate = Certificate::from_pem(&pem).expect("Failed to parse Root CA");

let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);

let client = ClientBuilder::new(&base_url, client_credentials)
.add_root_certificate(certificate)
.build_with_token(token);

let token = client.refresh_access_token().expect("Search failed.");

println!("Refreshed Access Token: '{:#?}'", token);
}
4 changes: 2 additions & 2 deletions examples/search.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use centerdevice::{client::search::*, CenterDevice, Client, ClientCredentials, Token};
use centerdevice::{client::search::*, CenterDevice, ClientBuilder, ClientCredentials, Token};

use std::env;

Expand All @@ -23,7 +23,7 @@ fn main() {
let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);

let client = Client::with_token("centerdevice.de", client_credentials, token);
let client = ClientBuilder::new("centerdevice.de", client_credentials).build_with_token(token);
let search = Search::new().fulltext("kartoffel");

let search_results = client.search_documents(search).expect("Search failed.");
Expand Down
4 changes: 2 additions & 2 deletions examples/upload.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use centerdevice::{client::upload::Upload, CenterDevice, Client, ClientCredentials, Token};
use centerdevice::{client::upload::Upload, CenterDevice, ClientBuilder, ClientCredentials, Token};

use mime_guess;
use std::{env, path::Path};
Expand All @@ -25,7 +25,7 @@ fn main() {

let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);
let client = Client::with_token("centerdevice.de", client_credentials, token);
let client = ClientBuilder::new("centerdevice.de", client_credentials).build_with_token(token);

let file_path = "examples/upload.rs";
let path = Path::new(file_path);
Expand Down
4 changes: 2 additions & 2 deletions examples/users.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use centerdevice::{client::users::*, CenterDevice, Client, ClientCredentials, Token};
use centerdevice::{client::users::*, CenterDevice, ClientBuilder, ClientCredentials, Token};

use std::env;

Expand All @@ -23,7 +23,7 @@ fn main() {
let client_credentials = ClientCredentials::new(&client_id, &client_secret);
let token = Token::new(access_token, refresh_token);

let client = Client::with_token("centerdevice.de", client_credentials, token);
let client = ClientBuilder::new("centerdevice.de", client_credentials).build_with_token(token);
let users_query = UsersQuery { all: true };

let users = client.search_users(users_query).expect("Search failed.");
Expand Down
55 changes: 52 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod errors;
pub mod utils;

pub use crate::client::auth::Token;
pub use reqwest::{blocking::Client as HttpClient, Certificate};

use crate::{
client::{
Expand All @@ -18,6 +19,8 @@ use crate::{
errors::Result,
};

static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);

pub trait CenterDevice {
fn refresh_access_token(&self) -> Result<Token>;
fn search_documents(&self, search: Search) -> Result<SearchResult>;
Expand All @@ -29,28 +32,74 @@ pub trait CenterDevice {
fn search_collections(&self, collections_query: CollectionsQuery) -> Result<CollectionsResult>;
}

pub struct ClientBuilder<'a> {
base_url: &'a str,
client_credentials: ClientCredentials<'a>,
root_cert: Option<Certificate>,
}

impl<'a> ClientBuilder<'a> {
pub fn new(base_url: &'a str, client_credentials: ClientCredentials<'a>) -> ClientBuilder<'a> {
ClientBuilder {
base_url,
client_credentials,
root_cert: None,
}
}

pub fn add_root_certificate(self, certificate: Certificate) -> Self {
Self {
root_cert: Some(certificate),
..self
}
}

pub fn build(self) -> UnauthorizedClient<'a> {
let http_client = Self::build_http_client(self.root_cert);
Client::new(self.base_url, self.client_credentials, http_client)
}

pub fn build_with_token(self, token: Token) -> AuthorizedClient<'a> {
let http_client = Self::build_http_client(self.root_cert);
Client::with_token(self.base_url, self.client_credentials, token, http_client)
}

fn build_http_client(root_cert: Option<Certificate>) -> HttpClient {
let mut client_builder = reqwest::blocking::Client::builder().user_agent(APP_USER_AGENT);
if let Some(cert) = root_cert {
client_builder = client_builder.add_root_certificate(cert)
};
client_builder.build().expect("Failed to build HTTP client")
}
}

pub struct Client {}

impl Client {
#[allow(clippy::new_ret_no_self)]
pub fn new<'a>(base_url: &'a str, client_credentials: ClientCredentials<'a>) -> UnauthorizedClient<'a> {
pub fn new<'a>(
base_url: &'a str,
client_credentials: ClientCredentials<'a>,
http_client: HttpClient,
) -> UnauthorizedClient<'a> {
UnauthorizedClient {
base_url,
client_credentials,
http_client: reqwest::blocking::Client::new(),
http_client,
}
}

pub fn with_token<'a>(
base_url: &'a str,
client_credentials: ClientCredentials<'a>,
token: Token,
http_client: HttpClient,
) -> AuthorizedClient<'a> {
AuthorizedClient {
base_url,
client_credentials,
token,
http_client: reqwest::blocking::Client::new(),
http_client,
}
}
}
Expand Down

0 comments on commit 738c262

Please sign in to comment.