1
1
use redis:: AsyncCommands ;
2
- use serde:: Deserialize ;
2
+ use serde:: { Deserialize , Serialize } ;
3
3
4
+ use super :: CacheError ;
4
5
use crate :: auth0:: cache:: { self , crypto, Cache } ;
5
6
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
+ }
7
23
8
24
#[ derive( Clone , Debug ) ]
9
25
pub struct RedisCache {
@@ -13,7 +29,7 @@ pub struct RedisCache {
13
29
14
30
impl RedisCache {
15
31
/// 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 > {
17
33
let client: redis:: Client = redis:: Client :: open ( redis_connection_url) ?;
18
34
// Ensure connection is fine. Should fail otherwise
19
35
let _ = client. get_multiplexed_async_connection ( ) . await ?;
@@ -24,7 +40,7 @@ impl RedisCache {
24
40
} )
25
41
}
26
42
27
- async fn get < T > ( & self , key : & str ) -> Result < Option < T > , Auth0Error >
43
+ async fn get < T > ( & self , key : & str ) -> Result < Option < T > , RedisCacheError >
28
44
where
29
45
for < ' de > T : Deserialize < ' de > ,
30
46
{
@@ -35,24 +51,30 @@ impl RedisCache {
35
51
. await ?
36
52
. map ( |value| crypto:: decrypt ( self . encryption_key . as_str ( ) , value. as_slice ( ) ) )
37
53
. 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 ( ( ) )
38
63
}
39
64
}
40
65
41
66
#[ async_trait:: async_trait]
42
67
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 > {
44
69
let key: & str = & cache:: token_key ( client_id, audience) ;
45
- self . get ( key) . await
70
+ self . get ( key) . await . map_err ( Into :: into )
46
71
}
47
72
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 > {
49
74
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)
56
78
}
57
79
}
58
80
0 commit comments