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

fix(http authn): fix bugs for http authn and http connector

zhouzb пре 4 година
родитељ
комит
42c5432514

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

@@ -3,7 +3,7 @@
   {vsn, "0.1.0"},
   {modules, []},
   {registered, [emqx_authn_sup, emqx_authn_registry]},
-  {applications, [kernel,stdlib]},
+  {applications, [kernel,stdlib,emqx_resource,ehttpc,epgsql,mysql]},
   {mod, {emqx_authn_app,[]}},
   {env, []},
   {licenses, ["Apache-2.0"]},

+ 13 - 6
apps/emqx_authn/src/simple_authn/emqx_authn_http.erl

@@ -72,7 +72,7 @@ common_fields() ->
     ] ++ proplists:delete(base_url, emqx_connector_http:fields(config)).
 
 validations() ->
-    [ {check_ssl_opts, fun emqx_connector_http:check_ssl_opts/1} ].
+    [ {check_ssl_opts, fun check_ssl_opts/1} ].
 
 url(type) -> binary();
 url(nullable) -> false;
@@ -108,26 +108,30 @@ create(ChainID, AuthenticatorName,
         #{method := Method,
           url := URL,
           accept := Accept,
-          content_type := ContentType,
           headers := Headers,
           form_data := FormData,
           request_timeout := RequestTimeout} = Config) ->
-    NHeaders = maps:merge(#{<<"accept">> => atom_to_binary(Accept, utf8),
-                            <<"content-type">> => atom_to_binary(ContentType, utf8)}, Headers),
+    ContentType = maps:get(content_type, Config, undefined),
+    DefaultHeader0 = case ContentType of
+                         undefined -> #{};
+                         _ -> #{<<"content-type">> => atom_to_binary(ContentType, utf8)}
+                     end,
+    DefaultHeader = DefaultHeader0#{<<"accept">> => atom_to_binary(Accept, utf8)},
+    NHeaders = maps:to_list(maps:merge(DefaultHeader, maps:from_list(Headers))),
     NFormData = preprocess_form_data(FormData),
     #{path := Path,
       query := Query} = URIMap = parse_url(URL),
     BaseURL = generate_base_url(URIMap),
     State = #{method          => Method,
               path            => Path,
-              base_query      => cow_qs:parse_qs(Query),
+              base_query      => cow_qs:parse_qs(list_to_binary(Query)),
               accept          => Accept,
               content_type    => ContentType,
               headers         => NHeaders,
               form_data       => NFormData,
               request_timeout => RequestTimeout},
     ResourceID = <<ChainID/binary, "/", AuthenticatorName/binary>>,
-    case emqx_resource:create_local(ResourceID, emqx_connector_http, Config#{base_url := BaseURL}) of
+    case emqx_resource:create_local(ResourceID, emqx_connector_http, Config#{base_url => BaseURL}) of
         {ok, _} ->
             {ok, State#{resource_id => ResourceID}};
         {error, already_created} ->
@@ -192,6 +196,9 @@ check_form_data(FormData) ->
             false
     end.
 
+check_ssl_opts(Conf) ->
+    emqx_connector_http:check_ssl_opts("url", Conf).
+
 preprocess_form_data(FormData) ->
     KVs = binary:split(FormData, [<<"&">>], [global]),
     [list_to_tuple(binary:split(KV, [<<"=">>], [global])) || KV <- KVs].

+ 12 - 8
apps/emqx_connector/src/emqx_connector_http.erl

@@ -32,7 +32,7 @@
         , fields/1
         , validations/0]).
 
--export([ check_ssl_opts/1 ]).
+-export([ check_ssl_opts/2 ]).
 
 -type connect_timeout() :: non_neg_integer() | infinity.
 -type pool_type() :: random | hash.
@@ -57,7 +57,7 @@ fields(config) ->
     , {pool_type,       fun pool_type/1}
     , {pool_size,       fun pool_size/1}
     , {ssl_opts,        #{type => hoconsc:ref(?MODULE, ssl_opts),
-                          nullable => true}}
+                          default => #{}}}
     ];
 
 fields(ssl_opts) ->
@@ -107,8 +107,9 @@ keyfile(type) -> string();
 keyfile(nullable) -> true;
 keyfile(_) -> undefined.
 
+%% TODO: certfile is required
 certfile(type) -> string();
-certfile(nullable) -> false;
+certfile(nullable) -> true;
 certfile(_) -> undefined.
 
 verify(type) -> boolean();
@@ -178,7 +179,7 @@ on_query(InstId, {KeyOrNum, Method, Request, Timeout}, AfterQuery, #{pool_name :
     end,
     Result.
 
-on_health_check(_InstId, #{server := {Host, Port}} = State) ->
+on_health_check(_InstId, #{host := Host, port := Port} = State) ->
     case gen_tcp:connect(Host, Port, emqx_misc:ipv6_probe([]), 3000) of
         {ok, Sock} ->
             gen_tcp:close(Sock),
@@ -199,13 +200,16 @@ check_base_url(URL) ->
     end.
 
 check_ssl_opts(Conf) ->
-    URL = hocon_schema:get_value("url", Conf),
+    check_ssl_opts("base_url", Conf).
+
+check_ssl_opts(URLFrom, Conf) ->
+    URL = hocon_schema:get_value(URLFrom, Conf),
     {ok, #{scheme := Scheme}} = emqx_http_lib:uri_parse(URL),
     SSLOpts = hocon_schema:get_value("ssl_opts", Conf),
-    case {Scheme, SSLOpts} of
-        {http, undefined} -> true;
+    case {Scheme, maps:size(SSLOpts)} of
+        {http, 0} -> true;
         {http, _} -> false;
-        {https, undefined} -> false;
+        {https, 0} -> false;
         {https, _} -> true
     end.