2023-12-13 14:57:12 +00:00
|
|
|
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
|
2023-10-16 13:22:54 +00:00
|
|
|
use reqwest::Client as HTTPClient;
|
2023-10-19 14:43:00 +00:00
|
|
|
use serde_json::json;
|
2023-10-03 13:29:31 +00:00
|
|
|
use std::collections::HashMap;
|
2023-10-03 08:30:59 +00:00
|
|
|
use std::env;
|
2023-10-16 13:22:54 +00:00
|
|
|
use std::error::Error;
|
2023-10-03 08:30:59 +00:00
|
|
|
|
2023-10-19 14:43:00 +00:00
|
|
|
use crate::SSEMessageData;
|
|
|
|
|
2023-12-13 15:55:26 +00:00
|
|
|
|
|
|
|
async fn get_author_id(user: &str) -> Result<i32, Box<dyn Error>> {
|
|
|
|
let api_base = env::var("API_BASE")?;
|
|
|
|
let query_name = "get_author";
|
|
|
|
let operation = "GetAuthor";
|
|
|
|
let mut headers = HeaderMap::new();
|
|
|
|
// headers.insert(AUTHORIZATION, HeaderValue::from_str(token)?);
|
|
|
|
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
|
|
|
|
|
|
|
|
let mut variables = HashMap::<String, String>::new();
|
|
|
|
variables.insert("user".to_string(), user.to_string());
|
|
|
|
|
|
|
|
let gql = json!({
|
|
|
|
"query": format!("query {} {{ {}(slug: String, user: String, author_id: Int){{ id }} }}", operation, query_name),
|
|
|
|
"operationName": operation,
|
|
|
|
"variables": variables
|
|
|
|
});
|
|
|
|
|
|
|
|
let client = HTTPClient::new();
|
|
|
|
let response = client
|
|
|
|
.post(&api_base)
|
|
|
|
.headers(headers)
|
|
|
|
.json(&gql)
|
|
|
|
.send()
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
if response.status().is_success() {
|
|
|
|
let r: HashMap<String, serde_json::Value> = response.json().await?;
|
|
|
|
let author_id = r
|
|
|
|
.get("data")
|
|
|
|
.and_then(|data| data.get(query_name))
|
|
|
|
.and_then(|claims| claims.get("id"))
|
|
|
|
.and_then(|id| id.as_i64());
|
|
|
|
|
|
|
|
match author_id {
|
|
|
|
Some(id) => {
|
|
|
|
println!("Author ID retrieved: {}", id);
|
|
|
|
Ok(id as i32)
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
Err(Box::new(std::io::Error::new(
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
"No author ID found in the response",
|
|
|
|
)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Err(Box::new(std::io::Error::new(
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
format!("Request failed with status: {}", response.status()),
|
|
|
|
)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-12-13 17:07:16 +00:00
|
|
|
pub async fn get_id_by_token(token: &str) -> Result<i32, Box<dyn Error>> {
|
2023-10-06 10:50:20 +00:00
|
|
|
let auth_api_base = env::var("AUTH_URL")?;
|
2023-12-13 15:35:44 +00:00
|
|
|
let query_name = "validate_jwt_token";
|
|
|
|
let operation = "ValidateToken";
|
2023-10-12 21:46:55 +00:00
|
|
|
let mut headers = HeaderMap::new();
|
2023-12-13 15:35:44 +00:00
|
|
|
// headers.insert(AUTHORIZATION, HeaderValue::from_str(token)?);
|
2023-10-12 21:46:55 +00:00
|
|
|
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
|
2023-10-11 17:08:25 +00:00
|
|
|
|
2023-12-13 15:35:44 +00:00
|
|
|
let mut variables = HashMap::<String, String>::new();
|
|
|
|
variables.insert("token".to_string(), token.to_string());
|
|
|
|
variables.insert("token_type".to_string(), "access_token".to_string());
|
|
|
|
|
2023-10-12 21:46:55 +00:00
|
|
|
let gql = json!({
|
2023-12-13 17:41:50 +00:00
|
|
|
"query": format!("query {}($params: ValidateJWTTokenInput!) {{ {}(params: $params) {{ is_valid claims }} }}", operation, query_name),
|
2023-12-13 15:35:44 +00:00
|
|
|
"operationName": operation,
|
|
|
|
"variables": variables
|
2023-10-12 21:46:55 +00:00
|
|
|
});
|
2023-12-13 17:07:16 +00:00
|
|
|
println!("GraphQL Query: {}", gql);
|
2023-10-16 13:22:54 +00:00
|
|
|
let client = HTTPClient::new();
|
|
|
|
let response = client
|
|
|
|
.post(&auth_api_base)
|
2023-10-12 21:46:55 +00:00
|
|
|
.headers(headers)
|
|
|
|
.json(&gql)
|
2023-10-03 08:30:59 +00:00
|
|
|
.send()
|
2023-12-13 15:35:44 +00:00
|
|
|
.await?;
|
2023-10-12 21:46:55 +00:00
|
|
|
|
|
|
|
if response.status().is_success() {
|
|
|
|
let r: HashMap<String, serde_json::Value> = response.json().await?;
|
2023-10-16 13:22:54 +00:00
|
|
|
let user_id = r
|
|
|
|
.get("data")
|
2023-12-13 15:35:44 +00:00
|
|
|
.and_then(|data| data.get(query_name))
|
2023-12-13 15:13:19 +00:00
|
|
|
.and_then(|query| query.get("claims"))
|
2023-12-13 14:57:12 +00:00
|
|
|
.and_then(|claims| claims.get("sub"))
|
2023-12-13 15:55:26 +00:00
|
|
|
.and_then(|id| id.as_str());
|
|
|
|
|
2023-10-12 21:46:55 +00:00
|
|
|
match user_id {
|
|
|
|
Some(id) => {
|
|
|
|
println!("User ID retrieved: {}", id);
|
2023-12-13 15:55:26 +00:00
|
|
|
let author_id = get_author_id(id).await?;
|
|
|
|
Ok(author_id as i32)
|
2023-10-16 13:22:54 +00:00
|
|
|
}
|
2023-10-12 21:46:55 +00:00
|
|
|
None => {
|
|
|
|
println!("No user ID found in the response");
|
2023-10-16 13:22:54 +00:00
|
|
|
Err(Box::new(std::io::Error::new(
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
"No user ID found in the response",
|
|
|
|
)))
|
2023-10-12 21:46:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2023-10-16 13:22:54 +00:00
|
|
|
Err(Box::new(std::io::Error::new(
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
format!("Request failed with status: {}", response.status()),
|
|
|
|
)))
|
2023-10-12 21:46:55 +00:00
|
|
|
}
|
2023-10-03 08:30:59 +00:00
|
|
|
}
|
|
|
|
|
2023-10-03 13:29:31 +00:00
|
|
|
async fn get_shout_followers(shout_id: &str) -> Result<Vec<i32>, Box<dyn Error>> {
|
|
|
|
let api_base = env::var("API_BASE")?;
|
2023-11-28 09:14:18 +00:00
|
|
|
let query = r#"query GetShoutFollowers($slug: String, shout_id: Int) {
|
|
|
|
get_shout_followers(slug: $slug, shout_id: $shout_id) { id }
|
2023-10-12 21:46:55 +00:00
|
|
|
}
|
|
|
|
"#;
|
|
|
|
let shout_id = shout_id.parse::<i32>()?;
|
|
|
|
let variables = json!({
|
|
|
|
"shout": shout_id
|
|
|
|
});
|
|
|
|
let body = json!({
|
|
|
|
"query": query,
|
2023-11-28 09:14:18 +00:00
|
|
|
"operationName": "GetShoutFollowers",
|
2023-10-12 21:46:55 +00:00
|
|
|
"variables": variables
|
|
|
|
});
|
|
|
|
|
2023-10-03 13:29:31 +00:00
|
|
|
let client = reqwest::Client::new();
|
2023-10-16 13:22:54 +00:00
|
|
|
let response = client.post(&api_base).json(&body).send().await?;
|
2023-10-03 08:30:59 +00:00
|
|
|
|
2023-10-12 21:46:55 +00:00
|
|
|
if response.status().is_success() {
|
|
|
|
let response_body: serde_json::Value = response.json().await?;
|
2023-11-28 09:14:18 +00:00
|
|
|
let ids: Vec<i32> = response_body["data"]["get_shout_followers"]
|
2023-10-12 21:46:55 +00:00
|
|
|
.as_array()
|
|
|
|
.ok_or("Failed to parse follower array")?
|
|
|
|
.iter()
|
2023-11-28 09:14:18 +00:00
|
|
|
.filter_map(|f| f["id"].as_i64().map(|id| id as i32))
|
2023-10-12 21:46:55 +00:00
|
|
|
.collect();
|
2023-10-03 13:29:31 +00:00
|
|
|
|
2023-10-12 21:46:55 +00:00
|
|
|
Ok(ids)
|
|
|
|
} else {
|
|
|
|
println!("Request failed with status: {}", response.status());
|
2023-10-16 13:22:54 +00:00
|
|
|
Err(Box::new(std::io::Error::new(
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
format!("Request failed with status: {}", response.status()),
|
|
|
|
)))
|
2023-10-12 21:46:55 +00:00
|
|
|
}
|
2023-10-03 13:29:31 +00:00
|
|
|
}
|
|
|
|
|
2023-10-16 13:22:54 +00:00
|
|
|
pub async fn is_fitting(
|
|
|
|
listener_id: i32,
|
2023-10-19 14:43:00 +00:00
|
|
|
message_data: SSEMessageData,
|
2023-10-16 13:22:54 +00:00
|
|
|
) -> Result<bool, &'static str> {
|
2023-10-19 14:43:00 +00:00
|
|
|
if message_data.entity == "reaction" {
|
|
|
|
// payload is Reaction
|
|
|
|
let shout_id = message_data.payload.get("shout").unwrap().as_str().unwrap();
|
|
|
|
let recipients = get_shout_followers(shout_id).await.unwrap();
|
2023-10-03 13:29:31 +00:00
|
|
|
|
2023-10-19 14:43:00 +00:00
|
|
|
Ok(recipients.contains(&listener_id))
|
|
|
|
} else if message_data.entity == "shout" {
|
|
|
|
// payload is Shout
|
2023-11-29 04:13:14 +00:00
|
|
|
|
2023-10-19 14:43:00 +00:00
|
|
|
// TODO: check all community subscribers if no then
|
|
|
|
// TODO: check all topics subscribers if no then
|
|
|
|
// TODO: check all authors subscribers
|
2023-12-13 14:57:12 +00:00
|
|
|
|
2023-10-19 14:43:00 +00:00
|
|
|
Ok(true)
|
|
|
|
} else if message_data.entity == "chat" {
|
2023-11-16 14:52:06 +00:00
|
|
|
// payload is Chat
|
|
|
|
Ok(true)
|
|
|
|
} else if message_data.entity == "message" {
|
|
|
|
// payload is Message
|
2023-10-19 14:43:00 +00:00
|
|
|
Ok(true)
|
|
|
|
} else if message_data.entity == "follower" {
|
|
|
|
// payload is Author
|
|
|
|
Ok(true)
|
|
|
|
}else {
|
|
|
|
eprintln!("[data] unknown entity");
|
|
|
|
eprintln!("{:?}", message_data);
|
|
|
|
Ok(false)
|
2023-10-03 13:29:31 +00:00
|
|
|
}
|
2023-10-16 13:22:54 +00:00
|
|
|
}
|