95 lines
2.5 KiB
Rust
95 lines
2.5 KiB
Rust
use based::request::api::{FallibleApiResponse, api_error};
|
|
use pacco::pkg::package::read_file_tar_raw;
|
|
use rocket::tokio::io::AsyncReadExt;
|
|
use rocket::{FromForm, State, post};
|
|
use serde_json::json;
|
|
|
|
use pacco::pkg::Package;
|
|
use pacco::pkg::arch::Architecture;
|
|
|
|
// /pkg/<repo>/<arch>/<pkg_name>
|
|
// /pkg/<repo>/<arch>/
|
|
|
|
use rocket::form::Form;
|
|
use rocket::fs::TempFile;
|
|
|
|
use crate::config::Config;
|
|
|
|
#[derive(FromForm)]
|
|
pub struct PkgUpload<'r> {
|
|
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,
|
|
config: &State<Config>,
|
|
) -> FallibleApiResponse {
|
|
// TODO : Permission System
|
|
if !user.0.is_admin() {
|
|
return Err(api_error("Forbidden"));
|
|
}
|
|
|
|
if config.is_mirrored_repo(repo) {
|
|
return Err(api_error("This repository is a mirror."));
|
|
}
|
|
|
|
let pkg_file = tmp_file_to_vec(&upload.pkg).await;
|
|
let content = read_file_tar_raw(&pkg_file, ".PKGINFO")
|
|
.ok_or_else(|| api_error("Unable to read package file"))?;
|
|
let pkg_info = Package::pkginfo_from_str(&content);
|
|
|
|
let pkg_name = pkg_info
|
|
.iter()
|
|
.find(|x| x.0 == "pkgname")
|
|
.ok_or_else(|| api_error("Package has no pkgname"))?
|
|
.1
|
|
.as_str();
|
|
|
|
let (version, rel) = Package::version(
|
|
&pkg_info
|
|
.iter()
|
|
.find(|x| x.0 == "pkgver")
|
|
.ok_or_else(|| api_error("Package has no pkgver"))?
|
|
.1,
|
|
);
|
|
|
|
let arch = pkg_info
|
|
.iter()
|
|
.find(|x| x.0 == "arch")
|
|
.ok_or_else(|| api_error("Package has no arch"))?
|
|
.1
|
|
.as_str();
|
|
|
|
let arch = Architecture::parse(&arch).ok_or_else(|| api_error("Invalid architecture"))?;
|
|
|
|
let (_, _, _, _, compression) = Package::extract_pkg_name(upload.pkg.name().unwrap())
|
|
.ok_or_else(|| api_error("Package has weird filename"))?;
|
|
|
|
let pkg = Package::new(repo, arch, pkg_name, &version, rel, compression);
|
|
|
|
pkg.save(
|
|
pkg_file,
|
|
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)}))
|
|
}
|