@@ -27,13 +27,47 @@ pub struct TokenStore {
2727}
2828
2929impl TokenStore {
30- pub async fn get_token (
30+ /// For a given [SerialNumber], get the hash of the **latest**, active auth token from the database,
31+ /// if exists. As implied, will return `None` if there is no token in the database where
32+ /// `valid_not_after` is smaller than the current system timestamp.
33+ pub async fn get_valid_token (
34+ & self ,
3135 serial_number : & SerialNumber ,
32- ) -> Result < Zeroizing < String > , SonataDbError > {
33- query ! (
34- // THIS IS WRONG I GOTTA REDO IT
35- "SELECT id WHERE i.serial_number = $1 FROM idcsr as i LEFT JOIN idcert AS c ON i.id JOIN user_tokens AS u ON i.serial_number"
36+ ) -> Result < Option < Zeroizing < String > > , SonataDbError > {
37+ let record = query ! (
38+ r#"
39+ WITH csr_id AS (
40+ -- Get the id from idcsr for the given numeric value
41+ SELECT id
42+ FROM idcsr
43+ WHERE serial_number = $1
44+ ),
45+ valid_cert AS (
46+ -- Check if this id exists in idcert
47+ SELECT c.id
48+ FROM csr_id c
49+ WHERE EXISTS (
50+ SELECT 1
51+ FROM idcert ic
52+ WHERE ic.idcsr_id = c.id
53+ )
54+ )
55+ -- Query user_tokens and select the token with the largest valid_not_after
56+ SELECT ut.token_hash
57+ FROM valid_cert vc
58+ JOIN user_tokens ut ON ut.cert_id = vc.id
59+ WHERE ut.valid_not_after >= NOW() -- only return non-expired tokens
60+ ORDER BY ut.valid_not_after DESC NULLS LAST
61+ LIMIT 1;
62+ "# ,
63+ serial_number. as_bigdecimal( )
3664 )
65+ . fetch_optional ( & self . p . pool )
66+ . await ?;
67+ match record {
68+ Some ( record) => Ok ( Some ( record. token_hash . into ( ) ) ) ,
69+ None => Ok ( None ) ,
70+ }
3771 }
3872}
3973
@@ -57,10 +91,6 @@ pub fn hash_auth_token(auth_token: &str) -> StdResult<String> {
5791 . to_string ( ) )
5892}
5993
60- pub ( crate ) async fn valid_token_in_db ( db : Database , token : & str ) -> crate :: errors:: SonataDbError {
61- todo ! ( )
62- }
63-
6494#[ cfg( test) ]
6595#[ allow( clippy:: unwrap_used) ]
6696mod test {
0 commit comments