1
- use super :: jsonapi:: Error ;
2
1
use axum:: {
3
2
async_trait,
4
3
body:: { Bytes , HttpBody } ,
5
4
extract:: {
6
5
rejection:: TypedHeaderRejection , FromRequest , FromRequestParts , Json as AxumJson ,
7
- Path as AxumPath , TypedHeader as AxumTypedHeader ,
6
+ Path as AxumPath , Query , TypedHeader as AxumTypedHeader ,
8
7
} ,
9
8
headers:: {
10
9
authorization:: { Authorization , Bearer } ,
@@ -21,6 +20,7 @@ use jsonwebtoken::{
21
20
use serde:: { de:: DeserializeOwned , Deserialize , Serialize } ;
22
21
use thiserror:: Error ;
23
22
23
+ use super :: jsonapi:: Error as JsonAPIError ;
24
24
use base:: setting:: { get_settings, SettingsError } ;
25
25
26
26
static HEADER_VALUE : & str = "application/vnd.api+json" ;
@@ -47,7 +47,7 @@ impl IntoResponse for JsonError {
47
47
JsonError :: Io | JsonError :: BodyRead ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
48
48
JsonError :: Mime | JsonError :: Syntax ( _) | JsonError :: Data ( _) => StatusCode :: BAD_REQUEST ,
49
49
} ;
50
- let err = Error {
50
+ let err = JsonAPIError {
51
51
status,
52
52
title : "Could not parse JSON request body" . to_string ( ) ,
53
53
detail : Some ( self . into ( ) ) ,
@@ -140,7 +140,7 @@ pub enum TypedHeaderError {
140
140
141
141
impl IntoResponse for TypedHeaderError {
142
142
fn into_response ( self ) -> Response {
143
- Error {
143
+ JsonAPIError {
144
144
status : StatusCode :: BAD_REQUEST ,
145
145
title : self . to_string ( ) ,
146
146
detail : match self {
@@ -173,12 +173,12 @@ where
173
173
T : DeserializeOwned + Send ,
174
174
S : Send + Sync ,
175
175
{
176
- type Rejection = Error ;
176
+ type Rejection = JsonAPIError ;
177
177
178
178
async fn from_request_parts ( parts : & mut Parts , state : & S ) -> Result < Self , Self :: Rejection > {
179
179
let AxumPath ( t) = AxumPath :: < T > :: from_request_parts ( parts, state)
180
180
. await
181
- . map_err ( |e| Error {
181
+ . map_err ( |e| Self :: Rejection {
182
182
status : StatusCode :: NOT_FOUND ,
183
183
title : "Invalid URL path" . to_string ( ) ,
184
184
detail : Some ( e. into ( ) ) ,
@@ -206,7 +206,7 @@ pub enum ClaimsError {
206
206
Settings ( #[ from] SettingsError ) ,
207
207
208
208
#[ error( "Missing Authorization header" ) ]
209
- TypedHeader ( # [ from ] TypedHeaderError ) ,
209
+ Missing ,
210
210
211
211
#[ error( "Invalid authentication token" ) ]
212
212
Unauthorized ( #[ from] JwtError ) ,
@@ -218,19 +218,26 @@ impl IntoResponse for ClaimsError {
218
218
ClaimsError :: Settings ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
219
219
_ => StatusCode :: UNAUTHORIZED ,
220
220
} ;
221
- Error {
221
+ JsonAPIError {
222
222
status,
223
223
title : self . to_string ( ) ,
224
224
detail : match self {
225
225
ClaimsError :: Settings ( e) => Some ( Box :: new ( e) ) ,
226
- ClaimsError :: TypedHeader ( e) => Some ( Box :: new ( e) ) ,
226
+ ClaimsError :: Missing => {
227
+ Some ( "No Authorization header or query parameter found" . into ( ) )
228
+ }
227
229
ClaimsError :: Unauthorized ( e) => Some ( Box :: new ( e) ) ,
228
230
} ,
229
231
}
230
232
. into_response ( )
231
233
}
232
234
}
233
235
236
+ #[ derive( Debug , Serialize , Deserialize ) ]
237
+ struct ClaimsQuery {
238
+ pub authorization : String ,
239
+ }
240
+
234
241
#[ async_trait]
235
242
impl < S > FromRequestParts < S > for Claims
236
243
where
@@ -239,9 +246,21 @@ where
239
246
type Rejection = ClaimsError ;
240
247
241
248
async fn from_request_parts ( parts : & mut Parts , state : & S ) -> Result < Self , Self :: Rejection > {
242
- let TypedHeader ( header) =
243
- TypedHeader :: < Authorization < Bearer > > :: from_request_parts ( parts, state) . await ?;
244
- check_token ( header. token ( ) ) . map ( |td| td. claims )
249
+ match TypedHeader :: < Authorization < Bearer > > :: from_request_parts ( parts, state)
250
+ . await
251
+ . ok ( )
252
+ {
253
+ Some ( TypedHeader ( header) ) => check_token ( header. token ( ) ) . map ( |td| td. claims ) ,
254
+ None => match Query :: < ClaimsQuery > :: from_request_parts ( parts, state)
255
+ . await
256
+ . ok ( )
257
+ {
258
+ Some ( Query ( ClaimsQuery { authorization } ) ) => {
259
+ check_token ( & authorization) . map ( |td| td. claims )
260
+ }
261
+ None => Err ( Self :: Rejection :: Missing ) ,
262
+ } ,
263
+ }
245
264
}
246
265
}
247
266
0 commit comments