diff --git a/apps/emqx_dashboard_sso/src/emqx_dashboard_sso.erl b/apps/emqx_dashboard_sso/src/emqx_dashboard_sso.erl index 2214be06f..971465587 100644 --- a/apps/emqx_dashboard_sso/src/emqx_dashboard_sso.erl +++ b/apps/emqx_dashboard_sso/src/emqx_dashboard_sso.erl @@ -13,7 +13,8 @@ create/2, update/3, destroy/2, - login/3 + login/3, + convert_certs/3 ]). -export([types/0, modules/0, provider/1, backends/0, format/1]). @@ -45,6 +46,11 @@ | {redirect, tuple()} | {error, Reason :: term()}. +-callback convert_certs( + Dir :: file:filename_all(), + config() +) -> config(). + %%------------------------------------------------------------------------------ %% Callback Interface %%------------------------------------------------------------------------------ @@ -68,6 +74,9 @@ destroy(Mod, State) -> login(Mod, Req, State) -> Mod:login(Req, State). +convert_certs(Mod, Dir, Config) -> + Mod:convert_certs(Dir, Config). + %%------------------------------------------------------------------------------ %% API %%------------------------------------------------------------------------------ diff --git a/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_ldap.erl b/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_ldap.erl index bea8ef7c6..83a57cf7b 100644 --- a/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_ldap.erl +++ b/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_ldap.erl @@ -22,7 +22,8 @@ login/2, create/1, update/2, - destroy/1 + destroy/1, + convert_certs/2 ]). %%------------------------------------------------------------------------------ @@ -163,3 +164,21 @@ ensure_user_exists(Username) -> Error 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}. diff --git a/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_manager.erl b/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_manager.erl index a3512ac2f..473881cf9 100644 --- a/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_manager.erl +++ b/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_manager.erl @@ -52,7 +52,7 @@ -record(?MOD_TAB, { backend :: atom(), - state :: map(), + state :: undefined | map(), last_error = ?NO_ERROR :: term() }). @@ -217,7 +217,7 @@ update_config(Backend, UpdateReq) -> end. pre_config_update(_, {update, _Backend, Config}, _OldConf) -> - maybe_write_certs(Config); + {ok, maybe_write_certs(Config)}; pre_config_update(_, {delete, _Backend}, undefined) -> throw(not_exists); pre_config_update(_, {delete, _Backend}, _OldConf) -> @@ -333,26 +333,13 @@ remove_handler() -> ok = emqx_conf:remove_handler(?MOD_KEY_PATH('?')). maybe_write_certs(#{<<"backend">> := Backend} = Conf) -> - case - emqx_tls_lib:ensure_ssl_files( - ssl_file_path(Backend), maps:get(<<"ssl">>, Conf, undefined) - ) - of - {ok, SSL} -> - {ok, new_ssl_source(Conf, SSL)}; - {error, Reason} -> - ?SLOG(error, Reason#{msg => "bad_ssl_config"}), - throw({bad_ssl_config, Reason}) - end. + Dir = certs_path(Backend), + Provider = provider(Backend), + emqx_dashboard_sso:convert_certs(Provider, Dir, Conf). -ssl_file_path(Backend) -> +certs_path(Backend) -> filename:join(["sso", Backend]). -new_ssl_source(Source, undefined) -> - Source; -new_ssl_source(Source, SSL) -> - Source#{<<"ssl">> => SSL}. - update_state(Backend, State) -> Data = ensure_backend_data(Backend), ets:insert(?MOD_TAB, Data#?MOD_TAB{state = State}). diff --git a/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_saml.erl b/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_saml.erl index fc2cadfe6..2549c1334 100644 --- a/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_saml.erl +++ b/apps/emqx_dashboard_sso/src/emqx_dashboard_sso_saml.erl @@ -22,7 +22,8 @@ -export([ create/1, update/2, - destroy/1 + destroy/1, + convert_certs/2 ]). -export([login/2, callback/2]). @@ -102,7 +103,7 @@ desc(_) -> create(#{sp_sign_request := true} = Config) -> try - do_create(ensure_cert_and_key(Config)) + do_create(Config) catch Kind:Error -> 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)} 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 %%------------------------------------------------------------------------------ +bin(X) -> iolist_to_binary(X). + do_create( #{ dashboard_addr := DashboardAddr, @@ -222,18 +244,6 @@ gen_redirect_response(DashboardAddr, Username) -> %% 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 ensure_user_exists(Username) -> case emqx_dashboard_admin:lookup_user(saml, Username) of