fix: 修复部分资源未授权访问,删除冗余 Admin 判断逻辑

This commit is contained in:
mofeng
2026-01-29 20:16:53 +08:00
parent 9cb0dd146e
commit 78aca25722
10 changed files with 43 additions and 77 deletions

View File

@@ -40,20 +40,20 @@ pub async fn auth_middleware(
mut request: Request,
next: Next,
) -> Result<Response, StatusCode> {
let raw_path = request.uri().path();
// When this middleware is mounted under /api, Axum strips the prefix for the inner router.
// Normalize the path so checks work whether it is mounted or not.
let path = raw_path.strip_prefix("/api").unwrap_or(raw_path);
// Check if system is initialized
if !state.config.is_initialized() {
// Allow access to setup endpoints when not initialized
let path = request.uri().path();
if path.starts_with("/api/setup")
|| path == "/api/info"
|| path.starts_with("/") && !path.starts_with("/api/")
{
// Allow only setup-related endpoints when not initialized
if is_setup_public_endpoint(path) {
return Ok(next.run(request).await);
}
}
// Public endpoints that don't require auth
let path = request.uri().path();
if is_public_endpoint(path) {
return Ok(next.run(request).await);
}
@@ -89,21 +89,14 @@ fn unauthorized_response(message: &str) -> Response {
/// Check if endpoint is public (no auth required)
fn is_public_endpoint(path: &str) -> bool {
// Note: paths here are relative to /api since middleware is applied before nest
// Note: paths here are relative to /api since middleware is applied within the nested router
matches!(
path,
"/"
| "/auth/login"
| "/info"
| "/health"
| "/setup"
| "/setup/init"
// Also check with /api prefix for direct access
| "/api/auth/login"
| "/api/info"
| "/api/health"
| "/api/setup"
| "/api/setup/init"
) || path.starts_with("/assets/")
|| path.starts_with("/static/")
|| path.ends_with(".js")
@@ -112,3 +105,11 @@ fn is_public_endpoint(path: &str) -> bool {
|| path.ends_with(".png")
|| path.ends_with(".svg")
}
/// Setup-only endpoints allowed before initialization.
fn is_setup_public_endpoint(path: &str) -> bool {
matches!(
path,
"/setup" | "/setup/init" | "/devices" | "/stream/codecs"
)
}

View File

@@ -465,7 +465,6 @@ pub async fn logout(
pub struct AuthCheckResponse {
pub authenticated: bool,
pub user: Option<String>,
pub is_admin: bool,
}
pub async fn auth_check(
@@ -481,7 +480,6 @@ pub async fn auth_check(
Json(AuthCheckResponse {
authenticated: true,
user: username,
is_admin: true,
})
}

View File

@@ -32,7 +32,7 @@ pub fn create_router(state: Arc<AppState>) -> Router {
.route("/setup", get(handlers::setup_status))
.route("/setup/init", post(handlers::setup_init));
// User routes (authenticated users - both regular and admin)
// Authenticated routes (all logged-in users)
let user_routes = Router::new()
.route("/info", get(handlers::system_info))
.route("/auth/logout", post(handlers::logout))
@@ -71,10 +71,6 @@ pub fn create_router(state: Arc<AppState>) -> Router {
.route("/audio/devices", get(handlers::list_audio_devices))
// Audio WebSocket endpoint
.route("/ws/audio", any(audio_ws_handler))
;
// Admin-only routes (require admin privileges)
let admin_routes = Router::new()
// Configuration management (domain-separated endpoints)
.route("/config", get(handlers::config::get_all_config))
.route("/config", post(handlers::update_config))
@@ -199,11 +195,10 @@ pub fn create_router(state: Arc<AppState>) -> Router {
.route("/terminal", get(handlers::terminal::terminal_index))
.route("/terminal/", get(handlers::terminal::terminal_index))
.route("/terminal/ws", get(handlers::terminal::terminal_ws))
.route("/terminal/{*path}", get(handlers::terminal::terminal_proxy))
;
.route("/terminal/{*path}", get(handlers::terminal::terminal_proxy));
// Combine protected routes (user + admin)
let protected_routes = Router::new().merge(user_routes).merge(admin_routes);
// Protected routes (all authenticated users)
let protected_routes = user_routes;
// Stream endpoints (accessible with auth, but typically embedded in pages)
let stream_routes = Router::new()