@@ -9,16 +9,24 @@ use axum::{
99use chrono:: { DateTime , Utc } ;
1010use nillion_nucs:: did:: Did ;
1111use serde:: { Deserialize , Serialize } ;
12+ use serde_with:: hex:: Hex ;
13+ use serde_with:: serde_as;
1214use strum:: EnumDiscriminants ;
1315use tracing:: error;
1416use utoipa:: { IntoParams , ToSchema } ;
1517
1618/// A request to get a subscription's status.
19+ #[ serde_as]
1720#[ derive( Deserialize , IntoParams ) ]
1821pub ( crate ) struct SubscriptionStatusArgs {
1922 /// The Did to check the subscription for.
2023 #[ param( value_type = String , example = "did:key:zQ3sh..." ) ]
21- did : Did ,
24+ did : Option < Did > ,
25+
26+ /// The Did to check the subscription for.
27+ #[ param( value_type = String ) ]
28+ #[ serde_as( as = "Option<Hex>" ) ]
29+ public_key : Option < [ u8 ; 33 ] > ,
2230
2331 /// The blind module to check the subscription for.
2432 #[ param( value_type = String , example = crate :: docs:: blind_module) ]
@@ -65,13 +73,17 @@ pub(crate) async fn handler(
6573 state : SharedState ,
6674 request : Query < SubscriptionStatusArgs > ,
6775) -> Result < Json < SubscriptionStatusResponse > , HandlerError > {
76+ let did = match ( request. did , request. public_key ) {
77+ ( Some ( did) , _) => did,
78+ #[ allow( deprecated) ]
79+ ( _, Some ( public_key) ) => Did :: nil ( public_key) ,
80+ _ => return Err ( HandlerError :: MissingIdentity ) ,
81+ } ;
6882 let expires_at =
69- state. databases . subscriptions . find_subscription_end ( & request. did , & request. blind_module ) . await . map_err (
70- |e| {
71- error ! ( "Subscription lookup failed: {e}" ) ;
72- HandlerError :: Internal
73- } ,
74- ) ?;
83+ state. databases . subscriptions . find_subscription_end ( & did, & request. blind_module ) . await . map_err ( |e| {
84+ error ! ( "Subscription lookup failed: {e}" ) ;
85+ HandlerError :: Internal
86+ } ) ?;
7587 let details = expires_at. map ( |expires_at| Subscription {
7688 expires_at,
7789 renewable_at : expires_at - state. parameters . subscription_renewal_threshold ,
@@ -83,13 +95,15 @@ pub(crate) async fn handler(
8395#[ derive( Debug , EnumDiscriminants ) ]
8496pub ( crate ) enum HandlerError {
8597 Internal ,
98+ MissingIdentity ,
8699}
87100
88101impl IntoResponse for HandlerError {
89102 fn into_response ( self ) -> Response {
90103 let discriminant = HandlerErrorDiscriminants :: from ( & self ) ;
91104 let ( code, message) = match self {
92105 Self :: Internal => ( StatusCode :: INTERNAL_SERVER_ERROR , "internal error" ) ,
106+ Self :: MissingIdentity => ( StatusCode :: BAD_REQUEST , "need either `did` or `public_key`" ) ,
93107 } ;
94108 let response = RequestHandlerError :: new ( message, format ! ( "{discriminant:?}" ) ) ;
95109 ( code, Json ( response) ) . into_response ( )
@@ -145,7 +159,38 @@ mod tests {
145159 let renewal_threshold = Duration :: from_secs ( 30 ) ;
146160 handler. builder . subscription_renewal_threshold = renewal_threshold;
147161
148- let request = SubscriptionStatusArgs { did : subscriber_did, blind_module } ;
162+ let request = SubscriptionStatusArgs { did : Some ( subscriber_did) , public_key : None , blind_module } ;
163+ let response = handler. invoke ( request) . await . expect ( "handler failed" ) ;
164+ assert ! ( response. subscribed) ;
165+ assert_eq ! (
166+ response. details,
167+ Some ( Subscription { expires_at: timestamp, renewable_at: timestamp - renewal_threshold } )
168+ ) ;
169+ }
170+
171+ #[ tokio:: test]
172+ async fn valid_request_public_key ( ) {
173+ let mut handler = Handler :: default ( ) ;
174+ let key = SecretKey :: random ( & mut rand:: thread_rng ( ) ) ;
175+ let public_key_bytes: [ u8 ; 33 ] = key. public_key ( ) . to_sec1_bytes ( ) . as_ref ( ) . try_into ( ) . unwrap ( ) ;
176+ #[ allow( deprecated) ]
177+ let subscriber_did = Did :: nil ( public_key_bytes) ;
178+ let now = Utc :: now ( ) ;
179+ let timestamp = now + Duration :: from_secs ( 120 ) ;
180+ let blind_module = BlindModule :: NilDb ;
181+ handler. builder . time_service . expect_current_time ( ) . returning ( move || now) ;
182+
183+ handler
184+ . builder
185+ . subscriptions_db
186+ . expect_find_subscription_end ( )
187+ . with ( eq ( subscriber_did) , eq ( blind_module) )
188+ . return_once ( move |_, _| Ok ( Some ( timestamp) ) ) ;
189+
190+ let renewal_threshold = Duration :: from_secs ( 30 ) ;
191+ handler. builder . subscription_renewal_threshold = renewal_threshold;
192+
193+ let request = SubscriptionStatusArgs { did : None , public_key : Some ( public_key_bytes) , blind_module } ;
149194 let response = handler. invoke ( request) . await . expect ( "handler failed" ) ;
150195 assert ! ( response. subscribed) ;
151196 assert_eq ! (
@@ -172,7 +217,7 @@ mod tests {
172217 . with ( eq ( subscriber_did) , eq ( blind_module) )
173218 . return_once ( move |_, _| Ok ( Some ( timestamp) ) ) ;
174219
175- let request = SubscriptionStatusArgs { did : subscriber_did, blind_module } ;
220+ let request = SubscriptionStatusArgs { did : Some ( subscriber_did) , public_key : None , blind_module } ;
176221 let response = handler. invoke ( request) . await . expect ( "handler failed" ) ;
177222 assert ! ( !response. subscribed) ;
178223 response. details . expect ( "subscription should still be returned" ) ;
0 commit comments