diff --git a/Cargo.lock b/Cargo.lock index 3919843..3425d30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,6 +142,8 @@ name = "cookie" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -796,6 +798,17 @@ name = "regex-syntax" version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ring" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rocket" version = "0.4.2" @@ -829,7 +842,7 @@ dependencies = [ "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_session 0.1.0 (git+https://git.ondrovo.com/packages/rocket_session.git)", + "rocket_session 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -881,15 +894,12 @@ dependencies = [ [[package]] name = "rocket_session" -version = "0.1.0" -source = "git+https://git.ondrovo.com/packages/rocket_session.git#2aaa877cb5121fcd19ac5e6f4817af9c8878d64b" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "json_dotpath 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1180,6 +1190,11 @@ name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "untrusted" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "url" version = "1.7.2" @@ -1382,11 +1397,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" +"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" "checksum rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "42c1e9deb3ef4fa430d307bfccd4231434b707ca1328fae339c43ad1201cc6f7" "checksum rocket_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "79aa1366f9b2eccddc05971e17c5de7bb75a5431eb12c2b5c66545fd348647f4" "checksum rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e0fa5c1392135adc0f96a02ba150ac4c765e27c58dbfd32aa40678e948f6e56f" "checksum rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1391457ee4e80b40d4b57fa5765c0f2836b20d73bcbee4e3f35d93cf3b80817" -"checksum rocket_session 0.1.0 (git+https://git.ondrovo.com/packages/rocket_session.git)" = "" +"checksum rocket_session 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f4d2f62206b13d4d0b2e52bd176e727519ba2326c9eea77978c54c25d48296bf" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" @@ -1425,6 +1441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum utf8-ranges 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" diff --git a/Cargo.toml b/Cargo.toml index 712c019..380a9a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ json_dotpath = "0.1.2" titlecase = "0.10.0" rand = "0.7.2" -rocket_session = { git = "https://git.ondrovo.com/packages/rocket_session.git" } +rocket_session = "0.1.1" # special data structure that preserves order indexmap = { version="1.3.0", features=["serde-1"] } diff --git a/src/main.rs b/src/main.rs index 4de67a4..a2172e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,8 @@ use rocket_contrib::templates::Template; //mod session; mod store; -use rocket_session::Session; +mod session; +use session::Session; use crate::store::form::{ collect_card_form, render_card_fields, render_empty_fields, MapFromForm, RenderedCard, @@ -30,6 +31,8 @@ use rocket::response::Redirect; use rocket::State; use std::env; use std::time::Duration; +use crate::session::SessionAccess; +//use crate::session::SessionAccess; #[derive(Serialize, Debug)] pub struct ListContext<'a> { @@ -64,7 +67,7 @@ fn route_index(store: State>, session: Session, page: Option>, session: Session, page: Option = rocket_session::Session<'a, serde_json::Map>; -const SESSION_ID: &'static str = "SESSID"; +pub trait SessionAccess { + fn get(&self, path: &str) -> Option; -type SessionsMap = HashMap; + fn get_or(&self, path: &str, def: T) -> T; -#[derive(Debug)] -struct SessionInstance { - data: serde_json::Map, - expires: Instant, -} + fn get_or_else T>(&self, path: &str, def: F) -> T; -#[derive(Default, Debug)] -pub struct SessionStore { - inner: RwLock, - lifespan: Duration, -} + fn get_or_default(&self, path: &str) -> T; -#[derive(PartialEq, Hash, Clone, Debug)] -pub struct SessionID(String); - -impl<'a, 'r> FromRequest<'a, 'r> for &'a SessionID { - type Error = (); - - fn from_request(request: &'a Request<'r>) -> Outcome { - Outcome::Success(request.local_cache(|| { - println!("get id"); - if let Some(cookie) = request.cookies().get(SESSION_ID) { - println!("from cookie"); - SessionID(cookie.value().to_string()) // FIXME avoid cloning - } else { - println!("new id"); - SessionID( - rand::thread_rng() - .sample_iter(&rand::distributions::Alphanumeric) - .take(16) - .collect(), - ) - } - })) - } -} + fn take(&self, path: &str) -> Option; -#[derive(Debug)] -pub struct Session<'a> { - store: State<'a, SessionStore>, - id: &'a SessionID, -} + fn replace(&self, path: &str, new: N) -> Option; -impl<'a, 'r> FromRequest<'a, 'r> for Session<'a> { - type Error = (); - - fn from_request(request: &'a Request<'r>) -> Outcome { - Outcome::Success(Session { - id: request.local_cache(|| { - if let Some(cookie) = request.cookies().get(SESSION_ID) { - SessionID(cookie.value().to_string()) - } else { - SessionID( - rand::thread_rng() - .sample_iter(&rand::distributions::Alphanumeric) - .take(16) - .collect(), - ) - } - }), - store: request.guard().unwrap(), - }) - } -} - -impl<'a> Session<'a> { - pub fn fairing() -> impl Fairing { - SessionFairing - } - - fn tap(&self, func : impl FnOnce(&mut serde_json::Map) -> T) -> T { - let mut wg = self.store.inner.write(); - if let Some(instance) = wg.get_mut(&self.id.0) { - instance.expires = Instant::now().add(self.store.lifespan); - func(&mut instance.data) - } else { - let mut data = Map::new(); - let rv = func(&mut data); - wg.insert(self.id.0.clone(), SessionInstance { - data: data, - expires: Instant::now().add(self.store.lifespan), - }); - rv - } - } + fn set(&self, path: &str, value: T); - pub fn renew(&self) { - self.tap(|_| ()) - } - - pub fn reset(&self) { - self.tap(|data| data.clear()) - } + fn remove(&self, path: &str) -> bool; +} - pub fn get(&self, path: &str) -> Option { +impl<'a> SessionAccess for Session<'a> { + fn get(&self, path: &str) -> Option { self.tap(|data| data.dot_get(path)) } - pub fn get_or(&self, path: &str, def: T) -> T { + fn get_or(&self, path: &str, def: T) -> T { self.get(path).unwrap_or(def) } - pub fn get_or_else T>(&self, path: &str, def: F) -> T { + fn get_or_else T>(&self, path: &str, def: F) -> T { self.get(path).unwrap_or_else(def) } - pub fn get_or_default(&self, path: &str) -> T { + fn get_or_default(&self, path: &str) -> T { self.get(path).unwrap_or_default() } - pub fn take(&self, path: &str) -> Option { + fn take(&self, path: &str) -> Option { self.tap(|data| data.dot_take(path)) } - pub fn replace(&self, path: &str, new: N) -> Option { + fn replace(&self, path: &str, new: N) -> Option { self.tap(|data| data.dot_replace(path, new)) } - pub fn set(&self, path: &str, value: T) { + fn set(&self, path: &str, value: T) { self.tap(|data| data.dot_set(path, value)); } - pub fn remove(&self, path: &str) -> bool { + fn remove(&self, path: &str) -> bool { self.tap(|data| data.dot_remove(path)) } } -/// Fairing struct -struct SessionFairing; - -impl Fairing for SessionFairing { - fn info(&self) -> Info { - Info { - name: "Session Fairing", - kind: fairing::Kind::Attach | fairing::Kind::Response, - } - } - - fn on_attach(&self, rocket: Rocket) -> Result { - Ok(rocket.manage(SessionStore::default())) - } - - fn on_response<'r>(&self, request: &'r Request, response: &mut Response) { - let session = request.local_cache(|| SessionID("".to_string())); - - if !session.0.is_empty() { - response.adjoin_header(Cookie::build(SESSION_ID, session.0.clone()).finish()); - } - } -}