summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Reeder <vpzomtrrfrt@gmail.com>2020-10-25 22:29:12 -0600
committerColin Reeder <vpzomtrrfrt@gmail.com>2020-10-25 22:29:12 -0600
commit4d341022d0546b121cef0da246e8b69eb79f76c7 (patch)
treeada1d8be9f44459e03011c754a747d052f46ac19
parent8c98e0d745412d488f9ae7d060c7248b55edf29c (diff)
Add UI for user suspension
-rw-r--r--res/lang/en.ftl6
-rw-r--r--src/resp_types.rs1
-rw-r--r--src/routes/mod.rs142
3 files changed, 149 insertions, 0 deletions
diff --git a/res/lang/en.ftl b/res/lang/en.ftl
index 52c6764..b1892e1 100644
--- a/res/lang/en.ftl
+++ b/res/lang/en.ftl
@@ -137,6 +137,12 @@ user_edit_submit = Save
user_edit_title = Edit Profile
user_id_prompt = User ID:
user_remote_note = This is a remote user, information on this page may be incomplete.
+user_suspend = Suspend
+user_suspend_title = Suspend User
+user_suspend_question = Suspend this user? They will not be allowed to log in unless unsuspended.
+user_suspend_undo = Unsuspend
+user_suspend_yes = Yes, suspend
+user_suspended_note = This user has been suspended.
username_prompt = Username:
view_at_source = View at Source
view_more_comments = View More Comments
diff --git a/src/resp_types.rs b/src/resp_types.rs
index 63bfcc2..0382cc9 100644
--- a/src/resp_types.rs
+++ b/src/resp_types.rs
@@ -146,6 +146,7 @@ pub struct RespUserInfo<'a> {
#[serde(flatten)]
pub base: RespMinimalAuthorInfo<'a>,
pub description: Cow<'a, str>,
+ pub suspended: Option<bool>,
pub your_note: Option<JustContentText<'a>>,
}
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index aab5813..67d3ad4 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -1349,6 +1349,7 @@ async fn page_user(
Some(render::rsx! {
<div class={"infoBox"}>
{lang.tr("user_remote_note", None)}
+ {" "}
<a href={remote_url.as_ref()}>{lang.tr("view_at_source", None)}{" ↗"}</a>
</div>
})
@@ -1357,6 +1358,42 @@ async fn page_user(
}
}
{
+ if base_data.is_site_admin() && user.as_ref().local {
+ Some(render::rsx! {
+ <>
+ {
+ if user.suspended == Some(true) {
+ Some(render::rsx! {
+ <div class={"infoBox"}>
+ {lang.tr("user_suspended_note", None)}
+ {" "}
+ <form method={"POST"} action={format!("/users/{}/suspend/undo", user_id)} class={"inline"}>
+ <button type={"submit"}>{lang.tr("user_suspend_undo", None)}</button>
+ </form>
+ </div>
+ })
+ } else {
+ None
+ }
+ }
+ {
+ if user.suspended == Some(false) {
+ Some(render::rsx! {
+ <div>
+ <a href={format!("/users/{}/suspend", user_id)}>{lang.tr("user_suspend", None)}</a>
+ </div>
+ })
+ } else {
+ None
+ }
+ }
+ </>
+ })
+ } else {
+ None
+ }
+ }
+ {
if let Some(your_note) = &user.your_note {
Some(render::rsx! {
<div>
@@ -1520,6 +1557,96 @@ async fn handler_user_edit_submit(
.body("Successfully created.".into())?)
}
+async fn page_user_suspend(
+ params: (i64,),
+ ctx: Arc<crate::RouteContext>,
+ req: hyper::Request<hyper::Body>,
+) -> Result<hyper::Response<hyper::Body>, crate::Error> {
+ let (user_id,) = params;
+
+ let lang = crate::get_lang_for_req(&req);
+ let cookies = get_cookie_map_for_req(&req)?;
+
+ let base_data =
+ fetch_base_data(&ctx.backend_host, &ctx.http_client, req.headers(), &cookies).await?;
+
+ let title = lang.tr("user_suspend_title", None);
+
+ Ok(html_response(render::html! {
+ <HTPage base_data={&base_data} lang={&lang} title={&title}>
+ <h1>{title.as_ref()}</h1>
+ <p>
+ {lang.tr("user_suspend_question", None)}
+ </p>
+ <form method={"POST"} action={format!("/users/{}/suspend/submit", user_id)}>
+ <a href={format!("/users/{}", user_id)}>{lang.tr("no_cancel", None)}</a>
+ {" "}
+ <button type={"submit"}>{lang.tr("user_suspend_yes", None)}</button>
+ </form>
+ </HTPage>
+ }))
+}
+
+async fn handler_user_suspend_submit(
+ params: (i64,),
+ ctx: Arc<crate::RouteContext>,
+ req: hyper::Request<hyper::Body>,
+) -> Result<hyper::Response<hyper::Body>, crate::Error> {
+ let (user_id,) = params;
+
+ let cookies = get_cookie_map_for_req(&req)?;
+
+ res_to_error(
+ ctx.http_client
+ .request(for_client(
+ hyper::Request::patch(format!(
+ "{}/api/unstable/users/{}",
+ ctx.backend_host, user_id
+ ))
+ .body(r#"{"suspended":true}"#.into())?,
+ req.headers(),
+ &cookies,
+ )?)
+ .await?,
+ )
+ .await?;
+
+ Ok(hyper::Response::builder()
+ .status(hyper::StatusCode::SEE_OTHER)
+ .header(hyper::header::LOCATION, format!("/users/{}", user_id))
+ .body("Successfully suspended.".into())?)
+}
+
+async fn handler_user_suspend_undo(
+ params: (i64,),
+ ctx: Arc<crate::RouteContext>,
+ req: hyper::Request<hyper::Body>,
+) -> Result<hyper::Response<hyper::Body>, crate::Error> {
+ let (user_id,) = params;
+
+ let cookies = get_cookie_map_for_req(&req)?;
+
+ res_to_error(
+ ctx.http_client
+ .request(for_client(
+ hyper::Request::patch(format!(
+ "{}/api/unstable/users/{}",
+ ctx.backend_host, user_id
+ ))
+ .body(r#"{"suspended":false}"#.into())?,
+ req.headers(),
+ &cookies,
+ )?)
+ .await?,
+ )
+ .await?;
+
+ Ok(hyper::Response::builder()
+ .status(hyper::StatusCode::SEE_OTHER)
+ .header(hyper::header::LOCATION, format!("/users/{}", user_id))
+ .body("Successfully unsuspended.".into())?)
+}
+
async fn page_user_your_note_edit(
params: (i64,),
ctx: Arc<crate::RouteContext>,
@@ -1821,6 +1948,21 @@ pub fn route_root() -> crate::RouteNode<()> {
),
)
.with_child(
+ "suspend",
+ crate::RouteNode::new()
+ .with_handler_async("GET", page_user_suspend)
+ .with_child(
+ "submit",
+ crate::RouteNode::new()
+ .with_handler_async("POST", handler_user_suspend_submit),
+ )
+ .with_child(
+ "undo",
+ crate::RouteNode::new()
+ .with_handler_async("POST", handler_user_suspend_undo),
+ ),
+ )
+ .with_child(
"your_note/edit",
crate::RouteNode::new()
.with_handler_async("GET", page_user_your_note_edit)