Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jbr committed Jul 15, 2020
0 parents commit eaa0b7a
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
16 changes: 16 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "async-redis-session"
version = "0.1.0"
authors = ["Jacob Rothstein <[email protected]>"]
edition = "2018"

[dependencies]
redis = { version = "0.16.0", features = ["aio"] }
async-session = "1.0.2"
serde = "1.0.114"
serde_json = "1.0.56"
async-trait = "0.1.36"
http-types = "2.2.1"

[patch.crates-io]
async-session = { path = "../async-session" }#git = "https://github.com/jbr/async-session", branch = "tide" }
83 changes: 83 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use async_session::{uuid::Uuid, Session, SessionStore};
use http_types::cookies::Cookie;
use redis::AsyncCommands;
use redis::{Client, RedisError};
use std::time::Duration;

#[derive(Clone)]
pub struct RedisSessionStore {
client: Client,
ttl: Duration,
}

impl RedisSessionStore {
pub fn from_client(client: Client) -> Self {
Self {
client,
ttl: Duration::from_secs(86400),
}
}

pub fn new(connection_info: impl redis::IntoConnectionInfo) -> Result<Self, RedisError> {
Ok(Self::from_client(Client::open(connection_info)?))
}
}

#[async_trait::async_trait]
impl SessionStore for RedisSessionStore {
type Error = Error;

async fn load_session(&self, cookie: Cookie<'_>) -> Result<Option<Session>, Self::Error> {
let mut connection = self.client.get_async_std_connection().await?;
let value: String = connection.get(cookie.value()).await?;
let session: Session = serde_json::from_str(&value)?;
Ok(Some(session))
}

async fn store_session(&self, session: Session) -> Result<String, Self::Error> {
let id = session.id();
let mut connection = self.client.get_async_std_connection().await?;
let string = serde_json::to_string(&session)?;

let _: () = connection
.set_ex(&id, string, self.ttl.as_secs() as usize)
.await?;

Ok(id)
}

async fn create_session(&self) -> Result<Session, Self::Error> {
let sess = Session::new();
sess.insert("id".to_string(), Uuid::new_v4().to_string());
Ok(sess)
}
}

#[derive(Debug)]
pub enum Error {
RedisError(RedisError),
SerdeError(serde_json::Error),
}

impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::RedisError(e) => e.fmt(f),
Error::SerdeError(e) => e.fmt(f),
}
}
}

impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
Self::SerdeError(e)
}
}

impl From<RedisError> for Error {
fn from(e: RedisError) -> Self {
Self::RedisError(e)
}
}

impl std::error::Error for Error {}

0 comments on commit eaa0b7a

Please sign in to comment.