@@ -296,6 +296,85 @@ has_additional_scopes_key(ResourceServer, Payload) when is_map(Payload) ->
296296 ScopeKey -> maps :is_key (ScopeKey , Payload )
297297 end .
298298
299+ % % Path is a binary expression which is a plain word like <<"roles">>
300+ % % or +1 word separated by . like <<"authorization.permissions.scopes">>
301+ % % The Payload is a map.
302+ % % Using the path <<"authorization.permissions.scopes">> as an example
303+ % % 1. lookup the key <<"authorization">> in the Payload
304+ % % 2. if it is found, the next map to use as payload is the value found from the key <<"authorization">>
305+ % % 3. lookup the key <<"permissions">> in the previous map
306+ % % 4. if it is found, it may be a map or a list of maps.
307+ % % 5. if it is a list of maps, iterate each element in the list
308+ % % 6. for each element in the list, which should be a map, find the key <<"scopes">>
309+ % % 7. because there are no more words/keys, return a list of all the values found
310+ % % associated to the word <<"scopes">>
311+ extract_token_value (R , Payload , Path , ValueMapperFun )
312+ when is_map (Payload ), is_binary (Path ), is_function (ValueMapperFun ) ->
313+ extract_token_value_from_map (R , Payload , [], split_path (Path ), ValueMapperFun );
314+ extract_token_value (_ , _ , _ , _ ) ->
315+ [].
316+
317+ extract_scope_list_from_token_value (_R , List ) when is_list (List ) -> List ;
318+ extract_scope_list_from_token_value (_R , Binary ) when is_binary (Binary ) ->
319+ binary :split (Binary , <<" " >>, [global , trim_all ]);
320+ extract_scope_list_from_token_value (# resource_server {id = ResourceServerId }, Map ) when is_map (Map ) ->
321+ case maps :get (ResourceServerId , Map , undefined ) of
322+ undefined -> [];
323+ Ks when is_list (Ks ) ->
324+ [erlang :iolist_to_binary ([ResourceServerId , <<" ." >>, K ]) || K <- Ks ];
325+ ClaimBin when is_binary (ClaimBin ) ->
326+ UnprefixedClaims = binary :split (ClaimBin , <<" " >>, [global , trim_all ]),
327+ [erlang :iolist_to_binary ([ResourceServerId , <<" ." >>, K ]) || K <- UnprefixedClaims ];
328+ _ -> []
329+ end ;
330+ extract_scope_list_from_token_value (_ , _ ) -> [].
331+
332+ extract_token_value_from_map (_ , _Map , Acc , [], _Mapper ) ->
333+ Acc ;
334+ extract_token_value_from_map (R , Map , Acc , [KeyStr ], Mapper ) when is_map (Map ) ->
335+ case maps :find (KeyStr , Map ) of
336+ {ok , Value } -> Acc ++ Mapper (R , Value );
337+ error -> Acc
338+ end ;
339+ extract_token_value_from_map (R , Map , Acc , [KeyStr | Rest ], Mapper ) when is_map (Map ) ->
340+ case maps :find (KeyStr , Map ) of
341+ {ok , M } when is_map (M ) -> extract_token_value_from_map (R , M , Acc , Rest , Mapper );
342+ {ok , L } when is_list (L ) -> extract_token_value_from_list (R , L , Acc , Rest , Mapper );
343+ {ok , Value } when Rest =:= [] -> Acc ++ Mapper (R , Value );
344+ _ -> Acc
345+ end ;
346+ extract_token_value_from_map (_ , _ , Acc , _ , _Mapper ) ->
347+ Acc .
348+
349+ extract_token_value_from_list (_ , [], Acc , [], _Mapper ) ->
350+ Acc ;
351+ extract_token_value_from_list (_ , [], Acc , [_KeyStr | _Rest ], _Mapper ) ->
352+ Acc ;
353+ extract_token_value_from_list (R , [H | T ], Acc , [KeyStr | Rest ] = KeyList , Mapper ) when is_map (H ) ->
354+ NewAcc = case maps :find (KeyStr , H ) of
355+ {ok , Map } when is_map (Map ) -> extract_token_value_from_map (R , Map , Acc , Rest , Mapper );
356+ {ok , List } when is_list (List ) -> extract_token_value_from_list (R , List , Acc , Rest , Mapper );
357+ {ok , Value } -> Acc ++ Mapper (R , Value );
358+ _ -> Acc
359+ end ,
360+ extract_token_value_from_list (R , T , NewAcc , KeyList , Mapper );
361+
362+ extract_token_value_from_list (R , [E | T ], Acc , [], Mapper ) ->
363+ extract_token_value_from_list (R , T , Acc ++ Mapper (R , E ), [], Mapper );
364+ extract_token_value_from_list (R , [E | _T ] = L , Acc , KeyList , Mapper ) when is_map (E ) ->
365+ extract_token_value_from_list (R , L , Acc , KeyList , Mapper );
366+ extract_token_value_from_list (R , [_ | T ], Acc , KeyList , Mapper ) ->
367+ extract_token_value_from_list (R , T , Acc , KeyList , Mapper ).
368+
369+
370+ % split_path(Path) when is_list(Path) ->
371+ % string:tokens(Path, ".");
372+ split_path (Path ) when is_binary (Path ) ->
373+ binary :split (Path , <<" ." >>, [global , trim_all ]).
374+
375+
376+
377+
299378-spec extract_scopes_from_additional_scopes_key (
300379 ResourceServer :: resource_server (), Payload :: map ()) -> map ().
301380extract_scopes_from_additional_scopes_key (ResourceServer , Payload ) ->
0 commit comments