use crate::utils::{is_key_valid, sha256_hex};
use actix_multipart::form::{json::Json as MPJson, tempfile::TempFile, MultipartForm};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
pub const FORMAT_SHA256: &str = "sha256";
pub const FORMAT_PLAIN: &str = "plain";
#[derive(Debug)]
pub struct AppConfig {
pub admin_key: String,
pub no_admin_key: bool,
pub local: bool,
pub enable_metrics: bool,
pub port: u16,
pub log_level: String,
pub original_length: u16,
pub metadata_length: u16,
pub key_length: u16,
pub key_prefix: String,
pub auth_counter: Arc<prometheus::IntCounterVec>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ApiKey(String);
impl ApiKey {
pub fn new(raw: &str, length: u16, prefix: &str) -> Option<Self> {
if is_key_valid(raw, length, prefix) {
Some(ApiKey(raw.to_string()))
} else {
None
}
}
pub fn hash(&self) -> String {
sha256_hex(&self.0)
}
}
#[derive(Debug, Serialize)]
pub struct Headers {
pub forwarded_for: String,
pub original_host: String,
pub original_uri: String,
pub metadata: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyFormat {
Sha256,
Plain,
}
impl KeyFormat {
pub fn from_str(s: &str) -> Option<Self> {
match s {
FORMAT_SHA256 => Some(KeyFormat::Sha256),
FORMAT_PLAIN => Some(KeyFormat::Plain),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
KeyFormat::Sha256 => FORMAT_SHA256,
KeyFormat::Plain => FORMAT_PLAIN,
}
}
}
#[derive(Debug, MultipartForm)]
pub struct LoadForm {
pub file: TempFile,
pub json: Option<MPJson<LoadMetadata>>,
}
#[derive(Debug, Deserialize)]
pub struct LoadMetadata {
pub format: Option<String>,
pub hash_input_file: Option<String>,
}
#[derive(Debug, Serialize)]
pub struct StatusResponse {
pub log_level: String,
pub no_admin_key: bool,
pub local: bool,
pub enable_metrics: bool,
pub original_length: u16,
pub metadata_length: u16,
pub file_hash: String,
pub file_date: String,
pub file_key_count: u32,
pub key_length: u16,
pub key_prefix: String,
}
#[cfg(test)]
mod api_key_tests {
use super::*;
use crate::utils;
#[test]
fn test_api_key_new_valid() {
let key = "prefix12345";
let api_key = ApiKey::new(key, 11, "prefix");
assert!(api_key.is_some());
}
#[test]
fn test_api_key_new_invalid_length() {
let key = "prefix1";
let api_key = ApiKey::new(key, 10, "prefix");
assert!(api_key.is_none());
}
#[test]
fn test_api_key_new_invalid_prefix() {
let key = "noprefix123";
let api_key = ApiKey::new(key, 11, "prefix");
assert!(api_key.is_none());
}
#[test]
fn test_api_key_hash() {
let key = "testkey";
let api_key = ApiKey::new(key, 7, "test").unwrap();
assert_eq!(api_key.hash(), utils::sha256_hex(key));
}
}
#[cfg(test)]
mod key_format_tests {
use super::*;
#[test]
fn test_key_format_from_str() {
assert_eq!(KeyFormat::from_str("sha256"), Some(KeyFormat::Sha256));
assert_eq!(KeyFormat::from_str("plain"), Some(KeyFormat::Plain));
assert_eq!(KeyFormat::from_str("unknown"), None);
}
#[test]
fn test_key_format_as_str() {
assert_eq!(KeyFormat::Sha256.as_str(), "sha256");
assert_eq!(KeyFormat::Plain.as_str(), "plain");
}
}