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(-)
@@ -237,7 +237,7 @@
"heck",
"proc-macro2",
"quote",
"syn",
"syn 2.0.43",
]
[[package]]
@@ -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])
@@ -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);