use crate::OAuthAgentType; use crate::advent::day::Day; use crate::advent::{AdventChallenge, AdventError, ChallengeCheckResponse}; use crate::atrium::safe_check_unknown_record_parse; use crate::lexicons::codes::advent; use async_trait::async_trait; use atrium_api::types::Collection; use sqlx::PgPool; pub struct DayOne { pub pool: PgPool, pub oauth_client: Option, } #[async_trait] impl AdventChallenge for DayOne { fn pool(&self) -> &PgPool { &self.pool } fn day(&self) -> Day { Day::One } fn has_part_two(&self) -> bool { true } async fn check_part_one( &self, did: String, _verification_code: Option, ) -> Result { let client = self .oauth_client .as_ref() .ok_or(AdventError::ShouldNotHappen( "No oauth client. This should not happen".to_string(), ))?; let record_res = client .api .com .atproto .repo .get_record( atrium_api::com::atproto::repo::get_record::ParametersData { cid: None, collection: advent::challenge::Day::NSID.parse().unwrap(), repo: did.parse().unwrap(), rkey: "1".parse().unwrap(), } .into(), ) .await; let record = match record_res { Ok(r) => r, Err(e) => { log::error!("Error getting record: {}", e); return Ok(ChallengeCheckResponse::Incorrect("Does not appear to be a record in your repo in the collection codes.advent.challenge.day with the record key of 1".to_string())); } }; let Some(challenge) = self.get_days_challenge(&did).await? else { log::error!("Could not find a challenge record for day: 1 for the user: {did:?}"); return Err(AdventError::ShouldNotHappen( "Could not find challenge record".to_string(), )); }; let record_data = match safe_check_unknown_record_parse::( record.value.clone(), ) { Ok(rd) => rd, Err(e) => { log::error!("Error parsing record: {e}"); return Ok(ChallengeCheckResponse::Incorrect(format!( "There is a record at the correct location, but it does not seem like it is correct. Try again:\n{e}" ))); } }; let verification_code = challenge .verification_code_one .ok_or(AdventError::ShouldNotHappen( "no verification code for day 1 challenge :/".to_string(), ))?; Ok(if record_data.part_one == verification_code { ChallengeCheckResponse::Correct } else { ChallengeCheckResponse::Incorrect(format!( "The code {} is incorrect", record_data.part_one )) }) } ///TODO this is just a straight copy and paste of part one since it's a proof of concept needs to share code better between the two async fn check_part_two( &self, did: String, _verification_code: Option, ) -> Result { match &self.oauth_client { None => Err(AdventError::ShouldNotHappen( "No oauth client. This should not happen".to_string(), )), Some(client) => { match client .api .com .atproto .repo .get_record( atrium_api::com::atproto::repo::get_record::ParametersData { cid: None, collection: advent::challenge::Day::NSID.parse().unwrap(), repo: did.parse().unwrap(), rkey: "1".parse().unwrap(), } .into(), ) .await { Ok(record) => { //TODO trouble, and make it double let challenge = self.get_days_challenge(&did).await?; match challenge { None => { log::error!( "Could not find a challenge record for day: {} for the user: {}", self.day(), did.clone() ); Err(AdventError::ShouldNotHappen( "Could not find a challenge record".to_string(), )) } Some(challenge) => { let parse_record_result = safe_check_unknown_record_parse::< advent::challenge::day::RecordData, >(record.value.clone()); match parse_record_result { Ok(record_data) => match record_data.part_two { None => { Ok(ChallengeCheckResponse::Incorrect("The record is there, it's the right kind. But aren't you forgetting something?".to_string())) } Some(part_two_code) => { match part_two_code == challenge .verification_code_two .unwrap_or("".to_string()) { true => Ok(ChallengeCheckResponse::Correct), false => { Ok(ChallengeCheckResponse::Incorrect(format!( "The code {} is incorrect", record_data.part_one ))) } } } }, Err(err) => { log::error!("Error parsing record: {}", err); Ok(ChallengeCheckResponse::Incorrect(format!( "There is a record at the correct location, but it does not seem like it is correct. Try again:\n{err}" ))) } } } } } Err(err) => { log::error!("Error getting record: {}", err); Ok(ChallengeCheckResponse::Incorrect("Does not appear to be a record in your repo in the collection codes.advent.challenge.day with the record key of 1".to_string())) } } } } } }