Passwords and refresh tokens go only to the system keychain; a refused keychain keeps them in memory until exit and says why. Gmail and Microsoft sign in by authorization code with S256 PKCE on a loopback redirect; refresh tokens are kept, and revoked grants ask to sign in again. Client IDs come from the build (env or oauth.env). ureq trace records never reach the log. Co-Authored-By: Claude <noreply@anthropic.com>
40 lines
1.2 KiB
Rust
40 lines
1.2 KiB
Rust
use std::{env, fs, io::ErrorKind, path::Path};
|
|
|
|
const KEYS: [&str; 3] = [
|
|
"ELY_GOOGLE_CLIENT_ID",
|
|
"ELY_GOOGLE_CLIENT_SECRET",
|
|
"ELY_MICROSOFT_CLIENT_ID",
|
|
];
|
|
|
|
/// Client IDs: CI secrets, else the local oauth.env.
|
|
fn main() {
|
|
let file = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../oauth.env");
|
|
println!("cargo:rerun-if-changed={}", file.display());
|
|
for key in KEYS {
|
|
println!("cargo:rerun-if-env-changed={key}");
|
|
}
|
|
let text = match fs::read_to_string(&file) {
|
|
Ok(text) => text,
|
|
Err(err) if err.kind() == ErrorKind::NotFound => return,
|
|
Err(err) => panic!("oauth.env unreadable: {err}"),
|
|
};
|
|
for (number, line) in text.lines().enumerate() {
|
|
let line = line.trim();
|
|
if line.is_empty() || line.starts_with('#') {
|
|
continue;
|
|
}
|
|
let Some((key, value)) = line.split_once('=') else {
|
|
panic!("oauth.env line {}: expected KEY=value", number + 1);
|
|
};
|
|
let key = key.trim();
|
|
assert!(
|
|
KEYS.contains(&key),
|
|
"oauth.env line {}: unknown key {key}",
|
|
number + 1
|
|
);
|
|
if env::var_os(key).is_none() {
|
|
println!("cargo:rustc-env={key}={}", value.trim());
|
|
}
|
|
}
|
|
}
|