use std::ops::Deref;
use crate::feed_api::FeedApiError;
use crate::models::{ApiSecret, Url};
pub struct InoreaderOAuth {
pub base_uri: Url,
pub client_id: String,
pub client_secret: String,
pub redirect_uri: String,
csrf_protection: String,
pub create_secret_url: Url,
}
impl InoreaderOAuth {
pub fn new() -> Self {
InoreaderOAuth {
base_uri: Url::parse("https://www.inoreader.com/").unwrap(),
client_id: "999997669".into(),
client_secret: "y0NxO1RQOZ1TduNq3tu03m1zAwRhw_nO".into(),
redirect_uri: "http://localhost".into(),
csrf_protection: "123456".into(),
create_secret_url: Url::parse(
"https://www.inoreader.com/?show_dialog=preferences_dialog&params={set_category:%27preferences_developer%27,ajax:true}",
)
.unwrap(),
}
}
pub fn login_url(&self, custom_api_secret: Option<&ApiSecret>) -> String {
let client_id = custom_api_secret
.map(|secret| secret.client_id.deref())
.unwrap_or_else(|| self.client_id.deref());
format!(
"https://www.inoreader.com/oauth2/auth?client_id={}&redirect_uri={}&response_type=code&scope=read+write&state={}",
client_id, self.redirect_uri, self.csrf_protection
)
}
pub fn redirect_uri(&self) -> String {
self.redirect_uri.clone()
}
pub fn parse_redirected_url(&self, url: &Url) -> Result<String, FeedApiError> {
if let Some(code) = url.query_pairs().find(|x| x.0 == "code")
&& let Some(state) = url.query_pairs().find(|x| x.0 == "state")
&& state.1 == self.csrf_protection
{
return Ok(code.1.to_string());
}
tracing::error!(%url, "Failed to parse redirected url");
Err(FeedApiError::Login)
}
}