feat(server): add repository prefix path configuration and service struct
- Add REPO_PREFIX_PATH environment variable support in Dockerfile and main.rs - Introduce GitksService struct with repo_prefix field to manage repository paths - Implement resolve and resolve_for_init methods for repository path handling - Add path traversal protection and validation for repository operations - Update all service implementations to use self.resolve instead of global resolve - Modify serve function to accept repo_prefix parameter and pass to GitksService - Remove global resolve functions and integrate them into GitksService struct - Add proper initialization of repo directory from environment variable
This commit is contained in:
@@ -16,6 +16,9 @@ COPY --from=builder /app/target/release/gitks /usr/local/bin/gitks
|
|||||||
|
|
||||||
ENV GITKS_HOST=0.0.0.0
|
ENV GITKS_HOST=0.0.0.0
|
||||||
ENV GITKS_PORT=50051
|
ENV GITKS_PORT=50051
|
||||||
|
ENV REPO_PREFIX_PATH=/data/repos
|
||||||
|
|
||||||
|
RUN mkdir -p /data/repos
|
||||||
|
|
||||||
EXPOSE 50051
|
EXPOSE 50051
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use gitks::server::serve;
|
use gitks::server::serve;
|
||||||
|
|
||||||
const DEFAULT_HOST: &str = "0.0.0.0";
|
const DEFAULT_HOST: &str = "0.0.0.0";
|
||||||
@@ -7,10 +9,29 @@ const DEFAULT_PORT: &str = "50051";
|
|||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
dotenvy::dotenv().ok();
|
dotenvy::dotenv().ok();
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let host = std::env::var("GITKS_HOST").unwrap_or_else(|_| DEFAULT_HOST.into());
|
let host = std::env::var("GITKS_HOST").unwrap_or_else(|_| DEFAULT_HOST.into());
|
||||||
let port = std::env::var("GITKS_PORT").unwrap_or_else(|_| DEFAULT_PORT.into());
|
let port = std::env::var("GITKS_PORT").unwrap_or_else(|_| DEFAULT_PORT.into());
|
||||||
|
|
||||||
|
let repo_prefix = std::env::var("REPO_PREFIX_PATH").map_err(|_| {
|
||||||
|
"REPO_PREFIX_PATH environment variable is required (e.g. /data/repos)"
|
||||||
|
})?;
|
||||||
|
let repo_prefix = PathBuf::from(&repo_prefix);
|
||||||
|
if !repo_prefix.is_absolute() {
|
||||||
|
return Err("REPO_PREFIX_PATH must be an absolute path".into());
|
||||||
|
}
|
||||||
|
if !repo_prefix.exists() {
|
||||||
|
std::fs::create_dir_all(&repo_prefix)?;
|
||||||
|
}
|
||||||
|
|
||||||
let addr: std::net::SocketAddr = format!("{host}:{port}").parse()?;
|
let addr: std::net::SocketAddr = format!("{host}:{port}").parse()?;
|
||||||
tracing::info!("starting gitks gRPC server on {addr}");
|
|
||||||
serve(addr).await?;
|
tracing::info!(
|
||||||
|
"starting gitks gRPC server on {addr}, repo prefix: {}",
|
||||||
|
repo_prefix.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
serve(addr, repo_prefix).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, into_stream, resolve};
|
use super::{GitksService, into_status, into_stream};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl archive_service_server::ArchiveService for GitksService {
|
impl archive_service_server::ArchiveService for GitksService {
|
||||||
@@ -12,7 +12,7 @@ impl archive_service_server::ArchiveService for GitksService {
|
|||||||
request: tonic::Request<ArchiveRequest>,
|
request: tonic::Request<ArchiveRequest>,
|
||||||
) -> Result<tonic::Response<Self::GetArchiveStream>, tonic::Status> {
|
) -> Result<tonic::Response<Self::GetArchiveStream>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let chunks = gb.get_archive(inner).map_err(into_status)?;
|
let chunks = gb.get_archive(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(into_stream(chunks)))
|
Ok(tonic::Response::new(into_stream(chunks)))
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ impl archive_service_server::ArchiveService for GitksService {
|
|||||||
request: tonic::Request<ListArchiveEntriesRequest>,
|
request: tonic::Request<ListArchiveEntriesRequest>,
|
||||||
) -> Result<tonic::Response<ListArchiveEntriesResponse>, tonic::Status> {
|
) -> Result<tonic::Response<ListArchiveEntriesResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.list_archive_entries(inner).map_err(into_status)?;
|
let resp = gb.list_archive_entries(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, into_stream, resolve};
|
use super::{GitksService, into_status, into_stream};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl blame_service_server::BlameService for GitksService {
|
impl blame_service_server::BlameService for GitksService {
|
||||||
@@ -12,7 +12,7 @@ impl blame_service_server::BlameService for GitksService {
|
|||||||
request: tonic::Request<BlameRequest>,
|
request: tonic::Request<BlameRequest>,
|
||||||
) -> Result<tonic::Response<BlameResponse>, tonic::Status> {
|
) -> Result<tonic::Response<BlameResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.blame(inner).map_err(into_status)?;
|
let resp = gb.blame(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ impl blame_service_server::BlameService for GitksService {
|
|||||||
request: tonic::Request<BlameRequest>,
|
request: tonic::Request<BlameRequest>,
|
||||||
) -> Result<tonic::Response<Self::StreamBlameStream>, tonic::Status> {
|
) -> Result<tonic::Response<Self::StreamBlameStream>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.blame(inner).map_err(into_status)?;
|
let resp = gb.blame(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(into_stream(resp.hunks)))
|
Ok(tonic::Response::new(into_stream(resp.hunks)))
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, resolve};
|
use super::{GitksService, into_status};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl branch_service_server::BranchService for GitksService {
|
impl branch_service_server::BranchService for GitksService {
|
||||||
@@ -9,7 +9,7 @@ impl branch_service_server::BranchService for GitksService {
|
|||||||
request: tonic::Request<ListBranchesRequest>,
|
request: tonic::Request<ListBranchesRequest>,
|
||||||
) -> Result<tonic::Response<ListBranchesResponse>, tonic::Status> {
|
) -> Result<tonic::Response<ListBranchesResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.list_branches(inner).map_err(into_status)?;
|
let resp = gb.list_branches(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ impl branch_service_server::BranchService for GitksService {
|
|||||||
request: tonic::Request<GetBranchRequest>,
|
request: tonic::Request<GetBranchRequest>,
|
||||||
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_branch(inner).map_err(into_status)?;
|
let resp = gb.get_branch(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ impl branch_service_server::BranchService for GitksService {
|
|||||||
request: tonic::Request<CreateBranchRequest>,
|
request: tonic::Request<CreateBranchRequest>,
|
||||||
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.create_branch(inner).map_err(into_status)?;
|
let resp = gb.create_branch(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ impl branch_service_server::BranchService for GitksService {
|
|||||||
request: tonic::Request<DeleteBranchRequest>,
|
request: tonic::Request<DeleteBranchRequest>,
|
||||||
) -> Result<tonic::Response<()>, tonic::Status> {
|
) -> Result<tonic::Response<()>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
gb.delete_branch(inner).map_err(into_status)?;
|
gb.delete_branch(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(()))
|
Ok(tonic::Response::new(()))
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ impl branch_service_server::BranchService for GitksService {
|
|||||||
request: tonic::Request<RenameBranchRequest>,
|
request: tonic::Request<RenameBranchRequest>,
|
||||||
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.rename_branch(inner).map_err(into_status)?;
|
let resp = gb.rename_branch(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ impl branch_service_server::BranchService for GitksService {
|
|||||||
request: tonic::Request<UpdateBranchTargetRequest>,
|
request: tonic::Request<UpdateBranchTargetRequest>,
|
||||||
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.update_branch_target(inner).map_err(into_status)?;
|
let resp = gb.update_branch_target(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ impl branch_service_server::BranchService for GitksService {
|
|||||||
request: tonic::Request<SetBranchUpstreamRequest>,
|
request: tonic::Request<SetBranchUpstreamRequest>,
|
||||||
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
) -> Result<tonic::Response<Branch>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.set_branch_upstream(inner).map_err(into_status)?;
|
let resp = gb.set_branch_upstream(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ impl branch_service_server::BranchService for GitksService {
|
|||||||
request: tonic::Request<CompareBranchRequest>,
|
request: tonic::Request<CompareBranchRequest>,
|
||||||
) -> Result<tonic::Response<CompareBranchResponse>, tonic::Status> {
|
) -> Result<tonic::Response<CompareBranchResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.compare_branch(inner).map_err(into_status)?;
|
let resp = gb.compare_branch(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, resolve};
|
use super::{GitksService, into_status};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl commit_service_server::CommitService for GitksService {
|
impl commit_service_server::CommitService for GitksService {
|
||||||
@@ -9,7 +9,7 @@ impl commit_service_server::CommitService for GitksService {
|
|||||||
request: tonic::Request<ListCommitsRequest>,
|
request: tonic::Request<ListCommitsRequest>,
|
||||||
) -> Result<tonic::Response<ListCommitsResponse>, tonic::Status> {
|
) -> Result<tonic::Response<ListCommitsResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.list_commits(inner).map_err(into_status)?;
|
let resp = gb.list_commits(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ impl commit_service_server::CommitService for GitksService {
|
|||||||
request: tonic::Request<GetCommitRequest>,
|
request: tonic::Request<GetCommitRequest>,
|
||||||
) -> Result<tonic::Response<Commit>, tonic::Status> {
|
) -> Result<tonic::Response<Commit>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_commit(inner).map_err(into_status)?;
|
let resp = gb.get_commit(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ impl commit_service_server::CommitService for GitksService {
|
|||||||
request: tonic::Request<GetCommitAncestorsRequest>,
|
request: tonic::Request<GetCommitAncestorsRequest>,
|
||||||
) -> Result<tonic::Response<GetCommitAncestorsResponse>, tonic::Status> {
|
) -> Result<tonic::Response<GetCommitAncestorsResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_commit_ancestors(inner).map_err(into_status)?;
|
let resp = gb.get_commit_ancestors(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ impl commit_service_server::CommitService for GitksService {
|
|||||||
request: tonic::Request<CreateCommitRequest>,
|
request: tonic::Request<CreateCommitRequest>,
|
||||||
) -> Result<tonic::Response<CreateCommitResponse>, tonic::Status> {
|
) -> Result<tonic::Response<CreateCommitResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.create_commit(inner).map_err(into_status)?;
|
let resp = gb.create_commit(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ impl commit_service_server::CommitService for GitksService {
|
|||||||
request: tonic::Request<RevertCommitRequest>,
|
request: tonic::Request<RevertCommitRequest>,
|
||||||
) -> Result<tonic::Response<CreateCommitResponse>, tonic::Status> {
|
) -> Result<tonic::Response<CreateCommitResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.revert_commit(inner).map_err(into_status)?;
|
let resp = gb.revert_commit(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ impl commit_service_server::CommitService for GitksService {
|
|||||||
request: tonic::Request<CherryPickCommitRequest>,
|
request: tonic::Request<CherryPickCommitRequest>,
|
||||||
) -> Result<tonic::Response<CreateCommitResponse>, tonic::Status> {
|
) -> Result<tonic::Response<CreateCommitResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.cherry_pick_commit(inner).map_err(into_status)?;
|
let resp = gb.cherry_pick_commit(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ impl commit_service_server::CommitService for GitksService {
|
|||||||
request: tonic::Request<CompareCommitsRequest>,
|
request: tonic::Request<CompareCommitsRequest>,
|
||||||
) -> Result<tonic::Response<CompareCommitsResponse>, tonic::Status> {
|
) -> Result<tonic::Response<CompareCommitsResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.compare_commits(inner).map_err(into_status)?;
|
let resp = gb.compare_commits(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, into_stream, resolve};
|
use super::{GitksService, into_status, into_stream};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl diff_service_server::DiffService for GitksService {
|
impl diff_service_server::DiffService for GitksService {
|
||||||
@@ -12,7 +12,7 @@ impl diff_service_server::DiffService for GitksService {
|
|||||||
request: tonic::Request<GetDiffRequest>,
|
request: tonic::Request<GetDiffRequest>,
|
||||||
) -> Result<tonic::Response<GetDiffResponse>, tonic::Status> {
|
) -> Result<tonic::Response<GetDiffResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_diff(inner).map_err(into_status)?;
|
let resp = gb.get_diff(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ impl diff_service_server::DiffService for GitksService {
|
|||||||
request: tonic::Request<GetCommitDiffRequest>,
|
request: tonic::Request<GetCommitDiffRequest>,
|
||||||
) -> Result<tonic::Response<GetDiffResponse>, tonic::Status> {
|
) -> Result<tonic::Response<GetDiffResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_commit_diff(inner).map_err(into_status)?;
|
let resp = gb.get_commit_diff(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ impl diff_service_server::DiffService for GitksService {
|
|||||||
request: tonic::Request<GetPatchRequest>,
|
request: tonic::Request<GetPatchRequest>,
|
||||||
) -> Result<tonic::Response<Self::GetPatchStream>, tonic::Status> {
|
) -> Result<tonic::Response<Self::GetPatchStream>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let items = gb.get_patch(inner).map_err(into_status)?;
|
let items = gb.get_patch(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(into_stream(items)))
|
Ok(tonic::Response::new(into_stream(items)))
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ impl diff_service_server::DiffService for GitksService {
|
|||||||
request: tonic::Request<GetDiffStatsRequest>,
|
request: tonic::Request<GetDiffStatsRequest>,
|
||||||
) -> Result<tonic::Response<DiffStats>, tonic::Status> {
|
) -> Result<tonic::Response<DiffStats>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_diff_stats(inner).map_err(into_status)?;
|
let resp = gb.get_diff_stats(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, resolve};
|
use super::{GitksService, into_status};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl merge_service_server::MergeService for GitksService {
|
impl merge_service_server::MergeService for GitksService {
|
||||||
@@ -9,7 +9,7 @@ impl merge_service_server::MergeService for GitksService {
|
|||||||
request: tonic::Request<CheckMergeRequest>,
|
request: tonic::Request<CheckMergeRequest>,
|
||||||
) -> Result<tonic::Response<MergeResult>, tonic::Status> {
|
) -> Result<tonic::Response<MergeResult>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.check_merge(inner).map_err(into_status)?;
|
let resp = gb.check_merge(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ impl merge_service_server::MergeService for GitksService {
|
|||||||
request: tonic::Request<MergeRequest>,
|
request: tonic::Request<MergeRequest>,
|
||||||
) -> Result<tonic::Response<MergeResult>, tonic::Status> {
|
) -> Result<tonic::Response<MergeResult>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.merge(inner).map_err(into_status)?;
|
let resp = gb.merge(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ impl merge_service_server::MergeService for GitksService {
|
|||||||
request: tonic::Request<ListMergeConflictsRequest>,
|
request: tonic::Request<ListMergeConflictsRequest>,
|
||||||
) -> Result<tonic::Response<ListMergeConflictsResponse>, tonic::Status> {
|
) -> Result<tonic::Response<ListMergeConflictsResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.list_merge_conflicts(inner).map_err(into_status)?;
|
let resp = gb.list_merge_conflicts(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ impl merge_service_server::MergeService for GitksService {
|
|||||||
request: tonic::Request<ResolveMergeConflictsRequest>,
|
request: tonic::Request<ResolveMergeConflictsRequest>,
|
||||||
) -> Result<tonic::Response<MergeResult>, tonic::Status> {
|
) -> Result<tonic::Response<MergeResult>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.resolve_merge_conflicts(inner).map_err(into_status)?;
|
let resp = gb.resolve_merge_conflicts(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ impl merge_service_server::MergeService for GitksService {
|
|||||||
request: tonic::Request<RebaseRequest>,
|
request: tonic::Request<RebaseRequest>,
|
||||||
) -> Result<tonic::Response<RebaseResult>, tonic::Status> {
|
) -> Result<tonic::Response<RebaseResult>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.rebase(inner).map_err(into_status)?;
|
let resp = gb.rebase(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
|
|||||||
+70
-43
@@ -21,8 +21,62 @@ use crate::pb::{
|
|||||||
tag_service_server, tree_service_server,
|
tag_service_server, tree_service_server,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone)]
|
||||||
pub struct GitksService;
|
pub struct GitksService {
|
||||||
|
/// 所有仓库的根路径前缀
|
||||||
|
pub(crate) repo_prefix: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GitksService {
|
||||||
|
pub(crate) fn resolve(
|
||||||
|
&self,
|
||||||
|
header: Option<&crate::pb::RepositoryHeader>,
|
||||||
|
) -> Result<GitBare, tonic::Status> {
|
||||||
|
let header =
|
||||||
|
header.ok_or_else(|| tonic::Status::invalid_argument("repository is required"))?;
|
||||||
|
let header = self.prefixed_header(header);
|
||||||
|
GitBare::from_repository_header(&header).map_err(into_status)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn resolve_for_init(
|
||||||
|
&self,
|
||||||
|
header: Option<&crate::pb::RepositoryHeader>,
|
||||||
|
) -> Result<PathBuf, tonic::Status> {
|
||||||
|
let header =
|
||||||
|
header.ok_or_else(|| tonic::Status::invalid_argument("repository is required"))?;
|
||||||
|
let relative_path = header.relative_path.trim();
|
||||||
|
if relative_path.is_empty() {
|
||||||
|
return Err(tonic::Status::invalid_argument("relative_path is required"));
|
||||||
|
}
|
||||||
|
let candidate = self.repo_prefix.join(relative_path);
|
||||||
|
// 路径穿越检查
|
||||||
|
let canonical = candidate
|
||||||
|
.canonicalize()
|
||||||
|
.unwrap_or_else(|_| candidate.clone());
|
||||||
|
let prefix_canon = self
|
||||||
|
.repo_prefix
|
||||||
|
.canonicalize()
|
||||||
|
.unwrap_or_else(|_| self.repo_prefix.clone());
|
||||||
|
if !canonical.starts_with(&prefix_canon) {
|
||||||
|
return Err(tonic::Status::invalid_argument(
|
||||||
|
"path traversal detected: relative_path escapes repo prefix",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(canonical)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 将客户端传入的 header 注入 repo_prefix 作为 storage_path
|
||||||
|
fn prefixed_header(
|
||||||
|
&self,
|
||||||
|
header: &crate::pb::RepositoryHeader,
|
||||||
|
) -> crate::pb::RepositoryHeader {
|
||||||
|
crate::pb::RepositoryHeader {
|
||||||
|
storage_path: self.repo_prefix.to_string_lossy().into_owned(),
|
||||||
|
relative_path: header.relative_path.clone(),
|
||||||
|
storage_name: header.storage_name.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn into_status(e: GitError) -> tonic::Status {
|
pub(crate) fn into_status(e: GitError) -> tonic::Status {
|
||||||
match &e {
|
match &e {
|
||||||
@@ -45,36 +99,6 @@ impl From<GitError> for tonic::Status {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resolve(
|
|
||||||
header: Option<&crate::pb::RepositoryHeader>,
|
|
||||||
) -> Result<GitBare, tonic::Status> {
|
|
||||||
let header = header.ok_or_else(|| tonic::Status::invalid_argument("repository is required"))?;
|
|
||||||
GitBare::from_repository_header(header).map_err(into_status)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn resolve_for_init(
|
|
||||||
header: Option<&crate::pb::RepositoryHeader>,
|
|
||||||
) -> Result<PathBuf, tonic::Status> {
|
|
||||||
let header = header.ok_or_else(|| tonic::Status::invalid_argument("repository is required"))?;
|
|
||||||
let storage_path = header.storage_path.trim();
|
|
||||||
let relative_path = header.relative_path.trim();
|
|
||||||
if storage_path.is_empty() {
|
|
||||||
return Err(tonic::Status::invalid_argument("storage_path is required"));
|
|
||||||
}
|
|
||||||
let p = std::path::Path::new(storage_path);
|
|
||||||
if !p.is_absolute() {
|
|
||||||
return Err(tonic::Status::invalid_argument(
|
|
||||||
"storage_path must be an absolute path",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let base = PathBuf::from(p);
|
|
||||||
Ok(if !relative_path.is_empty() {
|
|
||||||
base.join(relative_path)
|
|
||||||
} else {
|
|
||||||
base
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn into_stream<T: Send + 'static>(
|
pub(crate) fn into_stream<T: Send + 'static>(
|
||||||
items: Vec<T>,
|
items: Vec<T>,
|
||||||
) -> ReceiverStream<Result<T, tonic::Status>> {
|
) -> ReceiverStream<Result<T, tonic::Status>> {
|
||||||
@@ -97,18 +121,21 @@ pub(crate) fn git_cmd(gb: &GitBare, args: &[&str]) -> Result<std::process::Outpu
|
|||||||
.map_err(|e| tonic::Status::internal(e.to_string()))
|
.map_err(|e| tonic::Status::internal(e.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn serve(addr: std::net::SocketAddr) -> Result<(), tonic::transport::Error> {
|
pub async fn serve(
|
||||||
let svc = GitksService;
|
addr: std::net::SocketAddr,
|
||||||
|
repo_prefix: PathBuf,
|
||||||
|
) -> Result<(), tonic::transport::Error> {
|
||||||
|
let svc = GitksService { repo_prefix };
|
||||||
tonic::transport::Server::builder()
|
tonic::transport::Server::builder()
|
||||||
.add_service(repository_service_server::RepositoryServiceServer::new(svc))
|
.add_service(repository_service_server::RepositoryServiceServer::new(svc.clone()))
|
||||||
.add_service(archive_service_server::ArchiveServiceServer::new(svc))
|
.add_service(archive_service_server::ArchiveServiceServer::new(svc.clone()))
|
||||||
.add_service(blame_service_server::BlameServiceServer::new(svc))
|
.add_service(blame_service_server::BlameServiceServer::new(svc.clone()))
|
||||||
.add_service(branch_service_server::BranchServiceServer::new(svc))
|
.add_service(branch_service_server::BranchServiceServer::new(svc.clone()))
|
||||||
.add_service(commit_service_server::CommitServiceServer::new(svc))
|
.add_service(commit_service_server::CommitServiceServer::new(svc.clone()))
|
||||||
.add_service(diff_service_server::DiffServiceServer::new(svc))
|
.add_service(diff_service_server::DiffServiceServer::new(svc.clone()))
|
||||||
.add_service(merge_service_server::MergeServiceServer::new(svc))
|
.add_service(merge_service_server::MergeServiceServer::new(svc.clone()))
|
||||||
.add_service(pack_service_server::PackServiceServer::new(svc))
|
.add_service(pack_service_server::PackServiceServer::new(svc.clone()))
|
||||||
.add_service(tag_service_server::TagServiceServer::new(svc))
|
.add_service(tag_service_server::TagServiceServer::new(svc.clone()))
|
||||||
.add_service(tree_service_server::TreeServiceServer::new(svc))
|
.add_service(tree_service_server::TreeServiceServer::new(svc))
|
||||||
.serve(addr)
|
.serve(addr)
|
||||||
.await
|
.await
|
||||||
|
|||||||
+8
-8
@@ -3,7 +3,7 @@ use tokio_stream::wrappers::ReceiverStream;
|
|||||||
|
|
||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, resolve};
|
use super::{GitksService, into_status};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl pack_service_server::PackService for GitksService {
|
impl pack_service_server::PackService for GitksService {
|
||||||
@@ -16,7 +16,7 @@ impl pack_service_server::PackService for GitksService {
|
|||||||
request: tonic::Request<AdvertiseRefsRequest>,
|
request: tonic::Request<AdvertiseRefsRequest>,
|
||||||
) -> Result<tonic::Response<AdvertiseRefsResponse>, tonic::Status> {
|
) -> Result<tonic::Response<AdvertiseRefsResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.advertise_refs(inner).map_err(into_status)?;
|
let resp = gb.advertise_refs(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ impl pack_service_server::PackService for GitksService {
|
|||||||
.next()
|
.next()
|
||||||
.await
|
.await
|
||||||
.ok_or_else(|| tonic::Status::invalid_argument("empty upload-pack stream"))??;
|
.ok_or_else(|| tonic::Status::invalid_argument("empty upload-pack stream"))??;
|
||||||
let gb = resolve(first.repository.as_ref())?;
|
let gb = self.resolve(first.repository.as_ref())?;
|
||||||
|
|
||||||
let (tx, rx) = tokio::sync::mpsc::channel(16);
|
let (tx, rx) = tokio::sync::mpsc::channel(16);
|
||||||
tx.send(Ok(first))
|
tx.send(Ok(first))
|
||||||
@@ -57,7 +57,7 @@ impl pack_service_server::PackService for GitksService {
|
|||||||
.next()
|
.next()
|
||||||
.await
|
.await
|
||||||
.ok_or_else(|| tonic::Status::invalid_argument("empty receive-pack stream"))??;
|
.ok_or_else(|| tonic::Status::invalid_argument("empty receive-pack stream"))??;
|
||||||
let gb = resolve(first.repository.as_ref())?;
|
let gb = self.resolve(first.repository.as_ref())?;
|
||||||
|
|
||||||
let (tx, rx) = tokio::sync::mpsc::channel(16);
|
let (tx, rx) = tokio::sync::mpsc::channel(16);
|
||||||
tx.send(Ok(first))
|
tx.send(Ok(first))
|
||||||
@@ -80,7 +80,7 @@ impl pack_service_server::PackService for GitksService {
|
|||||||
request: tonic::Request<PackObjectsRequest>,
|
request: tonic::Request<PackObjectsRequest>,
|
||||||
) -> Result<tonic::Response<Self::PackObjectsStream>, tonic::Status> {
|
) -> Result<tonic::Response<Self::PackObjectsStream>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let stream = gb.pack_objects(inner).await?;
|
let stream = gb.pack_objects(inner).await?;
|
||||||
Ok(tonic::Response::new(stream))
|
Ok(tonic::Response::new(stream))
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ impl pack_service_server::PackService for GitksService {
|
|||||||
while let Some(msg) = stream.next().await {
|
while let Some(msg) = stream.next().await {
|
||||||
inputs.push(msg?);
|
inputs.push(msg?);
|
||||||
}
|
}
|
||||||
let gb = resolve(inputs.first().and_then(|r| r.repository.as_ref()))?;
|
let gb = self.resolve(inputs.first().and_then(|r| r.repository.as_ref()))?;
|
||||||
let resp = gb.index_pack(inputs).map_err(into_status)?;
|
let resp = gb.index_pack(inputs).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ impl pack_service_server::PackService for GitksService {
|
|||||||
request: tonic::Request<ListPackfilesRequest>,
|
request: tonic::Request<ListPackfilesRequest>,
|
||||||
) -> Result<tonic::Response<ListPackfilesResponse>, tonic::Status> {
|
) -> Result<tonic::Response<ListPackfilesResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.list_packfiles(inner).map_err(into_status)?;
|
let resp = gb.list_packfiles(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ impl pack_service_server::PackService for GitksService {
|
|||||||
request: tonic::Request<FsckRequest>,
|
request: tonic::Request<FsckRequest>,
|
||||||
) -> Result<tonic::Response<FsckResponse>, tonic::Status> {
|
) -> Result<tonic::Response<FsckResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.fsck(inner).map_err(into_status)?;
|
let resp = gb.fsck(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, git_cmd, into_status, repository_maint, resolve, resolve_for_init};
|
use super::{GitksService, git_cmd, into_status, repository_maint};
|
||||||
|
|
||||||
fn default_branch_name(gb: &crate::bare::GitBare) -> String {
|
fn default_branch_name(gb: &crate::bare::GitBare) -> String {
|
||||||
git_cmd(gb, &["symbolic-ref", "HEAD"])
|
git_cmd(gb, &["symbolic-ref", "HEAD"])
|
||||||
@@ -21,7 +21,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<GetRepositoryRequest>,
|
request: tonic::Request<GetRepositoryRequest>,
|
||||||
) -> Result<tonic::Response<Repository>, tonic::Status> {
|
) -> Result<tonic::Response<Repository>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let bare = gb.bare_dir.join("HEAD").exists();
|
let bare = gb.bare_dir.join("HEAD").exists();
|
||||||
let object_format = gb.object_format();
|
let object_format = gb.object_format();
|
||||||
Ok(tonic::Response::new(Repository {
|
Ok(tonic::Response::new(Repository {
|
||||||
@@ -38,7 +38,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<InitRepositoryRequest>,
|
request: tonic::Request<InitRepositoryRequest>,
|
||||||
) -> Result<tonic::Response<Repository>, tonic::Status> {
|
) -> Result<tonic::Response<Repository>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let bare_dir = resolve_for_init(inner.repository.as_ref())?;
|
let bare_dir = self.resolve_for_init(inner.repository.as_ref())?;
|
||||||
let gb = crate::bare::GitBare { bare_dir };
|
let gb = crate::bare::GitBare { bare_dir };
|
||||||
gb.init_repository(inner.bare).map_err(into_status)?;
|
gb.init_repository(inner.bare).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(Repository {
|
Ok(tonic::Response::new(Repository {
|
||||||
@@ -53,7 +53,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<DeleteRepositoryRequest>,
|
request: tonic::Request<DeleteRepositoryRequest>,
|
||||||
) -> Result<tonic::Response<()>, tonic::Status> {
|
) -> Result<tonic::Response<()>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let bare_dir = resolve_for_init(inner.repository.as_ref())?;
|
let bare_dir = self.resolve_for_init(inner.repository.as_ref())?;
|
||||||
std::fs::remove_dir_all(&bare_dir).map_err(|e| tonic::Status::internal(e.to_string()))?;
|
std::fs::remove_dir_all(&bare_dir).map_err(|e| tonic::Status::internal(e.to_string()))?;
|
||||||
Ok(tonic::Response::new(()))
|
Ok(tonic::Response::new(()))
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<RepositoryExistsRequest>,
|
request: tonic::Request<RepositoryExistsRequest>,
|
||||||
) -> Result<tonic::Response<RepositoryExistsResponse>, tonic::Status> {
|
) -> Result<tonic::Response<RepositoryExistsResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let bare_dir = resolve_for_init(inner.repository.as_ref())?;
|
let bare_dir = self.resolve_for_init(inner.repository.as_ref())?;
|
||||||
let exists = bare_dir.exists() && bare_dir.is_dir() && bare_dir.join("HEAD").exists();
|
let exists = bare_dir.exists() && bare_dir.is_dir() && bare_dir.join("HEAD").exists();
|
||||||
Ok(tonic::Response::new(RepositoryExistsResponse { exists }))
|
Ok(tonic::Response::new(RepositoryExistsResponse { exists }))
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<RepositoryObjectFormatRequest>,
|
request: tonic::Request<RepositoryObjectFormatRequest>,
|
||||||
) -> Result<tonic::Response<RepositoryObjectFormatResponse>, tonic::Status> {
|
) -> Result<tonic::Response<RepositoryObjectFormatResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
Ok(tonic::Response::new(RepositoryObjectFormatResponse {
|
Ok(tonic::Response::new(RepositoryObjectFormatResponse {
|
||||||
object_format: gb.object_format() as i32,
|
object_format: gb.object_format() as i32,
|
||||||
}))
|
}))
|
||||||
@@ -84,7 +84,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<GetDefaultBranchRequest>,
|
request: tonic::Request<GetDefaultBranchRequest>,
|
||||||
) -> Result<tonic::Response<GetDefaultBranchResponse>, tonic::Status> {
|
) -> Result<tonic::Response<GetDefaultBranchResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
Ok(tonic::Response::new(GetDefaultBranchResponse {
|
Ok(tonic::Response::new(GetDefaultBranchResponse {
|
||||||
name: default_branch_name(&gb),
|
name: default_branch_name(&gb),
|
||||||
}))
|
}))
|
||||||
@@ -95,7 +95,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<SetDefaultBranchRequest>,
|
request: tonic::Request<SetDefaultBranchRequest>,
|
||||||
) -> Result<tonic::Response<()>, tonic::Status> {
|
) -> Result<tonic::Response<()>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let refname = format!("refs/heads/{}", inner.name);
|
let refname = format!("refs/heads/{}", inner.name);
|
||||||
let out = git_cmd(&gb, &["symbolic-ref", "HEAD", &refname])?;
|
let out = git_cmd(&gb, &["symbolic-ref", "HEAD", &refname])?;
|
||||||
if !out.status.success() {
|
if !out.status.success() {
|
||||||
@@ -111,7 +111,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<GetRepositoryConfigRequest>,
|
request: tonic::Request<GetRepositoryConfigRequest>,
|
||||||
) -> Result<tonic::Response<GetRepositoryConfigResponse>, tonic::Status> {
|
) -> Result<tonic::Response<GetRepositoryConfigResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let mut entries = Vec::new();
|
let mut entries = Vec::new();
|
||||||
if inner.keys.is_empty() {
|
if inner.keys.is_empty() {
|
||||||
let out = git_cmd(&gb, &["config", "--list"])?;
|
let out = git_cmd(&gb, &["config", "--list"])?;
|
||||||
@@ -156,7 +156,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<SetRepositoryConfigRequest>,
|
request: tonic::Request<SetRepositoryConfigRequest>,
|
||||||
) -> Result<tonic::Response<()>, tonic::Status> {
|
) -> Result<tonic::Response<()>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
for entry in &inner.entries {
|
for entry in &inner.entries {
|
||||||
if entry.values.is_empty() {
|
if entry.values.is_empty() {
|
||||||
git_cmd(&gb, &["config", "--unset-all", &entry.key])?;
|
git_cmd(&gb, &["config", "--unset-all", &entry.key])?;
|
||||||
@@ -178,7 +178,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<RepositoryStatisticsRequest>,
|
request: tonic::Request<RepositoryStatisticsRequest>,
|
||||||
) -> Result<tonic::Response<RepositoryStatistics>, tonic::Status> {
|
) -> Result<tonic::Response<RepositoryStatistics>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
Ok(tonic::Response::new(repository_maint::get_statistics(&gb)))
|
Ok(tonic::Response::new(repository_maint::get_statistics(&gb)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<RepositoryHealthRequest>,
|
request: tonic::Request<RepositoryHealthRequest>,
|
||||||
) -> Result<tonic::Response<RepositoryHealthResponse>, tonic::Status> {
|
) -> Result<tonic::Response<RepositoryHealthResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
Ok(tonic::Response::new(repository_maint::check_health(
|
Ok(tonic::Response::new(repository_maint::check_health(
|
||||||
&gb,
|
&gb,
|
||||||
inner.connectivity_only,
|
inner.connectivity_only,
|
||||||
@@ -199,7 +199,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<GarbageCollectRequest>,
|
request: tonic::Request<GarbageCollectRequest>,
|
||||||
) -> Result<tonic::Response<RepositoryMaintenanceResponse>, tonic::Status> {
|
) -> Result<tonic::Response<RepositoryMaintenanceResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
Ok(tonic::Response::new(repository_maint::run_gc(
|
Ok(tonic::Response::new(repository_maint::run_gc(
|
||||||
&gb,
|
&gb,
|
||||||
inner.prune,
|
inner.prune,
|
||||||
@@ -212,7 +212,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<RepackRequest>,
|
request: tonic::Request<RepackRequest>,
|
||||||
) -> Result<tonic::Response<RepositoryMaintenanceResponse>, tonic::Status> {
|
) -> Result<tonic::Response<RepositoryMaintenanceResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
Ok(tonic::Response::new(repository_maint::run_repack(
|
Ok(tonic::Response::new(repository_maint::run_repack(
|
||||||
&gb,
|
&gb,
|
||||||
inner.full,
|
inner.full,
|
||||||
@@ -226,7 +226,7 @@ impl repository_service_server::RepositoryService for GitksService {
|
|||||||
request: tonic::Request<WriteCommitGraphRequest>,
|
request: tonic::Request<WriteCommitGraphRequest>,
|
||||||
) -> Result<tonic::Response<RepositoryMaintenanceResponse>, tonic::Status> {
|
) -> Result<tonic::Response<RepositoryMaintenanceResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
Ok(tonic::Response::new(
|
Ok(tonic::Response::new(
|
||||||
repository_maint::run_commit_graph_write(&gb, inner.split, inner.replace)?,
|
repository_maint::run_commit_graph_write(&gb, inner.split, inner.replace)?,
|
||||||
))
|
))
|
||||||
|
|||||||
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, resolve};
|
use super::{GitksService, into_status};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl tag_service_server::TagService for GitksService {
|
impl tag_service_server::TagService for GitksService {
|
||||||
@@ -9,7 +9,7 @@ impl tag_service_server::TagService for GitksService {
|
|||||||
request: tonic::Request<ListTagsRequest>,
|
request: tonic::Request<ListTagsRequest>,
|
||||||
) -> Result<tonic::Response<ListTagsResponse>, tonic::Status> {
|
) -> Result<tonic::Response<ListTagsResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.list_tags(inner).map_err(into_status)?;
|
let resp = gb.list_tags(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ impl tag_service_server::TagService for GitksService {
|
|||||||
request: tonic::Request<GetTagRequest>,
|
request: tonic::Request<GetTagRequest>,
|
||||||
) -> Result<tonic::Response<Tag>, tonic::Status> {
|
) -> Result<tonic::Response<Tag>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_tag(inner).map_err(into_status)?;
|
let resp = gb.get_tag(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ impl tag_service_server::TagService for GitksService {
|
|||||||
request: tonic::Request<CreateTagRequest>,
|
request: tonic::Request<CreateTagRequest>,
|
||||||
) -> Result<tonic::Response<Tag>, tonic::Status> {
|
) -> Result<tonic::Response<Tag>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.create_tag(inner).map_err(into_status)?;
|
let resp = gb.create_tag(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ impl tag_service_server::TagService for GitksService {
|
|||||||
request: tonic::Request<DeleteTagRequest>,
|
request: tonic::Request<DeleteTagRequest>,
|
||||||
) -> Result<tonic::Response<()>, tonic::Status> {
|
) -> Result<tonic::Response<()>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
gb.delete_tag(inner).map_err(into_status)?;
|
gb.delete_tag(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(()))
|
Ok(tonic::Response::new(()))
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ impl tag_service_server::TagService for GitksService {
|
|||||||
request: tonic::Request<VerifyTagRequest>,
|
request: tonic::Request<VerifyTagRequest>,
|
||||||
) -> Result<tonic::Response<VerifiedSignature>, tonic::Status> {
|
) -> Result<tonic::Response<VerifiedSignature>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.verify_tag(inner).map_err(into_status)?;
|
let resp = gb.verify_tag(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -1,6 +1,6 @@
|
|||||||
use crate::pb::*;
|
use crate::pb::*;
|
||||||
|
|
||||||
use super::{GitksService, into_status, into_stream, resolve};
|
use super::{GitksService, into_status, into_stream};
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl tree_service_server::TreeService for GitksService {
|
impl tree_service_server::TreeService for GitksService {
|
||||||
@@ -12,7 +12,7 @@ impl tree_service_server::TreeService for GitksService {
|
|||||||
request: tonic::Request<ListTreeRequest>,
|
request: tonic::Request<ListTreeRequest>,
|
||||||
) -> Result<tonic::Response<ListTreeResponse>, tonic::Status> {
|
) -> Result<tonic::Response<ListTreeResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.list_tree(inner).map_err(into_status)?;
|
let resp = gb.list_tree(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ impl tree_service_server::TreeService for GitksService {
|
|||||||
request: tonic::Request<GetTreeRequest>,
|
request: tonic::Request<GetTreeRequest>,
|
||||||
) -> Result<tonic::Response<Tree>, tonic::Status> {
|
) -> Result<tonic::Response<Tree>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_tree(inner).map_err(into_status)?;
|
let resp = gb.get_tree(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ impl tree_service_server::TreeService for GitksService {
|
|||||||
request: tonic::Request<GetBlobRequest>,
|
request: tonic::Request<GetBlobRequest>,
|
||||||
) -> Result<tonic::Response<Blob>, tonic::Status> {
|
) -> Result<tonic::Response<Blob>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_blob(inner).map_err(into_status)?;
|
let resp = gb.get_blob(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ impl tree_service_server::TreeService for GitksService {
|
|||||||
request: tonic::Request<GetRawBlobRequest>,
|
request: tonic::Request<GetRawBlobRequest>,
|
||||||
) -> Result<tonic::Response<Self::GetRawBlobStream>, tonic::Status> {
|
) -> Result<tonic::Response<Self::GetRawBlobStream>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let items = gb.get_raw_blob(inner).map_err(into_status)?;
|
let items = gb.get_raw_blob(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(into_stream(items)))
|
Ok(tonic::Response::new(into_stream(items)))
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ impl tree_service_server::TreeService for GitksService {
|
|||||||
request: tonic::Request<GetFileMetadataRequest>,
|
request: tonic::Request<GetFileMetadataRequest>,
|
||||||
) -> Result<tonic::Response<FileMetadata>, tonic::Status> {
|
) -> Result<tonic::Response<FileMetadata>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.get_file_metadata(inner).map_err(into_status)?;
|
let resp = gb.get_file_metadata(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ impl tree_service_server::TreeService for GitksService {
|
|||||||
request: tonic::Request<FindFilesRequest>,
|
request: tonic::Request<FindFilesRequest>,
|
||||||
) -> Result<tonic::Response<FindFilesResponse>, tonic::Status> {
|
) -> Result<tonic::Response<FindFilesResponse>, tonic::Status> {
|
||||||
let inner = request.into_inner();
|
let inner = request.into_inner();
|
||||||
let gb = resolve(inner.repository.as_ref())?;
|
let gb = self.resolve(inner.repository.as_ref())?;
|
||||||
let resp = gb.find_files(inner).map_err(into_status)?;
|
let resp = gb.find_files(inner).map_err(into_status)?;
|
||||||
Ok(tonic::Response::new(resp))
|
Ok(tonic::Response::new(resp))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user