summaryrefslogtreecommitdiff
path: root/src/handlers/admin.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/handlers/admin.rs')
-rw-r--r--src/handlers/admin.rs143
1 files changed, 0 insertions, 143 deletions
diff --git a/src/handlers/admin.rs b/src/handlers/admin.rs
deleted file mode 100644
index b0863af..0000000
--- a/src/handlers/admin.rs
+++ /dev/null
@@ -1,143 +0,0 @@
-use std::collections::HashMap;
-use std::io::{BufWriter, Write};
-
-use anyhow::Context;
-use axum::body::Bytes;
-use axum::extract::{Multipart, Path, Request, State};
-use axum::http::{HeaderMap, StatusCode};
-use axum::middleware::Next;
-use axum::response::{IntoResponse, Response};
-use axum::{Extension, Json};
-use rand::Rng;
-use subtle::ConstantTimeEq;
-
-use crate::db::product::get_all_products;
-use crate::db::story::{format_filepath, Story};
-use crate::db::ProductDatabaseHandler;
-use crate::error::AppError;
-
-use super::{ApiContext, AppState};
-
-pub fn generate_token() -> String {
- const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
- abcdefghijklmnopqrstuvwxyz\
- 0123456789)(*&^%$#@!~";
- let mut rng = rand::thread_rng();
- let token: String = (0..32)
- .map(|_| {
- let idx = rng.gen_range(0..CHARSET.len());
- CHARSET[idx] as char
- })
- .collect();
- println!("New Token generated: {}", token);
- token
-}
-
-pub async fn admin_middleware(
- State(state): State<AppState>,
- headers: HeaderMap,
- request: Request,
- next: Next,
-) -> Result<Response, StatusCode> {
- let mut expected_token = state.admin_token.lock().await;
-
- let token = headers
- .get("X-Admin-Token")
- .and_then(|header| header.to_str().ok())
- .ok_or(StatusCode::UNAUTHORIZED)?;
-
- if expected_token
- .as_bytes()
- .ct_ne(token.as_bytes())
- .unwrap_u8()
- == 1
- {
- eprintln!("Warning: Unauthorized access attempt with invalid token");
- *expected_token = generate_token();
- return Err(StatusCode::UNAUTHORIZED);
- }
- *expected_token = generate_token();
-
- Ok(next.run(request).await)
-}
-
-pub async fn admin_healthcheck() -> impl IntoResponse {
- StatusCode::OK
-}
-
-pub async fn upload_story(
- ctx: Extension<ApiContext>,
- mut multipart: Multipart,
-) -> Result<impl IntoResponse, AppError> {
- let mut form: HashMap<String, Bytes> = HashMap::new();
- while let Some(field) = multipart.next_field().await? {
- if let Some(label) = field.name() {
- form.insert(label.to_string(), field.bytes().await?);
- }
- }
-
- let name = if let Some(name_value) = form.get("name") {
- std::str::from_utf8(name_value).with_context(|| "Failed to parse name")?
- } else {
- return Ok(StatusCode::BAD_REQUEST.into_response());
- };
-
- let description = if let Some(description_value) = form.get("description") {
- std::str::from_utf8(description_value).with_context(|| "Failed to parse description")?
- } else {
- return Ok(StatusCode::BAD_REQUEST.into_response());
- };
-
- let language = if let Some(language_value) = form.get("language") {
- String::from_utf8(language_value.to_vec()).with_context(|| "Failed to parse language")?
- } else {
- return Ok(StatusCode::BAD_REQUEST.into_response());
- };
-
- let pdf = if let Some(pdf_value) = form.get("pdf") {
- let filename = format_filepath(name, "pdf");
- let file = std::fs::File::create_new(filename)?;
- BufWriter::new(file).write_all(pdf_value)?;
- pdf_value.to_vec()
- } else {
- return Ok(StatusCode::BAD_REQUEST.into_response());
- };
-
- let mut tags: Vec<&str> = Vec::new();
- if let Some(tags_value) = form.get("tag") {
- let tagstring = std::str::from_utf8(tags_value)?;
- for tag in tagstring.split(",") {
- tags.push(tag.trim());
- }
- }
-
- let story_template = Story {
- id: 0,
- pid: 0,
- language,
- pdf,
- };
-
- let story = story_template
- .post(&ctx.pool, name, description, tags)
- .await?;
- Ok((StatusCode::CREATED, Json(story)).into_response())
-}
-
-pub async fn delete_story(
- ctx: Extension<ApiContext>,
- Path(story_id): Path<i64>,
-) -> Result<impl IntoResponse, AppError> {
- Story::delete(&ctx.pool, story_id).await?;
- Ok((StatusCode::NO_CONTENT).into_response())
-}
-
-pub async fn get_stories(ctx: Extension<ApiContext>) -> Result<impl IntoResponse, AppError> {
- let stories = Story::get_all(&ctx.pool).await?;
- Ok((StatusCode::OK, Json(stories)).into_response())
-}
-
-pub async fn get_products(ctx: Extension<ApiContext>) -> Result<impl IntoResponse, AppError> {
- let products = get_all_products(&ctx.pool).await?;
- Ok((StatusCode::OK, Json(products)).into_response())
-}