fix(sso): add convet_certs callback for sso backends
must convert certs in pre_config_update so the cert path refernces are stored in raw config, otherwise the files might get gc:ed
This commit is contained in:
parent
45caa3bf01
commit
bb49914fd6
|
@ -13,7 +13,8 @@
|
||||||
create/2,
|
create/2,
|
||||||
update/3,
|
update/3,
|
||||||
destroy/2,
|
destroy/2,
|
||||||
login/3
|
login/3,
|
||||||
|
convert_certs/3
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([types/0, modules/0, provider/1, backends/0, format/1]).
|
-export([types/0, modules/0, provider/1, backends/0, format/1]).
|
||||||
|
@ -45,6 +46,11 @@
|
||||||
| {redirect, tuple()}
|
| {redirect, tuple()}
|
||||||
| {error, Reason :: term()}.
|
| {error, Reason :: term()}.
|
||||||
|
|
||||||
|
-callback convert_certs(
|
||||||
|
Dir :: file:filename_all(),
|
||||||
|
config()
|
||||||
|
) -> config().
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Callback Interface
|
%% Callback Interface
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
@ -68,6 +74,9 @@ destroy(Mod, State) ->
|
||||||
login(Mod, Req, State) ->
|
login(Mod, Req, State) ->
|
||||||
Mod:login(Req, State).
|
Mod:login(Req, State).
|
||||||
|
|
||||||
|
convert_certs(Mod, Dir, Config) ->
|
||||||
|
Mod:convert_certs(Dir, Config).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% API
|
%% API
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
login/2,
|
login/2,
|
||||||
create/1,
|
create/1,
|
||||||
update/2,
|
update/2,
|
||||||
destroy/1
|
destroy/1,
|
||||||
|
convert_certs/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
@ -163,3 +164,21 @@ ensure_user_exists(Username) ->
|
||||||
Error
|
Error
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
convert_certs(Dir, Conf) ->
|
||||||
|
case
|
||||||
|
emqx_tls_lib:ensure_ssl_files(
|
||||||
|
Dir, maps:get(<<"ssl">>, Conf, undefined)
|
||||||
|
)
|
||||||
|
of
|
||||||
|
{ok, SSL} ->
|
||||||
|
new_ssl_source(Conf, SSL);
|
||||||
|
{error, Reason} ->
|
||||||
|
?SLOG(error, Reason#{msg => "bad_ssl_config"}),
|
||||||
|
throw({bad_ssl_config, Reason})
|
||||||
|
end.
|
||||||
|
|
||||||
|
new_ssl_source(Source, undefined) ->
|
||||||
|
Source;
|
||||||
|
new_ssl_source(Source, SSL) ->
|
||||||
|
Source#{<<"ssl">> => SSL}.
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
|
|
||||||
-record(?MOD_TAB, {
|
-record(?MOD_TAB, {
|
||||||
backend :: atom(),
|
backend :: atom(),
|
||||||
state :: map(),
|
state :: undefined | map(),
|
||||||
last_error = ?NO_ERROR :: term()
|
last_error = ?NO_ERROR :: term()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ update_config(Backend, UpdateReq) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
pre_config_update(_, {update, _Backend, Config}, _OldConf) ->
|
pre_config_update(_, {update, _Backend, Config}, _OldConf) ->
|
||||||
maybe_write_certs(Config);
|
{ok, maybe_write_certs(Config)};
|
||||||
pre_config_update(_, {delete, _Backend}, undefined) ->
|
pre_config_update(_, {delete, _Backend}, undefined) ->
|
||||||
throw(not_exists);
|
throw(not_exists);
|
||||||
pre_config_update(_, {delete, _Backend}, _OldConf) ->
|
pre_config_update(_, {delete, _Backend}, _OldConf) ->
|
||||||
|
@ -333,26 +333,13 @@ remove_handler() ->
|
||||||
ok = emqx_conf:remove_handler(?MOD_KEY_PATH('?')).
|
ok = emqx_conf:remove_handler(?MOD_KEY_PATH('?')).
|
||||||
|
|
||||||
maybe_write_certs(#{<<"backend">> := Backend} = Conf) ->
|
maybe_write_certs(#{<<"backend">> := Backend} = Conf) ->
|
||||||
case
|
Dir = certs_path(Backend),
|
||||||
emqx_tls_lib:ensure_ssl_files(
|
Provider = provider(Backend),
|
||||||
ssl_file_path(Backend), maps:get(<<"ssl">>, Conf, undefined)
|
emqx_dashboard_sso:convert_certs(Provider, Dir, Conf).
|
||||||
)
|
|
||||||
of
|
|
||||||
{ok, SSL} ->
|
|
||||||
{ok, new_ssl_source(Conf, SSL)};
|
|
||||||
{error, Reason} ->
|
|
||||||
?SLOG(error, Reason#{msg => "bad_ssl_config"}),
|
|
||||||
throw({bad_ssl_config, Reason})
|
|
||||||
end.
|
|
||||||
|
|
||||||
ssl_file_path(Backend) ->
|
certs_path(Backend) ->
|
||||||
filename:join(["sso", Backend]).
|
filename:join(["sso", Backend]).
|
||||||
|
|
||||||
new_ssl_source(Source, undefined) ->
|
|
||||||
Source;
|
|
||||||
new_ssl_source(Source, SSL) ->
|
|
||||||
Source#{<<"ssl">> => SSL}.
|
|
||||||
|
|
||||||
update_state(Backend, State) ->
|
update_state(Backend, State) ->
|
||||||
Data = ensure_backend_data(Backend),
|
Data = ensure_backend_data(Backend),
|
||||||
ets:insert(?MOD_TAB, Data#?MOD_TAB{state = State}).
|
ets:insert(?MOD_TAB, Data#?MOD_TAB{state = State}).
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
-export([
|
-export([
|
||||||
create/1,
|
create/1,
|
||||||
update/2,
|
update/2,
|
||||||
destroy/1
|
destroy/1,
|
||||||
|
convert_certs/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([login/2, callback/2]).
|
-export([login/2, callback/2]).
|
||||||
|
@ -102,7 +103,7 @@ desc(_) ->
|
||||||
|
|
||||||
create(#{sp_sign_request := true} = Config) ->
|
create(#{sp_sign_request := true} = Config) ->
|
||||||
try
|
try
|
||||||
do_create(ensure_cert_and_key(Config))
|
do_create(Config)
|
||||||
catch
|
catch
|
||||||
Kind:Error ->
|
Kind:Error ->
|
||||||
Msg = failed_to_ensure_cert_and_key,
|
Msg = failed_to_ensure_cert_and_key,
|
||||||
|
@ -150,10 +151,31 @@ callback(_Req = #{body := Body}, #{sp := SP, dashboard_addr := DashboardAddr} =
|
||||||
{error, iolist_to_binary(Reason)}
|
{error, iolist_to_binary(Reason)}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
convert_certs(
|
||||||
|
Dir,
|
||||||
|
#{<<"sp_sign_request">> := true, <<"sp_public_key">> := Cert, <<"sp_private_key">> := Key} =
|
||||||
|
Conf
|
||||||
|
) ->
|
||||||
|
case
|
||||||
|
emqx_tls_lib:ensure_ssl_files(
|
||||||
|
Dir, #{enable => ture, certfile => Cert, keyfile => Key}, #{}
|
||||||
|
)
|
||||||
|
of
|
||||||
|
{ok, #{certfile := CertPath, keyfile := KeyPath}} ->
|
||||||
|
Conf#{<<"sp_public_key">> => bin(CertPath), <<"sp_private_key">> => bin(KeyPath)};
|
||||||
|
{error, Reason} ->
|
||||||
|
?SLOG(error, #{msg => "failed_to_save_sp_sign_keys", reason => Reason}),
|
||||||
|
throw("Failed to save sp signing key(s)")
|
||||||
|
end;
|
||||||
|
convert_certs(_Dir, Conf) ->
|
||||||
|
Conf.
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bin(X) -> iolist_to_binary(X).
|
||||||
|
|
||||||
do_create(
|
do_create(
|
||||||
#{
|
#{
|
||||||
dashboard_addr := DashboardAddr,
|
dashboard_addr := DashboardAddr,
|
||||||
|
@ -222,18 +244,6 @@ gen_redirect_response(DashboardAddr, Username) ->
|
||||||
%% Helpers functions
|
%% Helpers functions
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
ensure_cert_and_key(#{sp_public_key := Cert, sp_private_key := Key} = Config) ->
|
|
||||||
case
|
|
||||||
emqx_tls_lib:ensure_ssl_files(
|
|
||||||
?DIR, #{enable => ture, certfile => Cert, keyfile => Key}, #{}
|
|
||||||
)
|
|
||||||
of
|
|
||||||
{ok, #{certfile := CertPath, keyfile := KeyPath} = _NSSL} ->
|
|
||||||
Config#{sp_public_key => CertPath, sp_private_key => KeyPath};
|
|
||||||
{error, #{which_options := KeyPath}} ->
|
|
||||||
error({missing_key, lists:flatten(KeyPath)})
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% TODO: unify with emqx_dashboard_sso_manager:ensure_user_exists/1
|
%% TODO: unify with emqx_dashboard_sso_manager:ensure_user_exists/1
|
||||||
ensure_user_exists(Username) ->
|
ensure_user_exists(Username) ->
|
||||||
case emqx_dashboard_admin:lookup_user(saml, Username) of
|
case emqx_dashboard_admin:lookup_user(saml, Username) of
|
||||||
|
|
Loading…
Reference in New Issue