DSWQKJRHGLKXUDXKMRXCIQZKEGXYV3H5LPUMGSV4HQ4HYPTI47GQC
#[get("/new")]
// TODO decide if this routing file is the place for this guard to be at?
#[rocket::async_trait]
impl<'r> FromRequest<'r> for User {
type Error = ();
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
let db = try_outcome!(request.guard::<&State<Database>>().await);
// &State<Database>>().await);
let cookies = request.cookies();
let some_id = match get_user_id_from_cookie(cookies) {
Some(id) => id,
None => return Outcome::Failure((Status::Unauthorized, ())),
};
match User::find(db, some_id).await {
Ok(u) => Outcome::Success(u),
Err(_e) => Outcome::Failure((Status::Unauthorized, ())),
}
}
}
#[get("/new", rank = 2)]
#[derive(FromForm)]
struct ChangelistReq {
/// Because of the overlap with other routes in parameters, this route has
/// rank 2. This way the changelist matches first, and if it doesn't, this route
/// will respond. Note that in the push flow this order is reversed.
#[get("/<org_path>/<proj_path>/.pijul?<channel>&<id>", rank = 2)]
async fn remote_id(
db: &State<Database>,
repoman: &State<RepoMan>,
org_path: String,
proj_path: String,
// TODO figure out how to stream the response, instead of allocating all now
pub fn changelist(&self, channel: String, from: u64) -> Result<String, anyhow::Error> {
let txn = self.pristine()?.mut_txn_begin()?;
// TODO validate the txn needs closing?
// TODO validate the txn needs closing?
//
// Or does the drop function do that?
let chan = match txn.load_channel(&channel)? {
Some(c) => c,
None => bail!("failed to read channel transaction"),
};
let mut out: String = "".to_string();
for change in txn.log(&chan.read(), from)? {
let (offset, (hash, merkle)) = change?;
let h: libpijul::Hash = hash.into();
let m: libpijul::Merkle = merkle.into();
out.push_str(format!("{}.{}.{}", offset, h.to_base32(), m.to_base32()).as_str());
}
Ok(out)
}