gourami

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

commit d909e02a622208408365608fb8c1cc229f1b92f1
parent bbb531dbd354d0b8099c1093ce5eac2bcf6b13b3
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Sun, 19 Apr 2020 15:21:26 -0500

Cleanup and restructuring

Diffstat:
Mmigrations/2020-04-13-014917_initialize/up.sql | 7++++---
Msession.rs | 2+-
Msrc/db/schema.rs | 5++++-
Msrc/db/status.rs | 2++
Msrc/db/user.rs | 6------
Msrc/lib.rs | 18++++++++++++++++--
Msrc/session.rs | 2+-
Mtemplates/note.html | 2+-
Mtemplates/noteslist.html | 12+-----------
Atemplates/single_note.html | 14++++++++++++++
Mtemplates/user.html | 18++++++++++++++++--
11 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/migrations/2020-04-13-014917_initialize/up.sql b/migrations/2020-04-13-014917_initialize/up.sql @@ -3,10 +3,10 @@ CREATE TABLE users ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, username VARCHAR(255), - password VARCHAR(255), email VARCHAR(255), bio VARCHAR(1023) default "New here!", - created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP + created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP , + password VARCHAR(255) ); CREATE UNIQUE INDEX users_username_idx ON users (username); @@ -28,7 +28,8 @@ CREATE TABLE sessions ( CREATE TABLE notes ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - creator_id INTEGER, + creator_id INTEGER REFERENCES users(id), + creator_username VARCHAR(255), -- TODO: better solution here. maybe a view parent_id INTEGER, content TEXT, created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP diff --git a/session.rs b/session.rs @@ -48,7 +48,7 @@ impl Session { .and_then(|sessionkey| { u::users .inner_join(s::sessions) - .select((s::id, (u::id, u::username, u::realname))) + .select((s::id, u::username, u::realname))) .filter(s::cookie.eq(&sessionkey)) .first::<(i32, User)>(conn) .ok() diff --git a/src/db/schema.rs b/src/db/schema.rs @@ -2,6 +2,7 @@ table! { notes (id) { id -> Integer, creator_id -> Integer, + creator_username -> Varchar, parent_id -> Nullable<Integer>, content -> Text, created_time -> Timestamp, @@ -12,10 +13,10 @@ table! { users (id) { id -> Integer, username -> Varchar, - password -> Varchar, email -> Varchar, bio -> Text, created_time -> Timestamp, + password -> Varchar, } } @@ -29,5 +30,7 @@ table! { } joinable!(sessions -> users (user_id)); +joinable!(notes -> users (creator_id)); allow_tables_to_appear_in_same_query!(sessions, users); +allow_tables_to_appear_in_same_query!(notes, users); diff --git a/src/db/status.rs b/src/db/status.rs @@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize}; pub struct Note { pub id: i32, pub creator_id: i32, + pub creator_username: String, pub parent_id: Option<i32>, pub content: String, pub created_time: String, @@ -22,6 +23,7 @@ pub struct Note { pub struct NoteInput { //pub id: i32, //unsigned? pub creator_id: i32, + pub creator_username: String, pub parent_id: Option<i32>, pub content: String, // can we make this a slice? // pub published: chrono::NaiveDateTime, diff --git a/src/db/user.rs b/src/db/user.rs @@ -54,9 +54,3 @@ pub struct NewUser<'a> { pub password: &'a str, pub email: &'a str, } - -// impl<'a> NewUser<'a> { -// fn validate_and_insert() -> Result<Ok(()), Err> { -// } -// -// } diff --git a/src/lib.rs b/src/lib.rs @@ -4,7 +4,6 @@ extern crate diesel; #[macro_use] extern crate log; #[macro_use] extern crate lazy_static; -use std::convert::Infallible; use warp::{Reply, Filter, Rejection}; use warp::http; @@ -22,7 +21,6 @@ use diesel::sqlite::SqliteConnection; use diesel::insert_into; use serde::{Deserialize, Serialize}; use session::{Session}; -use std::sync::{Arc, Mutex}; use diesel::r2d2::{ConnectionManager, Pool, PooledConnection}; type SqlitePool = Pool<ConnectionManager<SqliteConnection>>; @@ -117,6 +115,7 @@ fn new_note(session: Option<Session>, req: NewNoteRequest) -> impl Reply { if let Some(s) = session { let new_note = NoteInput{ creator_id: s.user.id, + creator_username: s.user.username, parent_id: None, content: req.note_input.clone(), // how to avoid clone here? }; @@ -225,11 +224,22 @@ fn do_login(form: LoginForm) -> impl Reply { } } +fn do_logout(session: Option<Session>) -> impl Reply { + use db::schema::sessions::dsl::*; + if let Some(s) = session { + diesel::delete(sessions.filter(id.eq(s.id))).execute(&POOL.get().unwrap()).unwrap(); + } + warp::redirect::redirect(warp::http::Uri::from_static("/")) +} + fn render_timeline(session: Option<Session>) -> impl Reply { // no session -- anonymous let global = Global::from_session(session); use db::schema::notes::dsl::*; + // pulls a bunch of data i dont really need let results = notes + .order(id.desc()) + .limit(250) .load::<Note>(&POOL.get().unwrap()) .expect("Error loading posts"); render_template(&TimelineTemplate{ @@ -358,6 +368,10 @@ pub async fn run_server() { .and(form()) .map(do_login); + let do_login = path("logout") + .and(session_filter()) + .map(do_logout); + // CRUD actions let create_note = path("create_note") .and(session_filter()) diff --git a/src/session.rs b/src/session.rs @@ -51,7 +51,7 @@ impl Session { use db::schema::users::dsl as u; let result = u::users .inner_join(s::sessions) - .select((s::id, (u::id, u::username, u::email, u::created_time, u::bio, u::password))) // TODO figure out how to not select pw + .select((s::id, (u::id, u::username, u::email, u::bio, u::created_time, u::password))) // TODO figure out how to not select pw .filter(s::cookie.eq(sessionkey)) .first::<(i32, User)>(&POOL.get().unwrap()) .ok(); diff --git a/templates/note.html b/templates/note.html @@ -2,6 +2,6 @@ {% block content %} <div class="container"> - {{ note.id }} + {% include "single_note.html" %} </div> {% endblock %} diff --git a/templates/noteslist.html b/templates/noteslist.html @@ -1,13 +1,3 @@ {% for note in notes %} -<div class="row"> - <div class="note"> - <a href="/note/{{note.id}}">>{{note.id}}</a> {{note.created_time}} <a href="user/{{note.creator_id}}">@{{note.creator_id}}</a> | {{note.content}} - <form method="post" action="/{{note.id}}/delete" class="inline"> - <input type="hidden" name="extra_submit_param" value="extra_submit_value"> - <button type="submit" name="submit_param" value="submit_value" class="link-button"> - x - </button> - </form> - </div> -</div> + {% include "single_note.html" %} {% endfor %} diff --git a/templates/single_note.html b/templates/single_note.html @@ -0,0 +1,14 @@ +<div class="row"> +<div class="note"> + <a href="/note/{{note.id}}">>{{note.id}}</a> {{note.created_time}} <a + href="/user/{{note.creator_username}}">@{{note.creator_username}}</a> | {{note.content}} + {% if note.creator_id == global.user.id %} + <form method="post" action="/{{note.id}}/delete" class="inline"> + <input type="hidden" name="extra_submit_param" value="extra_submit_value"> + <button type="submit" name="submit_param" value="submit_value" class="link-button"> + x + </button> + {%endif%} + </form> +</div> +</div> diff --git a/templates/user.html b/templates/user.html @@ -2,8 +2,22 @@ {% block content %} <div class="container"> - {{ user.username }} {{user.id}} -bio: {{user.bio}} + <div class="row"> + <div class="col md"> + <b>user:</b> {{ user.username }} (#{{user.id}}) + <br> + <b>bio:</b> {{user.bio}} + </div> + {% if global.user.id == user.id%} + <div class="col md text-right"> + edit + <br> + <form method="post" action="/logout" class="inline"> + <button type="submit" name="submit_param" value="submit_value" + class="link-button">logout</button</form> + </div> + {% endif %} + </div> {% include "noteslist.html" %} </div> {% endblock %}