🏡 index : ~doyle/rgit.git

author Jordan Doyle <jordan@doyle.la> 2024-01-06 1:38:32.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2024-01-06 1:38:32.0 +00:00:00
commit
7f95c54933a0f1392f40614c6400c6c2e1a38b0d [patch]
tree
6d1aaaf7e8af98988d1f725e1c73c9fb3a7aac71
parent
deb257b2d6a294d14c0e88cd5c3479c5b1e477fd
download
7f95c54933a0f1392f40614c6400c6c2e1a38b0d.tar.gz

Ensure referenced repository exists before executing route handler



Diff

 Cargo.lock                        |  2 +-
 src/database/schema/repository.rs |  6 ++++++
 src/methods/repo/mod.rs           | 18 ++++++++++++++++++
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/Cargo.lock b/Cargo.lock
index 236dd48..cae5da3 100644
--- a/Cargo.lock
+++ a/Cargo.lock
@@ -237,7 +237,7 @@
 "heck",
 "proc-macro2",
 "quote",
 "syn",
 "syn 2.0.43",
]

[[package]]
diff --git a/src/database/schema/repository.rs b/src/database/schema/repository.rs
index 8eb48e5..42b0f62 100644
--- a/src/database/schema/repository.rs
+++ a/src/database/schema/repository.rs
@@ -33,6 +33,12 @@
pub type YokedRepository = Yoked<Repository<'static>>;

impl Repository<'_> {
    pub fn exists<P: AsRef<Path>>(database: &sled::Db, path: P) -> bool {
        database
            .contains_key(TreePrefix::repository_id(path))
            .unwrap_or_default()
    }

    pub fn fetch_all(database: &sled::Db) -> Result<BTreeMap<String, YokedRepository>> {
        database
            .scan_prefix([TreePrefix::Repository as u8])
diff --git a/src/methods/repo/mod.rs b/src/methods/repo/mod.rs
index 1b818eb..8bf8040 100644
--- a/src/methods/repo/mod.rs
+++ a/src/methods/repo/mod.rs
@@ -123,6 +123,16 @@
    let uri = uri_parts.into_iter().collect::<PathBuf>().clean();
    let path = scan_path.join(&uri);

    let db = request
        .extensions()
        .get::<sled::Db>()
        .expect("db extension missing");
    if path.as_os_str().is_empty()
        || !crate::database::schema::repository::Repository::exists(db, &uri)
    {
        return RepositoryNotFound.into_response();
    }

    request.extensions_mut().insert(ChildPath(child_path));
    request.extensions_mut().insert(Repository(uri));
    request.extensions_mut().insert(RepositoryPath(path));
@@ -160,6 +170,14 @@
}

pub type Result<T, E = Error> = std::result::Result<T, E>;

pub struct RepositoryNotFound;

impl IntoResponse for RepositoryNotFound {
    fn into_response(self) -> Response {
        (StatusCode::NOT_FOUND, "Repository not found").into_response()
    }
}

pub struct Error(anyhow::Error);