implement-websockets
~erin 2021-07-26 14:09:10 -04:00
parent b3fa390c72
commit 92f4eb8ec1
Signed by: erin
GPG Key ID: DA70E064A8C70F44
6 changed files with 452 additions and 104 deletions

334
Cargo.lock generated
View File

@ -128,6 +128,12 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
name = "cfg-if"
version = "0.1.10"
@ -320,6 +326,22 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "form_urlencoded"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
dependencies = [
"matches",
"percent-encoding 2.1.0",
]
[[package]]
name = "fs2"
version = "0.4.3"
@ -365,6 +387,55 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "futures-core"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
[[package]]
name = "futures-macro"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57"
dependencies = [
"autocfg",
"proc-macro-hack",
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.74",
]
[[package]]
name = "futures-sink"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53"
[[package]]
name = "futures-task"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2"
[[package]]
name = "futures-util"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
dependencies = [
"autocfg",
"futures-core",
"futures-macro",
"futures-sink",
"futures-task",
"pin-project-lite",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab",
]
[[package]]
name = "fxhash"
version = "0.2.1"
@ -446,6 +517,17 @@ dependencies = [
"digest",
]
[[package]]
name = "http"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "httparse"
version = "1.4.1"
@ -474,7 +556,7 @@ dependencies = [
"traitobject",
"typeable",
"unicase",
"url",
"url 1.7.2",
]
[[package]]
@ -488,6 +570,17 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "idna"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "indexmap"
version = "1.7.0"
@ -576,6 +669,28 @@ version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "lila-chat"
version = "0.6.0"
dependencies = [
"bincode",
"chrono",
"env_logger",
"futures-util",
"log 0.4.14",
"once_cell",
"random-string",
"rocket",
"rocket_contrib",
"serde",
"serde_json",
"sha1",
"sled",
"tokio",
"tokio-tungstenite",
"uuid",
]
[[package]]
name = "lock_api"
version = "0.4.4"
@ -646,12 +761,25 @@ dependencies = [
"kernel32-sys",
"libc",
"log 0.4.14",
"miow",
"miow 0.2.2",
"net2",
"slab",
"winapi 0.2.8",
]
[[package]]
name = "mio"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
dependencies = [
"libc",
"log 0.4.14",
"miow 0.3.7",
"ntapi",
"winapi 0.3.9",
]
[[package]]
name = "mio-extras"
version = "2.0.6"
@ -660,7 +788,7 @@ checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
dependencies = [
"lazycell",
"log 0.4.14",
"mio",
"mio 0.6.23",
"slab",
]
@ -676,6 +804,15 @@ dependencies = [
"ws2_32-sys",
]
[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "net2"
version = "0.2.37"
@ -699,12 +836,21 @@ dependencies = [
"fsevent-sys",
"inotify",
"libc",
"mio",
"mio 0.6.23",
"mio-extras",
"walkdir",
"winapi 0.3.9",
]
[[package]]
name = "ntapi"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "num-integer"
version = "0.1.44"
@ -806,24 +952,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pogchat"
version = "0.6.0"
name = "pin-project"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
dependencies = [
"bincode",
"chrono",
"env_logger",
"log 0.4.14",
"once_cell",
"random-string",
"rocket",
"rocket_contrib",
"serde",
"serde_json",
"sha1",
"sled",
"uuid",
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
dependencies = [
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.74",
]
[[package]]
name = "pin-project-lite"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "polyval"
version = "0.4.5"
@ -841,6 +1000,18 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]]
name = "proc-macro2"
version = "0.4.30"
@ -1076,6 +1247,19 @@ dependencies = [
"serde",
]
[[package]]
name = "sha-1"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81"
dependencies = [
"block-buffer",
"cfg-if 1.0.0",
"cpufeatures",
"digest",
"opaque-debug",
]
[[package]]
name = "sha1"
version = "0.6.0"
@ -1095,6 +1279,15 @@ dependencies = [
"opaque-debug",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
"libc",
]
[[package]]
name = "slab"
version = "0.4.3"
@ -1166,6 +1359,26 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
dependencies = [
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.74",
]
[[package]]
name = "time"
version = "0.1.43"
@ -1191,6 +1404,50 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio 0.7.13",
"num_cpus",
"once_cell",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2 1.0.27",
"quote 1.0.9",
"syn 1.0.74",
]
[[package]]
name = "tokio-tungstenite"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8"
dependencies = [
"futures-util",
"log 0.4.14",
"pin-project",
"tokio",
"tungstenite",
]
[[package]]
name = "toml"
version = "0.4.10"
@ -1206,6 +1463,25 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
[[package]]
name = "tungstenite"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5"
dependencies = [
"base64 0.13.0",
"byteorder",
"bytes",
"http",
"httparse",
"log 0.4.14",
"rand",
"sha-1",
"thiserror",
"url 2.2.2",
"utf-8",
]
[[package]]
name = "typeable"
version = "0.1.2"
@ -1273,11 +1549,29 @@ version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
dependencies = [
"idna",
"idna 0.1.5",
"matches",
"percent-encoding 1.0.1",
]
[[package]]
name = "url"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
"form_urlencoded",
"idna 0.2.3",
"matches",
"percent-encoding 2.1.0",
]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "uuid"
version = "0.8.2"

View File

@ -24,3 +24,6 @@ once_cell = "1.8.0"
random-string = "1.0"
sled = "0.34.6"
bincode = "1.3.3"
tokio = { version = "1.9.0", features = ["full"] }
futures-util = "0.3.16"
tokio-tungstenite = "0.15.0"

View File

@ -1,10 +1,10 @@
extern crate log;
use uuid::Uuid;
use crate::file_io::*;
use rocket::http::{Cookie, Cookies};
use crate::user::*;
use rocket_contrib::json::{Json, JsonValue};
use random_string::generate;
use rocket::http::{Cookie, Cookies};
use rocket_contrib::json::{Json, JsonValue};
use uuid::Uuid;
extern crate sha1;
// Post request to register a user and pin
@ -12,14 +12,17 @@ extern crate sha1;
pub fn register(data: Json<RegisterEvent>) -> JsonValue {
// check if the user exists
if let Some(_user) = db_read_user(&data.name.to_lowercase()).ok().flatten() {
warn!("Cannot create user {}! User is already in system.", data.name);
warn!(
"Cannot create user {}! User is already in system.",
data.name
);
return json!({
"status": "fail",
"reason": "user already exists",
});
} else {
let pin_hashed = sha1::Sha1::from(&data.pin).digest().to_string(); // hash the pin
let mut new_user: User = User {
name: data.name.to_string().to_lowercase(),
pin_hashed,
@ -29,20 +32,21 @@ pub fn register(data: Json<RegisterEvent>) -> JsonValue {
id: Uuid::new_v4(),
};
if new_user.name == "admin".to_string() { // if name is admin, make them an admin
if new_user.name == "admin".to_string() {
// if name is admin, make them an admin
new_user.role = UserType::Admin;
}
db_add(&new_user);
db_add(&new_user);
info!(
"succesfully created user {} with pin hash {}",
new_user.name.to_string(),
new_user.pin_hashed
);
return json!({
"status": "ok",
"reason": format!("user {} registered", new_user.name.to_string().to_lowercase()),
});
info!(
"succesfully created user {} with pin hash {}",
new_user.name.to_string(),
new_user.pin_hashed
);
return json!({
"status": "ok",
"reason": format!("user {} registered", new_user.name.to_string().to_lowercase()),
});
}
}
@ -69,7 +73,7 @@ pub fn check_token(name: String, mut cookies: Cookies) -> JsonValue {
"status": "fail",
"reason": "could not read cookie",
});
},
}
Some(token) => token,
};
@ -94,11 +98,11 @@ pub fn check_token(name: String, mut cookies: Cookies) -> JsonValue {
});
}
} else {
warn!("user {} not found", name);
return json!({
"status": "fail",
"reason": "user not found",
});
warn!("user {} not found", name);
return json!({
"status": "fail",
"reason": "user not found",
});
}
}
@ -113,7 +117,7 @@ pub fn logout(info: Json<LogoutEvent>, mut cookies: Cookies) -> JsonValue {
"status": "fail",
"reason": "could not read cookie",
});
},
}
Some(token) => token,
};
if token.value() == "NULL" {
@ -153,14 +157,13 @@ pub fn login(data: Json<LoginEvent>, mut cookies: Cookies) -> JsonValue {
if let Some(user) = db_read_user(&data.name.to_lowercase()).ok().flatten() {
let hashed_pin_input = sha1::Sha1::from(&data.pin.to_string()).digest().to_string();
if user.pin_hashed == hashed_pin_input { // check if pin hash matches
if user.pin_hashed == hashed_pin_input {
// check if pin hash matches
info!("pin correct for user {}", &user.name);
// Create token for user & set a cookie
let token = create_token(user);
let cookie = Cookie::build("token", token)
.path("/")
.finish();
let cookie = Cookie::build("token", token).path("/").finish();
cookies.remove_private(Cookie::named("token"));
cookies.add_private(cookie);
info!("set the token cookie");
@ -203,7 +206,7 @@ pub fn change_info(input: Json<ChangeEvent>, mut cookies: Cookies) -> JsonValue
"status": "fail",
"reason": "could not read cookie",
});
},
}
Some(token) => token,
};
if token.value() == "NULL" {
@ -216,7 +219,8 @@ pub fn change_info(input: Json<ChangeEvent>, mut cookies: Cookies) -> JsonValue
// find the user
if let Some(mut user) = db_read_user(&input.name.to_lowercase()).ok().flatten() {
if token.value() == user.session_token { // & if token matches:
if token.value() == user.session_token {
// & if token matches:
match input.changed_event {
ChangeEventType::Name => {
// remove the user first
@ -229,7 +233,7 @@ pub fn change_info(input: Json<ChangeEvent>, mut cookies: Cookies) -> JsonValue
"status": "ok",
"reason": format!("changed name of {} to {}", input.name, input.new_event),
});
},
}
ChangeEventType::Pin => {
// change the pin
let new_hashed_pin = sha1::Sha1::from(&input.new_event).digest().to_string();
@ -240,7 +244,7 @@ pub fn change_info(input: Json<ChangeEvent>, mut cookies: Cookies) -> JsonValue
"status": "ok",
"reason": "changed pin",
});
},
}
ChangeEventType::Pronouns => {
// change the pronouns
user.pronouns = input.new_event.clone();
@ -250,7 +254,7 @@ pub fn change_info(input: Json<ChangeEvent>, mut cookies: Cookies) -> JsonValue
"status": "ok",
"reason": "successfully changed pronouns",
});
},
}
};
} else {
warn!("incorrect pin for user {}", input.name);
@ -258,7 +262,7 @@ pub fn change_info(input: Json<ChangeEvent>, mut cookies: Cookies) -> JsonValue
"status": "fail",
"reason": "incorrect pin",
});
};
};
} else {
warn!("couldn't change users info, user does not exist");
return json!({
@ -290,7 +294,8 @@ pub fn get_user(name: String) -> JsonValue {
// Make a user into a moderator
fn premote(name: &str) -> JsonValue {
if let Some(mut user) = db_read_user(&name.to_lowercase()).ok().flatten() {
if user.role != UserType::Admin { // make sure mods can't demote admins ;3
if user.role != UserType::Admin {
// make sure mods can't demote admins ;3
user.role = UserType::Moderator;
db_remove(&user);
db_add(&user);
@ -318,7 +323,8 @@ fn premote(name: &str) -> JsonValue {
// Make a user into a normal user
fn demote(name: &str) -> JsonValue {
if let Some(mut user) = db_read_user(&name.to_lowercase()).ok().flatten() {
if user.role != UserType::Admin { // make sure mods can't demote admins ;3
if user.role != UserType::Admin {
// make sure mods can't demote admins ;3
user.role = UserType::Normal;
db_remove(&user);
db_add(&user);
@ -346,7 +352,8 @@ fn demote(name: &str) -> JsonValue {
// Kick a user (temporarilly log them out for a certain amount of time)
fn kick(name: &str) -> JsonValue {
if let Some(mut user) = db_read_user(&name.to_lowercase()).ok().flatten() {
if user.role != UserType::Admin { // make sure mods can't kick admins
if user.role != UserType::Admin {
// make sure mods can't kick admins
user.session_token = "NULL".to_string();
db_remove(&user);
db_add(&user);
@ -369,13 +376,13 @@ fn kick(name: &str) -> JsonValue {
"reason": "user not found",
});
}
}
// Ban a user (remove their account)
fn ban(name: &str) -> JsonValue {
if let Some(mut user) = db_read_user(&name.to_lowercase()).ok().flatten() {
if user.role != UserType::Admin { // make sure mods can't kick admins
if user.role != UserType::Admin {
// make sure mods can't kick admins
db_remove(&user);
info!("succesfully banned user {}", &user.name);
return json!({
@ -396,7 +403,6 @@ fn ban(name: &str) -> JsonValue {
"reason": "user not found",
});
}
}
/* User Management */
@ -409,19 +415,21 @@ pub fn moderation_actions(data: Json<ModerationAction>, mut cookies: Cookies) ->
"status": "fail",
"reason": "could not read cookie",
});
},
}
Some(token) => token,
};
if let Some(user) = db_read_user(&data.name.to_lowercase()).ok().flatten() {
if token.value() == "NULL" { // fail if token is NULL
if token.value() == "NULL" {
// fail if token is NULL
warn!("NULL token!");
return json!({
"status": "fail",
"reason": "NULL token",
});
} else if user.session_token == token.value() { // if token matches
} else if user.session_token == token.value() {
// if token matches
if user.role == UserType::Moderator || user.role == UserType::Admin {
match data.action {
match data.action {
ModActions::Kick => kick(&data.target),
ModActions::Ban => ban(&data.target),
ModActions::Demote => demote(&data.target),
@ -441,7 +449,7 @@ pub fn moderation_actions(data: Json<ModerationAction>, mut cookies: Cookies) ->
return json!({
"status": "fail",
"reason": "token does not match",
})
});
};
} else {
warn!("user not found");

View File

@ -1,14 +1,17 @@
/* Contains Rocket code for chat/message functionality */
extern crate log;
use once_cell::sync::Lazy;
use std::sync::Mutex;
use crate::file_io::db_read_user;
use rocket::http::{Cookie, Cookies};
use crate::message::{Message, MessageInput, MessageType};
use rocket_contrib::json::{Json, JsonValue};
use chrono::prelude::*;
use uuid::Uuid;
use crate::user::User;
use chrono::prelude::*;
use futures_util::StreamExt;
use once_cell::sync::Lazy;
use rocket::http::{Cookie, Cookies};
use rocket_contrib::json::{Json, JsonValue};
use std::sync::Mutex;
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::broadcast;
use uuid::Uuid;
static MESSAGES: Lazy<Mutex<Vec<Message>>> = Lazy::new(|| Mutex::new(Vec::new()));
@ -21,6 +24,15 @@ pub fn fetch_messages() -> Json<Vec<Message>> {
Json(messages)
}
async fn send_message_to_websocket() {
let (tx, mut rx1) = broadcast::channel(16);
let mut rx2 = tx.subscribe();
tokio::spawn(async move {
info!("message: {}", rx1.recv().await.unwrap());
});
tx.send(10).unwrap();
}
// Create full message object and write to file
fn create_message(message: Json<MessageInput>, user: &User) -> JsonValue {
let event_type = match message.body.chars().nth(0).unwrap() {
@ -28,7 +40,7 @@ fn create_message(message: Json<MessageInput>, user: &User) -> JsonValue {
':' => MessageType::Emote,
_ => MessageType::Normal,
};
if (message.body == "") | (message.body == " ") {
warn!("blank message given");
return json!({
@ -48,9 +60,13 @@ fn create_message(message: Json<MessageInput>, user: &User) -> JsonValue {
info!("created mesage: {:?}", message_obj);
info!("Date is: {}", message_obj.created_at.to_rfc2822());
std::thread::spawn(|| send_message_to_websocket());
/*
// append message to file
let mut messages = MESSAGES.lock().unwrap();
messages.push(message_obj.to_owned());
*/
return json!({
"status": "ok",
"reason": "message created",
@ -67,7 +83,8 @@ fn check_token(token: Cookie, message: Json<MessageInput<'_>>) -> JsonValue {
"status": "fail",
"reason": "NULL token",
});
} else if user.session_token == token.value() { // if token matches
} else if user.session_token == token.value() {
// if token matches
info!("user exists and given token matches");
return create_message(message, &user);
} else {
@ -75,7 +92,7 @@ fn check_token(token: Cookie, message: Json<MessageInput<'_>>) -> JsonValue {
return json!({
"status": "fail",
"reason": "token does not match",
})
});
};
};
warn!("user not found");
@ -95,25 +112,31 @@ pub fn send_message(message: Json<MessageInput<'_>>, mut cookies: Cookies) -> Js
"status": "fail",
"reason": "could not read cookie",
});
},
}
Some(token) => token,
};
check_token(token, message)
}
// Delete a message
/*
#[post("/message/delete", format = "json", data = "<message>")]
pub fn delete_message(message: Json<MessageInput<'_>>, mut cookies: Cookies) -> JsonValue {
let token = match cookies.get_private("token") {
None => {
warn!("couldn't get token cookie!");
return json!({
"status": "fail",
"reason": "could not read cookie",
});
},
Some(token) => token,
};
// Websocket Stuff //
pub async fn accept_connection(stream: TcpStream) {
let addr = stream
.peer_addr()
.expect("connected streams should have a peer address");
info!("Peer address: {}", addr);
let ws_stream = tokio_tungstenite::accept_async(stream)
.await
.expect("Error during the websocket handshake occurred");
info!("New WebSocket connection: {}", addr);
let (tx, mut rx1) = broadcast::channel::<usize>(16);
let mut rx2 = tx.subscribe();
loop {
let message = rx2.recv().await.unwrap();
info!("message recieved: {}", message);
}
}
*/

View File

@ -6,9 +6,11 @@ extern crate log;
extern crate rocket;
#[macro_use]
extern crate rocket_contrib;
use rocket_contrib::serve::StaticFiles;
use chat::accept_connection;
use rocket::fairing::AdHoc;
use rocket_contrib::serve::StaticFiles;
use std::io::Error;
use tokio::net::{TcpListener, TcpStream};
mod auth;
mod chat;
@ -16,14 +18,32 @@ mod file_io;
mod message;
mod user;
#[tokio::main]
async fn startup_websocket() -> Result<(), Error> {
let addr = "127.0.0.1:1312".to_string();
// Create the event loop and TCP listener we'll accept connections on.
let try_socket = TcpListener::bind(&addr).await;
let listener = try_socket.expect("Failed to bind");
info!("Listening on: {}", addr);
while let Ok((stream, _)) = listener.accept().await {
tokio::spawn(accept_connection(stream));
}
Ok(())
}
fn main() {
env_logger::init();
info!("Started up rocket");
// Start thread for tungstenite websockets
std::thread::spawn(|| startup_websocket());
let cors_fairing = AdHoc::on_response("CORS", |_, res| {
res.set_raw_header("Access-Control-Allow-Origin", "http://localhost:8000");
});
info!("Built CORS fairing");
info!("Started up rocket");
rocket::ignite()
.mount(
"/api",

View File

@ -13,11 +13,11 @@ pub enum UserType {
// Struct to store basic user data
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct User {
pub name: String, // unique username
pub pin_hashed: String, // sha1 hash of the pin
pub pronouns: String, // user's pronouns
pub name: String, // unique username
pub pin_hashed: String, // sha1 hash of the pin
pub pronouns: String, // user's pronouns
pub session_token: String, // generated session token
pub role: UserType, // type/role of user
pub role: UserType, // type/role of user
pub id: Uuid,
}
@ -25,18 +25,18 @@ pub struct User {
// enum of different moderator actions
#[derive(Deserialize, Debug)]
pub enum ModActions {
Kick, // Log the user out of their current session
Ban, // Remove the user
Demote, // Demote a user to a lower role
Kick, // Log the user out of their current session
Ban, // Remove the user
Demote, // Demote a user to a lower role
Premote, // Premote a user to a higher role
}
// struct to use for json input
#[derive(Deserialize, Debug)]
pub struct ModerationAction {
pub name: String, // name of the moderator
pub name: String, // name of the moderator
pub action: ModActions, // what action to take
pub target: String, // who to take the action on
pub target: String, // who to take the action on
}
/* Miscellaneous Events */
@ -72,7 +72,7 @@ pub enum ChangeEventType {
// change info event struct
#[derive(Deserialize, Debug)]
pub struct ChangeEvent {
pub name: String, // name of the user
pub name: String, // name of the user
pub changed_event: ChangeEventType, // which event to change
pub new_event: String, // the new value for the event
pub new_event: String, // the new value for the event
}