@@ -7,6 +7,7 @@ use error_stack::{report, IntoReport, ResultExt};
7
7
use external_services:: kms:: { self , decrypt:: KmsDecrypt } ;
8
8
use jsonwebtoken:: { decode, Algorithm , DecodingKey , Validation } ;
9
9
use masking:: { PeekInterface , StrongSecret } ;
10
+ use serde:: Serialize ;
10
11
11
12
use crate :: {
12
13
configs:: settings,
@@ -21,11 +22,51 @@ use crate::{
21
22
utils:: OptionExt ,
22
23
} ;
23
24
25
+ #[ derive( Clone , Debug ) ]
24
26
pub struct AuthenticationData {
25
27
pub merchant_account : domain:: MerchantAccount ,
26
28
pub key_store : domain:: MerchantKeyStore ,
27
29
}
28
30
31
+ #[ derive( Clone , Debug , Eq , PartialEq , Serialize ) ]
32
+ #[ serde( tag = "api_auth_type" ) ]
33
+ pub enum AuthenticationType {
34
+ ApiKey {
35
+ merchant_id : String ,
36
+ key_id : String ,
37
+ } ,
38
+ AdminApiKey ,
39
+ MerchantJWT {
40
+ merchant_id : String ,
41
+ user_id : Option < String > ,
42
+ } ,
43
+ MerchantID {
44
+ merchant_id : String ,
45
+ } ,
46
+ PublishableKey {
47
+ merchant_id : String ,
48
+ } ,
49
+ NoAuth ,
50
+ }
51
+
52
+ impl AuthenticationType {
53
+ pub fn get_merchant_id ( & self ) -> Option < & str > {
54
+ match self {
55
+ Self :: ApiKey {
56
+ merchant_id,
57
+ key_id : _,
58
+ }
59
+ | Self :: MerchantID { merchant_id }
60
+ | Self :: PublishableKey { merchant_id }
61
+ | Self :: MerchantJWT {
62
+ merchant_id,
63
+ user_id : _,
64
+ } => Some ( merchant_id. as_ref ( ) ) ,
65
+ Self :: AdminApiKey | Self :: NoAuth => None ,
66
+ }
67
+ }
68
+ }
69
+
29
70
pub trait AuthInfo {
30
71
fn get_merchant_id ( & self ) -> Option < & str > ;
31
72
}
@@ -46,13 +87,12 @@ impl AuthInfo for AuthenticationData {
46
87
pub trait AuthenticateAndFetch < T , A >
47
88
where
48
89
A : AppStateInfo ,
49
- T : AuthInfo ,
50
90
{
51
91
async fn authenticate_and_fetch (
52
92
& self ,
53
93
request_headers : & HeaderMap ,
54
94
state : & A ,
55
- ) -> RouterResult < T > ;
95
+ ) -> RouterResult < ( T , AuthenticationType ) > ;
56
96
}
57
97
58
98
#[ derive( Debug ) ]
69
109
& self ,
70
110
_request_headers : & HeaderMap ,
71
111
_state : & A ,
72
- ) -> RouterResult < ( ) > {
73
- Ok ( ( ) )
112
+ ) -> RouterResult < ( ( ) , AuthenticationType ) > {
113
+ Ok ( ( ( ) , AuthenticationType :: NoAuth ) )
74
114
}
75
115
}
76
116
83
123
& self ,
84
124
request_headers : & HeaderMap ,
85
125
state : & A ,
86
- ) -> RouterResult < AuthenticationData > {
126
+ ) -> RouterResult < ( AuthenticationData , AuthenticationType ) > {
87
127
let api_key = get_api_key ( request_headers)
88
128
. change_context ( errors:: ApiErrorResponse :: Unauthorized ) ?
89
129
. trim ( ) ;
@@ -139,10 +179,17 @@ where
139
179
. await
140
180
. to_not_found_response ( errors:: ApiErrorResponse :: Unauthorized ) ?;
141
181
142
- Ok ( AuthenticationData {
182
+ let auth = AuthenticationData {
143
183
merchant_account : merchant,
144
184
key_store,
145
- } )
185
+ } ;
186
+ Ok ( (
187
+ auth. clone ( ) ,
188
+ AuthenticationType :: ApiKey {
189
+ merchant_id : auth. merchant_account . merchant_id . clone ( ) ,
190
+ key_id : stored_api_key. key_id ,
191
+ } ,
192
+ ) )
146
193
}
147
194
}
148
195
@@ -183,7 +230,7 @@ where
183
230
& self ,
184
231
request_headers : & HeaderMap ,
185
232
state : & A ,
186
- ) -> RouterResult < ( ) > {
233
+ ) -> RouterResult < ( ( ) , AuthenticationType ) > {
187
234
let request_admin_api_key =
188
235
get_api_key ( request_headers) . change_context ( errors:: ApiErrorResponse :: Unauthorized ) ?;
189
236
let conf = state. conf ( ) ;
@@ -200,7 +247,7 @@ where
200
247
. attach_printable ( "Admin Authentication Failure" ) ) ?;
201
248
}
202
249
203
- Ok ( ( ) )
250
+ Ok ( ( ( ) , AuthenticationType :: AdminApiKey ) )
204
251
}
205
252
}
206
253
@@ -216,7 +263,7 @@ where
216
263
& self ,
217
264
_request_headers : & HeaderMap ,
218
265
state : & A ,
219
- ) -> RouterResult < AuthenticationData > {
266
+ ) -> RouterResult < ( AuthenticationData , AuthenticationType ) > {
220
267
let key_store = state
221
268
. store ( )
222
269
. get_merchant_key_store_by_merchant_id (
@@ -245,10 +292,16 @@ where
245
292
}
246
293
} ) ?;
247
294
248
- Ok ( AuthenticationData {
295
+ let auth = AuthenticationData {
249
296
merchant_account : merchant,
250
297
key_store,
251
- } )
298
+ } ;
299
+ Ok ( (
300
+ auth. clone ( ) ,
301
+ AuthenticationType :: MerchantID {
302
+ merchant_id : auth. merchant_account . merchant_id . clone ( ) ,
303
+ } ,
304
+ ) )
252
305
}
253
306
}
254
307
@@ -264,7 +317,7 @@ where
264
317
& self ,
265
318
request_headers : & HeaderMap ,
266
319
state : & A ,
267
- ) -> RouterResult < AuthenticationData > {
320
+ ) -> RouterResult < ( AuthenticationData , AuthenticationType ) > {
268
321
let publishable_key =
269
322
get_api_key ( request_headers) . change_context ( errors:: ApiErrorResponse :: Unauthorized ) ?;
270
323
@@ -279,6 +332,14 @@ where
279
332
e. change_context ( errors:: ApiErrorResponse :: InternalServerError )
280
333
}
281
334
} )
335
+ . map ( |auth| {
336
+ (
337
+ auth. clone ( ) ,
338
+ AuthenticationType :: PublishableKey {
339
+ merchant_id : auth. merchant_account . merchant_id . clone ( ) ,
340
+ } ,
341
+ )
342
+ } )
282
343
}
283
344
}
284
345
@@ -300,12 +361,12 @@ where
300
361
& self ,
301
362
request_headers : & HeaderMap ,
302
363
state : & A ,
303
- ) -> RouterResult < ( ) > {
364
+ ) -> RouterResult < ( ( ) , AuthenticationType ) > {
304
365
let mut token = get_jwt ( request_headers) ?;
305
366
token = strip_jwt_token ( token) ?;
306
367
decode_jwt :: < JwtAuthPayloadFetchUnit > ( token, state)
307
368
. await
308
- . map ( |_| ( ) )
369
+ . map ( |_| ( ( ) , AuthenticationType :: NoAuth ) )
309
370
}
310
371
}
311
372
@@ -323,7 +384,7 @@ where
323
384
& self ,
324
385
request_headers : & HeaderMap ,
325
386
state : & A ,
326
- ) -> RouterResult < AuthenticationData > {
387
+ ) -> RouterResult < ( AuthenticationData , AuthenticationType ) > {
327
388
let mut token = get_jwt ( request_headers) ?;
328
389
token = strip_jwt_token ( token) ?;
329
390
let payload = decode_jwt :: < JwtAuthPayloadFetchMerchantAccount > ( token, state) . await ?;
@@ -343,10 +404,17 @@ where
343
404
. await
344
405
. change_context ( errors:: ApiErrorResponse :: InvalidJwtToken ) ?;
345
406
346
- Ok ( AuthenticationData {
407
+ let auth = AuthenticationData {
347
408
merchant_account : merchant,
348
409
key_store,
349
- } )
410
+ } ;
411
+ Ok ( (
412
+ auth. clone ( ) ,
413
+ AuthenticationType :: MerchantJWT {
414
+ merchant_id : auth. merchant_account . merchant_id . clone ( ) ,
415
+ user_id : None ,
416
+ } ,
417
+ ) )
350
418
}
351
419
}
352
420
0 commit comments