feat: add auth middleware chain with ctx resolver and cookie parsing
This commit is contained in:
@@ -59,21 +59,69 @@ async fn list_files(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use axum::{Router, middleware};
|
||||
use axum_test::TestServer;
|
||||
use serde_json::json;
|
||||
use tower_cookies::CookieManagerLayer;
|
||||
|
||||
use crate::{model::FileController, web::routes_file::routes_file};
|
||||
use crate::{
|
||||
model::FileController,
|
||||
web::{
|
||||
mw_auth::{mw_ctx_resolver, mw_require_auth},
|
||||
routes_file::routes_file,
|
||||
},
|
||||
};
|
||||
|
||||
// Cookie format: user-[user-id].[expiration].[signature]
|
||||
const AUTH_COOKIE: &str = "auth-token=user-1.0123456789.a1b2c3d4e5f6";
|
||||
const BAD_AUTH_COOKIE: &str = "auth-token=user-1.0123456789";
|
||||
|
||||
async fn test_server() -> TestServer {
|
||||
let fc = FileController::new().await.unwrap();
|
||||
TestServer::new(routes_file(fc))
|
||||
let file_controller = FileController::new().await.unwrap();
|
||||
let routes_file =
|
||||
routes_file(file_controller.clone()).route_layer(middleware::from_fn(mw_require_auth));
|
||||
let app = Router::new()
|
||||
.nest("/api", routes_file)
|
||||
.layer(middleware::from_fn_with_state(
|
||||
file_controller,
|
||||
mw_ctx_resolver,
|
||||
))
|
||||
.layer(CookieManagerLayer::new());
|
||||
TestServer::new(app)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_requires_auth() {
|
||||
let server = test_server().await;
|
||||
server.get("/api/files").await.assert_status_unauthorized();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_requires_auth_invalid_cookie() {
|
||||
let server = test_server().await;
|
||||
server
|
||||
.get("/api/files")
|
||||
.add_header(axum::http::header::COOKIE, BAD_AUTH_COOKIE)
|
||||
.await
|
||||
.assert_status_unauthorized();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_requires_auth_post() {
|
||||
let server = test_server().await;
|
||||
server
|
||||
.post("/api/files")
|
||||
.json(&json!({"name": "a.txt", "file_type": "text"}))
|
||||
.await
|
||||
.assert_status_unauthorized();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_list_files_empty() {
|
||||
let server = test_server().await;
|
||||
server
|
||||
.get("/files")
|
||||
.get("/api/files")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.await
|
||||
.assert_status_ok()
|
||||
.assert_json(&json!([]));
|
||||
@@ -83,7 +131,8 @@ mod tests {
|
||||
async fn test_upload_and_list_files() {
|
||||
let server = test_server().await;
|
||||
let res = server
|
||||
.post("/files")
|
||||
.post("/api/files")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.json(&json!({"name": "a.txt", "file_type": "text"}))
|
||||
.await;
|
||||
res.assert_status_ok();
|
||||
@@ -91,7 +140,11 @@ mod tests {
|
||||
assert_eq!(file["name"], "a.txt");
|
||||
assert_eq!(file["id"], 0);
|
||||
|
||||
let list = server.get("/files").await.json::<serde_json::Value>();
|
||||
let list = server
|
||||
.get("/api/files")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.await
|
||||
.json::<serde_json::Value>();
|
||||
assert_eq!(list.as_array().unwrap().len(), 1);
|
||||
}
|
||||
|
||||
@@ -99,10 +152,14 @@ mod tests {
|
||||
async fn test_download_file() {
|
||||
let server = test_server().await;
|
||||
server
|
||||
.post("/files")
|
||||
.post("/api/files")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.json(&json!({"name": "b.txt", "file_type": "text"}))
|
||||
.await;
|
||||
let res = server.get("/files/0").await;
|
||||
let res = server
|
||||
.get("/api/files/0")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.await;
|
||||
res.assert_status_ok();
|
||||
assert_eq!(res.json::<serde_json::Value>()["name"], "b.txt");
|
||||
}
|
||||
@@ -110,23 +167,40 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn test_download_file_not_found() {
|
||||
let server = test_server().await;
|
||||
server.get("/files/99").await.assert_status_not_found();
|
||||
server
|
||||
.get("/api/files/99")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.await
|
||||
.assert_status_not_found();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_delete_file() {
|
||||
let server = test_server().await;
|
||||
server
|
||||
.post("/files")
|
||||
.post("/api/files")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.json(&json!({"name": "c.txt", "file_type": "text"}))
|
||||
.await;
|
||||
server.delete("/files/0").await.assert_status_ok();
|
||||
server.get("/files/0").await.assert_status_not_found();
|
||||
server
|
||||
.delete("/api/files/0")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.await
|
||||
.assert_status_ok();
|
||||
server
|
||||
.get("/api/files/0")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.await
|
||||
.assert_status_not_found();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_delete_file_not_found() {
|
||||
let server = test_server().await;
|
||||
server.delete("/files/99").await.assert_status_not_found();
|
||||
server
|
||||
.delete("/api/files/99")
|
||||
.add_header(axum::http::header::COOKIE, AUTH_COOKIE)
|
||||
.await
|
||||
.assert_status_not_found();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user