Skip to content

Commit

Permalink
Merge pull request #3375 from esl/keystore-remove-dynamic-modules
Browse files Browse the repository at this point in the history
  • Loading branch information
gustawlippa authored Nov 3, 2021
2 parents 0c2bca9 + 4ce1ea7 commit 9ca4366
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 28 deletions.
1 change: 0 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
mongoose_rdbms_backend,
mod_bosh_backend,
mod_global_distrib_mapping_backend,
mod_keystore_backend,
mod_mam_cassandra_arch_params,
mod_mam_cassandra_prefs_params, mod_mam_muc_cassandra_arch_params,
mod_pubsub_db_backend, mod_revproxy_dynamic,
Expand Down
21 changes: 2 additions & 19 deletions src/mod_keystore.erl
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@
key_name/0,
raw_key/0]).

-define(MOD_KEYSTORE_BACKEND, mod_keystore_backend).
-ignore_xref([
{?MOD_KEYSTORE_BACKEND, get_key, 1},
{?MOD_KEYSTORE_BACKEND, init_ram_key, 1},
{?MOD_KEYSTORE_BACKEND, init, 2},
behaviour_info/1, get_key/2, validate_opts/1
]).

Expand All @@ -48,25 +44,13 @@
%% A key ID is used to uniquely identify a key for storage backends.
%% It's used to maintain separate instances of a key with the same name
%% for different virtual hosts.
-type key_id() :: {key_name(), jid:server()}.
-type key_id() :: {key_name(), mongooseim:host_type()}.
-type raw_key() :: binary().
-type key_list() :: [{key_id(), raw_key()}].
-type key_type() :: ram | {file, file:name_all()}.

-type key() :: #key{id :: key_id(), key :: raw_key()}.

-callback init(mongooseim:host_type(), gen_mod:module_opts()) -> ok.

%% Cluster members race to decide whose key gets stored in the distributed database.
%% That's why ProposedKey (the key this cluster member tries to propagate to other nodes)
%% might not be the same as ActualKey (key of the member who will have won the race).
-callback init_ram_key(ProposedKey) -> Result when
ProposedKey :: key(),
Result :: {ok, ActualKey} | {error, any()},
ActualKey :: key().

-callback get_key(ID :: key_id()) -> key_list().

%%
%% gen_mod callbacks
%%
Expand All @@ -75,7 +59,6 @@
start(HostType, Opts) ->
validate_opts(Opts),
create_keystore_ets(),
gen_mod:start_backend_module(?MODULE, Opts),
mod_keystore_backend:init(HostType, Opts),
init_keys(HostType, Opts),
ejabberd_hooks:add(hooks(HostType)),
Expand Down Expand Up @@ -195,7 +178,7 @@ init_key({KeyName, ram}, HostType, Opts) ->
ProposedKey = crypto:strong_rand_bytes(get_key_size(Opts)),
KeyRecord = #key{id = {KeyName, HostType},
key = ProposedKey},
{ok, _ActualKey} = mod_keystore_backend:init_ram_key(KeyRecord),
{ok, _ActualKey} = mod_keystore_backend:init_ram_key(HostType, KeyRecord),
ok.

%% It's easier to trace these than ets:{insert, lookup} - much less noise.
Expand Down
42 changes: 42 additions & 0 deletions src/mod_keystore_backend.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
%% Just a proxy interface module between the main mod_keystore module and
%% the backend modules (i.e. mod_keystore_mnesia...).
-module(mod_keystore_backend).

-export([init/2, init_ram_key/2, get_key/1]).

-define(MAIN_MODULE, mod_keystore).

-callback init(mongooseim:host_type(), gen_mod:module_opts()) -> ok.

%% Cluster members race to decide whose key gets stored in the distributed database.
%% That's why ProposedKey (the key this cluster member tries to propagate to other nodes)
%% might not be the same as ActualKey (key of the member who will have won the race).
-callback init_ram_key(ProposedKey) -> Result when
ProposedKey :: mod_keystore:key(),
Result :: {ok, ActualKey} | {error, any()},
ActualKey :: mod_keystore:key().

-callback get_key(ID :: mod_keystore:key_id()) -> mod_keystore:key_list().

-spec init(mongooseim:host_type(), gen_mod:module_opts()) -> ok.
init(HostType, Opts) ->
mongoose_backend:init_per_host_type(HostType, ?MAIN_MODULE, [], Opts),
Args = [HostType, Opts],
mongoose_backend:call(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args).

%% Cluster members race to decide whose key gets stored in the distributed database.
%% That's why ProposedKey (the key this cluster member tries to propagate to other nodes)
%% might not be the same as ActualKey (key of the member who will have won the race).
-spec init_ram_key(HostType, ProposedKey) -> Result when
HostType :: mongooseim:host_type(),
ProposedKey :: mod_keystore:key(),
Result :: {ok, ActualKey} | {error, any()},
ActualKey :: mod_keystore:key().
init_ram_key(HostType, ProposedKey) ->
Args = [ProposedKey],
mongoose_backend:call(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args).

-spec get_key(ID :: mod_keystore:key_id()) -> mod_keystore:key_list().
get_key({_, HostType} = ID) ->
Args = [ID],
mongoose_backend:call(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args).
1 change: 1 addition & 0 deletions src/mod_keystore_mnesia.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-module(mod_keystore_mnesia).
-behaviour(mod_keystore_backend).

-export([init/2,
init_ram_key/1,
Expand Down
8 changes: 4 additions & 4 deletions src/mongoose_hooks.erl
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,12 @@ inbox_unread_count(LServer, Acc, User) ->
run_hook_for_host_type(inbox_unread_count, LServer, Acc, [User]).

%%% @doc The `get_key' hook is called to extract a key from `mod_keystore'.
-spec get_key(LServer, KeyName) -> Result when
LServer :: jid:lserver(),
-spec get_key(HostType, KeyName) -> Result when
HostType :: mongooseim:host_type(),
KeyName :: atom(),
Result :: mod_keystore:key_list().
get_key(LServer, KeyName) ->
run_hook_for_host_type(get_key, LServer, [], [{KeyName, LServer}]).
get_key(HostType, KeyName) ->
run_hook_for_host_type(get_key, HostType, [], [{KeyName, HostType}]).

-spec packet_to_component(Acc, From, To) -> Result when
Acc :: mongoose_acc:t(),
Expand Down
8 changes: 4 additions & 4 deletions test/keystore_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,12 @@ mock_mongoose_metrics() ->
ok.

%% Use a function like this in your module which is a client of mod_keystore.
-spec get_key(Domain, KeyName) -> Result when
Domain :: jid:server(),
-spec get_key(HostType, KeyName) -> Result when
HostType :: mongooseim:host_type(),
KeyName :: mod_keystore:key_name(),
Result :: mod_keystore:key_list().
get_key(Domain, KeyName) ->
mongoose_hooks:get_key(Domain, KeyName).
get_key(HostType, KeyName) ->
mongoose_hooks:get_key(HostType, KeyName).

%%{mod_keystore, [{keys, [{asdqwe_access_secret, ram},
%% {asdqwe_access_psk, {file, "priv/asdqwe_access_psk"}},
Expand Down

0 comments on commit 9ca4366

Please sign in to comment.