feat(handlers/render): Display edit form for user's own posts
Displays an edit form for posts that are owned by a user (which is currently defined as "email addresses match").
This commit is contained in:
parent
7a55786552
commit
705097dab9
5 changed files with 63 additions and 2 deletions
|
@ -54,6 +54,9 @@ pub enum ConverseError {
|
|||
#[fail(display = "error occured running timer: {}", error)]
|
||||
Timer { error: tokio_timer::Error },
|
||||
|
||||
#[fail(display = "user does not have permission to edit post {}", id)]
|
||||
PostEditForbidden { id: i32 },
|
||||
|
||||
// This variant is used as a catch-all for wrapping
|
||||
// actix-web-compatible response errors, such as the errors it
|
||||
// throws itself.
|
||||
|
|
|
@ -189,6 +189,41 @@ pub fn reply_thread(state: State<AppState>,
|
|||
.responder()
|
||||
}
|
||||
|
||||
/// This handler presents the user with the form to edit a post. If
|
||||
/// the user attempts to edit a post that they do not have access to,
|
||||
/// they are currently ungracefully redirected back to the post
|
||||
/// itself.
|
||||
pub fn edit_form(state: State<AppState>,
|
||||
mut req: HttpRequest<AppState>,
|
||||
query: Path<GetPost>) -> ConverseResponse {
|
||||
let author: Option<Author> = req.session().get(AUTHOR)
|
||||
.unwrap_or_else(|_| None);
|
||||
|
||||
state.db.send(query.into_inner())
|
||||
.flatten()
|
||||
.from_err()
|
||||
.and_then(move |post| {
|
||||
if let Some(author) = author {
|
||||
if author.email.eq(&post.author_email) {
|
||||
return Ok(post);
|
||||
}
|
||||
}
|
||||
|
||||
Err(ConverseError::PostEditForbidden { id: post.id })
|
||||
})
|
||||
.and_then(move |post| {
|
||||
let edit_msg = EditPostPage {
|
||||
id: post.id,
|
||||
post: post.body,
|
||||
};
|
||||
|
||||
state.renderer.send(edit_msg).from_err()
|
||||
})
|
||||
.flatten()
|
||||
.map(|page| HttpResponse::Ok().content_type(HTML).body(page))
|
||||
.responder()
|
||||
}
|
||||
|
||||
/// This handler executes a full-text search on the forum database and
|
||||
/// displays the results to the user.
|
||||
pub fn search_forum(state: State<AppState>,
|
||||
|
|
|
@ -181,6 +181,7 @@ fn start_http_server(base_url: String,
|
|||
.resource("/thread/submit", |r| r.method(Method::POST).with3(submit_thread))
|
||||
.resource("/thread/reply", |r| r.method(Method::POST).with3(reply_thread))
|
||||
.resource("/thread/{id}", |r| r.method(Method::GET).with3(forum_thread))
|
||||
.resource("/post/{id}/edit", |r| r.method(Method::GET).with3(edit_form))
|
||||
.resource("/search", |r| r.method(Method::GET).with2(search_forum))
|
||||
.resource("/oidc/login", |r| r.method(Method::GET).with(login))
|
||||
.resource("/oidc/callback", |r| r.method(Method::POST).with3(callback));
|
||||
|
|
|
@ -200,7 +200,7 @@ impl Handler<NewThreadPage> for Renderer {
|
|||
type Result = Result<String>;
|
||||
|
||||
fn handle(&mut self, msg: NewThreadPage, _: &mut Self::Context) -> Self::Result {
|
||||
let ctx: FormContext = FormContext {
|
||||
let ctx = FormContext {
|
||||
alerts: msg.alerts,
|
||||
title: msg.title,
|
||||
post: msg.post,
|
||||
|
@ -210,6 +210,28 @@ impl Handler<NewThreadPage> for Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Message used to render post editing page.
|
||||
pub struct EditPostPage {
|
||||
pub id: i32,
|
||||
pub post: String,
|
||||
}
|
||||
message!(EditPostPage, Result<String>);
|
||||
|
||||
impl Handler<EditPostPage> for Renderer {
|
||||
type Result = Result<String>;
|
||||
|
||||
fn handle(&mut self, msg: EditPostPage, _: &mut Self::Context) -> Self::Result {
|
||||
let ctx = FormContext {
|
||||
mode: EditingMode::EditPost,
|
||||
id: Some(msg.id),
|
||||
post: Some(msg.post),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(self.tera.render("post.html", &ctx)?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Message used to render search results
|
||||
#[derive(Serialize)]
|
||||
pub struct SearchResultPage {
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
<div class="d-inline-flex flex-row mt-auto ml-auto">
|
||||
{%- if post.editable %}
|
||||
<a href="#edit" class="badge badge-light border m-1 p-1">Edit</a>
|
||||
<a href="/post/{{ post.id }}/edit" class="badge badge-light border m-1 p-1">Edit</a>
|
||||
{% endif -%}
|
||||
<a href="#quote" class="badge badge-light border m-1 p-1">Quote</a>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue