this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add new build additional hook

+91 -104
+50 -87
shared/src/advent/challenges/day_two.rs
··· 1 1 use crate::advent::day::Day; 2 - use crate::advent::{ 3 - AdventChallenge, AdventError, AdventPart, ChallengeCheckResponse, get_random_token, 4 - }; 2 + use crate::advent::{AdventChallenge, AdventError, AdventPart, ChallengeCheckResponse}; 5 3 use crate::atrium::safe_check_unknown_record_parse; 6 4 use crate::lexicons::codes::advent; 7 5 use crate::lexicons::record::KnownRecord; ··· 31 29 true 32 30 } 33 31 34 - /// We are overriding the start challenge and using extra code 35 - async fn start_challenge(&self, did: String, part: AdventPart) -> Result<String, AdventError> { 36 - let code = get_random_token(); 37 - 38 - // For part one, create a record via the challenge agent and store the at_uri 39 - let additional_context: Option<serde_json::Value> = match part { 32 + /// Create a record via the challenge agent and return the at_uri as additional context 33 + async fn build_additional_context( 34 + &self, 35 + did: &str, 36 + part: &AdventPart, 37 + code: &str, 38 + ) -> Result<Option<serde_json::Value>, AdventError> { 39 + match part { 40 40 AdventPart::One => { 41 - match &self.challenge_agent { 42 - Some(agent) => { 43 - let agent_did = agent.did().await.ok_or_else(|| { 44 - AdventError::ShouldNotHappen( 45 - "Challenge agent has no DID".to_string(), 46 - ) 47 - })?; 41 + let Some(agent) = &self.challenge_agent else { 42 + log::warn!( 43 + "No challenge agent configured, skipping record creation for day two" 44 + ); 45 + return Ok(None); 46 + }; 48 47 49 - let record_data = advent::challenge::day::RecordData { 50 - part_one: code.clone(), 51 - part_two: None, 52 - created_at: None, 53 - }; 54 - let known_record: KnownRecord = record_data.into(); 55 - let record_value: atrium_api::types::Unknown = known_record.into(); 48 + let agent_did = agent.did().await.ok_or_else(|| { 49 + AdventError::ShouldNotHappen("Challenge agent has no DID".to_string()) 50 + })?; 56 51 57 - // Use a unique rkey per user based on the did to avoid collisions 58 - let rkey = did.replace(":", "_").replace(".", "_"); 52 + let record_data = advent::challenge::day::RecordData { 53 + part_one: code.to_string(), 54 + part_two: None, 55 + created_at: None, 56 + }; 57 + let known_record: KnownRecord = record_data.into(); 58 + let record_value: atrium_api::types::Unknown = known_record.into(); 59 59 60 - let put_result = agent 61 - .api 62 - .com 63 - .atproto 64 - .repo 65 - .put_record( 66 - atrium_api::com::atproto::repo::put_record::InputData { 67 - collection: advent::challenge::Day::NSID.parse().unwrap(), 68 - repo: agent_did.as_ref().parse().unwrap(), 69 - rkey: rkey.parse().unwrap(), 70 - record: record_value, 71 - swap_commit: None, 72 - swap_record: None, 73 - validate: Some(false), 74 - } 75 - .into(), 76 - ) 77 - .await; 60 + // Use a unique rkey per user based on the did to avoid collisions 61 + // let rkey = did.replace(":", "_").replace(".", "_"); 78 62 79 - match put_result { 80 - Ok(output) => Some(json!({"at_uri": output.uri})), 81 - Err(e) => { 82 - log::error!("Failed to create challenge record via agent: {e}"); 83 - None 84 - } 63 + let create_record_result = agent 64 + .api 65 + .com 66 + .atproto 67 + .repo 68 + .create_record( 69 + atrium_api::com::atproto::repo::create_record::InputData { 70 + collection: advent::challenge::Day::NSID.parse().unwrap(), 71 + repo: agent_did.as_ref().parse().unwrap(), 72 + rkey: None, 73 + record: record_value, 74 + swap_commit: None, 75 + validate: Some(false), 85 76 } 86 - } 87 - None => { 88 - log::warn!("No challenge agent configured, skipping record creation for day two"); 89 - None 77 + .into(), 78 + ) 79 + .await; 80 + 81 + match create_record_result { 82 + Ok(output) => Ok(Some(json!({"at_uri": output.uri}))), 83 + Err(e) => { 84 + log::error!("Failed to create challenge record via agent: {e}"); 85 + Ok(None) 90 86 } 91 87 } 92 88 } 93 - AdventPart::Two => None, 94 - }; 95 - 96 - match part { 97 - AdventPart::One => { 98 - sqlx::query( 99 - "INSERT INTO challenges (user_did, day, time_started, verification_code_one, additional_context) 100 - VALUES ($1, $2, NOW(), $3, $4) 101 - ON CONFLICT (user_did, day) 102 - DO UPDATE SET verification_code_one = $3, additional_context = $4 103 - WHERE challenges.user_did = $1 AND challenges.day = $2", 104 - ) 105 - .bind(&did) 106 - .bind(self.day() as i16) 107 - .bind(&code) 108 - .bind(&additional_context) 109 - .execute(self.pool()) 110 - .await?; 111 - } 112 - //TODO just going leave these as an update. It should never ideally be an insert 113 - AdventPart::Two => { 114 - sqlx::query( 115 - "UPDATE challenges 116 - SET verification_code_two = $3 117 - WHERE challenges.user_did = $1 AND challenges.day = $2", 118 - ) 119 - .bind(&did) 120 - .bind(self.day() as i16) 121 - .bind(&code) 122 - .execute(self.pool()) 123 - .await?; 124 - } 89 + AdventPart::Two => Ok(None), 125 90 } 126 - 127 - Ok(code) 128 91 } 129 92 130 93 async fn check_part_one(
+41 -17
shared/src/advent/mod.rs
··· 224 224 .await?) 225 225 } 226 226 227 + /// Hook for challenges to build additional context before the DB write. 228 + /// Override this to store extra data (e.g. an at_uri) in the additional_context column. 229 + async fn build_additional_context( 230 + &self, 231 + _did: &str, 232 + _part: &AdventPart, 233 + _code: &str, 234 + ) -> Result<Option<serde_json::Value>, AdventError> { 235 + Ok(None) 236 + } 237 + 227 238 async fn start_challenge(&self, did: String, part: AdventPart) -> Result<String, AdventError> { 228 239 let code = get_random_token(); 240 + let additional_context = self.build_additional_context(&did, &part, &code).await?; 241 + 229 242 match part { 230 - AdventPart::One => sqlx::query( 231 - "INSERT INTO challenges (user_did, day, time_started, verification_code_one) 232 - VALUES ($1, $2, NOW(), $3) 233 - ON CONFLICT (user_did, day) 234 - DO UPDATE SET verification_code_one = $3 235 - WHERE challenges.user_did = $1 AND challenges.day = $2", 236 - ), 243 + AdventPart::One => { 244 + sqlx::query( 245 + "INSERT INTO challenges (user_did, day, time_started, verification_code_one, additional_context) 246 + VALUES ($1, $2, NOW(), $3, $4) 247 + ON CONFLICT (user_did, day) 248 + DO UPDATE SET verification_code_one = $3, additional_context = COALESCE($4, challenges.additional_context) 249 + WHERE challenges.user_did = $1 AND challenges.day = $2", 250 + ) 251 + .bind(&did) 252 + .bind(self.day() as i16) 253 + .bind(&code) 254 + .bind(&additional_context) 255 + .execute(self.pool()) 256 + .await?; 257 + } 237 258 //TODO just going leave these as an update. It should never ideally be an insert 238 - AdventPart::Two => sqlx::query( 239 - "UPDATE challenges 240 - SET verification_code_two = $3 241 - WHERE challenges.user_did = $1 AND challenges.day = $2", 242 - ), 259 + AdventPart::Two => { 260 + sqlx::query( 261 + "UPDATE challenges 262 + SET verification_code_two = $3 263 + WHERE challenges.user_did = $1 AND challenges.day = $2", 264 + ) 265 + .bind(&did) 266 + .bind(self.day() as i16) 267 + .bind(&code) 268 + .execute(self.pool()) 269 + .await?; 270 + } 243 271 } 244 - .bind(did) 245 - .bind(self.day() as i16) 246 - .bind(code.clone()) 247 - .execute(self.pool()) 248 - .await?; 272 + 249 273 Ok(code) 250 274 } 251 275