gourami

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

commit 53f66c92568a673028008fe5140434ef01767e98
parent cf46771156c1562888ed83acad2c15b3acd68173
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Fri,  8 May 2020 16:04:42 -0500

Number of small changes

Allow users to share their email
Edit server message
Add user list to server message page

Diffstat:
Mdocs/ADMIN_GUIDE.md | 5+++++
Amigrations/2020-05-08-203656_showemail/down.sql | 2++
Amigrations/2020-05-08-203656_showemail/up.sql | 3+++
Msrc/db/schema.rs | 1+
Msrc/db/user.rs | 1+
Msrc/lib.rs | 18+++++++++++++++---
Mtemplates/base.html | 2+-
Mtemplates/edit_user.html | 21+++++++++++++++++++--
Mtemplates/server_info.html | 22++++++++++++++--------
Mtemplates/user.html | 8++++++++
10 files changed, 69 insertions(+), 14 deletions(-)

diff --git a/docs/ADMIN_GUIDE.md b/docs/ADMIN_GUIDE.md @@ -17,6 +17,11 @@ Gourami is built for small deployments -- I have not tested it or designed it fo I'm not big into formal rules or codes of context, but if you feel like that's important for your server, you may want to put it in your server message. +## Customizing Gourami + +You may want to customize parts of Gourami, such as the CSS format or server message. Right now, html templates are compiled into the binary. In retrospect, it might have been a better idea to use a templating engine that is rendered at runtime. If you want to customize the html, you'll have to edit the file and recompile. I may move towards a different templating library at some point. + + ## Securing your server I would recommend following basic Linux syadmin best practices: disable password login, consider a hardened Linux distro, set up a firewall, etc. I'm not a security expert here, I would recommend following guides produced by those who are. diff --git a/migrations/2020-05-08-203656_showemail/down.sql b/migrations/2020-05-08-203656_showemail/down.sql @@ -0,0 +1 @@ +-- This file should undo anything in `up.sql` +\ No newline at end of file diff --git a/migrations/2020-05-08-203656_showemail/up.sql b/migrations/2020-05-08-203656_showemail/up.sql @@ -0,0 +1,3 @@ +-- Your SQL goes here + +alter table users add show_email boolean default false; diff --git a/src/db/schema.rs b/src/db/schema.rs @@ -28,6 +28,7 @@ table! { created_time -> Timestamp, password -> Nullable<Varchar>, admin -> Bool, + show_email -> Bool, remote_url -> Nullable<Varchar>, } } diff --git a/src/db/user.rs b/src/db/user.rs @@ -49,6 +49,7 @@ pub struct User { pub created_time: String, pub password: Option<String>, pub admin: bool, + pub show_email: bool, pub remote_url: Option<String>, } diff --git a/src/lib.rs b/src/lib.rs @@ -107,6 +107,7 @@ struct RegisterTemplate<'a> { #[template(path = "server_info.html")] struct ServerInfoTemplate<'a> { global: Global<'a>, + users: Vec<User>, } const PAGE_SIZE: i64 = 50; @@ -197,7 +198,7 @@ fn delete_note(note_id: i32) -> Result<(), Box<dyn std::error::Error>> { struct NewNoteRequest { note_input: String, // has to be String redirect_url: String, - neighborhood: Option<String>, // "on" + neighborhood: Option<String>, // "on" TODO -- add a custom serialization here } async fn handle_new_note_form(u: Option<User>, f: NewNoteRequest) -> Result<impl Reply, Rejection> { @@ -478,6 +479,13 @@ fn get_single_note(note_id: i32) -> Option<Vec<UserNote>> { ) } +fn get_users() -> Result<Vec<User>, diesel::result::Error> { + use db::schema::users::dsl as u; + let conn = &POOL.get().unwrap(); + let users = u::users.load(conn); + users +} + /// We have to do a join here fn get_notes( params: GetPostsParams, @@ -609,8 +617,10 @@ impl<'a> Default for ErrorTemplate<'a> { } fn server_info_page(auth_user: Option<User>) -> impl Reply { + let users = get_users().unwrap(); render_template(&ServerInfoTemplate { global: Global::create(auth_user, "/server"), + users: users }) } @@ -702,7 +712,9 @@ pub fn post_inbox(message: Value) -> impl Reply { #[derive(Deserialize)] struct EditForm { redirect_url: String, - bio: Option<String>, + bio: String, + show_email: Option<String>, + email: String, } fn edit_user(user: Option<User>, user_name: String, f: EditForm) -> impl Reply { @@ -711,7 +723,7 @@ fn edit_user(user: Option<User>, user_name: String, f: EditForm) -> impl Reply { 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()))) + .set((bio.eq(&f.bio), email.eq(&f.email), show_email.eq(&f.show_email.is_some()))) .execute(conn) .unwrap(); } diff --git a/templates/base.html b/templates/base.html @@ -27,7 +27,7 @@ {% block content %} {% endblock %} </div> <div class="padded footer"> - Built with <a href="https://git.sr.ht/~alexwennerberg/gourami-social">gourami</a> + Built with <a href="https://github.com/alexwennerberg/gourami">gourami</a> </div> </div> </body> diff --git a/templates/edit_user.html b/templates/edit_user.html @@ -3,8 +3,25 @@ <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"> +<label for="bio"><b>bio:</b></label> +<input type="text" id="bio" name="bio" value="{{user.bio}}"> +<br> +<label for="email"><b>email:</b></label> +<input type="text" id="email" name="email" value= +{% match user.email %} + {%when Some with (e) %} + "{{e}}"> + {% when None %} + ""> +{%endmatch%} +<br> +<label for="show_email"><b>show_email?</b></label> +<input type="checkbox" id="show_email" name="show_email" +{% if user.show_email %} +checked> +{% else %} +unchecked> +{% endif %} <input type="hidden" name="redirect_url" value="/user/{{user.username}}"> <br> <button id="post" class="submit-button-style">submit</button> diff --git a/templates/server_info.html b/templates/server_info.html @@ -1,13 +1,19 @@ {% extends "base.html" %} - {% block content %} <div class="text-block padded"> - Welcome to the alpha instance of Gourami! Expect many changes in the future. Right now, all notes are on a shared timeline visible to all users on this instance. I welcome feedback and feature requests. Please let me know if you encounter any bugs! - <br> - Check out <a href="https://github.com/alexwennerberg/gourami/blob/master/PHILOSOPHY.md">this document</a> where I discuss some of the design principles and goals of Gourami. - <br> - This instance is invite-only. Contact me to get an invite URL if you want to invite someone. Posts are not visible except to users on this instance, unless they are shared with the "neighborhood", the network of users and other servers networked with this server. Here is a list of those servers: (TBD) - <br> - Contact email: <a href="mailto:alex@alexwennerberg.com">alex@alexwennerberg.com</a> or <a href="/user/alex">message me</a> on Gourami. + Welcome to Gourami, an intentionally small, private, minimalist, invite-only social network. See the <a href="https://github.com/alexwennerberg/gourami/blob/master/docs/USER_GUIDE.md">user guide</a> for more info or look at the <a href="https://github.com/alexwennerberg/gourami">project page</a>! Here is a list of users on this server -- maybe introduce yourself to someone you don't know! By default your email is not shared, but you can share it to other users on this instance on your edit user page. +<br> +<table> +<tr> + <th>username</th> + <th>bio</th> +</tr> +{% for user in users %} +<tr> + <td><a href="/user/{{user.username}}">{{user.username}}</a> {%if user.admin %}<em>admin</em>{%endif%}</td> + <td>{{user.bio}}</td> +</tr> +{% endfor %} </div> +</table> {% endblock %} diff --git a/templates/user.html b/templates/user.html @@ -6,6 +6,14 @@ <b>user:</b> {{ user.username }} (#{{user.id}}) <br> <b>bio:</b> {{user.bio}} + {% match user.email %} + {%when Some with (e) %} + {%if user.show_email%} + <br> + <b>email:</b> <a href="mailto:{{e}}">{{e}}</a> + {%endif %} + {% when None %} + {%endmatch%} {% if global.me.id == user.id%} <br> <a href="/user/{{user.username}}/edit">edit</a>