Explorar o código

Merge pull request #11206 from HJianBo/coap-bugs

Fix(coap): Make the username and password params to optional
JianBo He %!s(int64=2) %!d(string=hai) anos
pai
achega
daa6cf14fe

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

@@ -1,7 +1,7 @@
 %% -*- mode: erlang -*-
 %% -*- mode: erlang -*-
 {application, emqx_gateway, [
 {application, emqx_gateway, [
     {description, "The Gateway management application"},
     {description, "The Gateway management application"},
-    {vsn, "0.1.20"},
+    {vsn, "0.1.21"},
     {registered, []},
     {registered, []},
     {mod, {emqx_gateway_app, []}},
     {mod, {emqx_gateway_app, []}},
     {applications, [kernel, stdlib, emqx, emqx_authn, emqx_ctl]},
     {applications, [kernel, stdlib, emqx, emqx_authn, emqx_ctl]},

+ 5 - 1
apps/emqx_gateway/src/emqx_gateway_utils.erl

@@ -46,7 +46,8 @@
     global_chain/1,
     global_chain/1,
     listener_chain/3,
     listener_chain/3,
     find_gateway_definitions/0,
     find_gateway_definitions/0,
-    plus_max_connections/2
+    plus_max_connections/2,
+    random_clientid/1
 ]).
 ]).
 
 
 -export([stringfy/1]).
 -export([stringfy/1]).
@@ -631,3 +632,6 @@ ensure_gateway_loaded() ->
             emqx_gateway_mqttsn
             emqx_gateway_mqttsn
         ]
         ]
     ).
     ).
+
+random_clientid(GwName) when is_atom(GwName) ->
+    iolist_to_binary([atom_to_list(GwName), "-", emqx_utils:gen_id()]).

+ 13 - 26
apps/emqx_gateway_coap/src/emqx_coap_channel.erl

@@ -118,8 +118,8 @@ info(ctx, #channel{ctx = Ctx}) ->
     Ctx.
     Ctx.
 
 
 -spec stats(channel()) -> emqx_types:stats().
 -spec stats(channel()) -> emqx_types:stats().
-stats(_) ->
-    [].
+stats(#channel{session = Session}) ->
+    emqx_coap_session:stats(Session).
 
 
 -spec init(map(), map()) -> channel().
 -spec init(map(), map()) -> channel().
 init(
 init(
@@ -273,7 +273,7 @@ handle_call(
         SubReq, TempMsg, #{}, Session
         SubReq, TempMsg, #{}, Session
     ),
     ),
     NSession = maps:get(session, Result),
     NSession = maps:get(session, Result),
-    {reply, {ok, {MountedTopic, NSubOpts}}, Channel#channel{session = NSession}};
+    {reply, {ok, {MountedTopic, NSubOpts}}, [{event, updated}], Channel#channel{session = NSession}};
 handle_call(
 handle_call(
     {unsubscribe, Topic},
     {unsubscribe, Topic},
     _From,
     _From,
@@ -300,7 +300,7 @@ handle_call(
         UnSubReq, TempMsg, #{}, Session
         UnSubReq, TempMsg, #{}, Session
     ),
     ),
     NSession = maps:get(session, Result),
     NSession = maps:get(session, Result),
-    {reply, ok, Channel#channel{session = NSession}};
+    {reply, ok, [{event, updated}], Channel#channel{session = NSession}};
 handle_call(subscriptions, _From, Channel = #channel{session = Session}) ->
 handle_call(subscriptions, _From, Channel = #channel{session = Session}) ->
     Subs = emqx_coap_session:info(subscriptions, Session),
     Subs = emqx_coap_session:info(subscriptions, Session),
     {reply, {ok, maps:to_list(Subs)}, Channel};
     {reply, {ok, maps:to_list(Subs)}, Channel};
@@ -486,7 +486,6 @@ enrich_conninfo(
         conninfo = ConnInfo
         conninfo = ConnInfo
     }
     }
 ) ->
 ) ->
-    %% FIXME: generate a random clientid if absent
     case Queries of
     case Queries of
         #{<<"clientid">> := ClientId} ->
         #{<<"clientid">> := ClientId} ->
             Interval = maps:get(interval, emqx_keepalive:info(KeepAlive)),
             Interval = maps:get(interval, emqx_keepalive:info(KeepAlive)),
@@ -500,32 +499,20 @@ enrich_conninfo(
             },
             },
             {ok, Channel#channel{conninfo = NConnInfo}};
             {ok, Channel#channel{conninfo = NConnInfo}};
         _ ->
         _ ->
-            {error, "invalid queries", Channel}
+            {error, "clientid is required", Channel}
     end.
     end.
 
 
 enrich_clientinfo(
 enrich_clientinfo(
     {Queries, Msg},
     {Queries, Msg},
-    Channel = #channel{clientinfo = ClientInfo0}
+    Channel = #channel{conninfo = ConnInfo, clientinfo = ClientInfo0}
 ) ->
 ) ->
-    %% FIXME:
-    %% 1. generate a random clientid if absent;
-    %% 2. assgin username, password to `undefined` if absent
-    case Queries of
-        #{
-            <<"username">> := UserName,
-            <<"password">> := Password,
-            <<"clientid">> := ClientId
-        } ->
-            ClientInfo = ClientInfo0#{
-                username => UserName,
-                password => Password,
-                clientid => ClientId
-            },
-            {ok, NClientInfo} = fix_mountpoint(Msg, ClientInfo),
-            {ok, Channel#channel{clientinfo = NClientInfo}};
-        _ ->
-            {error, "invalid queries", Channel}
-    end.
+    ClientInfo = ClientInfo0#{
+        clientid => maps:get(clientid, ConnInfo),
+        username => maps:get(<<"username">>, Queries, undefined),
+        password => maps:get(<<"password">>, Queries, undefined)
+    },
+    {ok, NClientInfo} = fix_mountpoint(Msg, ClientInfo),
+    {ok, Channel#channel{clientinfo = NClientInfo}}.
 
 
 set_log_meta(_Input, #channel{clientinfo = #{clientid := ClientId}}) ->
 set_log_meta(_Input, #channel{clientinfo = #{clientid := ClientId}}) ->
     emqx_logger:set_metadata_clientid(ClientId),
     emqx_logger:set_metadata_clientid(ClientId),

+ 4 - 4
apps/emqx_gateway_coap/src/emqx_coap_session.erl

@@ -117,15 +117,15 @@ info(inflight, _) ->
 info(inflight_cnt, _) ->
 info(inflight_cnt, _) ->
     0;
     0;
 info(inflight_max, _) ->
 info(inflight_max, _) ->
-    0;
+    infinity;
 info(retry_interval, _) ->
 info(retry_interval, _) ->
     infinity;
     infinity;
 info(mqueue, _) ->
 info(mqueue, _) ->
     emqx_mqueue:init(#{max_len => 0, store_qos0 => false});
     emqx_mqueue:init(#{max_len => 0, store_qos0 => false});
-info(mqueue_len, #session{transport_manager = TM}) ->
-    maps:size(TM);
-info(mqueue_max, _) ->
+info(mqueue_len, _) ->
     0;
     0;
+info(mqueue_max, _) ->
+    infinity;
 info(mqueue_dropped, _) ->
 info(mqueue_dropped, _) ->
     0;
     0;
 info(next_pkt_id, _) ->
 info(next_pkt_id, _) ->

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

@@ -1,6 +1,6 @@
 {application, emqx_gateway_coap, [
 {application, emqx_gateway_coap, [
     {description, "CoAP Gateway"},
     {description, "CoAP Gateway"},
-    {vsn, "0.1.1"},
+    {vsn, "0.1.2"},
     {registered, []},
     {registered, []},
     {applications, [kernel, stdlib, emqx, emqx_gateway]},
     {applications, [kernel, stdlib, emqx, emqx_gateway]},
     {env, []},
     {env, []},

+ 39 - 0
apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl

@@ -133,6 +133,42 @@ t_connection(_) ->
     end,
     end,
     do(Action).
     do(Action).
 
 
+t_connection_optional_params(_) ->
+    UsernamePasswordAreOptional =
+        fun(Channel) ->
+            URI =
+                ?MQTT_PREFIX ++
+                    "/connection?clientid=client1",
+            Req = make_req(post),
+            {ok, created, Data} = do_request(Channel, URI, Req),
+            #coap_content{payload = Token0} = Data,
+            Token = binary_to_list(Token0),
+
+            timer:sleep(100),
+            ?assertNotEqual(
+                [],
+                emqx_gateway_cm_registry:lookup_channels(coap, <<"client1">>)
+            ),
+
+            disconnection(Channel, Token),
+
+            timer:sleep(100),
+            ?assertEqual(
+                [],
+                emqx_gateway_cm_registry:lookup_channels(coap, <<"client1">>)
+            )
+        end,
+    ClientIdIsRequired =
+        fun(Channel) ->
+            URI =
+                ?MQTT_PREFIX ++
+                    "/connection",
+            Req = make_req(post),
+            {error, bad_request, _} = do_request(Channel, URI, Req)
+        end,
+    do(UsernamePasswordAreOptional),
+    do(ClientIdIsRequired).
+
 t_connection_with_authn_failed(_) ->
 t_connection_with_authn_failed(_) ->
     ChId = {{127, 0, 0, 1}, 5683},
     ChId = {{127, 0, 0, 1}, 5683},
     {ok, Sock} = er_coap_udp_socket:start_link(),
     {ok, Sock} = er_coap_udp_socket:start_link(),
@@ -327,6 +363,9 @@ t_clients_subscription_api(_) ->
             maps:get(topic, SubsResp2)
             maps:get(topic, SubsResp2)
         ),
         ),
 
 
+        %% check subscription_cnt
+        {200, #{subscriptions_cnt := 1}} = request(get, "/gateways/coap/clients/client1"),
+
         {204, _} = request(delete, Path ++ "/tx"),
         {204, _} = request(delete, Path ++ "/tx"),
 
 
         {200, []} = request(get, Path)
         {200, []} = request(get, Path)

+ 1 - 4
apps/emqx_gateway_exproto/src/emqx_exproto_channel.erl

@@ -782,7 +782,7 @@ enrich_clientinfo(InClientInfo = #{proto_name := ProtoName}, ClientInfo) ->
 default_conninfo(ConnInfo) ->
 default_conninfo(ConnInfo) ->
     ConnInfo#{
     ConnInfo#{
         clean_start => true,
         clean_start => true,
-        clientid => anonymous_clientid(),
+        clientid => emqx_gateway_utils:random_clientid(exproto),
         username => undefined,
         username => undefined,
         conn_props => #{},
         conn_props => #{},
         connected => true,
         connected => true,
@@ -822,6 +822,3 @@ proto_name_to_protocol(<<>>) ->
     exproto;
     exproto;
 proto_name_to_protocol(ProtoName) when is_binary(ProtoName) ->
 proto_name_to_protocol(ProtoName) when is_binary(ProtoName) ->
     binary_to_atom(ProtoName).
     binary_to_atom(ProtoName).
-
-anonymous_clientid() ->
-    iolist_to_binary(["exproto-", emqx_utils:gen_id()]).

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

@@ -1,6 +1,6 @@
 {application, emqx_gateway_exproto, [
 {application, emqx_gateway_exproto, [
     {description, "ExProto Gateway"},
     {description, "ExProto Gateway"},
-    {vsn, "0.1.2"},
+    {vsn, "0.1.3"},
     {registered, []},
     {registered, []},
     {applications, [kernel, stdlib, grpc, emqx, emqx_gateway]},
     {applications, [kernel, stdlib, grpc, emqx, emqx_gateway]},
     {env, []},
     {env, []},

+ 1 - 0
changes/ce/fix-11206.en.md

@@ -0,0 +1 @@
+Make the username and password params of CoAP client to optional in connection mode.