From dd0a124698a0ded987f7b5b426607308b0e79ffc Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Fri, 18 Nov 2022 22:10:11 -0800 Subject: [PATCH] Make cookies --- Cargo.lock | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 37 +++++++++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5b80888..e029d95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 3764682..5f9fae9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,4 @@ description = "A simple web page that tracks votes" [dependencies] cgi = "0" fd-lock = "3" +rand = "0" diff --git a/src/main.rs b/src/main.rs index 700cce0..273a719 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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::>() + .try_into() + .unwrap() +} + +fn set_cookie(mut response: cgi::Response, path: &str) -> Result { + 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 { - Err(cgi::text_response(503, "Not Implemented")) + let voter = get_voter(&request); + let mut response = cgi::html_response(200, "You should vote"); + 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<()> { -- 2.44.1