Skip to content

Commit

Permalink
Basic oauth flow and store in config
Browse files Browse the repository at this point in the history
  • Loading branch information
wjzijderveld committed Dec 12, 2023
1 parent cb1e6a0 commit ccd2a0a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
68 changes: 67 additions & 1 deletion crates/mollie_cli/src/auth/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use crate::config::ConfigurationService;
use crate::config::{ConfigurationService, ConnectConfig};
use chrono::{DateTime, Utc};
use clap::{Parser, Subcommand};
use log::info;
use mollie_api::auth::{AccessCode, ApiKey};
use oauth2::{basic::BasicClient, ClientId, AuthUrl, TokenUrl, ClientSecret, AuthorizationCode, reqwest::async_http_client, CsrfToken, Scope, TokenResponse};
use url::Url;

mod oauth;
mod store;

#[derive(Parser)]
Expand Down Expand Up @@ -31,6 +35,17 @@ pub enum AuthCommands {
},
/// Get Auth information
Get {},
#[clap(arg_required_else_help(true))]
Connect {
#[clap(long)]
client_id: String,

#[clap(long)]
client_secret: Option<String>,

#[clap(long)]
finish: Option<String>,
}
}

pub async fn command(
Expand Down Expand Up @@ -67,6 +82,57 @@ pub async fn command(
info!("Test API Key: {:?}", config.test_api_key());
info!("Access Token: {:?}", config.access_code());
}
Some(AuthCommands::Connect { client_id, client_secret, finish }) => {
let client =
BasicClient::new(
ClientId::new(client_id.into()),
client_secret.clone().map(ClientSecret::new),
AuthUrl::new("https://my.mollie.com/oauth2/authorize".into()).unwrap(),
Some(TokenUrl::new("https://api.mollie.com/oauth2/tokens".into()).unwrap())
);

if let Some(finish) = finish {
let url = Url::parse(&finish).expect("Invalid finish url");
let code = url.query_pairs().find(|(key, _)| key == "code").unwrap().1;

let request = client
.exchange_code(AuthorizationCode::new(code.into()));
info!("{:#?}", request);

let result = request
.request_async(async_http_client)
.await;
info!("{:#?}", result);
if let Ok(new_config) = config_service.update(&|config| {
let res = result.as_ref();
let old_connect = config.auth.connect.clone().unwrap();
let expires_at: Option<DateTime<Utc>> = match res.unwrap().expires_in() {
Some(dur) => Some(Utc::now() + dur),
None => None
};
config.auth.connect = Some(ConnectConfig{
client_id: old_connect.client_id,
client_secret: old_connect.client_secret,
access_token: Some(res.unwrap().access_token().secret().to_string()),
refresh_token: Some(res.unwrap().refresh_token().unwrap().secret().to_string()),
expires_at,
});
}) {
if let Some(connect) = &new_config.auth.connect {
info!("{:#?}", connect);
}
}

} else {
let (auth_url, _csrf_token) = client
.authorize_url(CsrfToken::new_random)
.add_extra_param("approval_prompt", "force")
.add_scope(Scope::new("organizations.read".to_string()))
.url();

info!("Browse to: {}", auth_url);
}
}
None => {}
}
Ok(())
Expand Down
2 changes: 2 additions & 0 deletions crates/mollie_cli/src/config/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use chrono::DateTime;
use log::debug;
use mollie_api::auth::{AccessCode, ApiBearerToken, ApiKey};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -76,6 +77,7 @@ pub struct ConnectConfig {
pub client_secret: String,
pub refresh_token: Option<String>,
pub access_token: Option<String>,
pub expires_at: Option<DateTime<chrono::Utc>>,
}

fn default_api_config() -> ApiConfig {
Expand Down

0 comments on commit ccd2a0a

Please sign in to comment.