session-crate
Ondřej Hruška 5 years ago
parent d24af144fa
commit fdbc7947f6
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 17
      src/main.rs
  2. 47
      src/session.rs
  3. 3
      src/store/form.rs
  4. 31
      src/store/mod.rs

@ -12,18 +12,21 @@ use serde_json::Value;
use rocket_contrib::serve::StaticFiles; use rocket_contrib::serve::StaticFiles;
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
mod store;
mod session; mod session;
mod store;
use crate::store::form::{render_card_fields, render_empty_fields, RenderedCard, RenderedField, MapFromForm, collect_card_form}; use crate::store::form::{
collect_card_form, render_card_fields, render_empty_fields, MapFromForm, RenderedCard,
RenderedField,
};
use crate::store::Store; use crate::store::Store;
use parking_lot::RwLock; use parking_lot::RwLock;
use crate::session::{Session, SessionID, SessionStore};
use rocket::request::Form; use rocket::request::Form;
use rocket::response::Redirect; use rocket::response::Redirect;
use rocket::{State, Request}; use rocket::{Request, State};
use std::env; use std::env;
use crate::session::{SessionID, SessionStore, Session};
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
pub struct ListContext<'a> { pub struct ListContext<'a> {
@ -51,11 +54,7 @@ fn find_page_with_card(store: &Store, card_id: usize) -> Option<usize> {
} }
#[get("/?<page>")] #[get("/?<page>")]
fn route_index( fn route_index(store: State<RwLock<Store>>, session: Session, page: Option<usize>) -> Template {
store: State<RwLock<Store>>,
session : Session,
page: Option<usize>
) -> Template {
let rg = store.read(); let rg = store.read();
let mut count: usize = session.get_or_default("foo.bar.count"); let mut count: usize = session.get_or_default("foo.bar.count");

@ -1,16 +1,19 @@
use rocket::request::FromRequest; use json_dotpath::DotPaths;
use rocket::{Outcome, Request, State, http::{Status, Cookies, Cookie}, Response, Data, Rocket};
use std::ops::{Deref, DerefMut};
use std::collections::HashMap;
use parking_lot::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; use parking_lot::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
use serde_json::{Value, Map};
use rocket::fairing::{self, Fairing, Info};
use rand::Rng; use rand::Rng;
use std::borrow::Cow; use rocket::fairing::{self, Fairing, Info};
use serde::{Deserialize, Serialize}; use rocket::request::FromRequest;
use serde::de::DeserializeOwned;
use json_dotpath::DotPaths;
use rocket::response::ResponseBuilder; use rocket::response::ResponseBuilder;
use rocket::{
http::{Cookie, Cookies, Status},
Data, Outcome, Request, Response, Rocket, State,
};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use std::borrow::Cow;
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
const SESSION_ID: &'static str = "SESSID"; const SESSION_ID: &'static str = "SESSID";
@ -41,10 +44,12 @@ impl<'a, 'r> FromRequest<'a, 'r> for &'a SessionID {
SessionID(cookie.value().to_string()) // FIXME avoid cloning SessionID(cookie.value().to_string()) // FIXME avoid cloning
} else { } else {
println!("new id"); println!("new id");
SessionID(rand::thread_rng() SessionID(
rand::thread_rng()
.sample_iter(&rand::distributions::Alphanumeric) .sample_iter(&rand::distributions::Alphanumeric)
.take(16) .take(16)
.collect()) .collect(),
)
} }
})) }))
} }
@ -65,13 +70,15 @@ impl<'a, 'r> FromRequest<'a, 'r> for Session<'a> {
if let Some(cookie) = request.cookies().get(SESSION_ID) { if let Some(cookie) = request.cookies().get(SESSION_ID) {
SessionID(cookie.value().to_string()) SessionID(cookie.value().to_string())
} else { } else {
SessionID(rand::thread_rng() SessionID(
rand::thread_rng()
.sample_iter(&rand::distributions::Alphanumeric) .sample_iter(&rand::distributions::Alphanumeric)
.take(16) .take(16)
.collect()) .collect(),
)
} }
}), }),
store: request.guard().unwrap() store: request.guard().unwrap(),
}) })
} }
} }
@ -127,9 +134,7 @@ impl<'a> Session<'a> {
} else { } else {
let mut map = Map::new(); let mut map = Map::new();
map.dot_set(path, value); map.dot_set(path, value);
wg.insert(self.id.0.clone(), SessionInstance { wg.insert(self.id.0.clone(), SessionInstance { data: map });
data : map,
});
} }
} }
@ -148,7 +153,7 @@ impl Fairing for SessionFairing {
fn info(&self) -> Info { fn info(&self) -> Info {
Info { Info {
name: "Session Fairing", name: "Session Fairing",
kind: fairing::Kind::Attach | fairing::Kind::Response kind: fairing::Kind::Attach | fairing::Kind::Response,
} }
} }
@ -157,9 +162,7 @@ impl Fairing for SessionFairing {
} }
fn on_response<'r>(&self, request: &'r Request, response: &mut Response) { fn on_response<'r>(&self, request: &'r Request, response: &mut Response) {
let session = request.local_cache(|| { let session = request.local_cache(|| SessionID("".to_string()));
SessionID("".to_string())
});
if !session.0.is_empty() { if !session.0.is_empty() {
response.adjoin_header(Cookie::build(SESSION_ID, session.0.clone()).finish()); response.adjoin_header(Cookie::build(SESSION_ID, session.0.clone()).finish());

@ -4,8 +4,8 @@ use serde_json::Value;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use lazy_static::lazy_static;
use indexmap::map::IndexMap; use indexmap::map::IndexMap;
use lazy_static::lazy_static;
use rocket::request::{FormItems, FromForm}; use rocket::request::{FormItems, FromForm};
lazy_static! { lazy_static! {
@ -194,7 +194,6 @@ pub fn render_card_fields<'a>(
.collect() .collect()
} }
#[derive(Default)] #[derive(Default)]
pub struct MapFromForm { pub struct MapFromForm {
pub data: IndexMap<String, String>, pub data: IndexMap<String, String>,

@ -1,13 +1,13 @@
use crate::store::model::{Model, FieldKind}; use crate::store::model::{FieldKind, Model};
use indexmap::map::IndexMap; use indexmap::map::IndexMap;
use json_dotpath::DotPaths;
use serde::Serialize; use serde::Serialize;
use serde_json::Value; use serde_json::Value;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::{BTreeMap, BTreeSet};
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::collections::{BTreeMap, BTreeSet};
use json_dotpath::DotPaths;
pub mod form; pub mod form;
pub mod model; pub mod model;
@ -71,7 +71,11 @@ impl Store {
fn on_change(&mut self, changed_card: Option<usize>) { fn on_change(&mut self, changed_card: Option<usize>) {
if let Some(id) = changed_card { if let Some(id) = changed_card {
// this needs to be so ugly because of lifetimes - we need a mutable reference to the index // this needs to be so ugly because of lifetimes - we need a mutable reference to the index
Self::index_card(&mut self.index, &self.freeform_fields, self.data.cards.get(&id).unwrap()); Self::index_card(
&mut self.index,
&self.freeform_fields,
self.data.cards.get(&id).unwrap(),
);
} }
self.persist(); self.persist();
@ -133,12 +137,12 @@ impl Store {
FieldKind::FreeEnum { enum_group } => { FieldKind::FreeEnum { enum_group } => {
let enum_group = enum_group.as_ref().unwrap_or(key); let enum_group = enum_group.as_ref().unwrap_or(key);
free_enum_fields.push(KeyAndGroup(key.to_string(), enum_group.to_string())); free_enum_fields.push(KeyAndGroup(key.to_string(), enum_group.to_string()));
}, }
FieldKind::FreeTags { tag_group } => { FieldKind::FreeTags { tag_group } => {
let tag_group = tag_group.as_ref().unwrap_or(key); let tag_group = tag_group.as_ref().unwrap_or(key);
free_tag_fields.push(KeyAndGroup(key.to_string(), tag_group.to_string())); free_tag_fields.push(KeyAndGroup(key.to_string(), tag_group.to_string()));
}, }
_ => {}, _ => {}
} }
} }
@ -149,7 +153,11 @@ impl Store {
} }
/// This is an associated function to split the lifetimes /// This is an associated function to split the lifetimes
fn index_card<'a>(index : &mut Indexes, freeform_fields : &FreeformFieldsOfInterest, card : &'a Value) { fn index_card<'a>(
index: &mut Indexes,
freeform_fields: &FreeformFieldsOfInterest,
card: &'a Value,
) {
for KeyAndGroup(key, group) in &freeform_fields.free_enum_fields { for KeyAndGroup(key, group) in &freeform_fields.free_enum_fields {
if !index.free_enums.contains_key(key.as_str()) { if !index.free_enums.contains_key(key.as_str()) {
index.free_enums.insert(key.to_string(), Default::default()); index.free_enums.insert(key.to_string(), Default::default());
@ -196,12 +204,13 @@ struct FreeformFieldsOfInterest {
fn write_file(path: impl AsRef<Path>, bytes: &[u8]) { fn write_file(path: impl AsRef<Path>, bytes: &[u8]) {
let mut file = OpenOptions::new() let mut file = OpenOptions::new()
.write(true).create(true).truncate(true) .write(true)
.create(true)
.truncate(true)
.open(path) .open(path)
.expect("Error opening data file for writing."); .expect("Error opening data file for writing.");
file.write(bytes) file.write(bytes).expect("Error write data file");
.expect("Error write data file");
} }
fn load_file(path: impl AsRef<Path>) -> String { fn load_file(path: impl AsRef<Path>) -> String {

Loading…
Cancel
Save