use crate::error::GorError;
use crate::host::Host;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct UserResponse {
pub login: String,
}
pub fn verify_token(host: &Host, token: &str) -> Result<String, GorError> {
let client = reqwest::blocking::Client::new();
let url = host.api_url("/user");
tracing::info!("Verifying token with GET /user");
let response = client
.get(&url)
.header("Accept", "application/vnd.github+json")
.header("Authorization", format!("Bearer {token}"))
.header("User-Agent", concat!("gor/", env!("CARGO_PKG_VERSION")))
.send()
.map_err(GorError::Http)?;
let status = response.status();
if status == reqwest::StatusCode::UNAUTHORIZED {
return Err(GorError::Auth(
"token is invalid or expired (HTTP 401)".to_string(),
));
}
if status == reqwest::StatusCode::FORBIDDEN {
return Err(GorError::Auth(
"token lacks required permissions (HTTP 403)".to_string(),
));
}
if !status.is_success() {
let body = response.text().unwrap_or_default();
return Err(GorError::Auth(format!(
"token verification failed ({status}): {body}"
)));
}
let user: UserResponse = response
.json()
.map_err(|e| GorError::Auth(format!("failed to parse user response: {e}")))?;
Ok(user.login)
}
pub fn read_token_from_stdin() -> Result<String, GorError> {
use std::io::Read;
let mut buffer = String::new();
std::io::stdin()
.read_to_string(&mut buffer)
.map_err(GorError::Io)?;
Ok(buffer.trim().to_string())
}