@@ -58,6 +58,11 @@ description() ->
58
58
59
59
% %--------------------------------------------------------------------
60
60
61
+ -spec user_login_authentication (rabbit_types :username (), [term ()] | map ()) ->
62
+ {'ok' , rabbit_types :auth_user ()} |
63
+ {'refused' , string (), [any ()]} |
64
+ {'error' , any ()}.
65
+
61
66
user_login_authentication (Username , AuthProps ) ->
62
67
case authenticate (Username , AuthProps ) of
63
68
{refused , Msg , Args } = AuthResult ->
@@ -67,12 +72,21 @@ user_login_authentication(Username, AuthProps) ->
67
72
AuthResult
68
73
end .
69
74
75
+ -spec user_login_authorization (rabbit_types :username (), [term ()] | map ()) ->
76
+ {'ok' , any ()} |
77
+ {'ok' , any (), any ()} |
78
+ {'refused' , string (), [any ()]} |
79
+ {'error' , any ()}.
80
+
70
81
user_login_authorization (Username , AuthProps ) ->
71
82
case authenticate (Username , AuthProps ) of
72
83
{ok , # auth_user {impl = Impl }} -> {ok , Impl };
73
84
Else -> Else
74
85
end .
75
86
87
+ -spec check_vhost_access (AuthUser :: rabbit_types :auth_user (),
88
+ VHost :: rabbit_types :vhost (),
89
+ AuthzData :: rabbit_types :authz_data ()) -> boolean () | {'error' , any ()}.
76
90
check_vhost_access (# auth_user {impl = DecodedTokenFun },
77
91
VHost , _AuthzData ) ->
78
92
with_decoded_token (DecodedTokenFun (),
@@ -136,6 +150,11 @@ expiry_timestamp(#auth_user{impl = DecodedTokenFun}) ->
136
150
137
151
% %--------------------------------------------------------------------
138
152
153
+ -spec authenticate (Username , Props ) -> Result
154
+ when Username :: rabbit_types :username (),
155
+ Props :: list () | map (),
156
+ Result :: {ok , any ()} | {refused , list (), list ()} | {refused , {error , any ()}}.
157
+
139
158
authenticate (_ , AuthProps0 ) ->
140
159
AuthProps = to_map (AuthProps0 ),
141
160
Token = token_from_context (AuthProps ),
@@ -148,31 +167,45 @@ authenticate(_, AuthProps0) ->
148
167
{refused , " Authentication using an OAuth 2/JWT token failed: provided token is invalid" , []};
149
168
{refused , Err } ->
150
169
{refused , " Authentication using an OAuth 2/JWT token failed: ~tp " , [Err ]};
151
- {ok , DecodedToken } ->
152
- Func = fun (Token0 ) ->
153
- Username = username_from (
154
- ResourceServer # resource_server .preferred_username_claims ,
155
- Token0 ),
156
- Tags = tags_from (Token0 ),
157
- {ok , # auth_user {username = Username ,
158
- tags = Tags ,
159
- impl = fun () -> Token0 end }}
160
- end ,
161
- case with_decoded_token (DecodedToken , Func ) of
170
+ {ok , DecodedToken } ->
171
+ case with_decoded_token (DecodedToken , fun (In ) -> auth_user_from_token (In , ResourceServer ) end ) of
162
172
{error , Err } ->
163
173
{refused , " Authentication using an OAuth 2/JWT token failed: ~tp " , [Err ]};
164
174
Else ->
165
175
Else
166
176
end
167
177
end
168
178
end .
179
+
180
+ -type ok_extracted_auth_user () :: {ok , rabbit_types :auth_user ()}.
181
+ -type auth_user_extraction_fun () :: fun ((decoded_jwt_token ()) -> any ()).
182
+
183
+ -spec with_decoded_token (Token , Fun ) -> Result
184
+ when Token :: decoded_jwt_token (),
185
+ Fun :: auth_user_extraction_fun (),
186
+ Result :: {ok , any ()} | {'error' , any ()}.
169
187
with_decoded_token (DecodedToken , Fun ) ->
170
188
case validate_token_expiry (DecodedToken ) of
171
189
ok -> Fun (DecodedToken );
172
190
{error , Msg } = Err ->
173
191
rabbit_log :error (Msg ),
174
192
Err
175
193
end .
194
+
195
+ % % This is a helper function used with HOFs that may return errors.
196
+ -spec auth_user_from_token (Token , ResourceServer ) -> Result
197
+ when Token :: decoded_jwt_token (),
198
+ ResourceServer :: resource_server (),
199
+ Result :: ok_extracted_auth_user ().
200
+ auth_user_from_token (Token0 , ResourceServer ) ->
201
+ Username = username_from (
202
+ ResourceServer # resource_server .preferred_username_claims ,
203
+ Token0 ),
204
+ Tags = tags_from (Token0 ),
205
+ {ok , # auth_user {username = Username ,
206
+ tags = Tags ,
207
+ impl = fun () -> Token0 end }}.
208
+
176
209
ensure_same_username (PreferredUsernameClaims , CurrentDecodedToken , NewDecodedToken ) ->
177
210
CurUsername = username_from (PreferredUsernameClaims , CurrentDecodedToken ),
178
211
case {CurUsername , username_from (PreferredUsernameClaims , NewDecodedToken )} of
@@ -188,12 +221,10 @@ validate_token_expiry(#{<<"exp">> := Exp}) when is_integer(Exp) ->
188
221
end ;
189
222
validate_token_expiry (#{}) -> ok .
190
223
191
- -spec check_token (binary () | map (), {resource_server (), internal_oauth_provider ()}) ->
192
- {'ok' , map ()} |
193
- {'error' , term () }|
194
- {'refused' , 'signature_invalid' |
195
- {'error' , term ()} |
196
- {'invalid_aud' , term ()}}.
224
+ -spec check_token (raw_jwt_token (), {resource_server (), internal_oauth_provider ()}) ->
225
+ {'ok' , decoded_jwt_token ()} |
226
+ {'error' , term () } |
227
+ {'refused' , 'signature_invalid' | {'error' , term ()} | {'invalid_aud' , term ()}}.
197
228
198
229
check_token (DecodedToken , _ ) when is_map (DecodedToken ) ->
199
230
{ok , DecodedToken };
@@ -206,7 +237,7 @@ check_token(Token, {ResourceServer, InternalOAuthProvider}) ->
206
237
end .
207
238
208
239
-spec normalize_token_scope (
209
- ResourceServer :: resource_server (), DecodedToken :: map ()) -> map ().
240
+ ResourceServer :: resource_server (), DecodedToken :: decoded_jwt_token ()) -> map ().
210
241
normalize_token_scope (ResourceServer , Payload ) ->
211
242
Payload0 = maps :map (fun (K , V ) ->
212
243
case K of
@@ -395,7 +426,7 @@ resolve_scope_var(Elem, Token, Vhost) ->
395
426
end )
396
427
end .
397
428
398
- -spec tags_from (map ()) -> list (atom ()).
429
+ -spec tags_from (decoded_jwt_token ()) -> list (atom ()).
399
430
tags_from (DecodedToken ) ->
400
431
Scopes = maps :get (? SCOPE_JWT_FIELD , DecodedToken , []),
401
432
TagScopes = filter_matching_scope_prefix_and_drop_it (Scopes , ? TAG_SCOPE_PREFIX ),
0 commit comments