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.

zj
Sep 15, 2021, 8:22 AM
W2ZEVC64ORZWKRPSQ3JFLIV54FYOTHIK2VW7H7HASO3Z6RC66LSQC

Dependencies

  • [2] DSWQKJRH users: 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] FS2NWBVN pijul: 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
    [3.1277]
    [3.1277]
    use rocket::fs::TempFile;
  • edit in src/pijul.rs at line 57
    [3.1278]
    [3.1278]
    // 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
    [3.1310][2.2546:2581]()
    routes![remote_id, changelist]
    [3.1310]
    [3.1334]
    routes![remote_id, changelist, apply]
  • edit in src/models/pijul/repositories.rs at line 1
    [3.2571]
    [3.2572]
    use std::fmt::Write;
  • edit in src/models/pijul/repositories.rs at line 3
    [3.2596]
    [3.2596]
    use crate::models::pijul::changestores::Changestore;
  • edit in src/models/pijul/repositories.rs at line 26
    [3.2994][3.2994:2995]()
  • edit in src/models/pijul/repositories.rs at line 32
    [3.3292]
    [3.3292]
    }
    pub fn changestore(&self) -> Changestore {
    Changestore::new(self.full_path.clone())
  • replacement in src/models/pijul/repositories.rs at line 44
    [3.3418][3.3418:3484]()
    // init returns an error if there's already something on disk
    [3.3418]
    [3.3484]
    /// init returns an error if there's already something on disk
  • edit in src/models/pijul/repositories.rs at line 63
    [3.4070]
    [3.4070]
    /// 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
    [2.3724][2.3724:3818]()
    out.push_str(format!("{}.{}.{}", offset, h.to_base32(), m.to_base32()).as_str());
    [2.3724]
    [2.3818]
    write!(out, "{}.{}.{}\n", offset, h.to_base32(), m.to_base32())?;
  • edit in src/models/pijul/mod.rs at line 1
    [3.5211]
    [3.5212]
    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 disk
    pub 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)
    }
    }