@@ -11,7 +11,7 @@ use sf_std::{
1111 HeaderName ,
1212} ;
1313
14- use super :: { HttpCallError , HttpRequest , MapValue , MapValueObject } ;
14+ use super :: { HttpCallError , HttpRequest , HttpRequestSecurity , MapValue , MapValueObject } ;
1515
1616pub enum ApiKeyPlacement {
1717 Header ,
@@ -319,25 +319,65 @@ pub fn prepare_security_map(
319319pub fn resolve_security (
320320 security_map : & SecurityMap ,
321321 params : & mut HttpRequest ,
322+ security : & HttpRequestSecurity
322323) -> Result < ( ) , HttpCallError > {
323- let security = match params. security {
324- None => return Ok ( ( ) ) ,
325- Some ( ref security) => security,
326- } ;
324+ match security {
325+ HttpRequestSecurity :: FirstValid ( ref ids) => {
326+ let mut first_error = None ;
327+ for id in ids {
328+ match try_resolve_security ( security_map, params, id) {
329+ Ok ( ( ) ) => return Ok ( ( ) ) ,
330+ Err ( err) => {
331+ if first_error. is_none ( ) {
332+ first_error = Some ( err) ;
333+ }
334+ }
335+ }
336+ }
337+
338+ match first_error {
339+ None => Ok ( ( ) ) ,
340+ Some ( err) => return Err ( HttpCallError :: InvalidSecurityConfiguration (
341+ err
342+ ) )
343+ }
344+ }
345+ HttpRequestSecurity :: All ( ref ids) => {
346+ let mut all_errors = Vec :: new ( ) ;
347+ for id in ids {
348+ match try_resolve_security ( security_map, params, id) {
349+ Ok ( ( ) ) => ( ) ,
350+ Err ( err) => all_errors. push ( err. to_string ( ) )
351+ }
352+ }
327353
328- let security_config = security_map. get ( security. as_str ( ) ) ;
354+ if all_errors. len ( ) > 0 {
355+ return Err ( HttpCallError :: InvalidSecurityConfiguration (
356+ all_errors. join ( "\n " )
357+ ) )
358+ }
359+ Ok ( ( ) )
360+ }
361+ }
362+ }
363+ fn try_resolve_security (
364+ security_map : & SecurityMap ,
365+ params : & mut HttpRequest ,
366+ security : & str
367+ ) -> Result < ( ) , String > {
368+ let security_config = security_map. get ( security) ;
329369
330370 match security_config {
331371 None => {
332- return Err ( HttpCallError :: InvalidSecurityConfiguration ( format ! (
372+ return Err ( format ! (
333373 "Security configuration for {} is missing" ,
334374 security
335- ) ) ) ;
375+ ) ) ;
336376 }
337377 Some ( SecurityMapValue :: Error ( err) ) => {
338- return Err ( HttpCallError :: InvalidSecurityConfiguration (
378+ return Err (
339379 SecurityMisconfiguredError :: format_errors ( std:: slice:: from_ref ( err) ) ,
340- ) ) ;
380+ ) ;
341381 }
342382 Some ( SecurityMapValue :: Security ( Security :: Http ( HttpSecurity :: Basic {
343383 username,
@@ -384,10 +424,10 @@ pub fn resolve_security(
384424 if let Some ( body) = & params. body {
385425 let mut body =
386426 serde_json:: from_slice :: < serde_json:: Value > ( body) . map_err ( |e| {
387- HttpCallError :: InvalidSecurityConfiguration ( format ! (
427+ format ! (
388428 "Failed to parse body: {}" ,
389429 e
390- ) )
430+ )
391431 } ) ?;
392432
393433 let keys = if name. starts_with ( '/' ) {
@@ -397,50 +437,50 @@ pub fn resolve_security(
397437 } ;
398438
399439 if keys. is_empty ( ) {
400- return Err ( HttpCallError :: InvalidSecurityConfiguration ( format ! (
440+ return Err ( format ! (
401441 "Invalid field name '{}'" ,
402442 name
403- ) ) ) ;
443+ ) ) ;
404444 }
405445
406446 let mut nested = & mut body;
407447 for ( key_idx, key) in keys. iter ( ) . enumerate ( ) {
408448 if nested. is_array ( ) {
409449 let key_number = match key. parse :: < usize > ( ) {
410450 Ok ( n) => n,
411- Err ( _) => return Err ( HttpCallError :: InvalidSecurityConfiguration ( format ! (
451+ Err ( _) => return Err ( format ! (
412452 "Field value on path '/{}' is an array but provided key cannot be parsed as a number" ,
413453 & keys[ 0 ..=key_idx] . join( "/" )
414- ) ) )
454+ ) )
415455 } ;
416456 nested = & mut nested[ key_number] ;
417457 } else if nested. is_object ( ) {
418458 nested = & mut nested[ key] ;
419459 } else {
420- return Err ( HttpCallError :: InvalidSecurityConfiguration ( format ! (
460+ return Err ( format ! (
421461 "Field value on path '/{}' must be an object or an array" ,
422462 & keys[ 0 ..=key_idx] . join( "/" )
423- ) ) ) ;
463+ ) ) ;
424464 }
425465 }
426466 * nested = serde_json:: Value :: from ( apikey. to_string ( ) ) ;
427467
428468 params. body = Some ( serde_json:: to_vec ( & body) . map_err ( |e| {
429- HttpCallError :: InvalidSecurityConfiguration ( format ! (
469+ format ! (
430470 "Failed to serialize body: {}" ,
431471 e
432- ) )
472+ )
433473 } ) ?) ;
434474 } else {
435- return Err ( HttpCallError :: InvalidSecurityConfiguration (
475+ return Err (
436476 "Api key placement is set to body but the body is empty" . to_string ( ) ,
437- ) ) ;
477+ ) ;
438478 }
439479 }
440480 ( ApiKeyPlacement :: Body , None ) => {
441- return Err ( HttpCallError :: InvalidSecurityConfiguration (
481+ return Err (
442482 "Missing body type" . to_string ( ) ,
443- ) ) ;
483+ ) ;
444484 }
445485 } ,
446486 }
0 commit comments