googauth_lib/
lib.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2
3pub use config_file::*;
4pub use login_flow::google_login;
5pub use refresh_flow::refresh_google_login;
6
7pub use crate::errors::LibError;
8
9mod config_file;
10mod errors;
11mod login_flow;
12mod refresh_flow;
13
14/// Given a config name, that has been previously saved by [config_file::ConfigFile],
15/// fetch the access token, potentially refreshing it if needed.
16pub async fn get_access_token_from_config(
17    config_name: &str,
18    config_base_path: &ConfigBasePath,
19) -> Result<Token, LibError> {
20    let mut config = ConfigFile::read_config(config_name, config_base_path)?;
21
22    check_token(config.access_token.clone(), &mut config, config_base_path).await?;
23
24    match &config.access_token {
25        Some(access_token) => Ok(access_token.clone()),
26        None => Err(LibError::CouldNotReadConfigCorrupt(config.name)),
27    }
28}
29
30/// Given an optional [config_file::Token] and a [config_file::ConfigFile],
31/// check if it's valid and potentially refresh it if it is not.
32pub async fn check_token(
33    token: Option<Token>,
34    config: &mut ConfigFile,
35    config_base_path: &ConfigBasePath,
36) -> Result<(), LibError> {
37    let now = SystemTime::now()
38        .duration_since(UNIX_EPOCH)
39        .unwrap()
40        .as_secs();
41
42    let token_expiration = match token {
43        Some(token) => token.exp,
44        None => 0,
45    };
46
47    if token_expiration < now {
48        refresh_google_login(config, config_base_path).await?;
49    }
50
51    Ok(())
52}