From a02cff0e780bb735531594c4ece81e8628f79782 Mon Sep 17 00:00:00 2001 From: Evgeny Khramtsov Date: Fri, 14 Jun 2019 12:33:26 +0300 Subject: Use new configuration validator --- src/ejabberd_commands.erl | 147 +++------------------------------------------- 1 file changed, 7 insertions(+), 140 deletions(-) (limited to 'src/ejabberd_commands.erl') 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. -- cgit v1.2.3