this repo has no description
at main 99 lines 2.9 kB view raw
1use crate::session::AxumSessionStore; 2use axum::extract::{Path, Request, State}; 3use axum::http; 4use axum::{ 5 middleware, 6 response::{self, IntoResponse}, 7}; 8use shared::advent::{CompletionStatus, get_all_days_completion_status, get_global_unlock_day}; 9use sqlx::PgPool; 10 11pub async fn unlock( 12 State(pool): State<PgPool>, 13 Path(mut day): Path<u8>, 14 session: AxumSessionStore, 15 request: Request, 16 next: middleware::Next, 17) -> response::Response { 18 if day == 0 { 19 day = 1; 20 } 21 22 if day == 69 { 23 return (http::StatusCode::FORBIDDEN, "Really?").into_response(); 24 } 25 26 if day == 42 { 27 return ( 28 http::StatusCode::FORBIDDEN, 29 "Oh, you have all the answers, huh?", 30 ) 31 .into_response(); 32 } 33 34 if day > 25 || day < 1 { 35 return ( 36 http::StatusCode::FORBIDDEN, 37 "This isn't even a day in the advent calendar????", 38 ) 39 .into_response(); 40 } 41 let implemented_days = shared::advent::get_implemented_days(); 42 if !implemented_days.contains(&day) { 43 return ( 44 http::StatusCode::FORBIDDEN, 45 "This day hasn't been created yet!", 46 ) 47 .into_response(); 48 } 49 50 // Check if the day is globally unlocked via the settings table 51 let global_unlock_enabled = std::env::var("GLOBAL_UNLOCK_ENABLED") 52 .map(|v| v == "true") 53 .unwrap_or(false); 54 55 if global_unlock_enabled { 56 let global_unlock_day = get_global_unlock_day(&pool).await.unwrap_or(1); 57 if day <= global_unlock_day { 58 return next.run(request).await; 59 } else { 60 return ( 61 http::StatusCode::FORBIDDEN, 62 "Now just hold on a minute. It ain't time yet.", 63 ) 64 .into_response(); 65 } 66 } 67 68 // First implemented day is always accessible 69 let pos = implemented_days.iter().position(|&d| d == day).unwrap(); 70 if pos > 0 { 71 let prev_day = implemented_days[pos - 1]; 72 let did = session.get_did(); 73 74 let all_statuses = get_all_days_completion_status(&pool, did.as_ref()) 75 .await 76 .unwrap_or_else(|_| (1..=25).map(|d| (d, CompletionStatus::None)).collect()); 77 78 let prev_status = all_statuses 79 .iter() 80 .find(|(d, _)| *d == prev_day) 81 .map(|(_, s)| s) 82 .unwrap_or(&CompletionStatus::None); 83 84 //HACK hardcoded for the workshop since we don't have a part 2 for day 4 85 if (pos == 4 || pos == 5) && *prev_status == CompletionStatus::PartOne { 86 return next.run(request).await; 87 } 88 89 if *prev_status != CompletionStatus::Both { 90 return ( 91 http::StatusCode::FORBIDDEN, 92 "Now just hold on a minute. It ain't time yet.", 93 ) 94 .into_response(); 95 } 96 } 97 98 next.run(request).await 99}