aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_commands.erl
diff options
context:
space:
mode:
authorEvgeny Khramtsov <ekhramtsov@process-one.net>2019-06-14 12:33:26 +0300
committerEvgeny Khramtsov <ekhramtsov@process-one.net>2019-06-14 12:33:26 +0300
commita02cff0e780bb735531594c4ece81e8628f79782 (patch)
tree6fe7d8219d14f58183be1741fcea262c216db447 /src/ejabberd_commands.erl
parentReturn jid_malformed error when sending presence without nick to conference (diff)
Use new configuration validator
Diffstat (limited to '')
-rw-r--r--src/ejabberd_commands.erl147
1 files changed, 7 insertions, 140 deletions
diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl
index 921ed25c7..921047e9f 100644
--- a/src/ejabberd_commands.erl
+++ b/src/ejabberd_commands.erl
@@ -211,7 +211,6 @@
-author('badlop@process-one.net').
-behaviour(gen_server).
--behaviour(ejabberd_config).
-define(DEFAULT_VERSION, 1000000).
@@ -225,11 +224,8 @@
get_command_definition/2,
get_tags_commands/0,
get_tags_commands/1,
- get_exposed_commands/0,
register_commands/1,
unregister_commands/1,
- expose_commands/1,
- opt_type/1,
get_commands_spec/0,
get_commands_definition/0,
get_commands_definition/1,
@@ -245,6 +241,8 @@
-define(POLICY_ACCESS, '$policy').
+-type auth() :: {binary(), binary(), binary() | {oauth, binary()}, boolean()} | map().
+
-record(state, {}).
get_commands_spec() ->
@@ -292,7 +290,6 @@ init([]) ->
{attributes, record_info(fields, ejabberd_commands)},
{type, bag}]),
register_commands(get_commands_spec()),
- ejabberd_access_permissions:register_permission_addon(?MODULE, fun permission_addon/0),
{ok, #state{}}.
handle_call(_Request, _From, State) ->
@@ -338,29 +335,7 @@ unregister_commands(Commands) ->
mnesia:dirty_delete_object(Command)
end,
Commands),
- ejabberd_access_permissions:invalidate(),
- ok.
-
-%% @doc Expose command through ejabberd ReST API.
-%% Pass a list of command names or policy to expose.
--spec expose_commands([ejabberd_commands()|atom()|open|user|admin|restricted]) -> ok | {error, atom()}.
-
-expose_commands(Commands) ->
- Names = lists:map(fun(#ejabberd_commands{name = Name}) ->
- Name;
- (Name) when is_atom(Name) ->
- Name
- end,
- Commands),
-
- case ejabberd_config:add_option(commands, [{add_commands, Names}]) of
- ok ->
- ok;
- {aborted, Reason} ->
- {error, Reason};
- {atomic, Result} ->
- Result
- end.
+ ejabberd_access_permissions:invalidate().
-spec list_commands() -> [{atom(), [aterm()], string()}].
@@ -378,20 +353,6 @@ list_commands(Version) ->
args = Args,
desc = Desc} <- Commands].
-
--spec list_commands_policy(integer()) ->
- [{atom(), [aterm()], string(), atom()}].
-
-%% @doc Get a list of all the available commands, arguments,
-%% description, and policy in a given API version.
-list_commands_policy(Version) ->
- Commands = get_commands_definition(Version),
- [{Name, Args, Desc, Policy} ||
- #ejabberd_commands{name = Name,
- args = Args,
- desc = Desc,
- policy = Policy} <- Commands].
-
-spec get_command_format(atom()) -> {[aterm()], rterm()}.
%% @doc Get the format of arguments and result of a command.
@@ -402,12 +363,7 @@ get_command_format(Name, Version) when is_integer(Version) ->
get_command_format(Name, Auth) ->
get_command_format(Name, Auth, ?DEFAULT_VERSION).
--spec get_command_format(atom(),
- {binary(), binary(), binary(), boolean()} |
- noauth | admin,
- integer()) ->
- {[aterm()], rterm()}.
-
+-spec get_command_format(atom(), noauth | admin | auth(), integer()) -> {[aterm()], rterm()}.
get_command_format(Name, Auth, Version) ->
Admin = is_admin(Name, Auth, #{}),
#ejabberd_commands{args = Args,
@@ -422,12 +378,6 @@ get_command_format(Name, Auth, Version) ->
{Args, Result}
end.
-%% The oauth scopes for a command are the command name itself,
-%% also might include either 'ejabberd:user' or 'ejabberd:admin'
-cmd_scope(#ejabberd_commands{policy = Policy, name = Name}) ->
- [erlang:atom_to_binary(Name,utf8)] ++ [<<"ejabberd:user">> || Policy == user] ++ [<<"ejabberd:admin">> || Policy == admin].
-
-
-spec get_command_definition(atom()) -> ejabberd_commands().
%% @doc Get the definition record of a command.
@@ -533,95 +483,12 @@ get_tags_commands(Version) ->
%% -----------------------------
%% Access verification
%% -----------------------------
-
--spec check_auth(ejabberd_commands(), noauth) -> noauth_provided;
- (ejabberd_commands(),
- {binary(), binary(), binary(), boolean()}) ->
- {ok, binary(), binary()}.
-
-check_auth(_Command, noauth) ->
- no_auth_provided;
-check_auth(Command, {User, Server, {oauth, Token}, _}) ->
- ScopeList = cmd_scope(Command),
- case ejabberd_oauth:check_token(User, Server, ScopeList, Token) of
- true ->
- {ok, User, Server};
- _ ->
- throw({error, invalid_account_data})
- end;
-check_auth(_Command, {User, Server, Password, _}) when is_binary(Password) ->
- %% Check the account exists and password is valid
- case ejabberd_auth:check_password(User, <<"">>, Server, Password) of
- true -> {ok, User, Server};
- _ -> throw({error, invalid_account_data})
- end.
-
-get_exposed_commands() ->
- get_exposed_commands(?DEFAULT_VERSION).
-get_exposed_commands(Version) ->
- Opts0 = ejabberd_config:get_option(commands, []),
- Opts = lists:map(fun(V) when is_tuple(V) -> [V]; (V) -> V end, Opts0),
- CommandsList = list_commands_policy(Version),
- OpenCmds = [N || {N, _, _, open} <- CommandsList],
- RestrictedCmds = [N || {N, _, _, restricted} <- CommandsList],
- AdminCmds = [N || {N, _, _, admin} <- CommandsList],
- UserCmds = [N || {N, _, _, user} <- CommandsList],
- Cmds =
- lists:foldl(
- fun([{add_commands, L}], Acc) ->
- Cmds = expand_commands(L, OpenCmds, UserCmds, AdminCmds, RestrictedCmds),
- lists:usort(Cmds ++ Acc);
- ([{remove_commands, L}], Acc) ->
- Cmds = expand_commands(L, OpenCmds, UserCmds, AdminCmds, RestrictedCmds),
- Acc -- Cmds;
- (_, Acc) -> Acc
- end, [], Opts),
- Cmds.
-
-%% This is used to allow mixing command policy (like open, user, admin, restricted), with command entry
-expand_commands(L, OpenCmds, UserCmds, AdminCmds, RestrictedCmds) when is_atom(L) ->
- expand_commands([L], OpenCmds, UserCmds, AdminCmds, RestrictedCmds);
-expand_commands(L, OpenCmds, UserCmds, AdminCmds, RestrictedCmds) when is_list(L) ->
- lists:foldl(fun(open, Acc) -> OpenCmds ++ Acc;
- (user, Acc) -> UserCmds ++ Acc;
- (admin, Acc) -> AdminCmds ++ Acc;
- (restricted, Acc) -> RestrictedCmds ++ Acc;
- (Command, Acc) when is_atom(Command) ->
- [Command|Acc]
- end, [], L).
-
+-spec is_admin(atom(), admin | noauth | auth(), map()) -> boolean().
is_admin(_Name, admin, _Extra) ->
true;
is_admin(_Name, {_User, _Server, _, false}, _Extra) ->
false;
is_admin(_Name, Map, _extra) when is_map(Map) ->
true;
-is_admin(Name, Auth, Extra) ->
- {ACLInfo, Server} = case Auth of
- {U, S, _, _} ->
- {Extra#{usr=>jid:split(jid:make(U, S))}, S};
- _ ->
- {Extra, global}
- end,
- AdminAccess = ejabberd_config:get_option(commands_admin_access, none),
- case acl:access_matches(AdminAccess, ACLInfo, Server) of
- allow ->
- case catch check_auth(get_command_definition(Name), Auth) of
- {ok, _, _} -> true;
- no_auth_provided -> true;
- _ -> false
- end;
- deny -> false
- end.
-
-permission_addon() ->
- [{<<"'commands' option compatibility shim">>,
- {[],
- [{access, ejabberd_config:get_option(commands_admin_access, none)}],
- {get_exposed_commands(), []}}}].
-
--spec opt_type(atom()) -> fun((any()) -> any()) | [atom()].
-opt_type(commands_admin_access) -> fun acl:access_rules_validator/1;
-opt_type(commands) ->
- fun(V) when is_list(V) -> V end;
-opt_type(_) -> [commands, commands_admin_access].
+is_admin(_Name, _Auth, _Extra) ->
+ false.