7
7
8
8
-module (rabbit_oauth2_schema ).
9
9
10
+ -define (AUTH_OAUTH2 , " auth_oauth2" ).
11
+ -define (SCOPE_ALIASES , " scope_aliases" ).
12
+ -define (RESOURCE_SERVERS , " resource_servers" ).
13
+ -define (OAUTH_PROVIDERS , " oauth_providers" ).
14
+ -define (SIGNING_KEYS , " signing_keys" ).
15
+ -define (AUTH_OAUTH2_SCOPE_ALIASES , ? AUTH_OAUTH2 ++ " ." ++ ? SCOPE_ALIASES ).
16
+ -define (AUTH_OAUTH2_RESOURCE_SERVERS , ? AUTH_OAUTH2 ++ " ." ++ ? RESOURCE_SERVERS ).
17
+ -define (AUTH_OAUTH2_OAUTH_PROVIDERS , ? AUTH_OAUTH2 ++ " ." ++ ? OAUTH_PROVIDERS ).
18
+ -define (AUTH_OAUTH2_SIGNING_KEYS , ? AUTH_OAUTH2 ++ " ." ++ ? SIGNING_KEYS ).
10
19
11
20
-export ([
12
21
translate_oauth_providers /1 ,
13
22
translate_resource_servers /1 ,
14
23
translate_signing_keys /1 ,
15
- translate_endpoint_params /2
24
+ translate_endpoint_params /2 ,
25
+ translate_scope_aliases /1
16
26
]).
17
27
18
28
extract_key_as_binary ({Name ,_ }) -> list_to_binary (Name ).
19
29
extract_value ({_Name ,V }) -> V .
20
30
31
+ -spec translate_scope_aliases ([{list (), binary ()}]) -> map ().
32
+ translate_scope_aliases (Conf ) ->
33
+ Settings = cuttlefish_variable :filter_by_prefix (
34
+ ? AUTH_OAUTH2_SCOPE_ALIASES , Conf ),
35
+ maps :merge (extract_scope_alias_as_map (Settings ),
36
+ extract_scope_aliases_as_list_of_alias_scope_props (Settings )).
37
+
38
+ convert_space_separated_string_to_list_of_binaries (String ) ->
39
+ [ list_to_binary (V ) || V <- string :tokens (String , " " )].
40
+
41
+ extract_scope_alias_as_map (Settings ) ->
42
+ maps :from_list ([{
43
+ list_to_binary (Alias ),
44
+ convert_space_separated_string_to_list_of_binaries (Scope )
45
+ }
46
+ || {[? AUTH_OAUTH2 , ? SCOPE_ALIASES , Alias ], Scope } <- Settings ]).
47
+
48
+ extract_scope_aliases_as_list_of_alias_scope_props (Settings ) ->
49
+ KeyFun = fun extract_key_as_binary /1 ,
50
+ ValueFun = fun extract_value /1 ,
51
+
52
+ List0 = [{Index , {list_to_atom (Attr ), V }}
53
+ || {[? AUTH_OAUTH2 , ? SCOPE_ALIASES , Index , Attr ], V } <- Settings ],
54
+ List1 = maps :to_list (maps :groups_from_list (KeyFun , ValueFun , List0 )),
55
+ List2 = [extract_scope_alias_mapping (Proplist ) || {_ , Proplist } <- List1 ],
56
+ maps :from_list ([ V || V <- List2 , V =/= {}]).
57
+
58
+ extract_scope_alias_mapping (Proplist ) ->
59
+ Alias =
60
+ case proplists :get_value (alias , Proplist ) of
61
+ undefined -> {error , missing_alias_attribute };
62
+ A -> list_to_binary (A )
63
+ end ,
64
+ Scope =
65
+ case proplists :get_value (scope , Proplist ) of
66
+ undefined -> {error , missing_scope_attribute };
67
+ S -> convert_space_separated_string_to_list_of_binaries (S )
68
+ end ,
69
+ case {Alias , Scope } of
70
+ {{error , _ }, _ } ->
71
+ cuttlefish :warn (
72
+ " Skipped scope_aliases due to missing alias attribute" ),
73
+ {};
74
+ {_ , {error , _ }} ->
75
+ cuttlefish :warn (
76
+ " Skipped scope_aliases due to missing scope attribute" ),
77
+ {};
78
+ _ = V -> V
79
+ end .
80
+
81
+ extract_resource_server_scope_aliases_as_list_of_props (Settings ) ->
82
+ KeyFun = fun extract_key_as_binary /1 ,
83
+ ValueFun = fun extract_value /1 ,
84
+
85
+ List0 = [
86
+ {
87
+ Name ,
88
+ {Index , {list_to_atom (Attr ), V }}
89
+ } ||
90
+ {[
91
+ ? AUTH_OAUTH2 , ? RESOURCE_SERVERS , Name , ? SCOPE_ALIASES ,
92
+ Index , Attr
93
+ ], V
94
+ } <- Settings ],
95
+ Map0 = maps :groups_from_list (KeyFun , ValueFun , List0 ),
96
+
97
+ Map4 = maps :map (fun (_ , L ) ->
98
+ Map2 = maps :map (fun (_ , L2 ) -> extract_scope_alias_mapping (L2 ) end ,
99
+ maps :groups_from_list (KeyFun , ValueFun , L )),
100
+ Map3 = maps :filter (fun (_ ,V ) -> V =/= {} end , Map2 ),
101
+ [{scope_aliases , maps :from_list ([ V || {_ , V } <- maps :to_list (Map3 )])}]
102
+ end , Map0 ),
103
+
104
+ Map4 .
105
+
106
+ extract_resource_server_scope_aliases_as_map (Settings ) ->
107
+ KeyFun = fun extract_key_as_binary /1 ,
108
+ ValueFun = fun extract_value /1 ,
109
+
110
+ List0 = [
111
+ {
112
+ Name ,
113
+ {
114
+ list_to_binary (Alias ),
115
+ convert_space_separated_string_to_list_of_binaries (Scope )
116
+ }
117
+ } ||
118
+ {[
119
+ ? AUTH_OAUTH2 , ? RESOURCE_SERVERS , Name , ? SCOPE_ALIASES ,
120
+ Alias
121
+ ], Scope
122
+ } <- Settings ],
123
+ Map0 = maps :groups_from_list (KeyFun , ValueFun , List0 ),
124
+ maps :map (fun (_ , L ) -> [{scope_aliases , maps :from_list (L )}] end , Map0 ).
125
+
21
126
-spec translate_resource_servers ([{list (), binary ()}]) -> map ().
22
127
translate_resource_servers (Conf ) ->
23
- Settings = cuttlefish_variable :filter_by_prefix (" auth_oauth2.resource_servers " ,
24
- Conf ),
128
+ Settings = cuttlefish_variable :filter_by_prefix (
129
+ ? AUTH_OAUTH2_RESOURCE_SERVERS , Conf ),
25
130
Map = merge_list_of_maps ([
26
131
extract_resource_server_properties (Settings ),
27
- extract_resource_server_preferred_username_claims (Settings )
132
+ extract_resource_server_preferred_username_claims (Settings ),
133
+ extract_resource_server_scope_aliases_as_list_of_props (Settings ),
134
+ extract_resource_server_scope_aliases_as_map (Settings )
28
135
]),
29
136
Map0 = maps :map (fun (K ,V ) ->
30
137
case proplists :get_value (id , V ) of
31
138
undefined -> V ++ [{id , K }];
32
139
_ -> V
33
140
end end , Map ),
34
141
ResourceServers = maps :values (Map0 ),
35
- lists :foldl (fun (Elem ,AccMap ) ->
36
- maps :put (proplists :get_value (id , Elem ), Elem , AccMap ) end , #{},
37
- ResourceServers ).
142
+ lists :foldl (fun (Elem ,AccMap )-> maps :put (proplists :get_value (id , Elem ),
143
+ Elem , AccMap ) end , #{}, ResourceServers ).
38
144
39
145
-spec translate_oauth_providers ([{list (), binary ()}]) -> map ().
40
146
translate_oauth_providers (Conf ) ->
41
- Settings = cuttlefish_variable :filter_by_prefix (" auth_oauth2.oauth_providers " ,
42
- Conf ),
147
+ Settings = cuttlefish_variable :filter_by_prefix (
148
+ ? AUTH_OAUTH2_OAUTH_PROVIDERS , Conf ),
43
149
44
150
merge_list_of_maps ([
45
151
extract_oauth_providers_properties (Settings ),
@@ -52,8 +158,8 @@ translate_oauth_providers(Conf) ->
52
158
53
159
-spec translate_signing_keys ([{list (), binary ()}]) -> map ().
54
160
translate_signing_keys (Conf ) ->
55
- Settings = cuttlefish_variable :filter_by_prefix (" auth_oauth2.signing_keys " ,
56
- Conf ),
161
+ Settings = cuttlefish_variable :filter_by_prefix (
162
+ ? AUTH_OAUTH2_SIGNING_KEYS , Conf ),
57
163
ListOfKidPath = lists :map (fun ({Id , Path }) -> {
58
164
list_to_binary (lists :last (Id )), Path } end , Settings ),
59
165
translate_list_of_signing_keys (ListOfKidPath ).
@@ -66,9 +172,9 @@ translate_list_of_signing_keys(ListOfKidPath) ->
66
172
{ok , Bin } ->
67
173
string :trim (Bin , trailing , " \n " );
68
174
_Error ->
69
- % % this throws and makes Cuttlefish treak the key as invalid
70
- cuttlefish : invalid ( " file does not exist or cannot be " ++
71
- " read by the node " )
175
+ cuttlefish : invalid ( io_lib : format (
176
+ " File ~p does not exist or cannot be read by the node " ,
177
+ [ Path ]) )
72
178
end
73
179
end ,
74
180
maps :map (fun (_K , Path ) -> {pem , TryReadingFileFun (Path )} end ,
@@ -87,7 +193,6 @@ validator_file_exists(Attr, Filename) ->
87
193
{ok , _ } ->
88
194
Filename ;
89
195
_Error ->
90
- % % this throws and makes Cuttlefish treak the key as invalid
91
196
cuttlefish :invalid (io_lib :format (
92
197
" Invalid attribute (~p ) value: file ~p does not exist or " ++
93
198
" cannot be read by the node" , [Attr , Filename ]))
@@ -111,21 +216,23 @@ validator_https_uri(Attr, Uri) when is_list(Uri) ->
111
216
true -> Uri ;
112
217
false ->
113
218
cuttlefish :invalid (io_lib :format (
114
- " Invalid attribute (~p ) value: uri ~p must be a valid https uri " ,
115
- [Attr , Uri ]))
219
+ " Invalid attribute (~p ) value: uri ~p must be a valid " ++
220
+ " https uri " , [Attr , Uri ]))
116
221
end .
117
222
118
223
merge_list_of_maps (ListOfMaps ) ->
119
- lists :foldl (fun (Elem , AccIn ) -> maps :merge_with (fun ( _K , V1 , V2 ) -> V1 ++ V2 end ,
120
- Elem , AccIn ) end , #{}, ListOfMaps ).
224
+ lists :foldl (fun (Elem , AccIn ) -> maps :merge_with (
225
+ fun ( _K , V1 , V2 ) -> V1 ++ V2 end , Elem , AccIn ) end , #{}, ListOfMaps ).
121
226
122
227
extract_oauth_providers_properties (Settings ) ->
123
228
KeyFun = fun extract_key_as_binary /1 ,
124
229
ValueFun = fun extract_value /1 ,
125
230
126
- OAuthProviders = [
127
- {Name , mapOauthProviderProperty ({list_to_atom (Key ), list_to_binary (V )})}
128
- || {[" auth_oauth2" , " oauth_providers" , Name , Key ], V } <- Settings ],
231
+ OAuthProviders = [{Name , mapOauthProviderProperty (
232
+ {
233
+ list_to_atom (Key ),
234
+ list_to_binary (V )})
235
+ } || {[? AUTH_OAUTH2 , ? OAUTH_PROVIDERS , Name , Key ], V } <- Settings ],
129
236
maps :groups_from_list (KeyFun , ValueFun , OAuthProviders ).
130
237
131
238
@@ -134,7 +241,7 @@ extract_resource_server_properties(Settings) ->
134
241
ValueFun = fun extract_value /1 ,
135
242
136
243
OAuthProviders = [{Name , {list_to_atom (Key ), list_to_binary (V )}}
137
- || {[" auth_oauth2 " , " resource_servers " , Name , Key ], V } <- Settings ],
244
+ || {[? AUTH_OAUTH2 , ? RESOURCE_SERVERS , Name , Key ], V } <- Settings ],
138
245
maps :groups_from_list (KeyFun , ValueFun , OAuthProviders ).
139
246
140
247
mapOauthProviderProperty ({Key , Value }) ->
@@ -156,7 +263,7 @@ extract_oauth_providers_https(Settings) ->
156
263
ExtractProviderNameFun = fun extract_key_as_binary /1 ,
157
264
158
265
AttributesPerProvider = [{Name , mapHttpProperty ({list_to_atom (Key ), V })} ||
159
- {[" auth_oauth2 " , " oauth_providers " , Name , " https" , Key ], V } <- Settings ],
266
+ {[? AUTH_OAUTH2 , ? OAUTH_PROVIDERS , Name , " https" , Key ], V } <- Settings ],
160
267
161
268
maps :map (fun (_K ,V )-> [{https , V }] end ,
162
269
maps :groups_from_list (ExtractProviderNameFun , fun ({_ , V }) -> V end ,
@@ -172,7 +279,7 @@ extract_oauth_providers_algorithm(Settings) ->
172
279
KeyFun = fun extract_key_as_binary /1 ,
173
280
174
281
IndexedAlgorithms = [{Name , {Index , list_to_binary (V )}} ||
175
- {[" auth_oauth2 " , " oauth_providers " , Name , " algorithms" , Index ], V }
282
+ {[? AUTH_OAUTH2 , ? OAUTH_PROVIDERS , Name , " algorithms" , Index ], V }
176
283
<- Settings ],
177
284
SortedAlgorithms = lists :sort (fun ({_ ,{AI ,_ }},{_ ,{BI ,_ }}) -> AI < BI end ,
178
285
IndexedAlgorithms ),
@@ -184,7 +291,7 @@ extract_resource_server_preferred_username_claims(Settings) ->
184
291
KeyFun = fun extract_key_as_binary /1 ,
185
292
186
293
IndexedClaims = [{Name , {Index , list_to_binary (V )}} ||
187
- {[" auth_oauth2 " , " resource_servers " , Name , " preferred_username_claims" ,
294
+ {[? AUTH_OAUTH2 , ? RESOURCE_SERVERS , Name , " preferred_username_claims" ,
188
295
Index ], V } <- Settings ],
189
296
SortedClaims = lists :sort (fun ({_ ,{AI ,_ }},{_ ,{BI ,_ }}) -> AI < BI end ,
190
297
IndexedClaims ),
@@ -205,7 +312,7 @@ extract_oauth_providers_signing_keys(Settings) ->
205
312
KeyFun = fun extract_key_as_binary /1 ,
206
313
207
314
IndexedSigningKeys = [{Name , {list_to_binary (Kid ), list_to_binary (V )}} ||
208
- {[" auth_oauth2 " , " oauth_providers " , Name , " signing_keys " , Kid ], V }
315
+ {[? AUTH_OAUTH2 , ? OAUTH_PROVIDERS , Name , ? SIGNING_KEYS , Kid ], V }
209
316
<- Settings ],
210
317
maps :map (fun (_K ,V )-> [{signing_keys , translate_list_of_signing_keys (V )}] end ,
211
318
maps :groups_from_list (KeyFun , fun ({_ , V }) -> V end , IndexedSigningKeys )).
0 commit comments