@@ -361,131 +361,135 @@ extract_scopes_from_keycloak_permissions(Acc, [_ | T]) ->
361361
362362
363363put_location_attribute (Attribute , Map ) ->
364- put_attribute (binary :split (Attribute , <<" :" >>, [global , trim_all ]), Map ).
364+ put_attribute (binary :split (Attribute , <<" :" >>, [global , trim_all ]), Map ).
365365
366366put_attribute ([Key , Value | _ ], Map ) ->
367- case lists :member (Key , ? LOCATION_ATTRIBUTES ) of
368- true -> maps :put (Key , Value , Map );
369- false -> Map
370- end ;
367+ case lists :member (Key , ? LOCATION_ATTRIBUTES ) of
368+ true -> maps :put (Key , Value , Map );
369+ false -> Map
370+ end ;
371371put_attribute ([_ |_ ], Map ) -> Map .
372372
373373
374374% convert [ <<"cluster:A">>, <<"vhost:B" >>, <<"A">>, <<"unknown:C">> ] to #{ <<"cluster">> : <<"A">>, <<"vhost">> : <<"B">> }
375375% filtering out non-key-value-pairs and keys which are not part of LOCATION_ATTRIBUTES
376376convert_attribute_list_to_attribute_map (L ) ->
377- convert_attribute_list_to_attribute_map (L , #{}).
377+ convert_attribute_list_to_attribute_map (L , #{}).
378378convert_attribute_list_to_attribute_map ([H |L ],Map ) when is_binary (H ) ->
379- convert_attribute_list_to_attribute_map (L , put_location_attribute (H ,Map ));
379+ convert_attribute_list_to_attribute_map (L , put_location_attribute (H ,Map ));
380380convert_attribute_list_to_attribute_map ([], Map ) -> Map .
381381
382382build_permission_resource_path (Map ) ->
383- Vhost = maps :get (? VHOST_LOCATION_ATTRIBUTE , Map , <<" *" >>),
384- Resource = maps :get (? QUEUE_LOCATION_ATTRIBUTE , Map ,
385- maps :get (? EXCHANGE_LOCATION_ATTRIBUTE , Map , <<" *" >>)),
386- RoutingKey = maps :get (? ROUTING_KEY_LOCATION_ATTRIBUTE , Map , <<" *" >>),
383+ Vhost = maps :get (? VHOST_LOCATION_ATTRIBUTE , Map , <<" *" >>),
384+ Resource = maps :get (? QUEUE_LOCATION_ATTRIBUTE , Map ,
385+ maps :get (? EXCHANGE_LOCATION_ATTRIBUTE , Map , <<" *" >>)),
386+ RoutingKey = maps :get (? ROUTING_KEY_LOCATION_ATTRIBUTE , Map , <<" *" >>),
387387
388- <<Vhost /binary ," /" ,Resource /binary ," /" ,RoutingKey /binary >>.
388+ <<Vhost /binary ," /" ,Resource /binary ," /" ,RoutingKey /binary >>.
389389
390390map_locations_to_permission_resource_paths (ResourceServerId , L ) ->
391- Locations = case L of
392- undefined -> [];
393- LocationsAsList when is_list (LocationsAsList ) ->
394- lists :map (fun (Location ) -> convert_attribute_list_to_attribute_map (
395- binary :split (Location ,<<" /" >>,[global ,trim_all ])) end , LocationsAsList );
396- LocationsAsBinary when is_binary (LocationsAsBinary ) ->
397- [convert_attribute_list_to_attribute_map (
398- binary :split (LocationsAsBinary ,<<" /" >>,[global ,trim_all ]))]
399- end ,
391+ Locations = case L of
392+ undefined -> [];
393+ LocationsAsList when is_list (LocationsAsList ) ->
394+ lists :map (fun (Location ) -> convert_attribute_list_to_attribute_map (
395+ binary :split (Location ,<<" /" >>,[global ,trim_all ])) end , LocationsAsList );
396+ LocationsAsBinary when is_binary (LocationsAsBinary ) ->
397+ [convert_attribute_list_to_attribute_map (
398+ binary :split (LocationsAsBinary ,<<" /" >>,[global ,trim_all ]))]
399+ end ,
400400
401- FilteredLocations = lists :filtermap (fun (L2 ) ->
402- case cluster_matches_resource_server_id (L2 , ResourceServerId ) and
403- legal_queue_and_exchange_values (L2 ) of
404- true -> { true , build_permission_resource_path (L2 ) };
405- false -> false
406- end end , Locations ),
401+ FilteredLocations = lists :filtermap (fun (L2 ) ->
402+ case cluster_matches_resource_server_id (L2 , ResourceServerId ) and
403+ legal_queue_and_exchange_values (L2 ) of
404+ true -> { true , build_permission_resource_path (L2 ) };
405+ false -> false
406+ end end , Locations ),
407407
408- FilteredLocations .
408+ FilteredLocations .
409409
410410cluster_matches_resource_server_id (#{? CLUSTER_LOCATION_ATTRIBUTE := Cluster },
411- ResourceServerId ) ->
412- wildcard :match (ResourceServerId , Cluster );
411+ ResourceServerId ) ->
412+ wildcard :match (ResourceServerId , Cluster );
413413
414414cluster_matches_resource_server_id (_ ,_ ) ->
415- false .
415+ false .
416416
417417legal_queue_and_exchange_values (#{? QUEUE_LOCATION_ATTRIBUTE := Queue ,
418- ? EXCHANGE_LOCATION_ATTRIBUTE := Exchange }) ->
419- case Queue of
420- <<>> -> case Exchange of
421- <<>> -> true ;
422- _ -> false
423- end ;
424- _ -> case Exchange of
425- Queue -> true ;
426- _ -> false
427- end
428- end ;
418+ ? EXCHANGE_LOCATION_ATTRIBUTE := Exchange }) ->
419+ case Queue of
420+ <<>> ->
421+ case Exchange of
422+ <<>> -> true ;
423+ _ -> false
424+ end ;
425+ _ ->
426+ case Exchange of
427+ Queue -> true ;
428+ _ -> false
429+ end
430+ end ;
429431legal_queue_and_exchange_values (_ ) -> true .
430432
431433map_rich_auth_permissions_to_scopes (ResourceServerId , Permissions ) ->
432- map_rich_auth_permissions_to_scopes (ResourceServerId , Permissions , []).
434+ map_rich_auth_permissions_to_scopes (ResourceServerId , Permissions , []).
433435map_rich_auth_permissions_to_scopes (_ , [], Acc ) -> Acc ;
434436map_rich_auth_permissions_to_scopes (ResourceServerId ,
435437 [ #{? ACTIONS_FIELD := Actions , ? LOCATIONS_FIELD := Locations } | T ], Acc ) ->
436- ResourcePaths = map_locations_to_permission_resource_paths (ResourceServerId , Locations ),
437- case ResourcePaths of
438- [] -> map_rich_auth_permissions_to_scopes (ResourceServerId , T , Acc );
439- _ -> Scopes = case Actions of
440- undefined -> [];
441- ActionsAsList when is_list (ActionsAsList ) ->
442- build_scopes (ResourceServerId , skip_unknown_actions (ActionsAsList ), ResourcePaths );
443- ActionsAsBinary when is_binary (ActionsAsBinary ) ->
444- build_scopes (ResourceServerId , skip_unknown_actions ([ActionsAsBinary ]), ResourcePaths )
445- end ,
446- map_rich_auth_permissions_to_scopes (ResourceServerId , T , Acc ++ Scopes )
447- end .
438+ ResourcePaths = map_locations_to_permission_resource_paths (ResourceServerId , Locations ),
439+ case ResourcePaths of
440+ [] -> map_rich_auth_permissions_to_scopes (ResourceServerId , T , Acc );
441+ _ ->
442+ Scopes = case Actions of
443+ undefined -> [];
444+ ActionsAsList when is_list (ActionsAsList ) ->
445+ build_scopes (ResourceServerId ,
446+ skip_unknown_actions (ActionsAsList ), ResourcePaths );
447+ ActionsAsBinary when is_binary (ActionsAsBinary ) ->
448+ build_scopes (ResourceServerId ,
449+ skip_unknown_actions ([ActionsAsBinary ]), ResourcePaths )
450+ end ,
451+ map_rich_auth_permissions_to_scopes (ResourceServerId , T , Acc ++ Scopes )
452+ end .
448453
449454skip_unknown_actions (Actions ) ->
450- lists :filter (fun (A ) -> lists :member (A , ? ALLOWED_ACTION_VALUES ) end , Actions ).
455+ lists :filter (fun (A ) -> lists :member (A , ? ALLOWED_ACTION_VALUES ) end , Actions ).
451456
452457produce_list_of_user_tag_or_action_on_resources (ResourceServerId , ActionOrUserTag , Locations ) ->
453- case lists :member (ActionOrUserTag , ? ALLOWED_TAG_VALUES ) of
454- true -> [<< ResourceServerId /binary , " .tag:" , ActionOrUserTag /binary >>];
455- _ -> build_scopes_for_action (ResourceServerId , ActionOrUserTag , Locations , [])
456- end .
458+ case lists :member (ActionOrUserTag , ? ALLOWED_TAG_VALUES ) of
459+ true -> [<< ResourceServerId /binary , " .tag:" , ActionOrUserTag /binary >>];
460+ _ -> build_scopes_for_action (ResourceServerId , ActionOrUserTag , Locations , [])
461+ end .
457462
458463build_scopes_for_action (ResourceServerId , Action , [Location |Locations ], Acc ) ->
459- Scope = << ResourceServerId /binary , " ." , Action /binary , " :" , Location /binary >>,
460- build_scopes_for_action (ResourceServerId , Action , Locations , [ Scope | Acc ] );
464+ Scope = << ResourceServerId /binary , " ." , Action /binary , " :" , Location /binary >>,
465+ build_scopes_for_action (ResourceServerId , Action , Locations , [ Scope | Acc ] );
461466build_scopes_for_action (_ , _ , [], Acc ) -> Acc .
462467
463- build_scopes (ResourceServerId , Actions , Locations ) -> lists :flatmap (
464- fun (Action ) ->
465- produce_list_of_user_tag_or_action_on_resources (ResourceServerId , Action , Locations ) end , Actions ).
468+ build_scopes (ResourceServerId , Actions , Locations ) ->
469+ lists :flatmap (fun (Action ) ->
470+ produce_list_of_user_tag_or_action_on_resources (ResourceServerId ,
471+ Action , Locations ) end , Actions ).
466472
467473is_recognized_permission (#{? ACTIONS_FIELD := _ , ? LOCATIONS_FIELD := _ , ? TYPE_FIELD := Type }, ResourceServerType ) ->
468- case ResourceServerType of
469- <<>> -> false ;
470- V when V == Type -> true ;
471- _ -> false
472- end ;
474+ case ResourceServerType of
475+ <<>> -> false ;
476+ V when V == Type -> true ;
477+ _ -> false
478+ end ;
473479is_recognized_permission (_ , _ ) -> false .
474480
475481
476482-spec post_process_payload_in_rich_auth_request_format (ResourceServerId :: binary (), Payload :: map ()) -> map ().
477483% % https://oauth.net/2/rich-authorization-requests/
478484post_process_payload_in_rich_auth_request_format (ResourceServerId , #{<<" authorization_details" >> := Permissions } = Payload ) ->
479- ResourceServerType = rabbit_oauth2_config :get_resource_server_type (ResourceServerId ),
485+ ResourceServerType = rabbit_oauth2_config :get_resource_server_type (ResourceServerId ),
480486
481- FilteredPermissionsByType = lists :filter (fun (P ) ->
487+ FilteredPermissionsByType = lists :filter (fun (P ) ->
482488 is_recognized_permission (P , ResourceServerType ) end , Permissions ),
483- AdditionalScopes = map_rich_auth_permissions_to_scopes (ResourceServerId , FilteredPermissionsByType ),
484-
485- ExistingScopes = maps :get (? SCOPE_JWT_FIELD , Payload , []),
486- maps :put (? SCOPE_JWT_FIELD , AdditionalScopes ++ ExistingScopes , Payload ).
487-
489+ AdditionalScopes = map_rich_auth_permissions_to_scopes (ResourceServerId , FilteredPermissionsByType ),
488490
491+ ExistingScopes = maps :get (? SCOPE_JWT_FIELD , Payload , []),
492+ maps :put (? SCOPE_JWT_FIELD , AdditionalScopes ++ ExistingScopes , Payload ).
489493
490494validate_payload (ResourceServerId , DecodedToken ) ->
491495 ScopePrefix = rabbit_oauth2_config :get_scope_prefix (ResourceServerId ),
@@ -502,10 +506,10 @@ validate_payload(ResourceServerId, #{?AUD_JWT_FIELD := Aud} = DecodedToken, _Sco
502506 {error , Err } -> {refused , {invalid_aud , Err }}
503507 end ;
504508validate_payload (ResourceServerId , #{? SCOPE_JWT_FIELD := Scope } = DecodedToken , ScopePrefix ) ->
505- case rabbit_oauth2_config :is_verify_aud (ResourceServerId ) of
506- true -> {error , {badarg , {aud_field_is_missing }}};
507- false -> {ok , DecodedToken #{? SCOPE_JWT_FIELD => filter_scopes (Scope , ScopePrefix )}}
508- end .
509+ case rabbit_oauth2_config :is_verify_aud (ResourceServerId ) of
510+ true -> {error , {badarg , {aud_field_is_missing }}};
511+ false -> {ok , DecodedToken #{? SCOPE_JWT_FIELD => filter_scopes (Scope , ScopePrefix )}}
512+ end .
509513
510514filter_scopes (Scopes , <<" " >>) -> Scopes ;
511515filter_scopes (Scopes , ScopePrefix ) ->
@@ -533,44 +537,44 @@ get_scopes(#{}) -> [].
533537
534538-spec get_expanded_scopes (map (), # resource {}) -> [binary ()].
535539get_expanded_scopes (Token , # resource {virtual_host = VHost }) ->
536- Context = #{ token => Token , vhost => VHost },
537- case maps :get (? SCOPE_JWT_FIELD , Token , []) of
538- [] -> [];
539- Scopes -> lists :map (fun (Scope ) -> list_to_binary (parse_scope (Scope , Context )) end , Scopes )
540- end .
540+ Context = #{ token => Token , vhost => VHost },
541+ case maps :get (? SCOPE_JWT_FIELD , Token , []) of
542+ [] -> [];
543+ Scopes -> lists :map (fun (Scope ) -> list_to_binary (parse_scope (Scope , Context )) end , Scopes )
544+ end .
541545
542546parse_scope (Scope , Context ) ->
543- { Acc0 , _ } = lists :foldl (fun (Elem , { Acc , Stage }) -> parse_scope_part (Elem , Acc , Stage , Context ) end ,
544- { [], undefined }, re :split (Scope ," ([\{ .*\} ])" ,[{return ,list },trim ])),
545- Acc0 .
547+ { Acc0 , _ } = lists :foldl (fun (Elem , { Acc , Stage }) -> parse_scope_part (Elem , Acc , Stage , Context ) end ,
548+ { [], undefined }, re :split (Scope ," ([\{ .*\} ])" ,[{return ,list },trim ])),
549+ Acc0 .
546550
547551parse_scope_part (Elem , Acc , Stage , Context ) ->
548- case Stage of
549- error -> {Acc , error };
550- undefined ->
551- case Elem of
552- " {" -> { Acc , fun capture_var_name /3 };
553- Value -> { Acc ++ Value , Stage }
554- end ;
555- _ -> Stage (Elem , Acc , Context )
556- end .
552+ case Stage of
553+ error -> {Acc , error };
554+ undefined ->
555+ case Elem of
556+ " {" -> { Acc , fun capture_var_name /3 };
557+ Value -> { Acc ++ Value , Stage }
558+ end ;
559+ _ -> Stage (Elem , Acc , Context )
560+ end .
557561
558562capture_var_name (Elem , Acc , #{ token := Token , vhost := Vhost }) ->
559- { Acc ++ resolve_scope_var (Elem , Token , Vhost ), fun expect_closing_var /3 }.
563+ { Acc ++ resolve_scope_var (Elem , Token , Vhost ), fun expect_closing_var /3 }.
560564
561565expect_closing_var (" }" , Acc , _Context ) -> { Acc , undefined };
562566expect_closing_var (_ , _Acc , _Context ) -> {" " , error }.
563567
564568resolve_scope_var (Elem , Token , Vhost ) ->
565- case Elem of
566- " vhost" -> binary_to_list (Vhost );
567- _ ->
568- ElemAsBinary = list_to_binary (Elem ),
569- binary_to_list (case maps :get (ElemAsBinary , Token , ElemAsBinary ) of
569+ case Elem of
570+ " vhost" -> binary_to_list (Vhost );
571+ _ ->
572+ ElemAsBinary = list_to_binary (Elem ),
573+ binary_to_list (case maps :get (ElemAsBinary , Token , ElemAsBinary ) of
570574 Value when is_binary (Value ) -> Value ;
571575 _ -> ElemAsBinary
572576 end )
573- end .
577+ end .
574578
575579% % A token may be present in the password credential or in the rabbit_auth_backend_oauth2
576580% % credential. The former is the most common scenario for the first time authentication.
@@ -620,11 +624,11 @@ username_from(PreferredUsernameClaims, DecodedToken) ->
620624 Username .
621625
622626find_claim_in_token (Claim , Token ) ->
623- case maps :get (Claim , Token , undefined ) of
624- undefined -> false ;
625- ClaimValue when is_binary (ClaimValue ) -> {true , ClaimValue };
626- _ -> false
627- end .
627+ case maps :get (Claim , Token , undefined ) of
628+ undefined -> false ;
629+ ClaimValue when is_binary (ClaimValue ) -> {true , ClaimValue };
630+ _ -> false
631+ end .
628632
629633-define (TAG_SCOPE_PREFIX , <<" tag:" >>).
630634
0 commit comments