pacco/src/routes/mod.rs
JMARyA 67c31725c1
All checks were successful
ci/woodpecker/push/build Pipeline was successful
fix + test
2024-12-29 11:50:58 +01:00

114 lines
3.1 KiB
Rust

use based::request::api::{FallibleApiResponse, api_error};
use based::request::{RawResponse, RequestContext, respond_with};
use rocket::http::{ContentType, Status};
use rocket::tokio::io::AsyncReadExt;
use rocket::{FromForm, get, post};
use serde_json::json;
use pacco::pkg::arch::Architecture;
use pacco::pkg::{Package, Repository};
// /pkg/<repo>/<arch>/<pkg_name>
// /pkg/<repo>/<arch>/
use rocket::form::Form;
use rocket::fs::TempFile;
#[derive(FromForm)]
pub struct PkgUpload<'r> {
name: String,
arch: String,
version: String,
pkg: TempFile<'r>,
sig: Option<TempFile<'r>>,
}
pub async fn tmp_file_to_vec<'r>(tmp: &TempFile<'r>) -> Vec<u8> {
let mut buf = Vec::with_capacity(tmp.len() as usize);
tmp.open()
.await
.unwrap()
.read_to_end(&mut buf)
.await
.unwrap();
buf
}
#[post("/pkg/<repo>/upload", data = "<upload>")]
pub async fn upload_pkg(
repo: &str,
upload: Form<PkgUpload<'_>>,
user: based::auth::APIUser,
) -> FallibleApiResponse {
// TODO : Permission System
if !user.0.is_admin() {
return Err(api_error("Forbidden"));
}
let pkg = Package::new(
repo,
Architecture::parse(&upload.arch).ok_or_else(|| api_error("Invalid architecture"))?,
&upload.name,
&upload.version,
);
pkg.save(
tmp_file_to_vec(&upload.pkg).await,
if let Some(sig) = &upload.sig {
Some(tmp_file_to_vec(sig).await)
} else {
None
},
);
Ok(json!({"ok": format!("Added '{}' to '{}'", pkg.file_name(), repo)}))
}
#[get("/pkg/<repo>/<arch>/<pkg_name>")]
pub async fn pkg_route(repo: &str, arch: &str, pkg_name: &str, ctx: RequestContext) -> RawResponse {
let arch = Architecture::parse(arch).unwrap();
if let Some(repo) = Repository::new(repo) {
if pkg_name.ends_with("db.tar.gz")
|| pkg_name.ends_with("db")
|| pkg_name.ends_with("db.tar.gz.sig")
|| pkg_name.ends_with("db.sig")
{
if pkg_name.ends_with("sig") {
return respond_with(
Status::Ok,
ContentType::new("application", "pgp-signature"),
repo.sig_content(arch).unwrap(),
);
} else {
return respond_with(
Status::Ok,
ContentType::new("application", "tar"),
repo.db_content(arch).unwrap(),
);
}
}
let pkg = repo.get_pkg(pkg_name).unwrap();
if pkg_name.ends_with("pkg.tar.zst") {
return respond_with(
Status::Ok,
ContentType::new("application", "tar"),
pkg.pkg_content().unwrap(),
);
} else if pkg_name.ends_with("pkg.tar.zst.sig") {
return respond_with(
Status::Ok,
ContentType::new("application", "pgp-signature"),
pkg.sig_content().unwrap(),
);
}
}
respond_with(
Status::Ok,
ContentType::Plain,
"Not found".as_bytes().to_vec(),
)
}