diff --git a/src/common/wolves.rs b/src/common/wolves.rs index 766ee92..c13b163 100644 --- a/src/common/wolves.rs +++ b/src/common/wolves.rs @@ -1,3 +1,7 @@ +use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Sqlite}; +use crate::common::database::Wolves; + /** This file relates to anything that directly interacts with teh wolves API */ @@ -11,6 +15,45 @@ // pub members: Vec, // } +#[derive(Deserialize, Serialize, Debug)] +struct WolvesResultUserMin { + // committee: String, + member_id: String, + // first_name: String, + // last_name: String, + contact_email: String, + // opt_in_email: String, + // student_id: Option, + // note: Option, + // expiry: String, + // requested: String, + // approved: String, + // sitename: String, + // domain: String, +} +async fn add_users_wolves(db: &Pool, user: &WolvesResultUserMin) { + // expiry + match sqlx::query_as::<_, Wolves>( + " + INSERT INTO wolves (id_wolves, email) + VALUES ($1, $2) + ON CONFLICT(id_wolves) DO UPDATE SET email = $2 + ", + ) + .bind(&user.member_id) + .bind(&user.contact_email) + .fetch_optional(db) + .await + { + Ok(_) => {} + Err(e) => { + println!("Failure to insert into Wolves {:?}", user); + println!("{:?}", e); + } + } +} + + /** This is getting data for Clubs and Socs */ @@ -23,6 +66,7 @@ pub mod cns { use sqlx::{Pool, Sqlite}; use crate::Config; use crate::common::database::{get_server_config_bulk, DataBase, ServerMembers, ServerMembersWolves, Servers, Wolves}; + use crate::common::wolves::{add_users_wolves, WolvesResultUserMin}; #[derive(Deserialize, Serialize, Debug)] struct WolvesResultUser { @@ -41,6 +85,15 @@ pub mod cns { domain: String, } + impl From<&WolvesResultUser> for WolvesResultUserMin { + fn from(value: &WolvesResultUser) -> Self { + Self { + member_id: value.member_id.to_owned(), + contact_email: value.contact_email.to_owned(), + } + } + } + #[derive(Deserialize, Serialize, Debug)] struct WolvesResult { success: i8, @@ -83,12 +136,12 @@ pub mod cns { match existing.get(&(id as i64)) { None => { // user does not exist already, add everything - add_users_wolves(&db, &user).await; + add_users_wolves(&db, &WolvesResultUserMin::from(&user)).await; add_users_server_members(&db, server, &user).await; } Some(old) => { // always update wolves table, in case data has changed - add_users_wolves(&db, &user).await; + add_users_wolves(&db, &WolvesResultUserMin::from(&user)).await; if old.expiry != user.expiry { add_users_server_members(&db, server, &user).await; @@ -129,8 +182,10 @@ pub mod cns { return vec![]; } + let url = format!("{}/get_members", &config.wolves_url); + // get wolves data - if let Ok(mut res) = surf::post(&config.wolves_url).header("X-AM-Identity", wolves_api).await { + if let Ok(mut res) = surf::post(&url).header("X-AM-Identity", wolves_api).await { if let Ok(WolvesResult { success, result, @@ -147,27 +202,6 @@ pub mod cns { vec![] } - async fn add_users_wolves(db: &Pool, user: &WolvesResultUser) { - // expiry - match sqlx::query_as::<_, Wolves>( - " - INSERT INTO wolves (id_wolves, email) - VALUES ($1, $2) - ON CONFLICT(id_wolves) DO UPDATE SET email = $2 - ", - ) - .bind(&user.member_id) - .bind(&user.contact_email) - .fetch_optional(db) - .await - { - Ok(_) => {} - Err(e) => { - println!("Failure to insert into Wolves {:?}", user); - println!("{:?}", e); - } - } - } async fn add_users_server_members(db: &Pool, server: &GuildId, user: &WolvesResultUser) { match sqlx::query_as::<_, ServerMembers>( " @@ -198,4 +232,96 @@ pub mod committees {} /** get the data for an individual user */ -pub mod individual {} \ No newline at end of file +pub mod individual { + use serde::{Deserialize, Serialize}; + use serenity::client::Context; + use crate::common::database::DataBase; + use crate::common::wolves::{add_users_wolves, WolvesResultUserMin}; + use crate::Config; + + + #[derive(Deserialize, Serialize, Debug)] + struct WolvesResultUser { + // committee: String, + member_id: String, + // first_name: String, + // last_name: String, + contact_email: String, + // opt_in_email: String, + // student_id: Option, + // note: Option, + // expiry: String, + // requested: String, + // approved: String, + // sitename: String, + // domain: String, + } + + impl From<&WolvesResultUser> for WolvesResultUserMin { + fn from(value: &WolvesResultUser) -> Self { + Self { + member_id: value.member_id.to_owned(), + contact_email: value.contact_email.to_owned(), + } + } + } + + #[derive(Deserialize, Serialize, Debug)] + struct WolvesResult { + success: i8, + result: WolvesResultUser, + } + + + pub async fn get_user(ctx: &Context, email: &str) -> bool{ + let db_lock = { + let data_read = ctx.data.read().await; + data_read.get::().expect("Expected Database in TypeMap.").clone() + }; + let db = db_lock.read().await; + + let config_lock = { + let data_read = ctx.data.read().await; + data_read.get::().expect("Expected Config in TypeMap.").clone() + }; + let config = config_lock.read().await; + + // TODO: proper api key management + let api_key = ""; + // request data from wolves + match get_user_sub(&config, api_key, email).await { + None => { + false + } + // if exists save it and return true + Some(user) => { + // add to db + add_users_wolves(&db, &WolvesResultUserMin::from(&user)).await; + + true + } + } + } + + async fn get_user_sub(config: &Config, wolves_api: &str, email: &str) -> Option { + if config.wolves_url.is_empty() { + return None; + } + + // TODO: Change teh stored env value to teh base domain + let url = format!("{}/get_member", &config.wolves_url); + + // get wolves data + if let Ok(mut res) = surf::post(&url).header("X-AM-Identity", wolves_api).await { + if let Ok(WolvesResult { success, result, }) = res.body_json().await { + if success != 1 { + return None; + } + + return Some(result); + } + } + + None + } +} \ No newline at end of file