feat: check_device_acl

This commit is contained in:
dawnwinterLiu 2022-05-07 19:55:08 +08:00
parent fe2a0856b1
commit 5827515384
7 changed files with 79 additions and 92 deletions

View File

@ -20,6 +20,7 @@
-export([ -export([
check_acl/5 check_acl/5
, description/0 , description/0
, check_device_acl/3
]). ]).
check_acl(ClientInfo, PubSub, <<"$dg/", _/binary>> = Topic, _NoMatchAction, _Params) -> check_acl(ClientInfo, PubSub, <<"$dg/", _/binary>> = Topic, _NoMatchAction, _Params) ->
@ -140,8 +141,8 @@ do_check(_ClientInfo, _PubSub, _Topic) ->
check_device_acl(Token, DeviceID, UserId) -> check_device_acl(Token, DeviceID, UserId) ->
case dgiot_auth:get_session(Token) of case dgiot_auth:get_session(Token) of
#{<<"objectId">> := UserId, <<"ACL">> := Acl} -> #{<<"objectId">> := UserId, <<"roles">> := Roles} ->
UserAcl = maps:keys(Acl) ++ [<<"*">>], UserAcl = dgiot_role:get_aclNames(Roles),
DeviceAcl = maps:keys(dgiot_device:get_acl(DeviceID)), DeviceAcl = maps:keys(dgiot_device:get_acl(DeviceID)),
case DeviceAcl -- UserAcl of case DeviceAcl -- UserAcl of
DeviceAcl -> DeviceAcl ->

View File

@ -129,12 +129,10 @@ handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TC
<<"slaveid">> := SlaveId, <<"slaveid">> := SlaveId,
<<"address">> := Address} = DataSource <<"address">> := Address} = DataSource
} -> } ->
Datas = modbus_rtu:to_frame(DataSource#{<<"productid">> => ProductId}), %% io:format("~s ~p DataSource = ~p.~n", [?FILE, ?LINE, DataSource]),
lists:map(fun(X) -> Data = modbus_rtu:to_frame(DataSource),
dgiot_bridge:send_log(ChannelId, ProductId, DevAddr, "Channel sends [~p] to [DtuAddr:~p]", [dgiot_utils:binary_to_hex(X), DevAddr]), dgiot_bridge:send_log(ChannelId, ProductId, DevAddr, "Channel sends [~p] to [DtuAddr:~p]", [dgiot_utils:binary_to_hex(Data), DevAddr]),
dgiot_tcp_server:send(TCPState, X), dgiot_tcp_server:send(TCPState, Data),
timer:sleep(1000)
end, Datas),
{noreply, TCPState#tcp{state = State#state{env = #{product => ProductId, pn => SlaveId, di => Address}}}}; {noreply, TCPState#tcp{state = State#state{env = #{product => ProductId, pn => SlaveId, di => Address}}}};
#{<<"command">> := <<"rw">>, #{<<"command">> := <<"rw">>,
<<"product">> := ProductId, <<"product">> := ProductId,
@ -143,12 +141,9 @@ handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TC
<<"slaveid">> := SlaveId, <<"slaveid">> := SlaveId,
<<"address">> := Address} = DataSource <<"address">> := Address} = DataSource
} -> } ->
Datas = modbus_rtu:to_frame(DataSource#{<<"productid">> => ProductId}), Data = modbus_rtu:to_frame(DataSource),
lists:map(fun(X) -> dgiot_bridge:send_log(ChannelId, ProductId, DevAddr, "Channel sends [~p] to [DtuAddr:~p]", [dgiot_utils:binary_to_hex(Data), DevAddr]),
dgiot_bridge:send_log(ChannelId, ProductId, DevAddr, "Channel sends [~p] to [DtuAddr:~p]", [dgiot_utils:binary_to_hex(X), DevAddr]), dgiot_tcp_server:send(TCPState, Data),
dgiot_tcp_server:send(TCPState, X),
timer:sleep(1000)
end, Datas),
{noreply, TCPState#tcp{state = State#state{env = #{product => ProductId, pn => SlaveId, di => Address}}}}; {noreply, TCPState#tcp{state = State#state{env = #{product => ProductId, pn => SlaveId, di => Address}}}};
_Ot -> _Ot ->
?LOG(error, "_Ot ~p", [_Ot]), ?LOG(error, "_Ot ~p", [_Ot]),

View File

@ -127,16 +127,16 @@
zh => <<"寄存器个数(多个寄存器个数)"/utf8>> zh => <<"寄存器个数(多个寄存器个数)"/utf8>>
} }
}, },
<<"data">> => #{ <<"bytes">> => #{
order => 6, order => 6,
type => integer, type => integer,
required => true, required => true,
default => <<"2"/utf8>>, default => <<"2"/utf8>>,
title => #{ title => #{
zh => <<"数据长度(字节)"/utf8>> zh => <<"字节个数"/utf8>>
}, },
description => #{ description => #{
zh => <<"据长度(字节)"/utf8>> zh => <<"读写字节个数(字节)"/utf8>>
} }
} }
}). }).
@ -156,54 +156,43 @@ init(State) ->
%% {ok, State}. %% {ok, State}.
to_frame(#{ to_frame(#{
<<"data">> := Data, <<"registersnumber">> := Quality,
<<"slaveid">> := SlaveId, <<"slaveid">> := SlaveId,
<<"productid">> := ProductId, <<"operatetype">> := Operatetype,
<<"address">> := Address <<"address">> := Address
}) -> }) ->
encode_data(Data, Address, SlaveId, ProductId); encode_data(Quality, Address, SlaveId, Operatetype);
%%<<"cmd">> => Cmd, %%<<"cmd">> => Cmd,
%%<<"gateway">> => DtuAddr, %%<<"gateway">> => DtuAddr,
%%<<"addr">> => SlaveId, %%<<"addr">> => SlaveId,
%%<<"di">> => Address %%<<"di">> => Address
to_frame(#{ to_frame(_DataSource) ->
<<"data">> := Value, <<>>.
<<"gateway">> := DtuAddr,
<<"slaveid">> := SlaveId,
<<"address">> := Address
}) ->
case dgiot_device:get_subdevice(DtuAddr, SlaveId) of
not_find -> [];
[ProductId, _DevAddr] ->
encode_data(Value, Address, SlaveId, ProductId)
end.
%% Quality 16 %% Quality 16
encode_data(Data, Address, SlaveId, ProductId) -> encode_data(Quality, Address, SlaveId, OperateType) ->
lists:foldl(fun({_Cmd, Quality, OperateType}, Acc) -> {FunCode, NewQuality} =
{FunCode, NewQuality} = case OperateType of
case OperateType of <<"readCoils">> -> {?FC_READ_COILS, dgiot_utils:to_int(Quality)};
<<"readCoils">> -> {?FC_READ_COILS, dgiot_utils:to_int(dgiot_utils:to_int(Quality) / 2)}; <<"readInputs">> -> {?FC_READ_INPUTS, dgiot_utils:to_int(Quality)};
<<"readInputs">> -> {?FC_READ_INPUTS, dgiot_utils:to_int(dgiot_utils:to_int(Quality) / 2)}; <<"readHregs">> -> {?FC_READ_HREGS, dgiot_utils:to_int(Quality)};
<<"readHregs">> -> {?FC_READ_HREGS, dgiot_utils:to_int(dgiot_utils:to_int(Quality) / 2)}; <<"readIregs">> -> {?FC_READ_IREGS, dgiot_utils:to_int(Quality)};
<<"readIregs">> -> {?FC_READ_IREGS, dgiot_utils:to_int(dgiot_utils:to_int(Quality) / 2)}; <<"writeCoil">> -> {?FC_WRITE_COIL, dgiot_utils:to_int(Quality)};
<<"writeCoil">> -> {?FC_WRITE_COIL, dgiot_utils:to_int(Quality)}; <<"writeHreg">> -> {?FC_WRITE_HREG, dgiot_utils:to_int(Quality)}; %%线
<<"writeHreg">> -> {?FC_WRITE_HREG, dgiot_utils:to_int(Quality)}; %%线 <<"writeCoils">> -> {?FC_WRITE_COILS, dgiot_utils:to_int(Quality)};
<<"writeCoils">> -> {?FC_WRITE_COILS, dgiot_utils:to_int(Quality)}; <<"writeHregs">> -> {?FC_WRITE_HREGS, dgiot_utils:to_int(Quality)}; %%
<<"writeHregs">> -> {?FC_WRITE_HREGS, dgiot_utils:to_int(Quality)}; %% _ -> {?FC_READ_HREGS, dgiot_utils:to_int(dgiot_utils:to_int(Quality) / 2)}
_ -> {?FC_READ_HREGS, dgiot_utils:to_int(dgiot_utils:to_int(Quality) / 2)} end,
end, <<H:8, L:8>> = dgiot_utils:hex_to_binary(modbus_rtu:is16(Address)),
<<H:8, L:8>> = dgiot_utils:hex_to_binary(is16(Address)), <<Sh:8, Sl:8>> = dgiot_utils:hex_to_binary(modbus_rtu:is16(SlaveId)),
<<Sh:8, Sl:8>> = dgiot_utils:hex_to_binary(is16(SlaveId)), RtuReq = #rtu_req{
RtuReq = #rtu_req{ slaveId = Sh * 256 + Sl,
slaveId = Sh * 256 + Sl, funcode = dgiot_utils:to_int(FunCode),
funcode = dgiot_utils:to_int(FunCode), address = H * 256 + L,
address = H * 256 + L, quality = NewQuality
quality = NewQuality },
}, build_req_message(RtuReq).
Acc ++ [build_req_message(RtuReq)]
end, [], modbus_encoder(ProductId, SlaveId, Address, Data)).
is16(<<"0X", Data/binary>>) when size(Data) == 4 -> is16(<<"0X", Data/binary>>) when size(Data) == 4 ->
Data; Data;
@ -226,22 +215,22 @@ is16(Data) when size(Data) > 1 ->
is16(Data) -> is16(Data) ->
<<"000", Data/binary>>. <<"000", Data/binary>>.
set_params(Payload, ProductId, DevAddr) -> set_params(Payload, _ProductId, _DevAddr) ->
Length = length(maps:keys(Payload)), Length = length(maps:keys(Payload)),
Payloads = Payloads =
lists:foldl(fun(Index, Acc) -> lists:foldl(fun(Index, Acc) ->
case maps:find(dgiot_utils:to_binary(Index), Payload) of case maps:find(dgiot_utils:to_binary(Index), Payload) of
{ok, #{ {ok, #{
<<"identifier">> := Identifier, <<"identifier">> := _Identifier,
<<"name">> := Name, <<"name">> := _Name,
<<"productname">> := Productname, <<"productname">> := _Productname,
<<"dataForm">> := #{ <<"dataForm">> := #{
<<"protocol">> := <<"MODBUSRTU">>, <<"protocol">> := <<"MODBUSRTU">>,
<<"control">> := Setting}, <<"control">> := Setting},
<<"dataSource">> := #{ <<"dataSource">> := #{
<<"slaveid">> := SlaveId, <<"slaveid">> := SlaveId,
<<"address">> := Address, <<"address">> := Address,
<<"data">> := Bytes, <<"bytes">> := Bytes,
<<"operatetype">> := OperateType} = DataSource <<"operatetype">> := OperateType} = DataSource
} = Data} -> } = Data} ->
case maps:find(<<"value">>, Data) of case maps:find(<<"value">>, Data) of
@ -276,21 +265,21 @@ set_params(Payload, ProductId, DevAddr) ->
dataByteSize = dgiot_utils:to_int(Bytes), dataByteSize = dgiot_utils:to_int(Bytes),
quality = Value1 quality = Value1
}, },
DeviceId = dgiot_parse_id:get_deviceid(ProductId, DevAddr), %% DeviceId = dgiot_parse_id:get_deviceid(ProductId, DevAddr),
Sessiontoken = maps:get(<<"sessiontoken">>, Data, <<"">>), %% Sessiontoken = maps:get(<<"sessiontoken">>, Data, <<"">>),
{Username, Acl} = %% {Username, Acl} =
case dgiot_auth:get_session(Sessiontoken) of %% case dgiot_auth:get_session(Sessiontoken) of
#{<<"username">> := Name1, <<"ACL">> := Acl1} -> %% #{<<"username">> := Name1, <<"ACL">> := Acl1} ->
{Name1, Acl1}; %% {Name1, Acl1};
_ -> %% _ ->
{<<"">>, #{}} %% {<<"">>, #{}}
end, %% end,
?MLOG(info, #{<<"clientid">> => DeviceId, <<"username">> => Username, %% ?MLOG(info, #{<<"clientid">> => DeviceId, <<"username">> => Username,
<<"status">> => <<"ONLINE">>, <<"ACL">> => Acl, %% <<"status">> => <<"ONLINE">>, <<"ACL">> => Acl,
<<"devaddr">> => DevAddr, <<"productid">> => ProductId, %% <<"devaddr">> => DevAddr, <<"productid">> => ProductId,
<<"productname">> => Productname, <<"thingname">> => Name, %% <<"productname">> => Productname, <<"thingname">> => Name,
<<"protocol">> => <<"modbus">>, <<"identifier">> => Identifier, <<"value">> => Value1}, %% <<"protocol">> => <<"modbus">>, <<"identifier">> => Identifier, <<"value">> => Value1},
['device_operationlog']), %% ['device_operationlog']),
Acc ++ [build_req_message(RtuReq)]; Acc ++ [build_req_message(RtuReq)];
_ -> _ ->
Acc Acc
@ -638,7 +627,7 @@ format_value(Buff, #{<<"identifier">> := BitIdentifier,
<<"dataSource">> := #{ <<"dataSource">> := #{
<<"slaveid">> := BitIdentifier, <<"slaveid">> := BitIdentifier,
<<"address">> := Offset, <<"address">> := Offset,
<<"data">> := Len} <<"bytes">> := Len}
} -> } ->
IntOffset = dgiot_utils:to_int(Offset), IntOffset = dgiot_utils:to_int(Offset),
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -669,7 +658,7 @@ format_value(Buff, #{<<"identifier">> := BitIdentifier,
{map, Values}; {map, Values};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"short16_AB">> <<"originaltype">> := <<"short16_AB">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -678,7 +667,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"short16_BA">> <<"originaltype">> := <<"short16_BA">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -687,7 +676,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"ushort16_AB">> <<"originaltype">> := <<"ushort16_AB">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -696,7 +685,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"ushort16_BA">> <<"originaltype">> := <<"ushort16_BA">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -705,7 +694,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"long32_ABCD">> <<"originaltype">> := <<"long32_ABCD">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -715,7 +704,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"long32_CDAB">> <<"originaltype">> := <<"long32_CDAB">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -725,7 +714,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"ulong32_ABCD">> <<"originaltype">> := <<"ulong32_ABCD">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -735,7 +724,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"ulong32_CDAB">> <<"originaltype">> := <<"ulong32_CDAB">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -745,7 +734,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"float32_ABCD">> <<"originaltype">> := <<"float32_ABCD">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),
@ -755,7 +744,7 @@ format_value(Buff, #{<<"dataSource">> := #{
{Value, Rest}; {Value, Rest};
format_value(Buff, #{<<"dataSource">> := #{ format_value(Buff, #{<<"dataSource">> := #{
<<"data">> := Len, <<"bytes">> := Len,
<<"originaltype">> := <<"float32_CDAB">> <<"originaltype">> := <<"float32_CDAB">>
}}, _Props) -> }}, _Props) ->
IntLen = dgiot_utils:to_int(Len), IntLen = dgiot_utils:to_int(Len),

View File

@ -7,10 +7,6 @@
{ {
"name": "Data", "name": "Data",
"description": "数据管理" "description": "数据管理"
},
{
"name": "_User",
"description": "用户管理"
} }
], ],
"definitions": { "definitions": {

View File

@ -2,7 +2,7 @@
"tags": [ "tags": [
{ {
"name": "_User", "name": "_User",
"description": "用户" "description": "用户管理"
} }
], ],
"definitions": { "definitions": {

View File

@ -44,6 +44,7 @@
get_childacl/1, get_childacl/1,
get_roleids/1, get_roleids/1,
get_alcname/1, get_alcname/1,
get_aclNames/1,
get_acls/1 get_acls/1
]). ]).
@ -146,6 +147,11 @@ get_alcname(RoleId) ->
RoleName RoleName
end. end.
get_aclNames(Roles) ->
lists:foldl(fun(RoleId, Acc) ->
Acc ++ [dgiot_utils:to_binary(dgiot_role:get_alcname(RoleId))]
end, [<<"*">>], maps:keys(Roles)).
post_role(#{<<"tempname">> := TempName, <<"parent">> := Parent, <<"depname">> := DepName, post_role(#{<<"tempname">> := TempName, <<"parent">> := Parent, <<"depname">> := DepName,
<<"name">> := Name, <<"desc">> := Desc} = Body, SessionToken) -> <<"name">> := Name, <<"desc">> := Desc} = Body, SessionToken) ->
case dgiot_parse:query_object(<<"Dict">>, #{<<"order">> => <<"updatedAt">>, <<"limit">> => 1, <<"where">> => #{<<"key">> => TempName}}, case dgiot_parse:query_object(<<"Dict">>, #{<<"order">> => <<"updatedAt">>, <<"limit">> => 1, <<"where">> => #{<<"key">> => TempName}},

View File

@ -426,7 +426,7 @@ save_td(ProductId, DevAddr, Ack, _AppData) ->
dgiot_channelx:do_message(ChannelId, {topo_thing, ProductId, DeviceId, Data}), dgiot_channelx:do_message(ChannelId, {topo_thing, ProductId, DeviceId, Data}),
dgiot_tdengine_adapter:save(ProductId, DevAddr, Data), dgiot_tdengine_adapter:save(ProductId, DevAddr, Data),
dgiot_metrics:inc(dgiot_task, <<"task_save">>, 1), dgiot_metrics:inc(dgiot_task, <<"task_save">>, 1),
NotificationTopic = <<"$dg/user/", ProductId/binary, "/", DeviceId/binary, "/properties/report">>, NotificationTopic = <<"$dg/alarm/", ProductId/binary, "/", DeviceId/binary, "/properties/report">>,
dgiot_mqtt:publish(DeviceId, NotificationTopic, jsx:encode(Data)), dgiot_mqtt:publish(DeviceId, NotificationTopic, jsx:encode(Data)),
Data Data
end end