ui redesign, markdown fix + metadata and auth header
This commit is contained in:
+40
-3
@@ -1,11 +1,48 @@
|
||||
use crate::error::AppError;
|
||||
use axum::http::HeaderMap;
|
||||
use subtle::ConstantTimeEq;
|
||||
use tracing::warn;
|
||||
|
||||
const COOKIE_NAME: &str = "admin";
|
||||
|
||||
fn extract_token(headers: &HeaderMap) -> Option<String> {
|
||||
if let Some(auth) = headers.get("Authorization").and_then(|h| h.to_str().ok()) {
|
||||
if let Some(token) = auth.strip_prefix("Bearer ") {
|
||||
return Some(token.to_string());
|
||||
}
|
||||
}
|
||||
if let Some(cookie_header) = headers.get("Cookie").and_then(|h| h.to_str().ok()) {
|
||||
for part in cookie_header.split(';') {
|
||||
let part = part.trim();
|
||||
if let Some(value) = part.strip_prefix(&format!("{}=", COOKIE_NAME)) {
|
||||
return Some(value.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn token_matches(provided: &str, expected: &str) -> bool {
|
||||
let a = provided.as_bytes();
|
||||
let b = expected.as_bytes();
|
||||
if a.len() != b.len() {
|
||||
// Still do a constant-time compare to make timing uniform on the same-length path.
|
||||
let _ = a.ct_eq(a);
|
||||
return false;
|
||||
}
|
||||
a.ct_eq(b).into()
|
||||
}
|
||||
|
||||
pub fn is_authed(headers: &HeaderMap, admin_token: &str) -> bool {
|
||||
match extract_token(headers) {
|
||||
Some(t) => token_matches(&t, admin_token),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_auth(headers: &HeaderMap, admin_token: &str) -> Result<(), AppError> {
|
||||
let auth_header = headers.get("Authorization").and_then(|h| h.to_str().ok());
|
||||
if auth_header != Some(&format!("Bearer {}", admin_token)) {
|
||||
warn!("Unauthorized access attempt detected");
|
||||
if !is_authed(headers, admin_token) {
|
||||
warn!("Unauthorized access attempt");
|
||||
return Err(AppError::Unauthorized);
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user