mod archive; mod did_ext; mod diff; mod error; mod git_transport; mod last_commit; mod merge; pub mod metrics; mod routes; mod sniff; use std::{path::PathBuf, sync::Arc}; use axum::{ Router, routing::{get, post}, }; use bobbin_runtime::{Clock, ReqwestHttp}; use gitmirror_git::layout::Layout; use jacquard_axum::service_auth::{self, ServiceAuthError}; use jacquard_common::service_auth::ServiceAuthClaims; use jacquard_identity::JacquardResolver; use tangled_axum::atproto::{AtprotoService, ClaimsPolicy, Verified}; pub(crate) type Directory = JacquardResolver; #[derive(Clone)] pub struct AppState { pub(crate) layout: Arc, pub(crate) http: reqwest::Client, pub(crate) service_auth: service_auth::ServiceAuthConfig>, pub(crate) knot_policy: KnotPolicy, pub(crate) clock: Arc, pub(crate) stats: Arc, pub(crate) redis: Option, pub(crate) max_blob_bytes: u64, pub(crate) max_archive_bytes: u64, } impl AppState { #[allow(clippy::too_many_arguments)] pub fn new( repo_base: Arc, http: reqwest::Client, service_auth: service_auth::ServiceAuthConfig>, knot_policy: KnotPolicy, clock: Arc, redis: Option, max_blob_bytes: u64, max_archive_bytes: u64, ) -> Self { let layout = Arc::new(Layout::new((*repo_base).clone())); Self { layout, http, service_auth, knot_policy, clock, stats: Arc::default(), redis, max_blob_bytes, max_archive_bytes, } } } impl AtprotoService for AppState { type Resolver = Directory; fn resolver(&self) -> &Self::Resolver { self.service_auth.resolver() } async fn verify_claims( &self, claims: &ServiceAuthClaims, ) -> Result { ClaimsPolicy::from(&self.service_auth) .skip_audience() .check(claims, self.clock.now_unix_micros()) .await } } #[rustfmt::skip] pub fn router(state: AppState) -> Router { use routes::*; Router::new() .route("/xrpc/sh.tangled.git.temp2.getBlame", get(git::get_blame)) .route("/xrpc/sh.tangled.git.temp2.getDiff", get(git::get_diff)) .route("/xrpc/sh.tangled.git.temp2.getInterdiff", get(git::get_interdiff)) .route("/xrpc/sh.tangled.git.temp2.listCommits", get(git::list_commits)) .route("/xrpc/sh.tangled.git.temp2.mergeCheck", get(git::merge_check)) .route("/xrpc/sh.tangled.git.mergeCommit", post(git::merge_commit)) .route("/xrpc/org.tangled.temp.git.deleteBranch", post(git::delete_branch)) .route("/xrpc/org.tangled.temp.git.getArchive", get(reads::get_archive)) .route("/xrpc/org.tangled.temp.git.getBlob", get(reads::get_blob)) .route("/xrpc/org.tangled.temp.git.getEntry", get(reads::get_entry)) .route("/xrpc/org.tangled.temp.git.getMergeBase", get(reads::get_merge_base)) .route("/xrpc/org.tangled.temp.git.getRef", get(reads::get_ref)) .route("/xrpc/org.tangled.temp.git.getTree", get(reads::get_tree)) .route("/xrpc/org.tangled.temp.git.listBranches", get(reads::list_branches)) .route("/xrpc/org.tangled.temp.git.listTags", get(reads::list_tags)) .layer(axum::middleware::from_fn(metrics::metrics_middleware)) .with_state(state) } #[derive(Debug, Clone, Copy)] pub struct KnotPolicy { pub allow_private: bool, pub require_https: bool, }