Просмотр исходного кода

feat(authentication): add new apis

zhouzb 4 лет назад
Родитель
Сommit
54106790c7

+ 1 - 1
apps/emqx_authentication/rebar.config

@@ -15,4 +15,4 @@
 
 {cover_enabled, true}.
 {cover_opts, [verbose]}.
-{cover_export_enabled, true}.
+{cover_export_enabled, true}.

+ 72 - 42
apps/emqx_authentication/src/emqx_authentication.erl

@@ -1,5 +1,5 @@
 %%--------------------------------------------------------------------
-%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
+%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
 %%
 %% Licensed under the Apache License, Version 2.0 (the "License");
 %% you may not use this file except in compliance with the License.
@@ -29,13 +29,15 @@
 -export([ create_chain/1
         , delete_chain/1
         , lookup_chain/1
-        , add_services_to_chain/2
-        , delete_services_from_chain/2
+        , list_chains/0
+        , add_services/2
+        , delete_services/2
+        , update_service/3
         , lookup_service/2
         , list_services/1
-        , move_service_to_the_front_of_chain/2
-        , move_service_to_the_end_of_chain/2
-        , move_service_to_the_nth_of_chain/3
+        , move_service_to_the_front/2
+        , move_service_to_the_end/2
+        , move_service_to_the_nth/3
         ]).
 
 -export([ import_user_credentials/4
@@ -135,7 +137,7 @@ register_service_types([{_App, Mod, #{name := Name,
     register_service_types(Types, [ServiceType | Acc]).
 
 create_chain(Params = #{chain_id := ChainID}) ->
-    ServiceParams = maps:get(service_params, Params, []),
+    ServiceParams = maps:get(services, Params, []),
     case validate_service_params(ServiceParams) of
         {ok, NServiceParams} ->
             trans(
@@ -167,7 +169,7 @@ delete_chain(ChainID) ->
                 [] ->
                     {error, {not_found, {chain, ChainID}}};
                 [#chain{services = Services}] ->
-                    ok = delete_services(Services),
+                    ok = delete_services_(Services),
                     mnesia:delete(?CHAIN_TAB, ChainID, write)
             end
         end).
@@ -180,7 +182,11 @@ lookup_chain(ChainID) ->
             {ok, serialize_chain(Chain)}
     end.
 
-add_services_to_chain(ChainID, ServiceParams) ->
+list_chains() ->
+    Chains = ets:tab2list(?CHAIN_TAB),
+    [serialize_chain(Chain) || Chain <- Chains].
+
+add_services(ChainID, ServiceParams) ->
     case validate_service_params(ServiceParams) of
         {ok, NServiceParams} ->
             UpdateFun = fun(Chain = #chain{services = Services}) ->
@@ -203,13 +209,13 @@ add_services_to_chain(ChainID, ServiceParams) ->
             {error, Reason}
     end.
 
-delete_services_from_chain(ChainID, ServiceNames) ->
+delete_services(ChainID, ServiceNames) ->
     case no_duplicate_names(ServiceNames) of
         ok ->
             UpdateFun = fun(Chain = #chain{services = Services}) ->
                             case extract_services(ServiceNames, Services) of
                                 {ok, Extracted, Rest} ->
-                                    ok = delete_services(Extracted),
+                                    ok = delete_services_(Extracted),
                                     NChain = Chain#chain{services = Rest},
                                     mnesia:write(?CHAIN_TAB, NChain, write);
                                 {error, Reason} ->
@@ -221,6 +227,31 @@ delete_services_from_chain(ChainID, ServiceNames) ->
             {error, Reason}
     end.
 
+update_service(ChainID, ServiceName, NewParams) ->
+    UpdateFun = fun(Chain = #chain{services = Services}) ->
+                    case proplists:get_value(ServiceName, Services, undefined) of
+                        undefined ->
+                            {error, {not_found, {service, ServiceName}}};
+                        #service{type     = Type,
+                                 provider = Provider,
+                                 params   = OriginalParams,
+                                 state    = State} = Service ->
+                            Params = maps:merge(OriginalParams, NewParams),
+                            {ok, #service_type{params_spec = ParamsSpec}} = find_service_type(Type),
+                            NParams = emqx_rule_validator:validate_params(Params, ParamsSpec),
+                            case Provider:update(ChainID, ServiceName, NParams, State) of
+                                {ok, NState} ->
+                                    NService = Service#service{params = Params,
+                                                               state = NState},
+                                    NServices = lists:keyreplace(ServiceName, 1, Services, [{ServiceName, NService}]),
+                                    mnesia:write(?CHAIN_TAB, Chain#chain{services = NServices}, write);
+                                {error, Reason} ->
+                                    {error, Reason}
+                            end
+                    end
+                 end,
+    update_chain(ChainID, UpdateFun).
+
 lookup_service(ChainID, ServiceName) ->
     case mnesia:dirty_read(?CHAIN_TAB, ChainID) of
         [] ->
@@ -242,9 +273,9 @@ list_services(ChainID) ->
             {ok, [serialize_service(Service) || Service <- Services]}
     end.
 
-move_service_to_the_front_of_chain(ChainID, ServiceName) ->
+move_service_to_the_front(ChainID, ServiceName) ->
     UpdateFun = fun(Chain = #chain{services = Services}) ->
-                    case move_service_to_the_front(ServiceName, Services) of
+                    case move_service_to_the_front_(ServiceName, Services) of
                         {ok, NServices} ->
                             NChain = Chain#chain{services = NServices},
                             mnesia:write(?CHAIN_TAB, NChain, write);
@@ -254,9 +285,9 @@ move_service_to_the_front_of_chain(ChainID, ServiceName) ->
                  end,
     update_chain(ChainID, UpdateFun).
 
-move_service_to_the_end_of_chain(ChainID, ServiceName) ->
+move_service_to_the_end(ChainID, ServiceName) ->
     UpdateFun = fun(Chain = #chain{services = Services}) ->
-                    case move_service_to_the_end(ServiceName, Services) of
+                    case move_service_to_the_end_(ServiceName, Services) of
                         {ok, NServices} ->
                             NChain = Chain#chain{services = NServices},
                             mnesia:write(?CHAIN_TAB, NChain, write);
@@ -266,9 +297,9 @@ move_service_to_the_end_of_chain(ChainID, ServiceName) ->
                  end,
     update_chain(ChainID, UpdateFun).
 
-move_service_to_the_nth_of_chain(ChainID, ServiceName, N) ->
+move_service_to_the_nth(ChainID, ServiceName, N) ->
     UpdateFun = fun(Chain = #chain{services = Services}) ->
-                    case move_service_to_nth(ServiceName, Services, N) of
+                    case move_service_to_the_nth_(ServiceName, Services, N) of
                         {ok, NServices} ->
                             NChain = Chain#chain{services = NServices},
                             mnesia:write(?CHAIN_TAB, NChain, write);
@@ -380,15 +411,15 @@ create_services(ChainID, [#{name := Name,
                                state = State},
             create_services(ChainID, More, [{Name, Service} | Acc]);
         {error, Reason} ->
-            delete_services(Acc),
+            delete_services_(Acc),
             {error, Reason}
     end.
 
-delete_services([]) ->
+delete_services_([]) ->
     ok;
-delete_services([{_, #service{provider = Provider, state = State}} | More]) ->
+delete_services_([{_, #service{provider = Provider, state = State}} | More]) ->
     Provider:destroy(State),
-    delete_services(More).
+    delete_services_(More).
 
 extract_services(ServiceNames, Services) ->
     extract_services(ServiceNames, Services, []).
@@ -403,43 +434,43 @@ extract_services([ServiceName | More], Services, Acc) ->
             {error, {not_found, {service, ServiceName}}}
     end.
     
-move_service_to_the_front(ServiceName, Services) ->
-    move_service_to_the_front(ServiceName, Services, []).
+move_service_to_the_front_(ServiceName, Services) ->
+    move_service_to_the_front_(ServiceName, Services, []).
 
-move_service_to_the_front(ServiceName, [], _) ->
+move_service_to_the_front_(ServiceName, [], _) ->
     {error, {not_found, {service, ServiceName}}};
-move_service_to_the_front(ServiceName, [{ServiceName, _} = Service | More], Passed) ->
+move_service_to_the_front_(ServiceName, [{ServiceName, _} = Service | More], Passed) ->
     {ok, [Service | (lists:reverse(Passed) ++ More)]};
-move_service_to_the_front(ServiceName, [Service | More], Passed) ->
-    move_service_to_the_front(ServiceName, More, [Service | Passed]).
+move_service_to_the_front_(ServiceName, [Service | More], Passed) ->
+    move_service_to_the_front_(ServiceName, More, [Service | Passed]).
 
-move_service_to_the_end(ServiceName, Services) ->
-    move_service_to_the_end(ServiceName, Services, []).
+move_service_to_the_end_(ServiceName, Services) ->
+    move_service_to_the_end_(ServiceName, Services, []).
 
-move_service_to_the_end(ServiceName, [], _) ->
+move_service_to_the_end_(ServiceName, [], _) ->
     {error, {not_found, {service, ServiceName}}};
-move_service_to_the_end(ServiceName, [{ServiceName, _} = Service | More], Passed) ->
+move_service_to_the_end_(ServiceName, [{ServiceName, _} = Service | More], Passed) ->
     {ok, lists:reverse(Passed) ++ More ++ [Service]};
-move_service_to_the_end(ServiceName, [Service | More], Passed) ->
-    move_service_to_the_end(ServiceName, More, [Service | Passed]).
+move_service_to_the_end_(ServiceName, [Service | More], Passed) ->
+    move_service_to_the_end_(ServiceName, More, [Service | Passed]).
 
-move_service_to_nth(ServiceName, Services, N)
+move_service_to_the_nth_(ServiceName, Services, N)
   when N =< length(Services) andalso N > 0 ->
-    move_service_to_nth(ServiceName, Services, N, []);
-move_service_to_nth(_, _, _) ->
+    move_service_to_the_nth_(ServiceName, Services, N, []);
+move_service_to_the_nth_(_, _, _) ->
     {error, out_of_range}.
 
-move_service_to_nth(ServiceName, [], _, _) ->
+move_service_to_the_nth_(ServiceName, [], _, _) ->
     {error, {not_found, {service, ServiceName}}};
-move_service_to_nth(ServiceName, [{ServiceName, _} = Service | More], N, Passed)
+move_service_to_the_nth_(ServiceName, [{ServiceName, _} = Service | More], N, Passed)
   when N =< length(Passed) ->
     {L1, L2} = lists:split(N - 1, lists:reverse(Passed)),
     {ok, L1 ++ [Service] ++ L2 ++ More};
-move_service_to_nth(ServiceName, [{ServiceName, _} = Service | More], N, Passed) ->
+move_service_to_the_nth_(ServiceName, [{ServiceName, _} = Service | More], N, Passed) ->
     {L1, L2} = lists:split(N - length(Passed) - 1, More),
     {ok, lists:reverse(Passed) ++ L1 ++ [Service] ++ L2};
-move_service_to_nth(ServiceName, [Service | More], N, Passed) ->
-    move_service_to_nth(ServiceName, More, N, [Service | Passed]).
+move_service_to_the_nth_(ServiceName, [Service | More], N, Passed) ->
+    move_service_to_the_nth_(ServiceName, More, N, [Service | Passed]).
 
 update_chain(ChainID, UpdateFun) ->
     trans(
@@ -478,7 +509,6 @@ serialize_chain(#chain{id = ID,
       services => [serialize_service(Service) || Service <- Services],
       created_at => CreatedAt}.
 
-
 serialize_service({_, #service{name = Name,
                                type = Type,
                                params = Params}}) ->

+ 245 - 0
apps/emqx_authentication/src/emqx_authentication_api.erl

@@ -0,0 +1,245 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%--------------------------------------------------------------------
+
+-module(emqx_authentication_api).
+
+-export([ create_chain/2
+        , delete_chain/2
+        , lookup_chain/2
+        , list_chains/2
+        , add_services/2
+        , delete_services/2
+        , update_service/2
+        , lookup_service/2
+        , list_services/2
+        , move_service/2
+        , import_user_credentials/2
+        , add_user_creadential/2
+        ]).
+
+-import(minirest,  [return/1]).
+
+-rest_api(#{name   => list_chains,
+            method => 'GET',
+            path   => "/authentication/chains",
+            func   => list_chains,
+            descr  => "List all chains"
+           }).
+
+-rest_api(#{name   => create_chain,
+            method => 'POST',
+            path   => "/authentication/chains",
+            func   => create_chain,
+            descr  => "Create a chain"
+           }).
+
+create_chain(_Binding, Params = #{chain_id := ChainID}) ->
+    case emqx_authentication:create_chain(Params) of
+        {ok, ChainID} ->
+            return({ok, ChainID});
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+create_chain(_Binding, _Params) ->
+    return({error, serialize_error({missing_parameter, chain_id})}).
+
+delete_chain(_Binding, #{chain_id := ChainID}) ->
+    case emqx_authentication:delete_chain(ChainID) of
+        ok ->
+            return(ok);
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end.
+
+lookup_chain(_Binding, #{chain_id := ChainID}) ->
+    case emqx_authentication:lookup_chain(ChainID) of
+        {ok, Chain} ->
+            return({ok, Chain});
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+lookup_chain(_Binding, _Params) ->
+    return({error, serialize_error({missing_parameter, chain_id})}).
+
+list_chains(_Binding, _Params) ->
+    emqx_authentication:list_chains().
+
+add_services(_Binding, Params = #{chain_id := ChainID}) ->
+    case maps:get(services, Params, []) of
+        [] -> return(ok);
+        Services ->
+            case emqx_authentication:add_services(ChainID, Services) of
+                ok ->
+                    return(ok);
+                {error, Reason} ->
+                    return({error, serialize_error(Reason)})
+            end
+    end;
+add_services(_Binding, _Params) ->
+    return({error, serialize_error({missing_parameter, chain_id})}).
+
+delete_services(_Binding, #{chain_id := ChainID,
+                            service_names := ServiceNames}) ->
+    case emqx_authentication:delete_services(ChainID, ServiceNames) of
+        ok ->
+            return(ok);
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+delete_services(_Binding, #{chain_id := _}) ->
+    return({error, serialize_error({missing_parameter, service_names})});
+delete_services(_Binding, #{service_names := _}) ->
+    return({error, serialize_error({missing_parameter, chain_id})}).
+
+%% TODO: better input parameters
+update_service(_Binding, #{chain_id := ChainID,
+                           service_name := ServiceName,
+                           service_params := Params}) ->
+    case emqx_authentication:update_service(ChainID, ServiceName, Params) of
+        ok ->
+            return(ok);
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+update_service(_Binding, #{chain_id := _}) ->
+    return({error, serialize_error({missing_parameter, service_name})});
+update_service(_Binding, #{service_name := _}) ->
+    return({error, serialize_error({missing_parameter, chain_id})}).
+
+lookup_service(_Binding, #{chain_id := ChainID,
+                           service_name := ServiceName}) ->
+    case emqx_authentication:lookup_service(ChainID, ServiceName) of
+        {ok, Service} ->
+            return({ok, Service});
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+lookup_service(_Binding, #{chain_id := _}) ->
+    return({error, serialize_error({missing_parameter, service_name})});
+lookup_service(_Binding, #{service_name := _}) ->
+    return({error, serialize_error({missing_parameter, chain_id})}).
+
+list_services(_Binding, #{chain_id := ChainID}) ->
+    case emqx_authentication:list_services(ChainID) of
+        {ok, Service} ->
+            return({ok, Service});
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+list_services(_Binding, _Params) ->
+    return({error, serialize_error({missing_parameter, chain_id})}).
+
+move_service(_Binding, #{chain_id := ChainID,
+                         service_name := ServiceName,
+                         to := <<"the front">>}) ->
+    case emqx_authenticaiton:move_service_to_the_front(ChainID, ServiceName) of
+        ok ->
+            return(ok);
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+move_service(_Binding, #{chain_id := ChainID,
+                         service_name := ServiceName,
+                         to := <<"the end">>}) ->
+    case emqx_authenticaiton:move_service_to_the_end(ChainID, ServiceName) of
+        ok ->
+            return(ok);
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+move_service(_Binding, #{chain_id := ChainID,
+                         service_name := ServiceName,
+                         to := N}) when is_number(N) ->
+    case emqx_authenticaiton:move_service_to_the_nth(ChainID, ServiceName, N) of
+        ok ->
+            return(ok);
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+move_service(_Binding, Params) ->
+    Missed = get_missed_params(Params, [chain_id, service_name, to]),
+    return({error, serialize_error({missing_parameter, Missed})}).
+
+import_user_credentials(_Binding, #{chain_id := ChainID,
+                                    service_name := ServiceName,
+                                    filename := Filename,
+                                    file_format := FileFormat}) ->
+    case emqx_authentication:import_user_credentials(ChainID, ServiceName, Filename, FileFormat) of
+        ok ->
+            return(ok);
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+import_user_credentials(_Binding, Params) ->
+    Missed = get_missed_params(Params, [chain_id, service_name, filename, file_format]),
+    return({error, serialize_error({missing_parameter, Missed})}).
+
+add_user_creadential(_Binding, #{chain_id := ChainID,
+                                 service_name := ServiceName,
+                                 credential := Credential}) ->
+    case emqx_authentication:add_user_creadentials(ChainID, ServiceName, Credential) of
+        ok ->
+            return(ok);
+        {error, Reason} ->
+            return({error, serialize_error(Reason)})
+    end;
+add_user_creadential(_Binding, Params) ->
+    Missed = get_missed_params(Params, [chain_id, service_name, credential]),
+    return({error, serialize_error({missing_parameter, Missed})}).
+
+%%------------------------------------------------------------------------------
+%% Internal functions
+%%------------------------------------------------------------------------------
+
+serialize_error(Reason) when not is_map(Reason) ->
+    Error = serialize_error_(Reason),
+    emqx_json:encode(Error).
+
+serialize_error_({already_exists, {Type, ID}}) ->
+    #{code => "ALREADY_EXISTS",
+      message => io_lib:format("~p ~p already exists", [serialize_type(Type), ID])};
+serialize_error_({not_found, {Type, ID}}) ->
+    #{code => "NOT_FOUND",
+      message => io_lib:format("~p ~p not found", [serialize_type(Type), ID])};
+serialize_error_({duplicate, Name}) ->
+    #{code => "INVALID_PARAMETER",
+      message => io_lib:format("Service name ~p is duplicated", [Name])};
+serialize_error_({missing_parameter, Names = [_ | Rest]}) ->
+    Format = ["~p," || _ <- Rest] ++ ["~p"],
+    NFormat = binary_to_list(iolist_to_binary(Format)),
+    #{code => "MISSING_PARAMETER",
+      message => io_lib:format("The input parameters " ++ NFormat ++ " that are mandatory for processing this request are not supplied.", Names)};
+serialize_error_({missing_parameter, Name}) ->
+    #{code => "MISSING_PARAMETER",
+      message => io_lib:format("The input parameter ~p that is mandatory for processing this request is not supplied.", [Name])};
+serialize_error_(_) ->
+    #{code => "UNKNOWN_ERROR"}.
+
+serialize_type(service) ->
+    "Service";
+serialize_type(chain) ->
+    "Chain";
+serialize_type(service_type) ->
+    "Service type".
+
+get_missed_params(Actual, Expected) ->
+    Keys = lists:fold(fun(Key, Acc) ->
+                          case maps:is_key(Key, Actual) of
+                              true -> Acc;
+                              false -> [Key | Acc]
+                          end
+                      end, [], Expected),
+    lists:reverse(Keys).

+ 1 - 1
apps/emqx_authentication/src/emqx_authentication_app.erl

@@ -1,5 +1,5 @@
 %%--------------------------------------------------------------------
-%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
+%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
 %%
 %% Licensed under the Apache License, Version 2.0 (the "License");
 %% you may not use this file except in compliance with the License.

+ 5 - 1
apps/emqx_authentication/src/emqx_authentication_mnesia.erl

@@ -1,5 +1,5 @@
 %%--------------------------------------------------------------------
-%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
+%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
 %%
 %% Licensed under the Apache License, Version 2.0 (the "License");
 %% you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
 -include("emqx_authentication.hrl").
 
 -export([ create/3
+        , update/4
         , authenticate/2
         , destroy/1
         ]).
@@ -88,6 +89,9 @@ create(ChainID, ServiceName, #{<<"user_identity_type">> := Type,
               password_hash_algorithm => binary_to_atom(Algorithm, utf8)},
     {ok, State}.
 
+update(ChainID, ServiceName, Params, _State) ->
+    create(ChainID, ServiceName, Params).
+
 authenticate(ClientInfo = #{password := Password},
              #{user_group := UserGroup,
                user_identity_type := Type,

+ 1 - 1
apps/emqx_authentication/src/emqx_authentication_sup.erl

@@ -1,5 +1,5 @@
 %%--------------------------------------------------------------------
-%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
+%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
 %%
 %% Licensed under the Apache License, Version 2.0 (the "License");
 %% you may not use this file except in compliance with the License.

+ 16 - 16
apps/emqx_authentication/test/emqx_authentication_SUITE.erl

@@ -38,7 +38,7 @@ end_per_suite(_) ->
 t_chain(_) ->
     ChainID = <<"mychain">>,
     ChainParams = #{chain_id => ChainID,
-                    service_params => []},
+                    services => []},
     ?assertEqual({ok, ChainID}, ?AUTH:create_chain(ChainParams)),
     ?assertEqual({error, {already_exists, {chain, ChainID}}}, ?AUTH:create_chain(ChainParams)),
     ?assertMatch({ok, #{id := ChainID, services := []}}, ?AUTH:lookup_chain(ChainID)),
@@ -55,30 +55,30 @@ t_service(_) ->
                            user_identity_type => <<"username">>,
                            password_hash_algorithm => <<"sha256">>}},
     ChainParams = #{chain_id => ChainID,
-                    service_params => [ServiceParams1]},
+                    services => [ServiceParams1]},
     ?assertEqual({ok, ChainID}, ?AUTH:create_chain(ChainParams)),
     Service1 = ServiceParams1,
     ?assertMatch({ok, #{id := ChainID, services := [Service1]}}, ?AUTH:lookup_chain(ChainID)),
     ?assertEqual({ok, Service1}, ?AUTH:lookup_service(ChainID, ServiceName1)),
     ?assertEqual({ok, [Service1]}, ?AUTH:list_services(ChainID)),
-    ?assertEqual({error, {already_exists, {service, ServiceName1}}}, ?AUTH:add_services_to_chain(ChainID, [ServiceParams1])),
+    ?assertEqual({error, {already_exists, {service, ServiceName1}}}, ?AUTH:add_services(ChainID, [ServiceParams1])),
     ServiceName2 = <<"myservice2">>,
     ServiceParams2 = ServiceParams1#{name => ServiceName2},
-    ?assertEqual(ok, ?AUTH:add_services_to_chain(ChainID, [ServiceParams2])),
+    ?assertEqual(ok, ?AUTH:add_services(ChainID, [ServiceParams2])),
     Service2 = ServiceParams2,
     ?assertMatch({ok, #{id := ChainID, services := [Service1, Service2]}}, ?AUTH:lookup_chain(ChainID)),
     ?assertEqual({ok, Service2}, ?AUTH:lookup_service(ChainID, ServiceName2)),
     ?assertEqual({ok, [Service1, Service2]}, ?AUTH:list_services(ChainID)),
 
-    ?assertEqual(ok, ?AUTH:move_service_to_the_front_of_chain(ChainID, ServiceName2)),
+    ?assertEqual(ok, ?AUTH:move_service_to_the_front(ChainID, ServiceName2)),
     ?assertEqual({ok, [Service2, Service1]}, ?AUTH:list_services(ChainID)),
-    ?assertEqual(ok, ?AUTH:move_service_to_the_end_of_chain(ChainID, ServiceName2)),
+    ?assertEqual(ok, ?AUTH:move_service_to_the_end(ChainID, ServiceName2)),
     ?assertEqual({ok, [Service1, Service2]}, ?AUTH:list_services(ChainID)),
-    ?assertEqual(ok, ?AUTH:move_service_to_the_nth_of_chain(ChainID, ServiceName2, 1)),
+    ?assertEqual(ok, ?AUTH:move_service_to_the_nth(ChainID, ServiceName2, 1)),
     ?assertEqual({ok, [Service2, Service1]}, ?AUTH:list_services(ChainID)),
-    ?assertEqual({error, out_of_range}, ?AUTH:move_service_to_the_nth_of_chain(ChainID, ServiceName2, 3)),
-    ?assertEqual({error, out_of_range}, ?AUTH:move_service_to_the_nth_of_chain(ChainID, ServiceName2, 0)),
-    ?assertEqual(ok, ?AUTH:delete_services_from_chain(ChainID, [ServiceName1, ServiceName2])),
+    ?assertEqual({error, out_of_range}, ?AUTH:move_service_to_the_nth(ChainID, ServiceName2, 3)),
+    ?assertEqual({error, out_of_range}, ?AUTH:move_service_to_the_nth(ChainID, ServiceName2, 0)),
+    ?assertEqual(ok, ?AUTH:delete_services(ChainID, [ServiceName1, ServiceName2])),
     ?assertEqual({ok, []}, ?AUTH:list_services(ChainID)),
     ?assertEqual(ok, ?AUTH:delete_chain(ChainID)),
     ok.
@@ -92,7 +92,7 @@ t_mnesia_service(_) ->
                           user_identity_type => <<"username">>,
                           password_hash_algorithm => <<"sha256">>}},
     ChainParams = #{chain_id => ChainID,
-                    service_params => [ServiceParams]},
+                    services => [ServiceParams]},
     ?assertEqual({ok, ChainID}, ?AUTH:create_chain(ChainParams)),
     UserCredential = #{user_identity => <<"myuser">>,
                        password => <<"mypass">>},
@@ -116,8 +116,8 @@ t_mnesia_service(_) ->
 
     ?assertEqual(ok, ?AUTH:add_user_credential(ChainID, ServiceName, UserCredential)),
     ?assertMatch({ok, #{user_identity := <<"myuser">>}}, ?AUTH:lookup_user_credential(ChainID, ServiceName, <<"myuser">>)),
-    ?assertEqual(ok, ?AUTH:delete_services_from_chain(ChainID, [ServiceName])),
-    ?assertEqual(ok, ?AUTH:add_services_to_chain(ChainID, [ServiceParams])),
+    ?assertEqual(ok, ?AUTH:delete_services(ChainID, [ServiceName])),
+    ?assertEqual(ok, ?AUTH:add_services(ChainID, [ServiceParams])),
     ?assertMatch({error, not_found}, ?AUTH:lookup_user_credential(ChainID, ServiceName, <<"myuser">>)),
 
     ?assertEqual(ok, ?AUTH:delete_chain(ChainID)),
@@ -133,7 +133,7 @@ t_import(_) ->
                           user_identity_type => <<"username">>,
                           password_hash_algorithm => <<"sha256">>}},
     ChainParams = #{chain_id => ChainID,
-                    service_params => [ServiceParams]},
+                    services => [ServiceParams]},
     ?assertEqual({ok, ChainID}, ?AUTH:create_chain(ChainParams)),
     Dir = code:lib_dir(emqx_authentication, test),
     ?assertEqual(ok, ?AUTH:import_user_credentials(ChainID, ServiceName, filename:join([Dir, "data/user-credentials.json"]), json)),
@@ -165,7 +165,7 @@ t_multi_mnesia_service(_) ->
                            user_identity_type => <<"clientid">>,
                            password_hash_algorithm => <<"sha256">>}},
     ChainParams = #{chain_id => ChainID,
-                    service_params => [ServiceParams1, ServiceParams2]},
+                    services => [ServiceParams1, ServiceParams2]},
     ?assertEqual({ok, ChainID}, ?AUTH:create_chain(ChainParams)),
 
     ?assertEqual(ok, ?AUTH:add_user_credential(ChainID,
@@ -181,7 +181,7 @@ t_multi_mnesia_service(_) ->
                     clientid => <<"myclient">>,
 			        password => <<"mypass1">>},
     ?assertEqual(ok, ?AUTH:authenticate(ClientInfo1)),
-    ?assertEqual(ok, ?AUTH:move_service_to_the_front_of_chain(ChainID, ServiceName2)),
+    ?assertEqual(ok, ?AUTH:move_service_to_the_front(ChainID, ServiceName2)),
     ?assertEqual({error, bad_password}, ?AUTH:authenticate(ClientInfo1)),
     ClientInfo2 = ClientInfo1#{password => <<"mypass2">>},
     ?assertEqual(ok, ?AUTH:authenticate(ClientInfo2)),