]> git.amazingca.dev Git - autumn/ws/commitdiff
Add some finishing touches to 0.1.0
authorAmazingca <autumn@amazingca.dev>
Wed, 1 Jul 2026 20:37:47 +0000 (14:37 -0600)
committerAmazingca <autumn@amazingca.dev>
Wed, 1 Jul 2026 20:37:47 +0000 (14:37 -0600)
.gitignore
Cargo.lock
Cargo.toml
src/data.rs [new file with mode: 0644]
src/main.rs
src/routes.rs
src/server.rs

index ea8c4bf7f35f6f77f75d92ad8ce8349f6e81ddba..8b77cd34f3e998f423e9ff7f8e4fe63dc4be3f71 100644 (file)
@@ -1 +1,2 @@
 /target
+data
index 94bbc728439d742783970f4dd885fb8888ca4fcb..5daae0f909b2ba45d8e86bfb72df31ad8b95a52e 100644 (file)
@@ -11,12 +11,113 @@ dependencies = [
  "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"
@@ -46,9 +147,28 @@ version = "0.8.10"
 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"
index 21f0c62a555e59a4c5bce865616bcd0fe85df7d1..7249a6696138050538aebbb686067b917687d188 100644 (file)
@@ -6,4 +6,5 @@ description = "web-sync project"
 repository = "https://tangled.org/autumn.bsky.gay/ws"
 
 [dependencies]
+bcrypt = "0.19.2"
 regex = "1.12.3"
diff --git a/src/data.rs b/src/data.rs
new file mode 100644 (file)
index 0000000..5a34c3c
--- /dev/null
@@ -0,0 +1,30 @@
+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,
+        }
+    }
+}
index 61910e2b4f1dd0292710bc55dcba4a64cd0044a3..ce58c79ba3af0076296da3e04a3058cf1bece189 100644 (file)
@@ -1,6 +1,8 @@
+use bcrypt::hash;
 use regex::Regex;
 use std::{env, net::TcpListener, process::exit, thread};
 
+mod data;
 mod routes;
 mod server;
 
@@ -39,7 +41,7 @@ fn args_handler(conf: &mut ServerConfig, args: Vec<String>) {
                 });
         } else if item.contains("--token=") {
             unsafe {
-                env::set_var("token", item.replace("--token=", ""));
+                env::set_var("token", hash(item.replace("--token=", ""), 10).unwrap());
             }
         }
     }
index 0d89f99682650dff8a86ea27a1e3ea2b413df36e..0c2b295029988e4bba15f15b5bff3365494e2c01 100644 (file)
@@ -1,3 +1,4 @@
+use crate::data::data;
 use crate::server::server::get_authorization;
 
 pub fn home() -> (String, String) {
@@ -20,3 +21,41 @@ pub fn auth(headers: &Vec<String>) -> (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"),
+            )
+        }
+    }
+}
index f51b42658ceade683cf32b6b258193a74b69e3cb..d82e3d62f4e2e7d5d4ce29f490af23959a99665c 100644 (file)
@@ -1,6 +1,7 @@
 pub mod server {
 
     use crate::routes;
+    use bcrypt::verify;
     use std::{
         env,
         io::{BufReader, prelude::*},
@@ -11,8 +12,9 @@ pub mod server {
         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();
                     }
                 }
             }
@@ -22,6 +24,16 @@ pub mod server {
         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
@@ -47,6 +59,8 @@ pub mod server {
         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"),