diff options
Diffstat (limited to 'src/post_routes.rs')
-rw-r--r-- | src/post_routes.rs | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/src/post_routes.rs b/src/post_routes.rs index 0374cae..8cbd3b2 100644 --- a/src/post_routes.rs +++ b/src/post_routes.rs @@ -1,6 +1,7 @@ use git2::build::TreeUpdateBuilder; use git2::FileMode; use hyper::header; +use hyper::http::request::Parts; use hyper::http::response::Builder; use hyper::Body; use hyper::StatusCode; @@ -28,10 +29,10 @@ pub(crate) async fn build_response<C: Controller>( controller: &C, ctx: Context, body: Body, + parts: &mut Parts, ) -> Result<Response, Error> { if let Some(ref enforced_origin) = args.origin { - if ctx - .parts + if parts .headers .get(header::ORIGIN) .filter(|h| h.as_bytes() == enforced_origin.as_bytes()) @@ -44,12 +45,12 @@ pub(crate) async fn build_response<C: Controller>( } } match params.action.as_ref() { - "edit" => return update_blob(body, controller, ctx).await, - "upload" => return upload_blob(body, controller, ctx).await, - "move" => return move_entry(body, controller, ctx).await, - "remove" => return remove_entry(body, controller, ctx).await, - "diff" => return diff_blob(body, controller, ctx).await, - "preview" => return preview_edit(body, controller, ctx).await, + "edit" => return update_blob(body, controller, ctx, parts).await, + "upload" => return upload_blob(body, controller, ctx, parts).await, + "move" => return move_entry(body, controller, ctx, parts).await, + "remove" => return remove_entry(body, controller, ctx, parts).await, + "diff" => return diff_blob(body, controller, ctx, parts).await, + "preview" => return preview_edit(body, controller, ctx, parts).await, _ => return Err(Error::BadRequest("unknown POST action".into())), } } @@ -59,6 +60,7 @@ fn commit_file_update<C: Controller>( msg: Option<String>, controller: &C, ctx: &Context, + parts: &Parts, ) -> Result<(), Error> { let blob_id = ctx.repo.blob(data)?; @@ -70,7 +72,7 @@ fn commit_file_update<C: Controller>( let parent_tree = commit.tree()?; if parent_tree.get_path(&ctx.path).ok().map(|e| e.id()) == Some(blob_id) { // nothing changed, don't create an empty commit - return Err(Error::Redirect(ctx.parts.uri.path().to_string())); + return Err(Error::Redirect(parts.uri.path().to_string())); } (parent_tree, vec![commit]) } else { @@ -82,7 +84,7 @@ fn commit_file_update<C: Controller>( let new_tree_id = builder.create_updated(&ctx.repo, &parent_tree)?; - let signature = controller.signature(&ctx.repo, &ctx.parts)?; + let signature = controller.signature(&ctx.repo, &parts)?; ctx.commit( &signature, &msg.filter(|m| !m.trim().is_empty()).unwrap_or_else(|| { @@ -106,9 +108,10 @@ fn commit_file_update<C: Controller>( async fn update_blob<C: Controller>( body: Body, controller: &C, - mut ctx: Context, + ctx: Context, + parts: &mut Parts, ) -> Result<Response, Error> { - if !controller.may_write_path(&ctx) { + if !controller.may_write_path(&ctx, parts) { return Err(Error::Unauthorized( "you are not authorized to edit this file".into(), )); @@ -132,40 +135,41 @@ async fn update_blob<C: Controller>( } else { "this file has been deleted in the meantime, if you save you will re-create it" } - ), controller, &ctx).into()); + ), controller, &ctx, parts).into()); } } // normalize newlines as per HTML spec let text = data.text.replace("\r\n", "\n"); - if let Err(error) = controller.before_write(&text, &mut ctx) { - return Ok(edit_text_form(&data, Some(&error), controller, &ctx).into()); + if let Err(error) = controller.before_write(&text, &ctx, parts) { + return Ok(edit_text_form(&data, Some(&error), controller, &ctx, parts).into()); } - commit_file_update(text.as_bytes(), data.msg, controller, &ctx)?; + commit_file_update(text.as_bytes(), data.msg, controller, &ctx, &parts)?; - controller.after_write(&mut ctx); + controller.after_write(&ctx, parts); return Ok(Builder::new() .status(StatusCode::FOUND) - .header("location", ctx.parts.uri.path()) + .header("location", parts.uri.path()) .body("redirecting".into()) - .unwrap()); + .unwrap() + .into()); } async fn upload_blob<C: Controller>( body: Body, controller: &C, - mut ctx: Context, + ctx: Context, + parts: &mut Parts, ) -> Result<Response, Error> { - if !controller.may_write_path(&ctx) { + if !controller.may_write_path(&ctx, parts) { return Err(Error::Unauthorized( "you are not authorized to edit this file".into(), )); } // Extract the `multipart/form-data` boundary from the headers. - let boundary = ctx - .parts + let boundary = parts .headers .get(header::CONTENT_TYPE) .and_then(|ct| ct.to_str().ok()) @@ -180,15 +184,22 @@ async fn upload_blob<C: Controller>( { if field.name() == Some("file") { // TODO: make commit message customizable - commit_file_update(&field.bytes().await.unwrap(), None, controller, &ctx)?; + commit_file_update( + &field.bytes().await.unwrap(), + None, + controller, + &ctx, + &parts, + )?; - controller.after_write(&mut ctx); + controller.after_write(&ctx, parts); return Ok(Builder::new() .status(StatusCode::FOUND) - .header("location", ctx.parts.uri.path()) + .header("location", parts.uri.path()) .body("redirecting".into()) - .unwrap()); + .unwrap() + .into()); } } Err(Error::BadRequest( @@ -200,8 +211,9 @@ async fn move_entry<C: Controller>( body: Body, controller: &C, ctx: Context, + parts: &Parts, ) -> Result<Response, Error> { - if !controller.may_move_path(&ctx) { + if !controller.may_move_path(&ctx, parts) { return Err(Error::Unauthorized( "you are not authorized to move this file".into(), )); @@ -216,6 +228,7 @@ async fn move_entry<C: Controller>( Some("can not move entry to itself"), controller, &ctx, + parts, ); } @@ -228,6 +241,7 @@ async fn move_entry<C: Controller>( Some("destination already exists"), controller, &ctx, + parts, ); } @@ -252,7 +266,7 @@ async fn move_entry<C: Controller>( let new_tree_id = builder.create_updated(&ctx.repo, &parent_commit.tree()?)?; ctx.commit( - &controller.signature(&ctx.repo, &ctx.parts)?, + &controller.signature(&ctx.repo, &parts)?, &data .msg .take() @@ -269,7 +283,8 @@ async fn move_entry<C: Controller>( controller.build_url_path(&ctx.branch, &data.dest), ) .body("redirecting".into()) - .unwrap()) + .unwrap() + .into()) } #[derive(Deserialize)] @@ -281,8 +296,9 @@ async fn remove_entry<C: Controller>( body: Body, controller: &C, ctx: Context, + parts: &Parts, ) -> Result<Response, Error> { - if !controller.may_move_path(&ctx) { + if !controller.may_move_path(&ctx, parts) { return Err(Error::Unauthorized( "you are not authorized to remove this file".into(), )); @@ -294,7 +310,7 @@ async fn remove_entry<C: Controller>( let new_tree_id = builder.create_updated(&ctx.repo, &parent_commit.tree()?)?; ctx.commit( - &controller.signature(&ctx.repo, &ctx.parts)?, + &controller.signature(&ctx.repo, &parts)?, &data .msg .filter(|m| !m.trim().is_empty()) @@ -309,15 +325,17 @@ async fn remove_entry<C: Controller>( controller.build_url_path(&ctx.branch, ctx.path.parent().unwrap().to_str().unwrap()), ) .body("redirecting".into()) - .unwrap()) + .unwrap() + .into()) } async fn diff_blob<C: Controller>( body: Body, controller: &C, ctx: Context, + parts: &Parts, ) -> Result<Response, Error> { - if !controller.may_write_path(&ctx) { + if !controller.may_write_path(&ctx, parts) { return Err(Error::Unauthorized( "you are not authorized to edit this file".into(), )); @@ -331,7 +349,7 @@ async fn diff_blob<C: Controller>( let blob = ctx.repo.find_blob(entr.id()).unwrap(); let old_text = from_utf8(blob.content())?; - let mut page = edit_text_form(&form, None, controller, &ctx); + let mut page = edit_text_form(&form, None, controller, &ctx, parts); page.body.push_str(&diff(old_text, &new_text)); Ok(page.into()) } @@ -340,10 +358,11 @@ async fn preview_edit<C: Controller>( body: Body, controller: &C, ctx: Context, + parts: &Parts, ) -> Result<Response, Error> { let form: EditForm = body.into_form().await?; let new_text = form.text.replace("\r\n", "\n"); - let mut page = edit_text_form(&form, None, controller, &ctx); + let mut page = edit_text_form(&form, None, controller, &ctx, parts); page.body .push_str(&(get_renderer(&ctx.path).unwrap()(&new_text))); |