fix(authz): prohibit overriding of existing client/user
This commit is contained in:
parent
e035ff573d
commit
86a3ac0bef
|
@ -57,6 +57,7 @@
|
||||||
|
|
||||||
-define(BAD_REQUEST, 'BAD_REQUEST').
|
-define(BAD_REQUEST, 'BAD_REQUEST').
|
||||||
-define(NOT_FOUND, 'NOT_FOUND').
|
-define(NOT_FOUND, 'NOT_FOUND').
|
||||||
|
-define(ALREADY_EXISTS, 'ALREADY_EXISTS').
|
||||||
|
|
||||||
-define(TYPE_REF, ref).
|
-define(TYPE_REF, ref).
|
||||||
-define(TYPE_ARRAY, array).
|
-define(TYPE_ARRAY, array).
|
||||||
|
@ -120,6 +121,9 @@ schema("/authorization/sources/built_in_database/username") ->
|
||||||
204 => <<"Created">>,
|
204 => <<"Created">>,
|
||||||
400 => emqx_dashboard_swagger:error_codes(
|
400 => emqx_dashboard_swagger:error_codes(
|
||||||
[?BAD_REQUEST], <<"Bad username or bad rule schema">>
|
[?BAD_REQUEST], <<"Bad username or bad rule schema">>
|
||||||
|
),
|
||||||
|
409 => emqx_dashboard_swagger:error_codes(
|
||||||
|
[?ALREADY_EXISTS], <<"ALREADY_EXISTS">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,13 +420,21 @@ users(get, #{query_string := QueryString}) ->
|
||||||
{200, Result}
|
{200, Result}
|
||||||
end;
|
end;
|
||||||
users(post, #{body := Body}) when is_list(Body) ->
|
users(post, #{body := Body}) when is_list(Body) ->
|
||||||
|
case ensure_all_not_exists(<<"username">>, username, Body) of
|
||||||
|
[] ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(#{<<"username">> := Username, <<"rules">> := Rules}) ->
|
fun(#{<<"username">> := Username, <<"rules">> := Rules}) ->
|
||||||
emqx_authz_mnesia:store_rules({username, Username}, format_rules(Rules))
|
emqx_authz_mnesia:store_rules({username, Username}, format_rules(Rules))
|
||||||
end,
|
end,
|
||||||
Body
|
Body
|
||||||
),
|
),
|
||||||
{204}.
|
{204};
|
||||||
|
Exists ->
|
||||||
|
{409, #{
|
||||||
|
code => <<"ALREADY_EXISTS">>,
|
||||||
|
message => binfmt("Users '~ts' already exist", [binjoin(Exists)])
|
||||||
|
}}
|
||||||
|
end.
|
||||||
|
|
||||||
clients(get, #{query_string := QueryString}) ->
|
clients(get, #{query_string := QueryString}) ->
|
||||||
case
|
case
|
||||||
|
@ -443,13 +455,21 @@ clients(get, #{query_string := QueryString}) ->
|
||||||
{200, Result}
|
{200, Result}
|
||||||
end;
|
end;
|
||||||
clients(post, #{body := Body}) when is_list(Body) ->
|
clients(post, #{body := Body}) when is_list(Body) ->
|
||||||
|
case ensure_all_not_exists(<<"clientid">>, clientid, Body) of
|
||||||
|
[] ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(#{<<"clientid">> := ClientID, <<"rules">> := Rules}) ->
|
fun(#{<<"clientid">> := ClientID, <<"rules">> := Rules}) ->
|
||||||
emqx_authz_mnesia:store_rules({clientid, ClientID}, format_rules(Rules))
|
emqx_authz_mnesia:store_rules({clientid, ClientID}, format_rules(Rules))
|
||||||
end,
|
end,
|
||||||
Body
|
Body
|
||||||
),
|
),
|
||||||
{204}.
|
{204};
|
||||||
|
Exists ->
|
||||||
|
{409, #{
|
||||||
|
code => <<"ALREADY_EXISTS">>,
|
||||||
|
message => binfmt("Clients '~ts' already exist", [binjoin(Exists)])
|
||||||
|
}}
|
||||||
|
end.
|
||||||
|
|
||||||
user(get, #{bindings := #{username := Username}}) ->
|
user(get, #{bindings := #{username := Username}}) ->
|
||||||
case emqx_authz_mnesia:get_rules({username, Username}) of
|
case emqx_authz_mnesia:get_rules({username, Username}) of
|
||||||
|
@ -715,3 +735,29 @@ rules_example({ExampleName, ExampleType}) ->
|
||||||
value => Value
|
value => Value
|
||||||
}
|
}
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
ensure_all_not_exists(Key, Type, Cfgs) ->
|
||||||
|
lists:foldl(
|
||||||
|
fun(#{Key := Id}, Acc) ->
|
||||||
|
case emqx_authz_mnesia:get_rules({Type, Id}) of
|
||||||
|
not_found ->
|
||||||
|
Acc;
|
||||||
|
_ ->
|
||||||
|
[Id | Acc]
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
[],
|
||||||
|
Cfgs
|
||||||
|
).
|
||||||
|
|
||||||
|
binjoin([Bin]) ->
|
||||||
|
Bin;
|
||||||
|
binjoin(Bins) ->
|
||||||
|
binjoin(Bins, <<>>).
|
||||||
|
|
||||||
|
binjoin([H | T], Acc) ->
|
||||||
|
binjoin(T, <<H/binary, $,, Acc/binary>>);
|
||||||
|
binjoin([], Acc) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
|
binfmt(Fmt, Args) -> iolist_to_binary(io_lib:format(Fmt, Args)).
|
||||||
|
|
|
@ -74,6 +74,13 @@ t_api(_) ->
|
||||||
[?USERNAME_RULES_EXAMPLE]
|
[?USERNAME_RULES_EXAMPLE]
|
||||||
),
|
),
|
||||||
|
|
||||||
|
{ok, 409, _} =
|
||||||
|
request(
|
||||||
|
post,
|
||||||
|
uri(["authorization", "sources", "built_in_database", "username"]),
|
||||||
|
[?USERNAME_RULES_EXAMPLE]
|
||||||
|
),
|
||||||
|
|
||||||
{ok, 200, Request1} =
|
{ok, 200, Request1} =
|
||||||
request(
|
request(
|
||||||
get,
|
get,
|
||||||
|
@ -158,6 +165,14 @@ t_api(_) ->
|
||||||
uri(["authorization", "sources", "built_in_database", "clientid"]),
|
uri(["authorization", "sources", "built_in_database", "clientid"]),
|
||||||
[?CLIENTID_RULES_EXAMPLE]
|
[?CLIENTID_RULES_EXAMPLE]
|
||||||
),
|
),
|
||||||
|
|
||||||
|
{ok, 409, _} =
|
||||||
|
request(
|
||||||
|
post,
|
||||||
|
uri(["authorization", "sources", "built_in_database", "clientid"]),
|
||||||
|
[?CLIENTID_RULES_EXAMPLE]
|
||||||
|
),
|
||||||
|
|
||||||
{ok, 200, Request4} =
|
{ok, 200, Request4} =
|
||||||
request(
|
request(
|
||||||
get,
|
get,
|
||||||
|
|
Loading…
Reference in New Issue