Files
avam/avam-client/src/oauth.rs
2024-10-17 12:49:56 +02:00

96 lines
2.7 KiB
Rust

use std::time::Duration;
use tokio::{
sync::broadcast::{Receiver, Sender},
time::sleep,
};
use crate::{
config::Config, models::*, pipe::Pipe, state_machine::Event, BASE_URL, CLIENT_ID, REDIRECT_URI,
};
pub fn open_browser(
code_verifier: CodeVerifier,
code_challenge_method: CodeChallengeMethod,
) -> Result<(), anyhow::Error> {
let code_challenge = match code_challenge_method {
CodeChallengeMethod::Plain => {
use base64::prelude::*;
BASE64_URL_SAFE_NO_PAD.encode(code_verifier.to_string())
}
CodeChallengeMethod::Sha256 => {
use base64::prelude::*;
BASE64_URL_SAFE_NO_PAD.encode(sha256::digest(code_verifier.to_string()))
}
};
let request = AuthorizeRequest::new(
CLIENT_ID,
ResponseType::Code,
None,
code_challenge.clone(),
Some(code_challenge_method.clone()),
RedirectUri::new(REDIRECT_URI),
None,
);
let qs = serde_qs::to_string(&request)?;
open::that(format!("{}/oauth2/authorize?{}", BASE_URL, qs))?;
Ok(())
}
pub async fn start_code_listener(
pipe_sender: Sender<AuthorizationResponse>,
event_receiver: Receiver<Event>,
) -> Result<(), anyhow::Error> {
let pipe = Pipe::new(event_receiver.resubscribe());
pipe.listen(pipe_sender).await?;
Ok(())
}
pub async fn start_code_to_token(
config: Config,
mut pipe_receiver: Receiver<AuthorizationResponse>,
event_sender: Sender<Event>,
mut event_receiver: Receiver<Event>,
) -> Result<(), anyhow::Error> {
loop {
tokio::select! {
_ = sleep(Duration::from_millis(100)) => {
if let Ok(Event::Quit) = event_receiver.try_recv() {
tracing::info!("Shutting down Code Transformer");
break;
}
}
Ok(response) = pipe_receiver.recv() => {
let r = AuthorizationCodeRequest::new(
GrantType::AuthorizationCode,
response.code(),
REDIRECT_URI.into(),
CLIENT_ID,
config.code_verifier().unwrap()
);
let qs = serde_qs::to_string(&r)?;
let client = reqwest::Client::new();
let response = client
.post(format!("{}/oauth2/token", BASE_URL))
.body(qs)
.send()
.await?;
let response: AuthorizationCodeResponse = response.json().await?;
event_sender.send(Event::TokenReceived { token: response.token() })?;
}
}
}
tracing::info!("Code Transformer Shutdown");
Ok(())
}