Преглед изворни кода

Merge pull request #13618 from lafirest/fix/authz_api

fix(authz): enhanced type spec for the `authorization/sources` endpoint
lafirest пре 1 година
родитељ
комит
2bfc57639e

+ 39 - 17
apps/emqx_auth/src/emqx_authz/emqx_authz_schema.erl

@@ -53,10 +53,11 @@
 %%--------------------------------------------------------------------
 
 -type schema_ref() :: ?R_REF(module(), hocon_schema:name()).
-
+-type source_refs_type() :: source_refs | api_source_refs.
 -callback type() -> emqx_authz_source:source_type().
 -callback source_refs() -> [schema_ref()].
--callback select_union_member(emqx_config:raw_config()) -> schema_ref() | undefined | no_return().
+-callback select_union_member(emqx_config:raw_config(), source_refs_type()) ->
+    schema_ref() | undefined | no_return().
 -callback fields(hocon_schema:name()) -> [hocon_schema:field()].
 -callback api_source_refs() -> [schema_ref()].
 
@@ -138,9 +139,17 @@ authz_fields() ->
     AllTypes = lists:concat([Mod:source_refs() || Mod <- AuthzSchemaMods]),
     UnionMemberSelector =
         fun
-            (all_union_members) -> AllTypes;
+            (all_union_members) ->
+                AllTypes;
             %% must return list
-            ({value, Value}) -> [select_union_member(Value, AuthzSchemaMods)]
+            ({value, Value}) ->
+                [
+                    select_union_member(
+                        Value,
+                        AuthzSchemaMods,
+                        source_refs
+                    )
+                ]
         end,
     [
         {sources,
@@ -162,10 +171,23 @@ api_authz_fields() ->
     [{sources, ?HOCON(?ARRAY(api_source_type()), #{desc => ?DESC(sources)})}].
 
 api_source_type() ->
-    hoconsc:union(api_authz_refs()).
-
-api_authz_refs() ->
-    lists:concat([api_source_refs(Mod) || Mod <- source_schema_mods()]).
+    AuthzSchemaMods = source_schema_mods(),
+    AllTypes = lists:concat([api_source_refs(Mod) || Mod <- AuthzSchemaMods]),
+    UnionMemberSelector =
+        fun
+            (all_union_members) ->
+                AllTypes;
+            %% must return list
+            ({value, Value}) ->
+                [
+                    select_union_member(
+                        Value,
+                        AuthzSchemaMods,
+                        api_source_refs
+                    )
+                ]
+        end,
+    hoconsc:union(UnionMemberSelector).
 
 authz_common_fields(Type) ->
     [
@@ -186,10 +208,10 @@ source_types() ->
 %%--------------------------------------------------------------------
 
 api_source_refs(Mod) ->
-    try
-        Mod:api_source_refs()
-    catch
-        error:undef ->
+    case erlang:function_exported(Mod, api_source_refs, 0) of
+        true ->
+            Mod:api_source_refs();
+        _ ->
             Mod:source_refs()
     end.
 
@@ -217,19 +239,19 @@ array(Ref) -> array(Ref, Ref).
 array(Ref, DescId) ->
     ?HOCON(?ARRAY(?R_REF(Ref)), #{desc => ?DESC(DescId)}).
 
-select_union_member(#{<<"type">> := Type}, []) ->
+select_union_member(#{<<"type">> := Type}, [], _Type) ->
     throw(#{
         reason => "unknown_authz_type",
         got => Type
     });
-select_union_member(#{<<"type">> := _} = Value, [Mod | Mods]) ->
-    case Mod:select_union_member(Value) of
+select_union_member(#{<<"type">> := _} = Value, [Mod | Mods], Type) ->
+    case Mod:select_union_member(Value, Type) of
         undefined ->
-            select_union_member(Value, Mods);
+            select_union_member(Value, Mods, Type);
         Member ->
             Member
     end;
-select_union_member(_Value, _Mods) ->
+select_union_member(_Value, _Mods, _Type) ->
     throw("missing_type_field").
 
 default_authz() ->

+ 5 - 3
apps/emqx_auth/src/emqx_authz/sources/emqx_authz_file_schema.erl

@@ -28,7 +28,7 @@
     desc/1,
     source_refs/0,
     api_source_refs/0,
-    select_union_member/1
+    select_union_member/2
 ]).
 
 namespace() -> "authz".
@@ -77,7 +77,9 @@ source_refs() ->
 api_source_refs() ->
     [?R_REF(api_file)].
 
-select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}, source_refs) ->
     ?R_REF(file);
-select_union_member(_Value) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}, api_source_refs) ->
+    ?R_REF(api_file);
+select_union_member(_Value, _) ->
     undefined.

+ 3 - 3
apps/emqx_auth_http/src/emqx_authz_http_schema.erl

@@ -26,7 +26,7 @@
     fields/1,
     desc/1,
     source_refs/0,
-    select_union_member/1,
+    select_union_member/2,
     namespace/0
 ]).
 
@@ -68,7 +68,7 @@ desc(http_post) ->
 desc(_) ->
     undefined.
 
-select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value, _) ->
     Method = maps:get(<<"method">>, Value, undefined),
     case Method of
         <<"get">> ->
@@ -82,7 +82,7 @@ select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value) ->
                 got => Else
             })
     end;
-select_union_member(_Value) ->
+select_union_member(_Value, _) ->
     undefined.
 
 %%--------------------------------------------------------------------

+ 1 - 1
apps/emqx_auth_ldap/src/emqx_auth_ldap.app.src

@@ -1,7 +1,7 @@
 %% -*- mode: erlang -*-
 {application, emqx_auth_ldap, [
     {description, "EMQX LDAP Authentication and Authorization"},
-    {vsn, "0.1.3"},
+    {vsn, "0.1.4"},
     {registered, []},
     {mod, {emqx_auth_ldap_app, []}},
     {applications, [

+ 3 - 3
apps/emqx_auth_ldap/src/emqx_authz_ldap_schema.erl

@@ -26,7 +26,7 @@
     fields/1,
     desc/1,
     source_refs/0,
-    select_union_member/1,
+    select_union_member/2,
     namespace/0
 ]).
 
@@ -59,9 +59,9 @@ desc(_) ->
 source_refs() ->
     [?R_REF(ldap)].
 
-select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}, _) ->
     ?R_REF(ldap);
-select_union_member(_Value) ->
+select_union_member(_Value, _) ->
     undefined.
 
 %%--------------------------------------------------------------------

+ 3 - 3
apps/emqx_auth_mnesia/src/emqx_authz_mnesia_schema.erl

@@ -26,7 +26,7 @@
     fields/1,
     desc/1,
     source_refs/0,
-    select_union_member/1,
+    select_union_member/2,
     namespace/0
 ]).
 
@@ -57,7 +57,7 @@ desc(builtin_db) ->
 desc(_) ->
     undefined.
 
-select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}, _) ->
     ?R_REF(builtin_db);
-select_union_member(_Value) ->
+select_union_member(_Value, _) ->
     undefined.

+ 5 - 3
apps/emqx_auth_mongodb/src/emqx_authz_mongodb_schema.erl

@@ -16,12 +16,14 @@
 
 -module(emqx_authz_mongodb_schema).
 
+-behaviour(emqx_authz_schema).
+
 -export([
     type/0,
     fields/1,
     desc/1,
     source_refs/0,
-    select_union_member/1,
+    select_union_member/2,
     namespace/0
 ]).
 
@@ -57,7 +59,7 @@ desc(mongo_sharded) ->
 desc(_) ->
     undefined.
 
-select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value, _) ->
     MongoType = maps:get(<<"mongo_type">>, Value, undefined),
     case MongoType of
         <<"single">> ->
@@ -73,7 +75,7 @@ select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value) ->
                 got => Else
             })
     end;
-select_union_member(_Value) ->
+select_union_member(_Value, _) ->
     undefined.
 
 %%--------------------------------------------------------------------

+ 3 - 3
apps/emqx_auth_mysql/src/emqx_authz_mysql_schema.erl

@@ -27,7 +27,7 @@
     fields/1,
     desc/1,
     source_refs/0,
-    select_union_member/1
+    select_union_member/2
 ]).
 
 namespace() -> "authz".
@@ -48,9 +48,9 @@ desc(_) ->
 source_refs() ->
     [?R_REF(mysql)].
 
-select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}, _) ->
     ?R_REF(mysql);
-select_union_member(_Value) ->
+select_union_member(_Value, _) ->
     undefined.
 
 %%--------------------------------------------------------------------

+ 3 - 3
apps/emqx_auth_postgresql/src/emqx_authz_postgresql_schema.erl

@@ -27,7 +27,7 @@
     fields/1,
     desc/1,
     source_refs/0,
-    select_union_member/1
+    select_union_member/2
 ]).
 
 namespace() -> "authz".
@@ -47,9 +47,9 @@ desc(_) ->
 source_refs() ->
     [?R_REF(postgresql)].
 
-select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN}, _) ->
     ?R_REF(postgresql);
-select_union_member(_Value) ->
+select_union_member(_Value, _) ->
     undefined.
 
 %%--------------------------------------------------------------------

+ 3 - 3
apps/emqx_auth_redis/src/emqx_authz_redis_schema.erl

@@ -27,7 +27,7 @@
     fields/1,
     desc/1,
     source_refs/0,
-    select_union_member/1
+    select_union_member/2
 ]).
 
 namespace() -> "authz".
@@ -51,7 +51,7 @@ desc(_) ->
 source_refs() ->
     [?R_REF(redis_single), ?R_REF(redis_sentinel), ?R_REF(redis_cluster)].
 
-select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value) ->
+select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value, _) ->
     RedisType = maps:get(<<"redis_type">>, Value, undefined),
     case RedisType of
         <<"single">> ->
@@ -67,7 +67,7 @@ select_union_member(#{<<"type">> := ?AUTHZ_TYPE_BIN} = Value) ->
                 got => Else
             })
     end;
-select_union_member(_Value) ->
+select_union_member(_Value, _) ->
     undefined.
 
 %%--------------------------------------------------------------------

+ 2 - 0
changes/ce/fix-13618.en.md

@@ -0,0 +1,2 @@
+Enhanced type specification for the `authorization/sources` endpoint.
+