|
| 1 | +use crate::db::operations::{create_api_key, generate_api_key}; |
| 2 | +use crate::db::repr::Permission; |
| 3 | +use crate::prelude::types::*; |
| 4 | +use axum::Json; |
| 5 | +use axum::extract::State; |
| 6 | +use axum::http::StatusCode; |
| 7 | +use serde::{Deserialize, Serialize}; |
| 8 | +use std::sync::Arc; |
| 9 | +use tokio::sync::Mutex; |
| 10 | + |
| 11 | +#[derive(Deserialize)] |
| 12 | +pub struct CreateApiKeyRequest { |
| 13 | + pub name: String, |
| 14 | + pub permissions: Vec<Permission>, |
| 15 | + pub expires_at: Option<i64>, |
| 16 | +} |
| 17 | + |
| 18 | +#[derive(Serialize)] |
| 19 | +pub struct CreateApiKeyResponse { |
| 20 | + pub api_key: String, |
| 21 | + pub id: i64, |
| 22 | + pub name: String, |
| 23 | + pub permissions: Vec<Permission>, |
| 24 | + pub created_at: i64, |
| 25 | + pub expires_at: Option<i64>, |
| 26 | +} |
| 27 | + |
| 28 | +pub async fn create_api_key_handler( |
| 29 | + State(bot_state): State<Arc<Mutex<BotState>>>, |
| 30 | + Json(req): Json<CreateApiKeyRequest>, |
| 31 | +) -> Result<Json<CreateApiKeyResponse>, (StatusCode, String)> { |
| 32 | + if req.name.trim().is_empty() { |
| 33 | + return Err((StatusCode::BAD_REQUEST, "Name cannot be empty".to_string())); |
| 34 | + } |
| 35 | + |
| 36 | + if req.permissions.is_empty() { |
| 37 | + return Err(( |
| 38 | + StatusCode::BAD_REQUEST, |
| 39 | + "At least one permission is required".to_string(), |
| 40 | + )); |
| 41 | + } |
| 42 | + |
| 43 | + let db_pool = { |
| 44 | + let state_lock = bot_state.lock().await; |
| 45 | + match &state_lock.db_pool { |
| 46 | + Some(pool) => pool.clone(), |
| 47 | + None => { |
| 48 | + return Err(( |
| 49 | + StatusCode::INTERNAL_SERVER_ERROR, |
| 50 | + "Database not initialized".to_string(), |
| 51 | + )); |
| 52 | + } |
| 53 | + } |
| 54 | + }; |
| 55 | + |
| 56 | + let (plain_key, key_hash) = match generate_api_key() { |
| 57 | + Ok(keys) => keys, |
| 58 | + Err(e) => return Err((StatusCode::INTERNAL_SERVER_ERROR, e)), |
| 59 | + }; |
| 60 | + |
| 61 | + let api_key = match create_api_key( |
| 62 | + &db_pool, |
| 63 | + key_hash, |
| 64 | + req.name, |
| 65 | + req.permissions, |
| 66 | + req.expires_at, |
| 67 | + ) |
| 68 | + .await |
| 69 | + { |
| 70 | + Ok(key) => key, |
| 71 | + Err(e) => return Err((StatusCode::INTERNAL_SERVER_ERROR, e)), |
| 72 | + }; |
| 73 | + |
| 74 | + Ok(Json(CreateApiKeyResponse { |
| 75 | + api_key: plain_key, |
| 76 | + id: api_key.id, |
| 77 | + name: api_key.name, |
| 78 | + permissions: api_key.permissions, |
| 79 | + created_at: api_key.created_at, |
| 80 | + expires_at: api_key.expires_at, |
| 81 | + })) |
| 82 | +} |
0 commit comments