forked from
oppi.li/at-advent
this repo has no description
1use axum::extract::State;
2use axum::response::{IntoResponse, Redirect};
3use axum::Form;
4use axum::http::StatusCode;
5use shared::advent::get_global_unlock_day;
6use sqlx::PgPool;
7
8use crate::session::AxumSessionStore;
9use crate::templates::HtmlTemplate;
10use crate::templates::admin::AdminTemplate;
11
12fn get_admin_allow_list() -> Vec<String> {
13 std::env::var("ADMIN_DIDS")
14 .unwrap_or_default()
15 .split(',')
16 .map(|s| s.trim().to_string())
17 .filter(|s| !s.is_empty())
18 .collect()
19}
20
21fn is_admin(did: Option<&String>) -> bool {
22 let did = match did {
23 Some(d) => d,
24 None => return false,
25 };
26 let allow_list = get_admin_allow_list();
27 allow_list.contains(did)
28}
29
30pub async fn admin_page_handler(
31 State(pool): State<PgPool>,
32 session: AxumSessionStore,
33) -> impl IntoResponse {
34 let did = session.get_did();
35
36 if !is_admin(did.as_ref()) {
37 return (StatusCode::FORBIDDEN, "You are not authorized to access this page.").into_response();
38 }
39
40 let current_day = get_global_unlock_day(&pool).await.unwrap_or(1);
41
42 HtmlTemplate(AdminTemplate {
43 title: "Admin - Global Unlock",
44 current_unlock_day: current_day,
45 is_logged_in: session.logged_in(),
46 message: None,
47 })
48 .into_response()
49}
50
51#[derive(Debug, serde::Deserialize)]
52pub struct AdminForm {
53 pub action: String,
54}
55
56pub async fn admin_post_handler(
57 State(pool): State<PgPool>,
58 session: AxumSessionStore,
59 Form(form): Form<AdminForm>,
60) -> impl IntoResponse {
61 let did = session.get_did();
62
63 if !is_admin(did.as_ref()) {
64 return (StatusCode::FORBIDDEN, "You are not authorized to access this page.").into_response();
65 }
66
67 let current_day = get_global_unlock_day(&pool).await.unwrap_or(1);
68
69 let new_day: i32 = match form.action.as_str() {
70 "up" => (current_day as i32 + 1).min(25),
71 "down" => (current_day as i32 - 1).max(1),
72 _ => current_day as i32,
73 };
74
75 let result = sqlx::query("UPDATE settings SET unlocked_up_to_day = $1")
76 .bind(new_day)
77 .execute(&pool)
78 .await;
79
80 match result {
81 Ok(_) => Redirect::to("/admin").into_response(),
82 Err(e) => {
83 log::error!("Failed to update global unlock day: {}", e);
84 HtmlTemplate(AdminTemplate {
85 title: "Admin - Global Unlock",
86 current_unlock_day: current_day,
87 is_logged_in: session.logged_in(),
88 message: Some("Failed to update the unlock day.".to_string()),
89 })
90 .into_response()
91 }
92 }
93}