fix(sso): fix sso errors found when manual test

This commit is contained in:
firest 2023-09-19 19:15:52 +08:00
parent 2cddce5479
commit 285e529766
13 changed files with 180 additions and 140 deletions

View File

@ -103,11 +103,9 @@ add_default_user() ->
%% API
%%--------------------------------------------------------------------
-spec add_user(dashboard_username(), binary(), dashboard_user_role(), binary()) ->
{ok, map()} | {error, any()}.
add_user(Username, Password, Role, Desc) when is_binary(Password) ->
add_user(Username, Password, Role, Desc) when is_binary(Username), is_binary(Password) ->
case {legal_username(Username), legal_password(Password), legal_role(Role)} of
{ok, ok, ok} -> do_add_user(Username, Password, Role, Desc);
{{error, Reason}, _, _} -> {error, Reason};
@ -120,8 +118,6 @@ do_add_user(Username, Password, Role, Desc) ->
return(Res).
%% 0-9 or A-Z or a-z or $_
legal_username(?SSO_USERNAME(_, _)) ->
ok;
legal_username(<<>>) ->
{error, <<"Username cannot be empty">>};
legal_username(UserName) ->
@ -211,7 +207,7 @@ add_user_(Username, Password, Role, Desc) ->
description = Desc
},
mnesia:write(Admin),
#{username => Username, role => Role, description => Desc};
flatten_username(#{username => Username, role => Role, description => Desc});
[_] ->
mnesia:abort(<<"username_already_exist">>)
end.
@ -232,7 +228,8 @@ remove_user(Username) when is_binary(Username) ->
{error, Reason}
end.
-spec update_user(binary(), dashboard_user_role(), binary()) -> {ok, map()} | {error, term()}.
-spec update_user(dashboard_username(), dashboard_user_role(), binary()) ->
{ok, map()} | {error, term()}.
update_user(Username, Role, Desc) when is_binary(Username) ->
case legal_role(Role) of
ok ->
@ -279,7 +276,10 @@ update_user_(Username, Role, Desc) ->
mnesia:abort(<<"username_not_found">>);
[Admin] ->
mnesia:write(Admin#?ADMIN{role = Role, description = Desc}),
{role(Admin) =:= Role, #{username => Username, role => Role, description => Desc}}
{
role(Admin) =:= Role,
flatten_username(#{username => Username, role => Role, description => Desc})
}
end.
change_password(Username, OldPasswd, NewPasswd) when is_binary(Username) ->
@ -335,11 +335,11 @@ all_users() ->
role = Role
}
) ->
#{
flatten_username(#{
username => Username,
description => Desc,
role => ensure_role(Role)
}
})
end,
ets:tab2list(?ADMIN)
).
@ -417,10 +417,24 @@ legal_role(Role) ->
role(Data) ->
emqx_dashboard_rbac:role(Data).
-spec add_sso_user(atom(), binary(), dashboard_user_role(), binary()) ->
flatten_username(#{username := ?SSO_USERNAME(Backend, Name)} = Data) ->
Data#{
username := Name,
backend => Backend
};
flatten_username(#{username := Username} = Data) when is_binary(Username) ->
Data#{backend => local}.
-spec add_sso_user(dashboard_sso_backend(), binary(), dashboard_user_role(), binary()) ->
{ok, map()} | {error, any()}.
add_sso_user(Backend, Username, Role, Desc) ->
add_user(?SSO_USERNAME(Backend, Username), <<>>, Role, Desc).
add_sso_user(Backend, Username0, Role, Desc) when is_binary(Username0) ->
case legal_role(Role) of
ok ->
Username = ?SSO_USERNAME(Backend, Username0),
do_add_user(Username, <<>>, Role, Desc);
{error, _} = Error ->
Error
end.
-spec lookup_user(dashboard_sso_backend(), binary()) -> [emqx_admin()].
lookup_user(Backend, Username) when is_atom(Backend) ->
@ -434,6 +448,9 @@ legal_role(_) ->
role(_) ->
?ROLE_DEFAULT.
flatten_username(Data) ->
Data.
-endif.
-ifdef(TEST).

View File

@ -89,6 +89,7 @@ schema("/logout") ->
post => #{
tags => [<<"dashboard">>],
desc => ?DESC(logout_api),
parameters => sso_parameters(),
'requestBody' => fields([username]),
responses => #{
204 => <<"Dashboard logout successfully">>,
@ -114,7 +115,7 @@ schema("/users") ->
desc => ?DESC(create_user_api),
'requestBody' => fields([username, password, role, description]),
responses => #{
200 => fields([username, role, description])
200 => fields([username, role, description, backend])
}
}
};
@ -124,17 +125,17 @@ schema("/users/:username") ->
put => #{
tags => [<<"dashboard">>],
desc => ?DESC(update_user_api),
parameters => fields([username_in_path]),
parameters => sso_parameters(fields([username_in_path])),
'requestBody' => fields([role, description]),
responses => #{
200 => fields([username, role, description]),
200 => fields([username, role, description, backend]),
404 => response_schema(404)
}
},
delete => #{
tags => [<<"dashboard">>],
desc => ?DESC(delete_user_api),
parameters => fields([username_in_path]),
parameters => sso_parameters(fields([username_in_path])),
responses => #{
204 => <<"Delete User successfully">>,
400 => emqx_dashboard_swagger:error_codes(
@ -169,7 +170,7 @@ response_schema(404) ->
emqx_dashboard_swagger:error_codes([?USER_NOT_FOUND], ?DESC(users_api404)).
fields(user) ->
fields([username, description]);
fields([username, role, description, backend]);
fields(List) ->
[field(Key) || Key <- List, field_filter(Key)].
@ -206,7 +207,10 @@ field(old_pwd) ->
field(new_pwd) ->
{new_pwd, mk(binary(), #{desc => ?DESC(new_pwd)})};
field(role) ->
{role, mk(binary(), #{desc => ?DESC(role), example => ?ROLE_DEFAULT})}.
{role,
mk(binary(), #{desc => ?DESC(role), default => ?ROLE_DEFAULT, example => ?ROLE_DEFAULT})};
field(backend) ->
{backend, mk(binary(), #{desc => ?DESC(backend), example => <<"local">>})}.
%% -------------------------------------------------------------------------------------------------
%% API
@ -229,15 +233,16 @@ login(post, #{body := Params}) ->
end.
logout(_, #{
body := #{<<"username">> := Username},
body := #{<<"username">> := Username0} = Req,
headers := #{<<"authorization">> := <<"Bearer ", Token/binary>>}
}) ->
Username = username(Req, Username0),
case emqx_dashboard_admin:destroy_token_by_username(Username, Token) of
ok ->
?SLOG(info, #{msg => "Dashboard logout successfully", username => Username}),
?SLOG(info, #{msg => "Dashboard logout successfully", username => Username0}),
204;
_R ->
?SLOG(info, #{msg => "Dashboard logout failed.", username => Username}),
?SLOG(info, #{msg => "Dashboard logout failed.", username => Username0}),
{401, ?WRONG_TOKEN_OR_USERNAME, <<"Ensure your token & username">>}
end.
@ -266,9 +271,10 @@ users(post, #{body := Params}) ->
end
end.
user(put, #{bindings := #{username := Username}, body := Params}) ->
user(put, #{bindings := #{username := Username0}, body := Params} = Req) ->
Role = maps:get(<<"role">>, Params, ?ROLE_DEFAULT),
Desc = maps:get(<<"description">>, Params),
Username = username(Req, Username0),
case emqx_dashboard_admin:update_user(Username, Role, Desc) of
{ok, Result} ->
{200, filter_result(Result)};
@ -277,14 +283,15 @@ user(put, #{bindings := #{username := Username}, body := Params}) ->
{error, Reason} ->
{400, ?BAD_REQUEST, Reason}
end;
user(delete, #{bindings := #{username := Username}, headers := Headers}) ->
case Username == emqx_dashboard_admin:default_username() of
user(delete, #{bindings := #{username := Username0}, headers := Headers} = Req) ->
case Username0 == emqx_dashboard_admin:default_username() of
true ->
?SLOG(info, #{msg => "Dashboard delete admin user failed", username => Username}),
Message = list_to_binary(io_lib:format("Cannot delete user ~p", [Username])),
?SLOG(info, #{msg => "Dashboard delete admin user failed", username => Username0}),
Message = list_to_binary(io_lib:format("Cannot delete user ~p", [Username0])),
{400, ?NOT_ALLOWED, Message};
false ->
case is_self_auth(Username, Headers) of
Username = username(Req, Username0),
case is_self_auth(Username0, Headers) of
true ->
{400, ?NOT_ALLOWED, <<"Cannot delete self">>};
false ->
@ -293,13 +300,15 @@ user(delete, #{bindings := #{username := Username}, headers := Headers}) ->
{404, ?USER_NOT_FOUND, Reason};
{ok, _} ->
?SLOG(info, #{
msg => "Dashboard delete admin user", username => Username
msg => "Dashboard delete admin user", username => Username0
}),
{204}
end
end
end.
is_self_auth(?SSO_USERNAME(_, _), _) ->
fasle;
is_self_auth(Username, #{<<"authorization">> := Token}) ->
is_self_auth(Username, Token);
is_self_auth(Username, #{<<"Authorization">> := Token}) ->
@ -362,6 +371,19 @@ field_filter(_) ->
filter_result(Result) ->
Result.
sso_parameters() ->
sso_parameters([]).
sso_parameters(Params) ->
emqx_dashboard_sso_api:sso_parameters(Params).
username(#{bindings := #{backend := local}}, Username) ->
Username;
username(#{bindings := #{backend := Backend}}, Username) ->
?SSO_USERNAME(Backend, Username);
username(_Req, Username) ->
Username.
-else.
field_filter(role) ->
@ -372,6 +394,14 @@ field_filter(_) ->
filter_result(Result) when is_list(Result) ->
lists:map(fun filter_result/1, Result);
filter_result(Result) ->
maps:without([role], Result).
maps:without([role, backend], Result).
sso_parameters() ->
sso_parameters([]).
sso_parameters(Any) ->
Any.
username(_Req, Username) ->
Username.
-endif.

View File

@ -179,6 +179,9 @@ owner(Token) ->
{atomic, []} -> {error, not_found}
end.
jwk(?SSO_USERNAME(Backend, Name), Password, Salt) ->
BackendBin = erlang:atom_to_binary(Backend),
jwk(<<BackendBin/binary, "-", Name/binary>>, Password, Salt);
jwk(Username, Password, Salt) ->
Key = crypto:hash(md5, <<Salt/binary, Username/binary, Password/binary>>),
#{
@ -192,12 +195,17 @@ jwt_expiration_time() ->
token_ttl() ->
emqx_conf:get([dashboard, token_expired_time], ?EXPTIME).
format(Token, ?SSO_USERNAME(Backend, Name), Role, ExpTime) ->
format(Token, Backend, Name, Role, ExpTime);
format(Token, Username, Role, ExpTime) ->
format(Token, local, Username, Role, ExpTime).
format(Token, Backend, Username, Role, ExpTime) ->
#?ADMIN_JWT{
token = Token,
username = Username,
exptime = ExpTime,
extra = #{role => Role}
extra = #{role => Role, backend => Backend}
}.
%%--------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
# Dashboard Single sign-on
# Dashboard Single sign-On
Single Sign-On is a mechanism that allows a user to automatically sign in to multiple applications after signing in to one. This improves convenience and security.
@ -8,4 +8,4 @@ Please see our [contributing.md](../../CONTRIBUTING.md).
## License
See [APL](../../APL.txt).
See EMQ Business Source License 1.1, refer to [LICENSE](BSL.txt).

View File

@ -26,7 +26,7 @@
-callback update(Config :: config(), State :: state()) ->
{ok, NewState :: state()} | {error, Reason :: term()}.
-callback destroy(State :: state()) -> ok.
-callback sign(request(), State :: state()) ->
-callback login(request(), State :: state()) ->
{ok, Token :: binary()} | {error, Reason :: term()}.
%%------------------------------------------------------------------------------

View File

@ -27,12 +27,13 @@
]).
-export([
running/2,
login/2,
sso/2,
backend/2
]).
-export([sso_parameters/1]).
-define(BAD_USERNAME_OR_PWD, 'BAD_USERNAME_OR_PWD').
-define(BAD_REQUEST, 'BAD_REQUEST').
@ -47,8 +48,7 @@ api_spec() ->
paths() ->
[
"/sso",
"/sso/login",
"/sso/running",
"/sso/login/:backend",
"/sso/:backend"
].
@ -59,16 +59,17 @@ schema("/sso") ->
tags => [?TAGS],
desc => ?DESC(get_sso),
responses => #{
200 => array(ref(backend_status))
200 => array(enum(emqx_dashboard_sso:types()))
}
}
};
schema("/sso/login") ->
schema("/sso/login/:backend") ->
#{
'operationId' => login,
post => #{
tags => [?TAGS],
desc => ?DESC(login),
parameters => backend_name_in_path(),
'requestBody' => login_union(),
responses => #{
200 => emqx_dashboard_api:fields([token, version, license]),
@ -77,17 +78,6 @@ schema("/sso/login") ->
}
}
};
schema("/sso/running") ->
#{
'operationId' => running,
get => #{
tags => [?TAGS],
desc => ?DESC(get_running),
responses => #{
200 => array(enum(emqx_dashboard_sso:types()))
}
}
};
schema("/sso/:backend") ->
#{
'operationId' => backend,
@ -100,15 +90,6 @@ schema("/sso/:backend") ->
404 => response_schema(404)
}
},
post => #{
tags => [?TAGS],
desc => ?DESC(create_backend),
parameters => backend_name_in_path(),
'requestBody' => backend_union(),
responses => #{
200 => backend_union()
}
},
put => #{
tags => [?TAGS],
desc => ?DESC(update_backend),
@ -131,22 +112,19 @@ schema("/sso/:backend") ->
}.
fields(backend_status) ->
emqx_dashboard_sso_schema:common_backend_schema(enum(emqx_dashboard_sso:types())).
emqx_dashboard_sso_schema:common_backend_schema(emqx_dashboard_sso:types()).
%% -------------------------------------------------------------------------------------------------
%% API
running(get, _Request) ->
{200, emqx_dashboard_sso_manager:running()}.
login(post, #{backend := Backend} = Request) ->
login(post, #{bindings := #{backend := Backend}, body := Sign}) ->
case emqx_dashboard_sso_manager:lookup_state(Backend) of
undefined ->
{404, ?BACKEND_NOT_FOUND};
{404, ?BACKEND_NOT_FOUND, <<"Backend not found">>};
State ->
Provider = emqx_dashboard_sso:provider(Backend),
case Provider:login(Request, State) of
case Provider:login(Sign, State) of
{ok, Token} ->
?SLOG(info, #{msg => "Dashboard SSO login successfully", request => Request}),
?SLOG(info, #{msg => "Dashboard SSO login successfully", request => Sign}),
Version = iolist_to_binary(proplists:get_value(version, emqx_sys:info())),
{200, #{
token => Token,
@ -155,7 +133,9 @@ login(post, #{backend := Backend} = Request) ->
}};
{error, Reason} ->
?SLOG(info, #{
msg => "Dashboard SSO login failed", request => Request, reason => Reason
msg => "Dashboard SSO login failed",
request => Sign,
reason => Reason
}),
{401, ?BAD_USERNAME_OR_PWD, <<"Auth failed">>}
end
@ -166,7 +146,7 @@ sso(get, _Request) ->
{200,
lists:map(
fun(Backend) ->
maps:with([backend, enabled], Backend)
maps:with([backend, enable], Backend)
end,
maps:values(SSO)
)}.
@ -176,14 +156,15 @@ backend(get, #{bindings := #{backend := Type}}) ->
undefined ->
{404, ?BACKEND_NOT_FOUND};
Backend ->
{200, Backend}
{200, to_json(Backend)}
end;
backend(create, #{bindings := #{backend := Backend}, body := Config}) ->
on_backend_update(Backend, Config, fun emqx_dashboard_sso_manager:create/2);
backend(put, #{bindings := #{backend := Backend}, body := Config}) ->
on_backend_update(Backend, Config, fun emqx_dashboard_sso_manager:update/2);
backend(delete, #{bindings := #{backend := Backend}, body := Config}) ->
on_backend_update(Backend, Config, fun emqx_dashboard_sso_manager:delete/2).
backend(delete, #{bindings := #{backend := Backend}}) ->
handle_backend_update_result(emqx_dashboard_sso_manager:delete(Backend), undefined).
sso_parameters(Params) ->
backend_name_as_arg(query, [local], <<"local">>) ++ Params.
%% -------------------------------------------------------------------------------------------------
%% internal
@ -199,14 +180,18 @@ login_union() ->
hoconsc:union([Mod:login_ref() || Mod <- emqx_dashboard_sso:modules()]).
backend_name_in_path() ->
backend_name_as_arg(path, [], <<"ldap">>).
backend_name_as_arg(In, Extra, Default) ->
[
{name,
{backend,
mk(
binary(),
enum(Extra ++ emqx_dashboard_sso:types()),
#{
in => path,
in => In,
desc => ?DESC(backend_name_in_qs),
example => <<"ldap">>
required => true,
example => Default
}
)}
].
@ -216,7 +201,7 @@ on_backend_update(Backend, Config, Fun) ->
handle_backend_update_result(Result, Config).
valid_config(Backend, Config, Fun) ->
case maps:get(backend, Config, undefined) of
case maps:get(<<"backend">>, Config, undefined) of
Backend ->
Fun(Backend, Config);
_ ->
@ -224,12 +209,20 @@ valid_config(Backend, Config, Fun) ->
end.
handle_backend_update_result({ok, _}, Config) ->
{200, Config};
{200, to_json(Config)};
handle_backend_update_result(ok, _) ->
204;
handle_backend_update_result({error, not_exists}, _) ->
{404, ?BACKEND_NOT_FOUND};
{404, ?BACKEND_NOT_FOUND, <<"Backend not found">>};
handle_backend_update_result({error, already_exists}, _) ->
{400, ?BAD_REQUEST, <<"Backend already exists.">>};
{400, ?BAD_REQUEST, <<"Backend already exists">>};
handle_backend_update_result({error, Reason}, _) ->
{400, ?BAD_REQUEST, Reason}.
to_json(Data) ->
emqx_utils_maps:jsonable_map(
Data,
fun(K, V) ->
{K, emqx_utils_maps:binary_string(V)}
end
).

View File

@ -18,7 +18,7 @@
-export([
hocon_ref/0,
login_ref/0,
sign/2,
login/2,
create/1,
update/2,
destroy/1
@ -35,14 +35,14 @@ login_ref() ->
hoconsc:ref(?MODULE, login).
fields(ldap) ->
emqx_dashboard_sso_schema:common_backend_schema(ldap) ++
emqx_dashboard_sso_schema:common_backend_schema([ldap]) ++
[
{query_timeout, fun query_timeout/1}
] ++
emqx_ldap:fields(config) ++ emqx_ldap:fields(bind_opts);
fields(login) ->
[
emqx_dashboard_sso_schema:backend_schema(ldap)
emqx_dashboard_sso_schema:backend_schema([ldap])
| emqx_dashboard_sso_schema:username_password_schema()
].
@ -61,7 +61,7 @@ create(Config0) ->
case emqx_dashboard_sso_manager:create_resource(ResourceId, emqx_ldap, Config) of
{ok, _} ->
{ok, State#{resource_id => ResourceId}};
Error ->
{error, _} = Error ->
Error
end.
@ -70,7 +70,7 @@ update(Config0, #{resource_id := ResourceId} = _State) ->
case emqx_dashboard_sso_manager:update_resource(ResourceId, emqx_ldap, Config) of
{ok, _} ->
{ok, NState#{resource_id => ResourceId}};
Error ->
{error, _} = Error ->
Error
end.
@ -78,8 +78,8 @@ destroy(#{resource_id := ResourceId}) ->
_ = emqx_resource:remove_local(ResourceId),
ok.
sign(
#{username := Username} = Req,
login(
#{<<"username">> := Username} = Req,
#{
query_timeout := Timeout,
resource_id := ResourceId
@ -101,8 +101,7 @@ sign(
)
of
ok ->
User = ensure_user_exists(Username),
{ok, emqx_dashboard_token:sign(User, <<>>)};
ensure_user_exists(Username);
{error, _} = Error ->
Error
end;
@ -128,7 +127,12 @@ parse_config(Config) ->
ensure_user_exists(Username) ->
case emqx_dashboard_admin:lookup_user(ldap, Username) of
[User] ->
User;
{ok, emqx_dashboard_token:sign(User, <<>>)};
[] ->
emqx_dashboard_admin:add_sso_user(ldap, Username, ?ROLE_VIEWER, <<>>)
case emqx_dashboard_admin:add_sso_user(ldap, Username, ?ROLE_VIEWER, <<>>) of
{ok, _} ->
ensure_user_exists(Username);
Error ->
Error
end
end.

View File

@ -30,7 +30,6 @@
]).
-export([
create/2,
update/2,
delete/1,
pre_config_update/3,
@ -68,8 +67,6 @@ running() ->
emqx:get_config([emqx_dashboard_sso])
).
create(Backend, Config) ->
update_config(Backend, {?FUNCTION_NAME, Backend, Config}).
update(Backend, Config) ->
update_config(Backend, {?FUNCTION_NAME, Backend, Config}).
delete(Backend) ->
@ -85,7 +82,7 @@ lookup_state(Backend) ->
make_resource_id(Backend) ->
BackendBin = bin(Backend),
emqx_resource:generate_id(BackendBin).
emqx_resource:generate_id(<<"sso:", BackendBin/binary>>).
create_resource(ResourceId, Module, Config) ->
Result = emqx_resource:create_local(
@ -95,7 +92,7 @@ create_resource(ResourceId, Module, Config) ->
Config,
?DEFAULT_RESOURCE_OPTS
),
start_resource_if_enabled(Result, ResourceId, Config).
start_resource_if_enabled(ResourceId, Result, Config).
update_resource(ResourceId, Module, Config) ->
Result = emqx_resource:recreate_local(
@ -127,6 +124,9 @@ init([]) ->
handle_call({update_config, Req, NewConf, OldConf}, _From, State) ->
Result = on_config_update(Req, NewConf, OldConf),
io:format(">>> on_config_update:~p~n,Req:~p~n NewConf:~p~n OldConf:~p~n", [
Result, Req, NewConf, OldConf
]),
{reply, Result, State};
handle_call(_Request, _From, State) ->
Reply = ok,
@ -166,60 +166,43 @@ start_backend_services() ->
maps:to_list(Backends)
).
update_config(Backend, UpdateReq) ->
case emqx_conf:update([dashboard_sso, Backend], UpdateReq, #{override_to => cluster}) of
update_config(_Backend, UpdateReq) ->
case emqx_conf:update([dashboard_sso], UpdateReq, #{override_to => cluster}) of
{ok, UpdateResult} ->
#{post_config_update := #{?MODULE := Result}} = UpdateResult,
{ok, Result};
Result;
Error ->
Error
end.
pre_config_update(_Path, {create, Backend, Config}, OldConf) ->
case maps:find(Backend, OldConf) of
{ok, _} ->
throw(already_exists);
error ->
{ok, OldConf#{Backend => Config}}
end;
pre_config_update(_Path, {update, Backend, Config}, OldConf) ->
case maps:find(Backend, OldConf) of
error ->
throw(not_exists);
{ok, _} ->
{ok, OldConf#{Backend => Config}}
end;
BackendBin = bin(Backend),
{ok, OldConf#{BackendBin => Config}};
pre_config_update(_Path, {delete, Backend}, OldConf) ->
case maps:find(Backend, OldConf) of
BackendBin = bin(Backend),
case maps:find(BackendBin, OldConf) of
error ->
throw(not_exists);
{ok, _} ->
{ok, maps:remove(Backend, OldConf)}
{ok, maps:remove(BackendBin, OldConf)}
end.
post_config_update(_Path, UpdateReq, NewConf, OldConf, _AppEnvs) ->
Result = call({update_config, UpdateReq, NewConf, OldConf}),
{ok, Result}.
on_config_update({create, Backend, Config}, _NewConf, _OldConf) ->
on_config_update({update, Backend, _Config}, NewConf, _OldConf) ->
Provider = provider(Backend),
Config = maps:get(Backend, NewConf),
case lookup(Backend) of
undefined ->
Provider = provider(Backend),
on_backend_updated(
Provider:create(Config),
fun(State) ->
ets:insert(dashboard_sso, #dashboard_sso{backend = Backend, state = State})
end
);
_Data ->
{error, already_exists}
end;
on_config_update({update, Backend, Config}, _NewConf, _OldConf) ->
case lookup(Backend) of
undefined ->
{error, not_exists};
Data ->
Provider = provider(Backend),
on_backend_updated(
Provider:update(Config, Data#dashboard_sso.state),
fun(State) ->

View File

@ -14,7 +14,7 @@
backend_schema/1,
username_password_schema/0
]).
-import(hoconsc, [ref/2, mk/2]).
-import(hoconsc, [ref/2, mk/2, enum/1]).
%%------------------------------------------------------------------------------
%% Hocon Schema
@ -39,6 +39,7 @@ desc(dashboard_sso) ->
desc(_) ->
undefined.
-spec common_backend_schema(list(atom())) -> proplists:proplist().
common_backend_schema(Backend) ->
[
{enable,
@ -54,7 +55,7 @@ common_backend_schema(Backend) ->
backend_schema(Backend) ->
{backend,
mk(Backend, #{
mk(enum(Backend), #{
required => true,
desc => ?DESC(backend)
})}.

View File

@ -1,6 +1,6 @@
{application, emqx_enterprise, [
{description, "EMQX Enterprise Edition"},
{vsn, "0.1.2"},
{vsn, "0.1.3"},
{registered, []},
{applications, [
kernel,

View File

@ -75,8 +75,16 @@ fields(config) ->
?HOCON(emqx_schema:timeout_duration_ms(), #{
desc => ?DESC(request_timeout),
default => <<"5s">>
})},
{ssl,
?HOCON(?R_REF(?MODULE, ssl), #{
default => #{<<"enable">> => false},
desc => ?DESC(emqx_connector_schema_lib, "ssl")
})}
] ++ emqx_connector_schema_lib:ssl_fields();
];
fields(ssl) ->
Schema = emqx_schema:client_ssl_opts_schema(#{}),
lists:keydelete("user_lookup_fun", 1, Schema);
fields(bind_opts) ->
[
{bind_password,

View File

@ -79,4 +79,10 @@ users_api404.desc:
version.desc:
"""EMQX Version"""
role.desc:
"""User role"""
backend.desc:
"""User account source"""
}

View File

@ -10,21 +10,11 @@ login.desc:
login.label:
"""Get Dashboard Auth Token."""
get_running.desc:
"""Get Running SSO backends"""
get_running.label:
"""Running SSO"""
get_backend.desc:
"""Get details of a backend"""
get_backend.label:
"""Backend Details"""
create_backend.desc:
"""Create a backend"""
create_backend.label:
"""Create Backend"""
update_backend.desc:
"""Update a backend"""
update_backend.label: