pijul: HTTP push now works While missing Auth{n,z}, one can now push to the main channel. The patches are stored and normal Pijul command can be run in the repository on disk.
Dependencies
- [2]
DSWQKJRHusers: Introduce User guard for routes Rockets guards are very powerful to disallow users for certain routes. This far this wasn't implemented, and allowed no-one other than the first user to sign up. This change introduces the User guard and employs it for a few routes. The guard works by checking the encrypted cookie for the user_id, and perform a database lookup on it. - [3]
FS2NWBVNpijul: Start of push/pull work This change includes one API endpoint, .pijul. It allows for getting a channels remote ID. A lot of plumbing around repositories is added too, from init to opening pristine and actions like it.
Change contents
- edit in src/pijul.rs at line 54
use rocket::fs::TempFile; - edit in src/pijul.rs at line 57
// TODO pijul: When this endpoint returns a 4XX or 5XX status code, it thinks the push still// succeeded.#[post("/<org_path>/<proj_path>/.pijul?<apply>", data = "<patch>")]async fn apply(db: &State<Database>,repoman: &State<RepoMan>,org_path: String,proj_path: String,apply: String,mut patch: TempFile<'_>,) -> rocket::http::Status {let p = if let Some(p) = projects::find(db, org_path, proj_path).await {p} else {return rocket::http::Status::NotFound;};let patch_path = p.repository(&repoman.storage_root).unwrap().changestore().change_file(apply).unwrap();match patch.persist_to(patch_path).await {Ok(_) => rocket::http::Status::Accepted,Err(_e) => rocket::http::Status::InternalServerError,}} - replacement in src/pijul.rs at line 87
routes![remote_id, changelist]routes![remote_id, changelist, apply] - edit in src/models/pijul/repositories.rs at line 1
use std::fmt::Write; - edit in src/models/pijul/repositories.rs at line 3
use crate::models::pijul::changestores::Changestore; - edit in src/models/pijul/repositories.rs at line 26
- edit in src/models/pijul/repositories.rs at line 32
}pub fn changestore(&self) -> Changestore {Changestore::new(self.full_path.clone()) - replacement in src/models/pijul/repositories.rs at line 44
// init returns an error if there's already something on disk/// init returns an error if there's already something on disk - edit in src/models/pijul/repositories.rs at line 63
/// Either initiate a Pijul repository, or open the one already present on/// disk. Fails if the pristine cannot be opened correctly. - replacement in src/models/pijul/repositories.rs at line 122
out.push_str(format!("{}.{}.{}", offset, h.to_base32(), m.to_base32()).as_str());write!(out, "{}.{}.{}\n", offset, h.to_base32(), m.to_base32())?; - edit in src/models/pijul/mod.rs at line 1
pub mod changestores; - file addition: changestores.rs[3.2530]
use std::path::PathBuf;use libpijul::Base32;use libpijul::Hash;use anyhow::bail;const CHANGES_DIR: &str = "changes";pub struct Changestore {path: PathBuf,}impl Changestore {pub fn new(repo_path: PathBuf) -> Self {Changestore { path: repo_path }}// change_file will ensure parent directories are created thus has side-effects on diskpub fn change_file(&self, hash: String) -> Result<PathBuf, anyhow::Error> {let h = if let Some(h) = Hash::from_base32(hash.as_bytes()) {h} else {bail!("invalid hash to store a change")};let mut path = self.dir().clone();libpijul::changestore::filesystem::push_filename(&mut path, &h);std::fs::create_dir_all(path.parent().unwrap())?;Ok(path)}fn dir(&self) -> PathBuf {self.path.join(CHANGES_DIR)}}