From 97dd938363230dee64f89ed81d572071d4c21d94 Mon Sep 17 00:00:00 2001 From: anlicheng Date: Mon, 21 Aug 2023 17:54:48 +0800 Subject: [PATCH] fix host auth status --- apps/iot/src/http_handler/host_handler.erl | 12 ++--- apps/iot/src/iot_host.erl | 61 ++++++++++------------ 2 files changed, 32 insertions(+), 41 deletions(-) diff --git a/apps/iot/src/http_handler/host_handler.erl b/apps/iot/src/http_handler/host_handler.erl index 03f7efc..ff5feae 100644 --- a/apps/iot/src/http_handler/host_handler.erl +++ b/apps/iot/src/http_handler/host_handler.erl @@ -37,14 +37,10 @@ handle_request("POST", "/host/reload", _, #{<<"uuid">> := UUID}) when is_binary( lager:debug("[host_handler] will reload host uuid: ~p", [UUID]), case iot_host_sup:ensured_host_started(UUID) of {ok, Pid} when is_pid(Pid) -> - case iot_host:reload(Pid) of - ok -> - lager:debug("[host_handler] already_started reload host uuid: ~p, success", [UUID]), - {ok, 200, iot_util:json_data(<<"success">>)}; - {error, ReloadError} -> - lager:debug("[host_handler] reload host uuid: ~p, error: ~p", [UUID, ReloadError]), - {ok, 200, iot_util:json_error(400, <<"reload error">>)} - end; + {ok, #{<<"authorize_status">> := AuthorizeStatus}} = host_bo:get_host_by_uuid(UUID), + ok = iot_host:activate(Pid, AuthorizeStatus =:= 1), + lager:debug("[host_handler] already_started reload host uuid: ~p, success", [UUID]), + {ok, 200, iot_util:json_data(<<"success">>)}; Error -> lager:debug("[host_handler] reload host uuid: ~p, error: ~p", [UUID, Error]), {ok, 200, iot_util:json_error(404, <<"reload error">>)} diff --git a/apps/iot/src/iot_host.erl b/apps/iot/src/iot_host.erl index 91d509c..49e57c6 100644 --- a/apps/iot/src/iot_host.erl +++ b/apps/iot/src/iot_host.erl @@ -12,17 +12,13 @@ -behaviour(gen_statem). -%% 主机是否授权 --define(HOST_DENIED, 0). --define(HOST_AUTHED, 1). - %% 主机状态 -define(STATE_DENIED, denied). -define(STATE_ACTIVATED, activated). -define(STATE_SESSION, session). %% API --export([start_link/2, get_name/1, get_alias_name/1, get_pid/1, handle/2, reload/1, activate/2]). +-export([start_link/2, get_name/1, get_alias_name/1, get_pid/1, handle/2, activate/2]). -export([get_metric/1, publish_message/4, get_aes/1]). -export([create_session/2, attach_channel/2]). -export([reload_device/2, delete_device/2, activate_device/3]). @@ -68,11 +64,6 @@ get_alias_name(HostId0) when is_integer(HostId0) -> handle(Pid, Packet) when is_pid(Pid) -> gen_statem:cast(Pid, {handle, Packet}). -%% 重新加载主机的基本信息 --spec reload(Pid :: pid()) -> ok | {error, Reason :: any()}. -reload(Pid) when is_pid(Pid) -> - gen_statem:call(Pid, reload). - -spec get_aes(Pid :: pid()) -> {ok, Aes :: binary()}. get_aes(Pid) when is_pid(Pid) -> gen_statem:call(Pid, get_aes). @@ -147,7 +138,7 @@ init([UUID]) -> case host_bo:get_host_by_uuid(UUID) of {ok, #{<<"authorize_status">> := AuthorizeStatus, <<"id">> := HostId}} -> Aes = list_to_binary(iot_util:rand_bytes(32)), - StateName = case AuthorizeStatus =:= ?HOST_AUTHED of + StateName = case AuthorizeStatus =:= 0 of false -> ?STATE_DENIED; true -> ?STATE_ACTIVATED end, @@ -197,7 +188,8 @@ handle_event({call, From}, get_aes, _, State = #state{aes = Aes}) -> {keep_state, State, [{reply, From, {ok, Aes}}]}; %% 发送普通格式的消息, 激活的时候,会话时创建不成功的; 发送aes类型的命令的时候,必须要求session是存在的 -handle_event({call, From}, {publish_message, ReceiverPid, CommandType, {aes, Command0}}, ?STATE_SESSION, State = #state{aes = AES, channel_pid = ChannelPid}) -> +handle_event({call, From}, {publish_message, ReceiverPid, CommandType, {aes, Command0}}, ?STATE_SESSION, State = #state{uuid = UUID, aes = AES, channel_pid = ChannelPid}) -> + lager:debug("[iot_host] host: ~p, will publish aes message: ~p", [UUID, Command0]), Command = iot_cipher_aes:encrypt(AES, Command0), %% 通过websocket发送请求 Ref = ws_channel:publish(ChannelPid, ReceiverPid, <>), @@ -207,7 +199,7 @@ handle_event({call, From}, {publish_message, ReceiverPid, CommandType, {aes, Com %% 只要channel存在,就负责将消息推送到边缘端主机 handle_event({call, From}, {publish_message, ReceiverPid, CommandType, Command}, _, State = #state{uuid = UUID, channel_pid = ChannelPid}) when is_binary(Command), is_pid(ChannelPid) -> %% 通过websocket发送请求 - lager:debug("[iot_host] host: ~p, will publish_message: ~p", [UUID, Command]), + lager:debug("[iot_host] host: ~p, will publish message: ~p", [UUID, Command]), Ref = ws_channel:publish(ChannelPid, ReceiverPid, <>), {keep_state, State, [{reply, From, {ok, Ref}}]}; @@ -215,30 +207,33 @@ handle_event({call, From}, {publish_message, ReceiverPid, CommandType, Command}, handle_event({call, From}, {publish_message, _, _, _}, _, State) -> {keep_state, State, [{reply, From, {error, <<"主机状态错误,发送命令失败"/utf8>>}}]}; -%% 重新加载主机信息 -handle_event({call, From}, reload, StateName, State = #state{uuid = UUID}) -> - %% 重新加载主机信息 - {ok, Host = #{<<"authorize_status">> := AuthorizeStatus}} = host_bo:get_host_by_uuid(UUID), - lager:debug("[iot_host] reload host uuid: ~p, successed", [Host]), - case StateName == ?STATE_DENIED andalso AuthorizeStatus =:= ?HOST_AUTHED of - true -> +%% 关闭授权 +handle_event({call, From}, {activate, Auth}, StateName, State = #state{host_id = HostId, uuid = UUID, monitor_ref = MRef, channel_pid = ChannelPid}) -> + case {StateName, Auth} of + {?STATE_DENIED, false} -> + {keep_state, State, [{reply, From, ok}]}; + {?STATE_DENIED, true} -> {next_state, ?STATE_ACTIVATED, State, [{reply, From, ok}]}; - false -> + {?STATE_ACTIVATED, false} -> + {ok, _} = host_bo:change_status(UUID, ?HOST_OFFLINE), + change_devices_status(HostId, ?DEVICE_OFFLINE), + + {next_state, ?STATE_DENIED, State, [{reply, From, ok}]}; + {?STATE_ACTIVATED, true} -> + {keep_state, State, [{reply, From, ok}]}; + {?STATE_SESSION, false} -> + %% 取消之前的monitor + erlang:demonitor(MRef), + ws_channel:stop(ChannelPid, closed), + + {ok, _} = host_bo:change_status(UUID, ?HOST_OFFLINE), + change_devices_status(HostId, ?DEVICE_OFFLINE), + + {next_state, ?STATE_DENIED, State#state{monitor_ref = undefined, channel_pid = undefined}, [{reply, From, ok}]}; + {?STATE_SESSION, true} -> {keep_state, State, [{reply, From, ok}]} end; -%% 关闭授权 -handle_event({call, From}, {activate, false}, _, State = #state{host_id = HostId, uuid = UUID}) -> - {ok, _} = host_bo:change_status(UUID, ?HOST_OFFLINE), - change_devices_status(HostId, ?DEVICE_OFFLINE), - - {next_state, ?STATE_DENIED, State, [{reply, From, ok}]}; -%% 开启授权 -handle_event({call, From}, {activate, true}, ?STATE_DENIED, State) -> - {next_state, ?STATE_ACTIVATED, State, [{reply, From, ok}]}; -handle_event({call, From}, {activate, true}, _, State) -> - {keep_state, State, [{reply, From, ok}]}; - %% 绑定channel handle_event({call, From}, {attach_channel, ChannelPid}, _, State = #state{uuid = UUID, channel_pid = undefined}) -> lager:debug("[iot_host] attach_channel host_id uuid: ~p, channel: ~p", [UUID, ChannelPid]),