aboutsummaryrefslogtreecommitdiff
path: root/src/post_routes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/post_routes.rs')
-rw-r--r--src/post_routes.rs91
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)));