From 60845d6e0f2533e42af9dfa902aa210c7f0ac484 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Thu, 14 Dec 2023 20:14:55 +0800 Subject: [PATCH] fix: /repositories should requires authentication as well (#1042) --- ee/tabby-webserver/src/lib.rs | 4 +-- ee/tabby-webserver/src/repositories/mod.rs | 39 ++++++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/ee/tabby-webserver/src/lib.rs b/ee/tabby-webserver/src/lib.rs index d74adf7f53e5..41808aea5e26 100644 --- a/ee/tabby-webserver/src/lib.rs +++ b/ee/tabby-webserver/src/lib.rs @@ -52,8 +52,8 @@ pub async fn attach_webserver( ) .route("/graphql", routing::get(playground("/graphql", None))) .layer(Extension(schema)) - .route("/hub", routing::get(ws_handler).with_state(ctx)) - .nest("/repositories", repositories::routes()); + .route("/hub", routing::get(ws_handler).with_state(ctx.clone())) + .nest("/repositories", repositories::routes(ctx.clone())); let ui = ui .route("/graphiql", routing::get(graphiql("/graphql", None))) diff --git a/ee/tabby-webserver/src/repositories/mod.rs b/ee/tabby-webserver/src/repositories/mod.rs index b9d3ca2c9e41..455015d4c892 100644 --- a/ee/tabby-webserver/src/repositories/mod.rs +++ b/ee/tabby-webserver/src/repositories/mod.rs @@ -1,21 +1,56 @@ mod resolve; +use std::sync::Arc; + use anyhow::Result; -use axum::{extract::Path, http::StatusCode, response::Response, routing, Json, Router}; +use axum::{ + extract::{Path, State}, + http::{Request, StatusCode}, + middleware::{from_fn_with_state, Next}, + response::{IntoResponse, Response}, + routing, Json, Router, +}; +use hyper::Body; +use juniper_axum::extract::AuthBearer; use tabby_common::path::repositories_dir; use tracing::{instrument, warn}; use crate::{ repositories, repositories::resolve::{resolve_dir, resolve_file, resolve_meta, Meta, ResolveParams}, + schema::{auth::AuthenticationService, ServiceLocator}, }; -pub fn routes() -> Router { +pub fn routes(locator: Arc) -> Router { Router::new() .route("/:name/resolve/", routing::get(repositories::resolve)) .route("/:name/resolve/*path", routing::get(repositories::resolve)) .route("/:name/meta/", routing::get(repositories::meta)) .route("/:name/meta/*path", routing::get(repositories::meta)) + .layer(from_fn_with_state(locator, require_login_middleware)) +} + +async fn require_login_middleware( + State(locator): State>, + AuthBearer(token): AuthBearer, + request: Request, + next: Next, +) -> axum::response::Response { + let unauthorized = axum::response::Response::builder() + .status(StatusCode::UNAUTHORIZED) + .body(Body::empty()) + .unwrap() + .into_response(); + + let Some(token) = token else { + return unauthorized; + }; + + let Ok(_) = locator.auth().verify_access_token(&token).await else { + return unauthorized; + }; + + next.run(request).await } #[instrument(skip(repo))]