gourami

[UNMAINTAINED] Activitypub server in Rust
Log | Files | Refs | README | LICENSE

commit 91b2dd2a724e387a5d21d1b65099cde64083f625
parent f7eb3c364f9b2d2d039fbbdeb5726f78859e1321
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Sun, 26 Apr 2020 13:04:31 -0500

Add edit user

Diffstat:
Mmigrations/2020-04-13-014917_initialize/up.sql | 3++-
Msrc/db/schema.rs | 1+
Msrc/db/user.rs | 1+
Msrc/lib.rs | 40++++++++++++++++++++++++++++++++++++++++
Msrc/routes.rs | 16+++++++++++++---
Mtemplates/base.html | 2+-
Atemplates/edit_user.html | 12++++++++++++
Mtemplates/user.html | 2++
8 files changed, 72 insertions(+), 5 deletions(-)

diff --git a/migrations/2020-04-13-014917_initialize/up.sql b/migrations/2020-04-13-014917_initialize/up.sql @@ -6,7 +6,8 @@ CREATE TABLE users ( email VARCHAR(255), bio VARCHAR(1023) default "New here!", created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP , - password VARCHAR(255) + password VARCHAR(255), + admin BOOLEAN default false ); CREATE UNIQUE INDEX users_username_idx ON users (username); diff --git a/src/db/schema.rs b/src/db/schema.rs @@ -22,6 +22,7 @@ table! { bio -> Text, created_time -> Timestamp, password -> Varchar, + admin -> Bool, } } diff --git a/src/db/user.rs b/src/db/user.rs @@ -40,6 +40,7 @@ pub struct User { pub bio: String, pub created_time: String, pub password: String, // is this OK? hashed + pub admin: bool, } // TODO -- default "anonymous" user diff --git a/src/lib.rs b/src/lib.rs @@ -490,6 +490,46 @@ fn user_page(auth_user: Option<User>, user_name: String, params: GetPostsParams, } +#[derive(Template)] +#[template(path = "edit_user.html")] +struct UserEditTemplate<'a> { + global: Global<'a>, + user: User, +} + +fn render_user_edit_page(user: Option<User>, user_name: String) -> impl Reply { + let u = user.clone().unwrap(); + let global = Global::create(user, "/edit"); + if u.username == user_name || u.admin { + render_template(&UserEditTemplate{global: global, user: u}) + } + else { + render_template(&ErrorTemplate{global: global, error_message: "You don't have permission to edit this page", ..Default::default()}) + } +} + + +#[derive(Deserialize)] +struct EditForm { + redirect_url: String, + bio: Option<String>, +} + +fn edit_user(user: Option<User>, user_name: String, f: EditForm) -> impl Reply { + let u = user.clone().unwrap(); + let conn = &POOL.get().unwrap(); + if u.username == user_name || u.admin { + use db::schema::users::dsl::*; + diesel::update( + users + .find(u.id)) + .set(bio.eq(&f.bio.unwrap_or(String::new()))) + .execute(conn).unwrap(); + } + let red: http::Uri = f.redirect_url.parse().unwrap(); + redirect(red) +} + async fn handle_rejection(err: Rejection) -> Result<impl Reply, Infallible> { Ok(render_template(&ErrorTemplate{global: Global::create(None, "error"), error_message: "You do not have access to this page, it does not exist, or something went wrong."})) } diff --git a/src/routes.rs b/src/routes.rs @@ -8,7 +8,8 @@ pub async fn run_server() { // NOT TESTED YET let public = false; // std::env::var("PUBLIC").unwrap_or("false"); let session_filter = move || session::create_session_filter(public).clone(); - + let private_session_filter = move || session::create_session_filter(false).clone(); + // TODO - -create a filter that gives only certain users access to pages // we have to pass the full paths for redirect to work without javascript let home = warp::path::end() @@ -23,6 +24,15 @@ pub async fn run_server() { .and(path::full()) .map(user_page); + let user_edit_page = private_session_filter() + .and(path!("user" / String / "edit" )) + .map(render_user_edit_page); + + let edit_user = private_session_filter() + .and(path!("user" / String / "edit")) + .and(form()) + .map(edit_user); + let note_page = session_filter() .and(path!("note" / i32)) .and(path::full()) @@ -114,8 +124,8 @@ pub async fn run_server() { // TODO secure against xss // used for api based authentication // let api_filter = session::create_session_filter(&POOL.get()); - let html_renders = home.or(login_page).or(register_page).or(user_page).or(note_page).or(server_info_page).or(notification_page); - let forms = do_register.or(do_login).or(do_logout).or(create_note).or(delete_note); + let html_renders = home.or(login_page).or(register_page).or(user_page).or(note_page).or(server_info_page).or(notification_page).or(user_edit_page); + let forms = do_register.or(do_login).or(do_logout).or(create_note).or(delete_note).or(edit_user); // let api // catch all for any other paths diff --git a/templates/base.html b/templates/base.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html lang="en"> <head> - <link rel="stylesheet" type="text/css" href="../static/css/style.css"> + <link rel="stylesheet" type="text/css" href="/static/css/style.css"> <meta charset="utf-8"/> <title>🐟{{global.title}}</title> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"/> diff --git a/templates/edit_user.html b/templates/edit_user.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% block content %} +<form method="POST" action="/user/{{user.username}}/edit"> +<b>user:</b> {{ user.username }} (#{{user.id}}) +<br> +<label for="bio"><b>bio:<b></label> +<input type="text" id="bio" name="bio"> +<input type="hidden" name="redirect_url" value="/user/{{user.username}}"> +<br> +<button id="post" class="submit-button-style">submit</button> +</form> +{% endblock %} diff --git a/templates/user.html b/templates/user.html @@ -7,6 +7,8 @@ <br> <b>bio:</b> {{user.bio}} {% if global.me.id == user.id%} + <br> + <a href="/user/{{user.username}}/edit">edit</a> <div> <form method="post" action="/logout" class="inline"> <button type="submit" name="submit_param" value="submit_value"