chore: add authz tag to match_rule_error log
This commit is contained in:
parent
9e4a84cf76
commit
52031441cf
|
@ -163,7 +163,7 @@ qos_from_opts(Opts) ->
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
catch
|
catch
|
||||||
{bad_qos, QoS} ->
|
throw:{bad_qos, QoS} ->
|
||||||
throw(#{
|
throw(#{
|
||||||
reason => invalid_authorization_qos,
|
reason => invalid_authorization_qos,
|
||||||
qos => QoS
|
qos => QoS
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
-module(emqx_authz_utils).
|
-module(emqx_authz_utils).
|
||||||
|
|
||||||
|
-feature(maybe_expr, enable).
|
||||||
|
|
||||||
-include_lib("emqx/include/emqx_placeholder.hrl").
|
-include_lib("emqx/include/emqx_placeholder.hrl").
|
||||||
-include_lib("emqx_authz.hrl").
|
-include_lib("emqx_authz.hrl").
|
||||||
-include_lib("snabbkaffe/include/trace.hrl").
|
-include_lib("snabbkaffe/include/trace.hrl").
|
||||||
|
@ -37,7 +39,7 @@
|
||||||
render_sql_params/2,
|
render_sql_params/2,
|
||||||
client_vars/1,
|
client_vars/1,
|
||||||
vars_for_rule_query/2,
|
vars_for_rule_query/2,
|
||||||
parse_rule_from_row/2
|
do_authorize/6
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
@ -221,14 +223,18 @@ content_type(Headers) when is_list(Headers) ->
|
||||||
|
|
||||||
-define(RAW_RULE_KEYS, [<<"permission">>, <<"action">>, <<"topic">>, <<"qos">>, <<"retain">>]).
|
-define(RAW_RULE_KEYS, [<<"permission">>, <<"action">>, <<"topic">>, <<"qos">>, <<"retain">>]).
|
||||||
|
|
||||||
parse_rule_from_row(ColumnNames, Row) ->
|
-spec parse_rule_from_row([binary()], [binary()] | map()) ->
|
||||||
RuleRaw = maps:with(?RAW_RULE_KEYS, maps:from_list(lists:zip(ColumnNames, to_list(Row)))),
|
{ok, emqx_authz_rule:rule()} | {error, term()}.
|
||||||
case emqx_authz_rule_raw:parse_rule(RuleRaw) of
|
parse_rule_from_row(_ColumnNames, RuleMap = #{}) ->
|
||||||
|
case emqx_authz_rule_raw:parse_rule(RuleMap) of
|
||||||
{ok, {Permission, Action, Topics}} ->
|
{ok, {Permission, Action, Topics}} ->
|
||||||
emqx_authz_rule:compile({Permission, all, Action, Topics});
|
{ok, emqx_authz_rule:compile({Permission, all, Action, Topics})};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
error(Reason)
|
{error, Reason}
|
||||||
end.
|
end;
|
||||||
|
parse_rule_from_row(ColumnNames, Row) ->
|
||||||
|
RuleMap = maps:with(?RAW_RULE_KEYS, maps:from_list(lists:zip(ColumnNames, to_list(Row)))),
|
||||||
|
parse_rule_from_row(ColumnNames, RuleMap).
|
||||||
|
|
||||||
vars_for_rule_query(Client, ?authz_action(PubSub, Qos) = Action) ->
|
vars_for_rule_query(Client, ?authz_action(PubSub, Qos) = Action) ->
|
||||||
Client#{
|
Client#{
|
||||||
|
@ -281,3 +287,39 @@ to_list(Tuple) when is_tuple(Tuple) ->
|
||||||
tuple_to_list(Tuple);
|
tuple_to_list(Tuple);
|
||||||
to_list(List) when is_list(List) ->
|
to_list(List) when is_list(List) ->
|
||||||
List.
|
List.
|
||||||
|
|
||||||
|
do_authorize(Type, Client, Action, Topic, ColumnNames, Row) ->
|
||||||
|
try
|
||||||
|
maybe
|
||||||
|
{ok, Rule} ?= parse_rule_from_row(ColumnNames, Row),
|
||||||
|
{matched, Permission} ?= emqx_authz_rule:match(Client, Action, Topic, Rule),
|
||||||
|
{matched, Permission}
|
||||||
|
else
|
||||||
|
nomatch ->
|
||||||
|
nomatch;
|
||||||
|
{error, Reason0} ->
|
||||||
|
log_match_rule_error(Type, Row, Reason0),
|
||||||
|
nomatch
|
||||||
|
end
|
||||||
|
catch
|
||||||
|
throw:Reason1 ->
|
||||||
|
log_match_rule_error(Type, Row, Reason1),
|
||||||
|
nomatch
|
||||||
|
end.
|
||||||
|
|
||||||
|
log_match_rule_error(Type, Row, Reason0) ->
|
||||||
|
Msg0 = #{
|
||||||
|
msg => "match_rule_error",
|
||||||
|
rule => Row,
|
||||||
|
type => Type
|
||||||
|
},
|
||||||
|
Msg1 =
|
||||||
|
case is_map(Reason0) of
|
||||||
|
true -> maps:merge(Msg0, Reason0);
|
||||||
|
false -> Msg0#{reason => Reason0}
|
||||||
|
end,
|
||||||
|
?SLOG(
|
||||||
|
error,
|
||||||
|
Msg1,
|
||||||
|
#{tag => "AUTHZ"}
|
||||||
|
).
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
{application, emqx_auth_mysql, [
|
{application, emqx_auth_mysql, [
|
||||||
{description, "EMQX MySQL Authentication and Authorization"},
|
{description, "EMQX MySQL Authentication and Authorization"},
|
||||||
{vsn, "0.2.0"},
|
{vsn, "0.2.1"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{mod, {emqx_auth_mysql_app, []}},
|
{mod, {emqx_auth_mysql_app, []}},
|
||||||
{applications, [
|
{applications, [
|
||||||
|
|
|
@ -101,19 +101,9 @@ authorize(
|
||||||
do_authorize(_Client, _Action, _Topic, _ColumnNames, []) ->
|
do_authorize(_Client, _Action, _Topic, _ColumnNames, []) ->
|
||||||
nomatch;
|
nomatch;
|
||||||
do_authorize(Client, Action, Topic, ColumnNames, [Row | Tail]) ->
|
do_authorize(Client, Action, Topic, ColumnNames, [Row | Tail]) ->
|
||||||
try
|
case emqx_authz_utils:do_authorize(mysql, Client, Action, Topic, ColumnNames, Row) of
|
||||||
emqx_authz_rule:match(
|
nomatch ->
|
||||||
Client, Action, Topic, emqx_authz_utils:parse_rule_from_row(ColumnNames, Row)
|
do_authorize(Client, Action, Topic, ColumnNames, Tail);
|
||||||
)
|
{matched, Permission} ->
|
||||||
of
|
{matched, Permission}
|
||||||
{matched, Permission} -> {matched, Permission};
|
|
||||||
nomatch -> do_authorize(Client, Action, Topic, ColumnNames, Tail)
|
|
||||||
catch
|
|
||||||
error:Reason ->
|
|
||||||
?SLOG(error, #{
|
|
||||||
msg => "match_rule_error",
|
|
||||||
reason => Reason,
|
|
||||||
rule => Row
|
|
||||||
}),
|
|
||||||
do_authorize(Client, Action, Topic, ColumnNames, Tail)
|
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
{application, emqx_auth_postgresql, [
|
{application, emqx_auth_postgresql, [
|
||||||
{description, "EMQX PostgreSQL Authentication and Authorization"},
|
{description, "EMQX PostgreSQL Authentication and Authorization"},
|
||||||
{vsn, "0.2.0"},
|
{vsn, "0.2.1"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{mod, {emqx_auth_postgresql_app, []}},
|
{mod, {emqx_auth_postgresql_app, []}},
|
||||||
{applications, [
|
{applications, [
|
||||||
|
|
|
@ -107,22 +107,11 @@ authorize(
|
||||||
do_authorize(_Client, _Action, _Topic, _ColumnNames, []) ->
|
do_authorize(_Client, _Action, _Topic, _ColumnNames, []) ->
|
||||||
nomatch;
|
nomatch;
|
||||||
do_authorize(Client, Action, Topic, ColumnNames, [Row | Tail]) ->
|
do_authorize(Client, Action, Topic, ColumnNames, [Row | Tail]) ->
|
||||||
try
|
case emqx_authz_utils:do_authorize(postgresql, Client, Action, Topic, ColumnNames, Row) of
|
||||||
emqx_authz_rule:match(
|
nomatch ->
|
||||||
Client, Action, Topic, emqx_authz_utils:parse_rule_from_row(ColumnNames, Row)
|
do_authorize(Client, Action, Topic, ColumnNames, Tail);
|
||||||
)
|
{matched, Permission} ->
|
||||||
of
|
{matched, Permission}
|
||||||
{matched, Permission} -> {matched, Permission};
|
|
||||||
nomatch -> do_authorize(Client, Action, Topic, ColumnNames, Tail)
|
|
||||||
catch
|
|
||||||
error:Reason:Stack ->
|
|
||||||
?SLOG(error, #{
|
|
||||||
msg => "match_rule_error",
|
|
||||||
reason => Reason,
|
|
||||||
rule => Row,
|
|
||||||
stack => Stack
|
|
||||||
}),
|
|
||||||
do_authorize(Client, Action, Topic, ColumnNames, Tail)
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
column_names(Columns) ->
|
column_names(Columns) ->
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
{application, emqx_auth_redis, [
|
{application, emqx_auth_redis, [
|
||||||
{description, "EMQX Redis Authentication and Authorization"},
|
{description, "EMQX Redis Authentication and Authorization"},
|
||||||
{vsn, "0.2.0"},
|
{vsn, "0.2.1"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{mod, {emqx_auth_redis_app, []}},
|
{mod, {emqx_auth_redis_app, []}},
|
||||||
{applications, [
|
{applications, [
|
||||||
|
|
|
@ -92,44 +92,30 @@ authorize(
|
||||||
do_authorize(_Client, _Action, _Topic, []) ->
|
do_authorize(_Client, _Action, _Topic, []) ->
|
||||||
nomatch;
|
nomatch;
|
||||||
do_authorize(Client, Action, Topic, [TopicFilterRaw, RuleEncoded | Tail]) ->
|
do_authorize(Client, Action, Topic, [TopicFilterRaw, RuleEncoded | Tail]) ->
|
||||||
try
|
case parse_rule(RuleEncoded) of
|
||||||
emqx_authz_rule:match(
|
{ok, RuleMap0} ->
|
||||||
Client,
|
RuleMap =
|
||||||
Action,
|
maps:merge(
|
||||||
Topic,
|
#{
|
||||||
compile_rule(RuleEncoded, TopicFilterRaw)
|
<<"permission">> => <<"allow">>,
|
||||||
)
|
<<"topic">> => TopicFilterRaw
|
||||||
of
|
},
|
||||||
{matched, Permission} -> {matched, Permission};
|
RuleMap0
|
||||||
nomatch -> do_authorize(Client, Action, Topic, Tail)
|
),
|
||||||
catch
|
case emqx_authz_utils:do_authorize(redis, Client, Action, Topic, undefined, RuleMap) of
|
||||||
error:Reason:Stack ->
|
nomatch ->
|
||||||
?SLOG(error, #{
|
do_authorize(Client, Action, Topic, Tail);
|
||||||
msg => "match_rule_error",
|
{matched, Permission} ->
|
||||||
reason => Reason,
|
{matched, Permission}
|
||||||
rule_encoded => RuleEncoded,
|
end;
|
||||||
topic_filter_raw => TopicFilterRaw,
|
{error, Reason} ->
|
||||||
stacktrace => Stack
|
?SLOG(error, Reason#{
|
||||||
|
msg => "parse_rule_error",
|
||||||
|
rule => RuleEncoded
|
||||||
}),
|
}),
|
||||||
do_authorize(Client, Action, Topic, Tail)
|
do_authorize(Client, Action, Topic, Tail)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
compile_rule(RuleBin, TopicFilterRaw) ->
|
|
||||||
RuleRaw =
|
|
||||||
maps:merge(
|
|
||||||
#{
|
|
||||||
<<"permission">> => <<"allow">>,
|
|
||||||
<<"topic">> => TopicFilterRaw
|
|
||||||
},
|
|
||||||
parse_rule(RuleBin)
|
|
||||||
),
|
|
||||||
case emqx_authz_rule_raw:parse_rule(RuleRaw) of
|
|
||||||
{ok, {Permission, Action, Topics}} ->
|
|
||||||
emqx_authz_rule:compile({Permission, all, Action, Topics});
|
|
||||||
{error, Reason} ->
|
|
||||||
error(Reason)
|
|
||||||
end.
|
|
||||||
|
|
||||||
parse_cmd(Query) ->
|
parse_cmd(Query) ->
|
||||||
case emqx_redis_command:split(Query) of
|
case emqx_redis_command:split(Query) of
|
||||||
{ok, Cmd} ->
|
{ok, Cmd} ->
|
||||||
|
@ -154,17 +140,17 @@ validate_cmd(Cmd) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
parse_rule(<<"publish">>) ->
|
parse_rule(<<"publish">>) ->
|
||||||
#{<<"action">> => <<"publish">>};
|
{ok, #{<<"action">> => <<"publish">>}};
|
||||||
parse_rule(<<"subscribe">>) ->
|
parse_rule(<<"subscribe">>) ->
|
||||||
#{<<"action">> => <<"subscribe">>};
|
{ok, #{<<"action">> => <<"subscribe">>}};
|
||||||
parse_rule(<<"all">>) ->
|
parse_rule(<<"all">>) ->
|
||||||
#{<<"action">> => <<"all">>};
|
{ok, #{<<"action">> => <<"all">>}};
|
||||||
parse_rule(Bin) when is_binary(Bin) ->
|
parse_rule(Bin) when is_binary(Bin) ->
|
||||||
case emqx_utils_json:safe_decode(Bin, [return_maps]) of
|
case emqx_utils_json:safe_decode(Bin, [return_maps]) of
|
||||||
{ok, Map} when is_map(Map) ->
|
{ok, Map} when is_map(Map) ->
|
||||||
maps:with([<<"qos">>, <<"action">>, <<"retain">>], Map);
|
{ok, maps:with([<<"qos">>, <<"action">>, <<"retain">>], Map)};
|
||||||
{ok, _} ->
|
{ok, _} ->
|
||||||
error({invalid_topic_rule, Bin, notamap});
|
{error, #{reason => invalid_topic_rule_not_map, value => Bin}};
|
||||||
{error, Error} ->
|
{error, _Error} ->
|
||||||
error({invalid_topic_rule, Bin, Error})
|
{error, #{reason => invalid_topic_rule_not_json, value => Bin}}
|
||||||
end.
|
end.
|
||||||
|
|
Loading…
Reference in New Issue