mirror of
https://github.com/OMGeeky/twba.uploader.git
synced 2026-01-05 10:40:20 +01:00
111 lines
3.8 KiB
Rust
111 lines
3.8 KiB
Rust
use crate::client::youtube::flow_delegate::CustomFlowDelegate;
|
|
use crate::prelude::*;
|
|
use anyhow::{anyhow, Context};
|
|
use google_youtube3::api::Scope;
|
|
use google_youtube3::{hyper::client::HttpConnector, hyper_rustls::HttpsConnector, oauth2};
|
|
use std::collections::HashMap;
|
|
use std::fmt::Debug;
|
|
use std::path::{Path, PathBuf};
|
|
use tokio::fs;
|
|
use tracing::instrument;
|
|
use yup_oauth2::authenticator::Authenticator;
|
|
#[instrument]
|
|
pub(super) async fn get_auth<USER: EasyString>(
|
|
application_secret_path: &String,
|
|
scopes: &Vec<Scope>,
|
|
user: Option<USER>,
|
|
) -> Result<Authenticator<HttpsConnector<HttpConnector>>> {
|
|
trace!(
|
|
"getting auth for user: {:?} with scopes: {:?} and secret_path: {:?}",
|
|
user,
|
|
scopes,
|
|
application_secret_path
|
|
);
|
|
|
|
let app_secret = oauth2::read_application_secret(application_secret_path)
|
|
.await
|
|
.context("could not read application secret from path")?;
|
|
|
|
let persistent_path =
|
|
get_and_validate_persistent_path(&crate::CONF.google.path_auth_cache, user.clone()).await?;
|
|
trace!(
|
|
"persistent path for auth for user: {:?}: {:?}",
|
|
user,
|
|
&persistent_path
|
|
);
|
|
|
|
trace!("creating authenticator");
|
|
let user = user.map(|x| x.into());
|
|
let method = oauth2::InstalledFlowReturnMethod::Interactive;
|
|
let auth = oauth2::InstalledFlowAuthenticator::builder(app_secret, method)
|
|
.flow_delegate(Box::new(CustomFlowDelegate::new(user, &crate::CONF)))
|
|
.persist_tokens_to_disk(persistent_path)
|
|
.force_account_selection(true)
|
|
.build()
|
|
.await
|
|
.context("error creating authenticator")?;
|
|
|
|
trace!("got authenticator, requesting scopes");
|
|
let access_token = auth
|
|
.token(scopes)
|
|
.await
|
|
.context("could not get access to the requested scopes")?;
|
|
trace!("got scope access: {:?}", access_token);
|
|
Ok(auth)
|
|
}
|
|
|
|
async fn get_and_validate_persistent_path<TEMPLATE: EasyString, USER: EasyString>(
|
|
persistent_path_template: TEMPLATE,
|
|
user: Option<USER>,
|
|
) -> Result<PathBuf> {
|
|
let persistent_path = get_persistent_path(persistent_path_template, user.clone())?;
|
|
let persistent_path = Path::new(&persistent_path);
|
|
info!(
|
|
"Persistent auth path for user:{:?} => {}",
|
|
user,
|
|
persistent_path.display()
|
|
);
|
|
|
|
if persistent_path.is_dir() {
|
|
warn!("persistent path is a dir: {}", persistent_path.display());
|
|
}
|
|
|
|
let persistent_path_parent_folder = persistent_path
|
|
.parent()
|
|
.context("could not get parent folder")?;
|
|
if !persistent_path_parent_folder.exists() {
|
|
debug!(
|
|
"persistent path parent folder does not exist, creating it: {}",
|
|
persistent_path_parent_folder.display()
|
|
);
|
|
fs::create_dir_all(persistent_path_parent_folder)
|
|
.await
|
|
.context("could not create dirs")?;
|
|
} else if !persistent_path_parent_folder.is_dir() {
|
|
error!(
|
|
"persistent path parent folder is not a dir: {}",
|
|
persistent_path_parent_folder.display()
|
|
);
|
|
return Err(anyhow!(
|
|
"persistent path parent folder is not a dir: {}",
|
|
persistent_path_parent_folder.display()
|
|
)
|
|
.into());
|
|
}
|
|
Ok(persistent_path.to_path_buf())
|
|
}
|
|
|
|
fn get_persistent_path<TEMPLATE: EasyString, USER: EasyString>(
|
|
persistent_path_template: TEMPLATE,
|
|
user: Option<USER>,
|
|
) -> Result<String> {
|
|
let user: String = match user {
|
|
Some(user) => user.into(),
|
|
None => "unknown".to_string(),
|
|
};
|
|
let vars: HashMap<String, String> = HashMap::from([("user".to_string(), user)]);
|
|
let persistent_path = strfmt::strfmt(&persistent_path_template.into(), &vars)
|
|
.context("could not replace user in persistent path")?;
|
|
Ok(persistent_path)
|
|
}
|