"memchr",
]
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "bcrypt"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f3c067aa24dd4ed5c79cf222a38f260c8f23d3b82a062fba3f28c6fe563b753"
+dependencies = [
+ "base64",
+ "blowfish",
+ "getrandom",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "blowfish"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62ce3946557b35e71d1bbe07ec385073ce9eda05043f95de134eb578fcf1a298"
+dependencies = [
+ "byteorder",
+ "cipher",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "cipher"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c"
+dependencies = [
+ "crypto-common",
+ "inout",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
+dependencies = [
+ "hybrid-array",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+]
+
+[[package]]
+name = "hybrid-array"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c"
+dependencies = [
+ "typenum",
+]
+
+[[package]]
+name = "inout"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7"
+dependencies = [
+ "hybrid-array",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.186"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+[[package]]
+name = "r-efi"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
+
[[package]]
name = "regex"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
+name = "typenum"
+version = "1.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
+
[[package]]
name = "ws"
version = "0.1.0"
dependencies = [
+ "bcrypt",
"regex",
]
+
+[[package]]
+name = "zeroize"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
repository = "https://tangled.org/autumn.bsky.gay/ws"
[dependencies]
+bcrypt = "0.19.2"
regex = "1.12.3"
--- /dev/null
+pub mod data {
+
+ use crate::server::server::get_client_data;
+ use std::{
+ fs::{read_to_string, write},
+ path::Path,
+ };
+
+ fn exists() -> bool {
+ Path::new("./data").exists()
+ }
+
+ pub fn pull_data() -> Option<String> {
+ if !exists() {
+ None
+ } else {
+ Some(read_to_string("./data").expect("Issue reading file"))
+ }
+ }
+
+ pub fn push_data(headers: &Vec<String>) -> bool {
+ match get_client_data(headers) {
+ Some(x) => match write("./data", x.as_str()) {
+ Ok(_) => true,
+ Err(_) => false,
+ },
+ None => false,
+ }
+ }
+}
+use bcrypt::hash;
use regex::Regex;
use std::{env, net::TcpListener, process::exit, thread};
+mod data;
mod routes;
mod server;
});
} else if item.contains("--token=") {
unsafe {
- env::set_var("token", item.replace("--token=", ""));
+ env::set_var("token", hash(item.replace("--token=", ""), 10).unwrap());
}
}
}
+use crate::data::data;
use crate::server::server::get_authorization;
pub fn home() -> (String, String) {
)
}
}
+
+pub fn pull(headers: &Vec<String>) -> (String, String) {
+ if !get_authorization(headers) {
+ (
+ String::from("403 FORBIDDEN"),
+ String::from("You are not authorized to view this endpoint"),
+ )
+ } else {
+ match data::pull_data() {
+ Some(x) => (String::from("200 OK"), String::from(x)),
+ None => (
+ String::from("404 NOT FOUND"),
+ String::from("No data exists on the server yet"),
+ ),
+ }
+ }
+}
+
+pub fn push(headers: &Vec<String>) -> (String, String) {
+ if !get_authorization(headers) {
+ (
+ String::from("403 FORBIDDEN"),
+ String::from("You are not authorized to view this endpoint"),
+ )
+ } else {
+ if data::push_data(headers) {
+ (
+ String::from("200 OK"),
+ String::from("Data successfully synced to server"),
+ )
+ } else {
+ (
+ String::from("500 SERVER ERROR"),
+ String::from("Issue pushing data to server"),
+ )
+ }
+ }
+}
pub mod server {
use crate::routes;
+ use bcrypt::verify;
use std::{
env,
io::{BufReader, prelude::*},
match env::var("token") {
Ok(x) => {
for header in headers {
- if header.contains("Authorization: Basic ") {
- return header.replace("Authorization: Basic ", "") == x;
+ if header.starts_with("Authorization: Basic ") {
+ return verify(header.replace("Authorization: Basic ", ""), x.as_str())
+ .unwrap();
}
}
}
false
}
+ pub fn get_client_data(headers: &Vec<String>) -> Option<String> {
+ for header in headers {
+ if header.starts_with("Data: ") {
+ return Some(header.replace("Data: ", ""));
+ }
+ }
+
+ None
+ }
+
pub fn handle_connection(mut stream: TcpStream) {
let buf_reader = BufReader::new(&stream);
let request_data: Vec<_> = buf_reader
match request_line.as_str() {
"GET / HTTP/1.1" => routes::home(),
"GET /auth HTTP/1.1" => routes::auth(headers),
+ "GET /pull HTTP/1.1" => routes::pull(headers),
+ "POST /push HTTP/1.1" => routes::push(headers),
_ => (
String::from("404 NOT FOUND"),
String::from("The provided endpoint was not found"),