]> git.scottworley.com Git - voter/commitdiff
Make cookies
authorScott Worley <scottworley@scottworley.com>
Sat, 19 Nov 2022 06:10:11 +0000 (22:10 -0800)
committerScott Worley <scottworley@scottworley.com>
Sat, 19 Nov 2022 06:10:11 +0000 (22:10 -0800)
Cargo.lock
Cargo.toml
src/main.rs

index 5b80888aa5e1f9b1c636f1b3510f3d7e273e2b1f..e029d95918ba2f07b8020da80926c9be87450506 100644 (file)
@@ -73,6 +73,17 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
+[[package]]
+name = "getrandom"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
 [[package]]
 name = "http"
 version = "0.2.8"
@@ -112,6 +123,42 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bb68f22743a3fb35785f1e7f844ca5a3de2dde5bd0c0ef5b372065814699b121"
 
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
 [[package]]
 name = "rustix"
 version = "0.36.2"
@@ -132,8 +179,15 @@ version = "0.1.0"
 dependencies = [
  "cgi",
  "fd-lock",
+ "rand",
 ]
 
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
 [[package]]
 name = "winapi"
 version = "0.3.9"
index 37646824b331c9f6ae3a2b1877eb4b7a724a8c0a..5f9fae9a6efd69db62280bfdc1df3a3878a6c10f 100644 (file)
@@ -10,3 +10,4 @@ description = "A simple web page that tracks votes"
 [dependencies]
 cgi = "0"
 fd-lock = "3"
+rand = "0"
index 700cce03f3f7f4b74ac6654ea9e22a5709335631..273a719740e2a49e7017fb93fe4ebb318d17f8a0 100644 (file)
@@ -1,3 +1,4 @@
+use rand::prelude::*;
 use std::io::prelude::*;
 use std::path::{Path, PathBuf};
 
@@ -43,8 +44,42 @@ fn get_voter(request: &cgi::Request) -> Result<&[u8], cgi::Response> {
     }
 }
 
+fn make_random_id() -> [u8; COOKIE_LENGTH] {
+    std::iter::from_fn(random)
+        .filter(|c| {
+            (b'A'..=b'Z').contains(c) || (b'a'..=b'z').contains(c) || (b'0'..=b'9').contains(c)
+        })
+        .take(COOKIE_LENGTH)
+        .collect::<Vec<_>>()
+        .try_into()
+        .unwrap()
+}
+
+fn set_cookie(mut response: cgi::Response, path: &str) -> Result<cgi::Response, cgi::Response> {
+    response.headers_mut().append(
+        cgi::http::header::SET_COOKIE,
+        cgi::http::header::HeaderValue::from_bytes(
+            &[
+                COOKIE_NAME,
+                b"=",
+                &make_random_id(),
+                b"; Secure HttpOnly SameSite=Strict Max-Age=30000000 Path=",
+                path.as_bytes(),
+            ]
+            .concat(),
+        )
+        .map_err(|_| cgi::text_response(503, "Couldn't make cookie"))?,
+    );
+    Ok(response)
+}
+
 fn prompt_for_vote(dir: PathBuf, request: cgi::Request) -> Result<cgi::Response, cgi::Response> {
-    Err(cgi::text_response(503, "Not Implemented"))
+    let voter = get_voter(&request);
+    let mut response = cgi::html_response(200, "<html><body>You should vote</body></html>");
+    if voter.is_err() {
+        response = set_cookie(response, request.uri().path())?
+    }
+    Ok(response)
 }
 
 fn write_vote(dir: PathBuf, voter: &[u8], vote: &[u8]) -> std::io::Result<()> {