chore(authz mnesia): in the mnesia table, replace atom with int
This commit is contained in:
parent
9b3917e0d3
commit
673b12a46d
|
@ -55,6 +55,10 @@ authorization {
|
||||||
# collection: mqtt_authz
|
# collection: mqtt_authz
|
||||||
# selector: { "$or": [ { "username": "%u" }, { "clientid": "%c" } ] }
|
# selector: { "$or": [ { "username": "%u" }, { "clientid": "%c" } ] }
|
||||||
# },
|
# },
|
||||||
|
{
|
||||||
|
type: built-in-database
|
||||||
|
path: "{{ platform_etc_dir }}/acl.conf"
|
||||||
|
}
|
||||||
{
|
{
|
||||||
type: file
|
type: file
|
||||||
path: "{{ platform_etc_dir }}/acl.conf"
|
path: "{{ platform_etc_dir }}/acl.conf"
|
||||||
|
|
|
@ -19,15 +19,6 @@
|
||||||
|
|
||||||
-type(sources() :: [map()]).
|
-type(sources() :: [map()]).
|
||||||
|
|
||||||
-define(ACL_SHARDED, emqx_acl_sharded).
|
|
||||||
|
|
||||||
-define(ACL_TABLE, emqx_acl).
|
|
||||||
|
|
||||||
-record(emqx_acl, {
|
|
||||||
who :: username() | clientid() | all,
|
|
||||||
rules :: [ {permission(), action(), emqx_topic:topic()} ]
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(APP, emqx_authz).
|
-define(APP, emqx_authz).
|
||||||
|
|
||||||
-define(ALLOW_DENY(A), ((A =:= allow) orelse (A =:= <<"allow">>) orelse
|
-define(ALLOW_DENY(A), ((A =:= allow) orelse (A =:= <<"allow">>) orelse
|
||||||
|
@ -38,6 +29,20 @@
|
||||||
(A =:= all) orelse (A =:= <<"all">>)
|
(A =:= all) orelse (A =:= <<"all">>)
|
||||||
)).
|
)).
|
||||||
|
|
||||||
|
-define(ACL_SHARDED, emqx_acl_sharded).
|
||||||
|
|
||||||
|
-define(ACL_TABLE, emqx_acl).
|
||||||
|
|
||||||
|
%% To save some space, use an integer for label, 0 for 'all', {1, Username} and {2, ClientId}.
|
||||||
|
-define(ACL_TABLE_ALL, 0).
|
||||||
|
-define(ACL_TABLE_USERNAME, 1).
|
||||||
|
-define(ACL_TABLE_CLIENTID, 2).
|
||||||
|
|
||||||
|
-record(emqx_acl, {
|
||||||
|
who :: ?ACL_TABLE_ALL| {?ACL_TABLE_USERNAME, binary()} | {?ACL_TABLE_CLIENTID, binary()},
|
||||||
|
rules :: [ {permission(), action(), emqx_topic:topic()} ]
|
||||||
|
}).
|
||||||
|
|
||||||
-record(authz_metrics, {
|
-record(authz_metrics, {
|
||||||
allow = 'client.authorize.allow',
|
allow = 'client.authorize.allow',
|
||||||
deny = 'client.authorize.deny',
|
deny = 'client.authorize.deny',
|
||||||
|
|
|
@ -409,7 +409,7 @@ records(get, #{bindings := #{type := <<"username">>},
|
||||||
query_string := Qs
|
query_string := Qs
|
||||||
}) ->
|
}) ->
|
||||||
MatchSpec = ets:fun2ms(
|
MatchSpec = ets:fun2ms(
|
||||||
fun({?ACL_TABLE, {username, Username}, Rules}) ->
|
fun({?ACL_TABLE, {?ACL_TABLE_USERNAME, Username}, Rules}) ->
|
||||||
[{username, Username}, {rules, Rules}]
|
[{username, Username}, {rules, Rules}]
|
||||||
end),
|
end),
|
||||||
Format = fun ([{username, Username}, {rules, Rules}]) ->
|
Format = fun ([{username, Username}, {rules, Rules}]) ->
|
||||||
|
@ -436,7 +436,7 @@ records(get, #{bindings := #{type := <<"clientid">>},
|
||||||
query_string := Qs
|
query_string := Qs
|
||||||
}) ->
|
}) ->
|
||||||
MatchSpec = ets:fun2ms(
|
MatchSpec = ets:fun2ms(
|
||||||
fun({?ACL_TABLE, {clientid, Clientid}, Rules}) ->
|
fun({?ACL_TABLE, {?ACL_TABLE_CLIENTID, Clientid}, Rules}) ->
|
||||||
[{clientid, Clientid}, {rules, Rules}]
|
[{clientid, Clientid}, {rules, Rules}]
|
||||||
end),
|
end),
|
||||||
Format = fun ([{clientid, Clientid}, {rules, Rules}]) ->
|
Format = fun ([{clientid, Clientid}, {rules, Rules}]) ->
|
||||||
|
@ -460,7 +460,7 @@ records(get, #{bindings := #{type := <<"clientid">>},
|
||||||
end;
|
end;
|
||||||
records(get, #{bindings := #{type := <<"all">>}}) ->
|
records(get, #{bindings := #{type := <<"all">>}}) ->
|
||||||
MatchSpec = ets:fun2ms(
|
MatchSpec = ets:fun2ms(
|
||||||
fun({?ACL_TABLE, all, Rules}) ->
|
fun({?ACL_TABLE, ?ACL_TABLE_ALL, Rules}) ->
|
||||||
[{rules, Rules}]
|
[{rules, Rules}]
|
||||||
end),
|
end),
|
||||||
{200, [ #{rules => [ #{topic => Topic,
|
{200, [ #{rules => [ #{topic => Topic,
|
||||||
|
@ -472,7 +472,7 @@ records(post, #{bindings := #{type := <<"username">>},
|
||||||
body := Body}) when is_list(Body) ->
|
body := Body}) when is_list(Body) ->
|
||||||
lists:foreach(fun(#{<<"username">> := Username, <<"rules">> := Rules}) ->
|
lists:foreach(fun(#{<<"username">> := Username, <<"rules">> := Rules}) ->
|
||||||
ekka_mnesia:dirty_write(#emqx_acl{
|
ekka_mnesia:dirty_write(#emqx_acl{
|
||||||
who = {username, Username},
|
who = {?ACL_TABLE_USERNAME, Username},
|
||||||
rules = format_rules(Rules)
|
rules = format_rules(Rules)
|
||||||
})
|
})
|
||||||
end, Body),
|
end, Body),
|
||||||
|
@ -481,7 +481,7 @@ records(post, #{bindings := #{type := <<"clientid">>},
|
||||||
body := Body}) when is_list(Body) ->
|
body := Body}) when is_list(Body) ->
|
||||||
lists:foreach(fun(#{<<"clientid">> := Clientid, <<"rules">> := Rules}) ->
|
lists:foreach(fun(#{<<"clientid">> := Clientid, <<"rules">> := Rules}) ->
|
||||||
ekka_mnesia:dirty_write(#emqx_acl{
|
ekka_mnesia:dirty_write(#emqx_acl{
|
||||||
who = {clientid, Clientid},
|
who = {?ACL_TABLE_CLIENTID, Clientid},
|
||||||
rules = format_rules(Rules)
|
rules = format_rules(Rules)
|
||||||
})
|
})
|
||||||
end, Body),
|
end, Body),
|
||||||
|
@ -489,15 +489,15 @@ records(post, #{bindings := #{type := <<"clientid">>},
|
||||||
records(put, #{bindings := #{type := <<"all">>},
|
records(put, #{bindings := #{type := <<"all">>},
|
||||||
body := #{<<"rules">> := Rules}}) ->
|
body := #{<<"rules">> := Rules}}) ->
|
||||||
ekka_mnesia:dirty_write(#emqx_acl{
|
ekka_mnesia:dirty_write(#emqx_acl{
|
||||||
who = all,
|
who = ?ACL_TABLE_ALL,
|
||||||
rules = format_rules(Rules)
|
rules = format_rules(Rules)
|
||||||
}),
|
}),
|
||||||
{204}.
|
{204}.
|
||||||
|
|
||||||
record(get, #{bindings := #{type := <<"username">>, key := Key}}) ->
|
record(get, #{bindings := #{type := <<"username">>, key := Key}}) ->
|
||||||
case mnesia:dirty_read(?ACL_TABLE, {username, Key}) of
|
case mnesia:dirty_read(?ACL_TABLE, {?ACL_TABLE_USERNAME, Key}) of
|
||||||
[] -> {404, #{code => <<"NOT_FOUND">>, message => <<"Not Found">>}};
|
[] -> {404, #{code => <<"NOT_FOUND">>, message => <<"Not Found">>}};
|
||||||
[#emqx_acl{who = {username, Username}, rules = Rules}] ->
|
[#emqx_acl{who = {?ACL_TABLE_USERNAME, Username}, rules = Rules}] ->
|
||||||
{200, #{username => Username,
|
{200, #{username => Username,
|
||||||
rules => [ #{topic => Topic,
|
rules => [ #{topic => Topic,
|
||||||
action => Action,
|
action => Action,
|
||||||
|
@ -506,9 +506,9 @@ record(get, #{bindings := #{type := <<"username">>, key := Key}}) ->
|
||||||
}
|
}
|
||||||
end;
|
end;
|
||||||
record(get, #{bindings := #{type := <<"clientid">>, key := Key}}) ->
|
record(get, #{bindings := #{type := <<"clientid">>, key := Key}}) ->
|
||||||
case mnesia:dirty_read(?ACL_TABLE, {clientid, Key}) of
|
case mnesia:dirty_read(?ACL_TABLE, {?ACL_TABLE_CLIENTID, Key}) of
|
||||||
[] -> {404, #{code => <<"NOT_FOUND">>, message => <<"Not Found">>}};
|
[] -> {404, #{code => <<"NOT_FOUND">>, message => <<"Not Found">>}};
|
||||||
[#emqx_acl{who = {clientid, Clientid}, rules = Rules}] ->
|
[#emqx_acl{who = {?ACL_TABLE_CLIENTID, Clientid}, rules = Rules}] ->
|
||||||
{200, #{clientid => Clientid,
|
{200, #{clientid => Clientid,
|
||||||
rules => [ #{topic => Topic,
|
rules => [ #{topic => Topic,
|
||||||
action => Action,
|
action => Action,
|
||||||
|
@ -519,22 +519,22 @@ record(get, #{bindings := #{type := <<"clientid">>, key := Key}}) ->
|
||||||
record(put, #{bindings := #{type := <<"username">>, key := Username},
|
record(put, #{bindings := #{type := <<"username">>, key := Username},
|
||||||
body := #{<<"username">> := Username, <<"rules">> := Rules}}) ->
|
body := #{<<"username">> := Username, <<"rules">> := Rules}}) ->
|
||||||
ekka_mnesia:dirty_write(#emqx_acl{
|
ekka_mnesia:dirty_write(#emqx_acl{
|
||||||
who = {username, Username},
|
who = {?ACL_TABLE_USERNAME, Username},
|
||||||
rules = format_rules(Rules)
|
rules = format_rules(Rules)
|
||||||
}),
|
}),
|
||||||
{204};
|
{204};
|
||||||
record(put, #{bindings := #{type := <<"clientid">>, key := Clientid},
|
record(put, #{bindings := #{type := <<"clientid">>, key := Clientid},
|
||||||
body := #{<<"clientid">> := Clientid, <<"rules">> := Rules}}) ->
|
body := #{<<"clientid">> := Clientid, <<"rules">> := Rules}}) ->
|
||||||
ekka_mnesia:dirty_write(#emqx_acl{
|
ekka_mnesia:dirty_write(#emqx_acl{
|
||||||
who = {clientid, Clientid},
|
who = {?ACL_TABLE_CLIENTID, Clientid},
|
||||||
rules = format_rules(Rules)
|
rules = format_rules(Rules)
|
||||||
}),
|
}),
|
||||||
{204};
|
{204};
|
||||||
record(delete, #{bindings := #{type := <<"username">>, key := Key}}) ->
|
record(delete, #{bindings := #{type := <<"username">>, key := Key}}) ->
|
||||||
ekka_mnesia:dirty_delete({?ACL_TABLE, {username, Key}}),
|
ekka_mnesia:dirty_delete({?ACL_TABLE, {?ACL_TABLE_USERNAME, Key}}),
|
||||||
{204};
|
{204};
|
||||||
record(delete, #{bindings := #{type := <<"clientid">>, key := Key}}) ->
|
record(delete, #{bindings := #{type := <<"clientid">>, key := Key}}) ->
|
||||||
ekka_mnesia:dirty_delete({?ACL_TABLE, {clientid, Key}}),
|
ekka_mnesia:dirty_delete({?ACL_TABLE, {?ACL_TABLE_CLIENTID, Key}}),
|
||||||
{204}.
|
{204}.
|
||||||
|
|
||||||
format_rules(Rules) when is_list(Rules) ->
|
format_rules(Rules) when is_list(Rules) ->
|
||||||
|
|
|
@ -52,15 +52,15 @@ authorize(#{username := Username,
|
||||||
clientid := Clientid
|
clientid := Clientid
|
||||||
} = Client, PubSub, Topic, #{type := 'built-in-database'}) ->
|
} = Client, PubSub, Topic, #{type := 'built-in-database'}) ->
|
||||||
|
|
||||||
Rules = case mnesia:dirty_read(?ACL_TABLE, {clientid, Clientid}) of
|
Rules = case mnesia:dirty_read(?ACL_TABLE, {?ACL_TABLE_CLIENTID, Clientid}) of
|
||||||
[] -> [];
|
[] -> [];
|
||||||
[#emqx_acl{rules = Rules0}] when is_list(Rules0) -> Rules0
|
[#emqx_acl{rules = Rules0}] when is_list(Rules0) -> Rules0
|
||||||
end
|
end
|
||||||
++ case mnesia:dirty_read(?ACL_TABLE, {username, Username}) of
|
++ case mnesia:dirty_read(?ACL_TABLE, {?ACL_TABLE_USERNAME, Username}) of
|
||||||
[] -> [];
|
[] -> [];
|
||||||
[#emqx_acl{rules = Rules1}] when is_list(Rules1) -> Rules1
|
[#emqx_acl{rules = Rules1}] when is_list(Rules1) -> Rules1
|
||||||
end
|
end
|
||||||
++ case mnesia:dirty_read(?ACL_TABLE, all) of
|
++ case mnesia:dirty_read(?ACL_TABLE, ?ACL_TABLE_ALL) of
|
||||||
[] -> [];
|
[] -> [];
|
||||||
[#emqx_acl{rules = Rules2}] when is_list(Rules2) -> Rules2
|
[#emqx_acl{rules = Rules2}] when is_list(Rules2) -> Rules2
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -54,17 +54,17 @@ end_per_suite(_Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init_per_testcase(t_authz, Config) ->
|
init_per_testcase(t_authz, Config) ->
|
||||||
mnesia:transaction(fun ekka_mnesia:dirty_write/1, [#emqx_acl{who = {username, <<"test_username">>},
|
mnesia:transaction(fun ekka_mnesia:dirty_write/1, [#emqx_acl{who = {?ACL_TABLE_USERNAME, <<"test_username">>},
|
||||||
rules = [{allow, publish, <<"test/%u">>},
|
rules = [{allow, publish, <<"test/%u">>},
|
||||||
{allow, subscribe, <<"eq #">>}
|
{allow, subscribe, <<"eq #">>}
|
||||||
]
|
]
|
||||||
}]),
|
}]),
|
||||||
mnesia:transaction(fun ekka_mnesia:dirty_write/1, [#emqx_acl{who = {clientid, <<"test_clientid">>},
|
mnesia:transaction(fun ekka_mnesia:dirty_write/1, [#emqx_acl{who = {?ACL_TABLE_CLIENTID, <<"test_clientid">>},
|
||||||
rules = [{allow, publish, <<"test/%c">>},
|
rules = [{allow, publish, <<"test/%c">>},
|
||||||
{deny, subscribe, <<"eq #">>}
|
{deny, subscribe, <<"eq #">>}
|
||||||
]
|
]
|
||||||
}]),
|
}]),
|
||||||
mnesia:transaction(fun ekka_mnesia:dirty_write/1, [#emqx_acl{who = all,
|
mnesia:transaction(fun ekka_mnesia:dirty_write/1, [#emqx_acl{who = ?ACL_TABLE_ALL,
|
||||||
rules = [{deny, all, <<"#">>}]
|
rules = [{deny, all, <<"#">>}]
|
||||||
}]),
|
}]),
|
||||||
Config;
|
Config;
|
||||||
|
|
Loading…
Reference in New Issue