~vpzom/hitide

4d341022d0546b121cef0da246e8b69eb79f76c7 — Colin Reeder 6 months ago 8c98e0d
Add UI for user suspension
3 files changed, 149 insertions(+), 0 deletions(-)

M res/lang/en.ftl
M src/resp_types.rs
M src/routes/mod.rs
M res/lang/en.ftl => res/lang/en.ftl +6 -0
@@ 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

M src/resp_types.rs => src/resp_types.rs +1 -0
@@ 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>>,
}


M src/routes/mod.rs => src/routes/mod.rs +142 -0
@@ 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)