Skip to content

Commit 32f1a3f

Browse files
committed
Replace redis errors with a generic cache error
1 parent 9d24937 commit 32f1a3f

File tree

5 files changed

+56
-23
lines changed

5 files changed

+56
-23
lines changed

src/auth0/cache/inmemory.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@ use dashmap::DashMap;
22

33
use crate::auth0::cache;
44
use crate::auth0::cache::Cache;
5-
use crate::auth0::errors::Auth0Error;
65
use crate::auth0::token::Token;
76

7+
use super::CacheError;
8+
89
#[derive(Default, Clone, Debug)]
910
pub struct InMemoryCache {
1011
key_value: DashMap<String, Token>,
1112
}
1213

1314
#[async_trait::async_trait]
1415
impl Cache for InMemoryCache {
15-
async fn get_token(&self, client_id: &str, aud: &str) -> Result<Option<Token>, Auth0Error> {
16+
async fn get_token(&self, client_id: &str, aud: &str) -> Result<Option<Token>, CacheError> {
1617
let token = self
1718
.key_value
1819
.get(&cache::token_key(client_id, aud))
1920
.map(|v| v.to_owned());
2021
Ok(token)
2122
}
2223

23-
async fn put_token(&self, client_id: &str, aud: &str, token: &Token) -> Result<(), Auth0Error> {
24+
async fn put_token(&self, client_id: &str, aud: &str, token: &Token) -> Result<(), CacheError> {
2425
let key: String = cache::token_key(client_id, aud);
2526
let _ = self.key_value.insert(key, token.clone());
2627
Ok(())

src/auth0/cache/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pub use inmemory::InMemoryCache;
22
pub use redis_impl::RedisCache;
3+
use std::error::Error;
34

4-
use crate::auth0::errors::Auth0Error;
55
use crate::auth0::Token;
66

77
mod crypto;
@@ -13,11 +13,15 @@ const TOKEN_PREFIX: &str = "auth0rs_tokens";
1313
// The version of the token for backwards incompatible changes
1414
const TOKEN_VERSION: &str = "2";
1515

16+
#[derive(thiserror::Error, Debug)]
17+
#[error(transparent)]
18+
pub struct CacheError(pub Box<dyn Error>);
19+
1620
#[async_trait::async_trait]
1721
pub trait Cache: Send + Sync + std::fmt::Debug {
18-
async fn get_token(&self, client_id: &str, aud: &str) -> Result<Option<Token>, Auth0Error>;
22+
async fn get_token(&self, client_id: &str, aud: &str) -> Result<Option<Token>, CacheError>;
1923

20-
async fn put_token(&self, client_id: &str, aud: &str, token: &Token) -> Result<(), Auth0Error>;
24+
async fn put_token(&self, client_id: &str, aud: &str, token: &Token) -> Result<(), CacheError>;
2125
}
2226

2327
pub(in crate::auth0::cache) fn token_key(caller: &str, audience: &str) -> String {

src/auth0/cache/redis_impl.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
use redis::AsyncCommands;
2-
use serde::Deserialize;
2+
use serde::{Deserialize, Serialize};
33

4+
use super::CacheError;
45
use crate::auth0::cache::{self, crypto, Cache};
56
use crate::auth0::token::Token;
6-
use crate::auth0::Auth0Error;
7+
8+
#[derive(Debug, thiserror::Error)]
9+
pub enum RedisCacheError {
10+
#[error(transparent)]
11+
Serde(#[from] serde_json::Error),
12+
#[error("redis error: {0}")]
13+
Redis(#[from] redis::RedisError),
14+
#[error("couldn't decrypt stored token: {0}")]
15+
Crypto(#[from] chacha20poly1305::Error),
16+
}
17+
18+
impl From<RedisCacheError> for super::CacheError {
19+
fn from(val: RedisCacheError) -> Self {
20+
CacheError(Box::new(val))
21+
}
22+
}
723

824
#[derive(Clone, Debug)]
925
pub struct RedisCache {
@@ -13,7 +29,7 @@ pub struct RedisCache {
1329

1430
impl RedisCache {
1531
/// Redis connection string(eg. `"redis://{host}:{port}?{ParamKey1}={ParamKey2}"`)
16-
pub async fn new(redis_connection_url: String, token_encryption_key: String) -> Result<Self, Auth0Error> {
32+
pub async fn new(redis_connection_url: String, token_encryption_key: String) -> Result<Self, RedisCacheError> {
1733
let client: redis::Client = redis::Client::open(redis_connection_url)?;
1834
// Ensure connection is fine. Should fail otherwise
1935
let _ = client.get_multiplexed_async_connection().await?;
@@ -24,7 +40,7 @@ impl RedisCache {
2440
})
2541
}
2642

27-
async fn get<T>(&self, key: &str) -> Result<Option<T>, Auth0Error>
43+
async fn get<T>(&self, key: &str) -> Result<Option<T>, RedisCacheError>
2844
where
2945
for<'de> T: Deserialize<'de>,
3046
{
@@ -35,24 +51,30 @@ impl RedisCache {
3551
.await?
3652
.map(|value| crypto::decrypt(self.encryption_key.as_str(), value.as_slice()))
3753
.transpose()
54+
.map_err(|_| todo!())
55+
}
56+
57+
async fn put<T: Serialize>(&self, key: &str, lifetime_in_seconds: u64, v: T) -> Result<(), RedisCacheError> {
58+
let mut connection = self.client.get_multiplexed_async_connection().await?;
59+
60+
let encrypted_value: Vec<u8> = crypto::encrypt(&v, self.encryption_key.as_str()).unwrap();
61+
let _: () = connection.set_ex(key, encrypted_value, lifetime_in_seconds).await?;
62+
Ok(())
3863
}
3964
}
4065

4166
#[async_trait::async_trait]
4267
impl Cache for RedisCache {
43-
async fn get_token(&self, client_id: &str, audience: &str) -> Result<Option<Token>, Auth0Error> {
68+
async fn get_token(&self, client_id: &str, audience: &str) -> Result<Option<Token>, CacheError> {
4469
let key: &str = &cache::token_key(client_id, audience);
45-
self.get(key).await
70+
self.get(key).await.map_err(Into::into)
4671
}
4772

48-
async fn put_token(&self, client_id: &str, audience: &str, value_ref: &Token) -> Result<(), Auth0Error> {
73+
async fn put_token(&self, client_id: &str, audience: &str, value_ref: &Token) -> Result<(), CacheError> {
4974
let key: &str = &cache::token_key(client_id, audience);
50-
51-
let mut connection = self.client.get_multiplexed_async_connection().await?;
52-
let encrypted_value: Vec<u8> = crypto::encrypt(value_ref, self.encryption_key.as_str())?;
53-
let expiration = value_ref.lifetime_in_seconds();
54-
let _: () = connection.set_ex(key, encrypted_value, expiration).await?;
55-
Ok(())
75+
self.put(key, value_ref.lifetime_in_seconds(), value_ref)
76+
.await
77+
.map_err(Into::into)
5678
}
5779
}
5880

src/auth0/errors.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use thiserror::Error;
22

3+
use super::cache;
4+
35
#[derive(Debug, Error)]
46
pub enum Auth0Error {
57
#[error(transparent)]
@@ -12,8 +14,8 @@ pub enum Auth0Error {
1214
JwtFetchDeserializationError(String, reqwest::Error),
1315
#[error("failed to fetch jwt from {0}. Status code: {0}; error: {1}")]
1416
JwksHttpError(String, reqwest::Error),
15-
#[error("redis error: {0}")]
16-
RedisError(#[from] redis::RedisError),
17+
#[error("cache error: {0}")]
18+
CacheError(#[from] cache::CacheError),
1719
#[error(transparent)]
1820
CryptoError(#[from] chacha20poly1305::Error),
1921
}

src/auth0/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod refresh;
1010
mod token;
1111
mod util;
1212

13-
use cache::Cache;
13+
use cache::{Cache, CacheError};
1414
pub use client::Auth0Client;
1515
pub use config::{CacheType, Config};
1616
pub use errors::Auth0Error;
@@ -29,7 +29,11 @@ impl Auth0 {
2929
} else {
3030
let redis_conn = config.cache_type().redis_connection_url().to_string();
3131
let encryption_key = config.token_encryption_key().to_string();
32-
Box::new(cache::RedisCache::new(redis_conn, encryption_key).await?)
32+
Box::new(
33+
cache::RedisCache::new(redis_conn, encryption_key)
34+
.await
35+
.map_err(Into::<CacheError>::into)?,
36+
)
3337
};
3438

3539
let client = client::Auth0Client::from_config(&config, client);

0 commit comments

Comments
 (0)