Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: auth cache #643

Merged
merged 28 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
32ccc0a
feat: initial commit of auth cache
oddgrd Feb 19, 2023
619fd24
fix: expiration logic
oddgrd Feb 20, 2023
1865085
refactor: switch dashmap to ttlc_cache
oddgrd Feb 20, 2023
a5f2054
feat: rewrite the cache as a tower service
oddgrd Feb 20, 2023
4d7e38b
feat: add cache layer to convert_cookie
oddgrd Feb 20, 2023
a797c14
feat: cachemanagement trait
oddgrd Feb 20, 2023
959cd92
feat: refactor layer to be applied to router not specific handlers
oddgrd Feb 21, 2023
ffd0ab1
refactor: move comment
oddgrd Feb 21, 2023
678b0d5
feat: set cache in cachelayer, invalidate cached jwt on logout
oddgrd Feb 21, 2023
5dc8f0a
feat: error handling in the cache layer
oddgrd Feb 21, 2023
ff86f99
Merge branch 'main' into feature/eng-439-cache-layer
oddgrd Feb 22, 2023
e783901
feat: implement cache layer on gateway
oddgrd Feb 22, 2023
5abde31
refactor: remove the cache from auth
oddgrd Feb 22, 2023
650e541
refactor: revert changes needed for cache in auth
oddgrd Feb 22, 2023
17c78f3
feat: invalidate jwt on logout calls
oddgrd Feb 22, 2023
45baf3e
refactor: clean up logout cache invalidation
oddgrd Feb 22, 2023
ec9702a
refactor: remove cache from shared state
oddgrd Feb 22, 2023
9c9b27f
refactor: remove comment
oddgrd Feb 22, 2023
ae8dd08
feat: add prepare.sh to auth
oddgrd Feb 22, 2023
541144c
feat: move cache to auth layer
oddgrd Feb 22, 2023
678cce2
feat: invalidate cache on logout
oddgrd Feb 23, 2023
a6265c2
refactor: error handling in extract expiration
oddgrd Feb 23, 2023
26b591d
refactor: remove cache-layer, add comment
oddgrd Feb 24, 2023
a4fad11
docs: add comment about logout cache invalidation
oddgrd Feb 24, 2023
b6ab3c5
refactor: cachemanager new fn, remove comment
oddgrd Feb 24, 2023
7e34b4f
fix: make sure cookie is shuttle cookie
oddgrd Feb 24, 2023
f0aa8cb
feat: add buffer to cache expiration
oddgrd Feb 25, 2023
d0e2a3a
fix: fmt
oddgrd Feb 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions auth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,30 @@ anyhow = { workspace = true }
async-trait = { workspace = true }
oddgrd marked this conversation as resolved.
Show resolved Hide resolved
axum = { workspace = true, features = ["headers"] }
axum-sessions = "0.4.1"
chrono = { workspace = true, features = ["serde"] }
clap = { workspace = true }
http = { workspace = true }
jsonwebtoken = { workspace = true}
hyper = { workspace = true }
jsonwebtoken = { workspace = true }
opentelemetry = { workspace = true }
opentelemetry-datadog = { workspace = true }
rand = { workspace = true }
ring = { workspace = true }
serde = { workspace = true, features = [ "derive" ] }
sqlx = { version = "0.6.2", features = [ "sqlite", "json", "runtime-tokio-native-tls", "migrate" ] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sqlx = { version = "0.6.2", features = ["sqlite", "json", "runtime-tokio-native-tls", "migrate"] }
strum = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1.22.0", features = [ "full" ] }
tokio = { version = "1.22.0", features = ["full"] }
tower = { workspace = true, features = ["util"] }
tracing = { workspace = true }
tracing-opentelemetry = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
ttl_cache = "0.5.1"

[dependencies.shuttle-common]
workspace = true
features = ["backend", "models"]

[dev-dependencies]
axum-extra = { version = "0.5.0", features = ["cookie"] }
hyper = { workspace = true }
serde_json = { workspace = true }
tower = { workspace = true, features = ["util"] }
8 changes: 8 additions & 0 deletions auth/prepare.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env sh

###############################################################################
# This file is used by our common Containerfile incase the container for this #
# service might need some extra preparation steps for its final image #
###############################################################################

# Nothing to prepare in container image here
9 changes: 6 additions & 3 deletions auth/src/api/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use tracing::field;
use crate::{
secrets::{EdDsaManager, KeyManager},
user::{UserManagement, UserManager},
COOKIE_EXPIRATION,
};

use super::handlers::{
Expand Down Expand Up @@ -102,7 +103,7 @@ impl ApiBuilder {
self.session_layer = Some(
SessionLayer::new(store, &secret)
.with_cookie_name("shuttle.sid")
.with_session_ttl(Some(std::time::Duration::from_secs(60 * 60 * 24))) // One day
.with_session_ttl(Some(COOKIE_EXPIRATION))
.with_secure(true),
);

Expand All @@ -116,10 +117,12 @@ impl ApiBuilder {
let user_manager = UserManager { pool };
let key_manager = EdDsaManager::new();

self.router.layer(session_layer).with_state(RouterState {
let state = RouterState {
user_manager: Arc::new(Box::new(user_manager)),
key_manager: Arc::new(Box::new(key_manager)),
})
};

self.router.layer(session_layer).with_state(state)
}
}

Expand Down
16 changes: 8 additions & 8 deletions auth/src/api/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub(crate) async fn login(
.expect("to set account name");
session
.insert("account_tier", user.account_tier)
.expect("to set account name");
.expect("to set account tier");

Ok(Json(user.into()))
}
Expand All @@ -74,9 +74,9 @@ pub(crate) async fn convert_cookie(

let claim = Claim::new(account_name, account_tier.into());

let response = shuttle_common::backends::auth::ConvertResponse {
token: claim.into_token(key_manager.private_key())?,
};
let token = claim.into_token(key_manager.private_key())?;

let response = shuttle_common::backends::auth::ConvertResponse { token };

Ok(Json(response))
}
Expand All @@ -92,15 +92,15 @@ pub(crate) async fn convert_key(
let User {
name, account_tier, ..
} = user_manager
.get_user_by_key(key)
.get_user_by_key(key.clone())
.await
.map_err(|_| StatusCode::UNAUTHORIZED)?;

let claim = Claim::new(name.to_string(), account_tier.into());

let response = shuttle_common::backends::auth::ConvertResponse {
token: claim.into_token(key_manager.private_key())?,
};
let token = claim.into_token(key_manager.private_key())?;

let response = shuttle_common::backends::auth::ConvertResponse { token };

Ok(Json(response))
}
Expand Down
4 changes: 3 additions & 1 deletion auth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod error;
mod secrets;
mod user;

use std::{io, str::FromStr};
use std::{io, str::FromStr, time::Duration};

use args::StartArgs;
use sqlx::{
Expand All @@ -22,6 +22,8 @@ use crate::{
pub use api::ApiBuilder;
pub use args::{Args, Commands, InitArgs};

pub const COOKIE_EXPIRATION: Duration = Duration::from_secs(60 * 60 * 24); // One day

pub static MIGRATIONS: Migrator = sqlx::migrate!("./migrations");

pub async fn start(pool: SqlitePool, args: StartArgs) -> io::Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion common/src/backends/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ pub struct ConvertResponse {
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct Claim {
/// Expiration time (as UTC timestamp).
exp: usize,
pub exp: usize,
/// Issued at (as UTC timestamp).
iat: usize,
/// Issuer.
Expand Down
Loading