fix issues#101 - access_control for PUBLISH packet should be optimized

This commit is contained in:
Ery Lee 2015-04-21 12:14:27 +08:00
parent 04f44cb2a1
commit aab6dcf8d1
1 changed files with 18 additions and 4 deletions

View File

@ -146,7 +146,7 @@ handle(Packet = ?CONNECT_PACKET(Var), State = #proto_state{peername = Peername =
handle(Packet = ?PUBLISH_PACKET(?QOS_0, Topic, _PacketId, _Payload), handle(Packet = ?PUBLISH_PACKET(?QOS_0, Topic, _PacketId, _Payload),
State = #proto_state{clientid = ClientId, session = Session}) -> State = #proto_state{clientid = ClientId, session = Session}) ->
case emqttd_access_control:check_acl(client(State), publish, Topic) of case check_acl(publish, Topic, State) of
allow -> allow ->
emqttd_session:publish(Session, ClientId, {?QOS_0, emqtt_message:from_packet(Packet)}); emqttd_session:publish(Session, ClientId, {?QOS_0, emqtt_message:from_packet(Packet)});
deny -> deny ->
@ -156,7 +156,7 @@ handle(Packet = ?PUBLISH_PACKET(?QOS_0, Topic, _PacketId, _Payload),
handle(Packet = ?PUBLISH_PACKET(?QOS_1, Topic, PacketId, _Payload), handle(Packet = ?PUBLISH_PACKET(?QOS_1, Topic, PacketId, _Payload),
State = #proto_state{clientid = ClientId, session = Session}) -> State = #proto_state{clientid = ClientId, session = Session}) ->
case emqttd_access_control:check_acl(client(State), publish, Topic) of case check_acl(publish, Topic, State) of
allow -> allow ->
emqttd_session:publish(Session, ClientId, {?QOS_1, emqtt_message:from_packet(Packet)}), emqttd_session:publish(Session, ClientId, {?QOS_1, emqtt_message:from_packet(Packet)}),
send(?PUBACK_PACKET(?PUBACK, PacketId), State); send(?PUBACK_PACKET(?PUBACK, PacketId), State);
@ -167,7 +167,7 @@ handle(Packet = ?PUBLISH_PACKET(?QOS_1, Topic, PacketId, _Payload),
handle(Packet = ?PUBLISH_PACKET(?QOS_2, Topic, PacketId, _Payload), handle(Packet = ?PUBLISH_PACKET(?QOS_2, Topic, PacketId, _Payload),
State = #proto_state{clientid = ClientId, session = Session}) -> State = #proto_state{clientid = ClientId, session = Session}) ->
case emqttd_access_control:check_acl(client(State), publish, Topic) of case check_acl(publish, Topic, State) of
allow -> allow ->
NewSession = emqttd_session:publish(Session, ClientId, {?QOS_2, emqtt_message:from_packet(Packet)}), NewSession = emqttd_session:publish(Session, ClientId, {?QOS_2, emqtt_message:from_packet(Packet)}),
send(?PUBACK_PACKET(?PUBREC, PacketId), State#proto_state{session = NewSession}); send(?PUBACK_PACKET(?PUBREC, PacketId), State#proto_state{session = NewSession});
@ -191,7 +191,7 @@ handle(?PUBACK_PACKET(Type, PacketId), State = #proto_state{session = Session})
{ok, NewState}; {ok, NewState};
handle(?SUBSCRIBE_PACKET(PacketId, TopicTable), State = #proto_state{clientid = ClientId, session = Session}) -> handle(?SUBSCRIBE_PACKET(PacketId, TopicTable), State = #proto_state{clientid = ClientId, session = Session}) ->
AllowDenies = [emqttd_access_control:check_acl(client(State), subscribe, Topic) || {Topic, _Qos} <- TopicTable], AllowDenies = [check_acl(subscribe, Topic, State) || {Topic, _Qos} <- TopicTable],
case lists:member(deny, AllowDenies) of case lists:member(deny, AllowDenies) of
true -> true ->
%%TODO: return 128 QoS when deny... %%TODO: return 128 QoS when deny...
@ -343,6 +343,20 @@ validate_qos(_) -> false.
try_unregister(undefined, _) -> ok; try_unregister(undefined, _) -> ok;
try_unregister(ClientId, _) -> emqttd_cm:unregister(ClientId). try_unregister(ClientId, _) -> emqttd_cm:unregister(ClientId).
%% publish ACL is cached in process dictionary.
check_acl(publish, Topic, State) ->
case get({acl, publish, Topic}) of
undefined ->
AllowDeny = emqttd_access_control:check_acl(client(State), publish, Topic),
put({acl, publish, Topic}, AllowDeny),
AllowDeny;
AllowDeny ->
AllowDeny
end;
check_acl(subscribe, Topic, State) ->
emqttd_access_control:check_acl(client(State), subscribe, Topic).
sent_stats(?PACKET(Type)) -> sent_stats(?PACKET(Type)) ->
emqttd_metrics:inc('packets/sent'), emqttd_metrics:inc('packets/sent'),
inc(Type). inc(Type).