mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-22 17:28:25 +01:00
Merge branch 'add-error-reason'
This commit is contained in:
commit
232915184c
@ -68,7 +68,9 @@ parse_request(#iq{type = set, lang = Lang, sub_el = SubEl, xmlns = ?NS_COMMANDS}
|
||||
xdata = XData,
|
||||
others = Others
|
||||
};
|
||||
parse_request(_) -> {error, ?ERR_BAD_REQUEST}.
|
||||
parse_request(#iq{lang = Lang}) ->
|
||||
Text = <<"Failed to parse ad-hoc command request">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Text)}.
|
||||
|
||||
%% Borrowed from mod_vcard.erl
|
||||
find_xdata_el(#xmlel{children = SubEls}) ->
|
||||
|
@ -619,8 +619,9 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
send_element(StateData, Res),
|
||||
fsm_next_state(wait_for_auth, StateData);
|
||||
{auth, _ID, set, {_U, _P, _D, <<"">>}} ->
|
||||
Err = jlib:make_error_reply(El,
|
||||
?ERR_AUTH_NO_RESOURCE_PROVIDED((StateData#state.lang))),
|
||||
Lang = StateData#state.lang,
|
||||
Txt = <<"No resource provided">>,
|
||||
Err = jlib:make_error_reply(El, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)),
|
||||
send_element(StateData, Err),
|
||||
fsm_next_state(wait_for_auth, StateData);
|
||||
{auth, _ID, set, {U, P, D, R}} ->
|
||||
@ -685,7 +686,10 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
Err = jlib:make_error_reply(El, ?ERR_NOT_AUTHORIZED),
|
||||
Lang = StateData#state.lang,
|
||||
Txt = <<"Legacy authentication failed">>,
|
||||
Err = jlib:make_error_reply(
|
||||
El, ?ERRT_NOT_AUTHORIZED(Lang, Txt)),
|
||||
send_element(StateData, Err),
|
||||
fsm_next_state(wait_for_auth, StateData)
|
||||
end;
|
||||
@ -706,7 +710,9 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
||||
Lang = StateData#state.lang,
|
||||
Txt = <<"Legacy authentication forbidden">>,
|
||||
Err = jlib:make_error_reply(El, ?ERRT_NOT_ALLOWED(Lang, Txt)),
|
||||
send_element(StateData, Err),
|
||||
fsm_next_state(wait_for_auth, StateData)
|
||||
end
|
||||
@ -1013,7 +1019,7 @@ wait_for_bind({xmlstreamelement, #xmlel{name = Name, attrs = Attrs} = El},
|
||||
end;
|
||||
wait_for_bind({xmlstreamelement, El}, StateData) ->
|
||||
case jlib:iq_query_info(El) of
|
||||
#iq{type = set, xmlns = ?NS_BIND, sub_el = SubEl} =
|
||||
#iq{type = set, lang = Lang, xmlns = ?NS_BIND, sub_el = SubEl} =
|
||||
IQ ->
|
||||
U = StateData#state.user,
|
||||
R1 = fxml:get_path_s(SubEl,
|
||||
@ -1025,7 +1031,8 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
|
||||
end,
|
||||
case R of
|
||||
error ->
|
||||
Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST),
|
||||
Txt = <<"Malformed resource">>,
|
||||
Err = jlib:make_error_reply(El, ?ERRT_BAD_REQUEST(Lang, Txt)),
|
||||
send_element(StateData, Err),
|
||||
fsm_next_state(wait_for_bind, StateData);
|
||||
_ ->
|
||||
@ -1099,6 +1106,7 @@ open_session(StateData) ->
|
||||
U = StateData#state.user,
|
||||
R = StateData#state.resource,
|
||||
JID = StateData#state.jid,
|
||||
Lang = StateData#state.lang,
|
||||
case acl:match_rule(StateData#state.server,
|
||||
StateData#state.access, JID) of
|
||||
allow ->
|
||||
@ -1136,7 +1144,8 @@ open_session(StateData) ->
|
||||
StateData#state.server, [JID]),
|
||||
?INFO_MSG("(~w) Forbidden session for ~s",
|
||||
[StateData#state.socket, jid:to_string(JID)]),
|
||||
{error, ?ERR_NOT_ALLOWED}
|
||||
Txt = <<"Denied by ACL">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
|
||||
end.
|
||||
|
||||
session_established({xmlstreamelement, #xmlel{name = Name} = El}, StateData)
|
||||
@ -2275,30 +2284,32 @@ get_priority_from_presence(PresencePacket) ->
|
||||
end.
|
||||
|
||||
process_privacy_iq(From, To,
|
||||
#iq{type = Type, sub_el = SubEl} = IQ, StateData) ->
|
||||
{Res, NewStateData} = case Type of
|
||||
get ->
|
||||
R = ejabberd_hooks:run_fold(privacy_iq_get,
|
||||
StateData#state.server,
|
||||
{error,
|
||||
?ERR_FEATURE_NOT_IMPLEMENTED},
|
||||
[From, To, IQ,
|
||||
StateData#state.privacy_list]),
|
||||
{R, StateData};
|
||||
set ->
|
||||
case ejabberd_hooks:run_fold(privacy_iq_set,
|
||||
StateData#state.server,
|
||||
{error,
|
||||
?ERR_FEATURE_NOT_IMPLEMENTED},
|
||||
[From, To, IQ])
|
||||
of
|
||||
{result, R, NewPrivList} ->
|
||||
{{result, R},
|
||||
StateData#state{privacy_list =
|
||||
NewPrivList}};
|
||||
R -> {R, StateData}
|
||||
end
|
||||
end,
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ, StateData) ->
|
||||
Txt = <<"No module is handling this query">>,
|
||||
{Res, NewStateData} =
|
||||
case Type of
|
||||
get ->
|
||||
R = ejabberd_hooks:run_fold(
|
||||
privacy_iq_get,
|
||||
StateData#state.server,
|
||||
{error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)},
|
||||
[From, To, IQ,
|
||||
StateData#state.privacy_list]),
|
||||
{R, StateData};
|
||||
set ->
|
||||
case ejabberd_hooks:run_fold(
|
||||
privacy_iq_set,
|
||||
StateData#state.server,
|
||||
{error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)},
|
||||
[From, To, IQ])
|
||||
of
|
||||
{result, R, NewPrivList} ->
|
||||
{{result, R},
|
||||
StateData#state{privacy_list =
|
||||
NewPrivList}};
|
||||
R -> {R, StateData}
|
||||
end
|
||||
end,
|
||||
IQRes = case Res of
|
||||
{result, Result} ->
|
||||
IQ#iq{type = result, sub_el = Result};
|
||||
@ -2365,15 +2376,16 @@ process_unauthenticated_stanza(StateData, El) ->
|
||||
_ -> El
|
||||
end,
|
||||
case jlib:iq_query_info(NewEl) of
|
||||
#iq{} = IQ ->
|
||||
#iq{lang = L} = IQ ->
|
||||
Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
|
||||
StateData#state.server, empty,
|
||||
[StateData#state.server, IQ,
|
||||
StateData#state.ip]),
|
||||
case Res of
|
||||
empty ->
|
||||
Txt = <<"Authentication required">>,
|
||||
ResIQ = IQ#iq{type = error,
|
||||
sub_el = [?ERR_SERVICE_UNAVAILABLE]},
|
||||
sub_el = [?ERRT_SERVICE_UNAVAILABLE(L, Txt)]},
|
||||
Res1 = jlib:replace_from_to(jid:make(<<"">>,
|
||||
StateData#state.server,
|
||||
<<"">>),
|
||||
@ -2879,6 +2891,7 @@ handle_unacked_stanzas(StateData)
|
||||
false
|
||||
end
|
||||
end,
|
||||
Lang = StateData#state.lang,
|
||||
ReRoute = case ResendOnTimeout of
|
||||
true ->
|
||||
fun(From, To, El, Time) ->
|
||||
@ -2887,9 +2900,11 @@ handle_unacked_stanzas(StateData)
|
||||
end;
|
||||
false ->
|
||||
fun(From, To, El, _Time) ->
|
||||
Txt = <<"User session not found">>,
|
||||
Err =
|
||||
jlib:make_error_reply(El,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
jlib:make_error_reply(
|
||||
El,
|
||||
?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end
|
||||
end,
|
||||
@ -2897,7 +2912,9 @@ handle_unacked_stanzas(StateData)
|
||||
?DEBUG("Dropping presence stanza from ~s",
|
||||
[jid:to_string(From)]);
|
||||
(From, To, #xmlel{name = <<"iq">>} = El, _Time) ->
|
||||
Err = jlib:make_error_reply(El, ?ERR_SERVICE_UNAVAILABLE),
|
||||
Txt = <<"User session not found">>,
|
||||
Err = jlib:make_error_reply(
|
||||
El, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
(From, To, El, Time) ->
|
||||
%% We'll drop the stanza if it was <forwarded/> by some
|
||||
|
@ -74,7 +74,7 @@ start_link() ->
|
||||
process_iq(From, To, Packet) ->
|
||||
IQ = jlib:iq_query_info(Packet),
|
||||
case IQ of
|
||||
#iq{xmlns = XMLNS} ->
|
||||
#iq{xmlns = XMLNS, lang = Lang} ->
|
||||
Host = To#jid.lserver,
|
||||
case ets:lookup(?IQTABLE, {XMLNS, Host}) of
|
||||
[{_, Module, Function}] ->
|
||||
@ -87,8 +87,10 @@ process_iq(From, To, Packet) ->
|
||||
gen_iq_handler:handle(Host, Module, Function, Opts,
|
||||
From, To, IQ);
|
||||
[] ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_FEATURE_NOT_IMPLEMENTED),
|
||||
Txt = <<"No module is handling this query">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet,
|
||||
?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
reply ->
|
||||
@ -166,8 +168,10 @@ refresh_iq_handlers() ->
|
||||
ejabberd_local ! refresh_iq_handlers.
|
||||
|
||||
bounce_resource_packet(From, To, Packet) ->
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"No available resource found">>,
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_ITEM_NOT_FOUND),
|
||||
?ERRT_ITEM_NOT_FOUND(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err),
|
||||
stop.
|
||||
|
||||
|
@ -312,8 +312,10 @@ do_route(From, To, Packet) ->
|
||||
<<"error">> -> ok;
|
||||
<<"result">> -> ok;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"No s2s connection found">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end,
|
||||
false
|
||||
|
@ -280,7 +280,9 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
||||
and (FromJID /= error) ->
|
||||
ejabberd_router:route(FromJID, ToJID, NewEl);
|
||||
true ->
|
||||
Err = jlib:make_error_reply(NewEl, ?ERR_BAD_REQUEST),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, El),
|
||||
Txt = <<"Incorrect stanza name or from/to JID">>,
|
||||
Err = jlib:make_error_reply(NewEl, ?ERRT_BAD_REQUEST(Lang, Txt)),
|
||||
send_element(StateData, Err),
|
||||
error
|
||||
end,
|
||||
@ -360,7 +362,9 @@ handle_info({route, From, To, Packet}, StateName,
|
||||
attrs = Attrs2, children = Els}),
|
||||
send_text(StateData, Text);
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)),
|
||||
ejabberd_router:route_error(To, From, Err, Packet)
|
||||
end,
|
||||
{next_state, StateName, StateData};
|
||||
|
@ -159,8 +159,10 @@ check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
|
||||
-spec bounce_offline_message(jid(), jid(), xmlel()) -> stop.
|
||||
|
||||
bounce_offline_message(From, To, Packet) ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"User session not found">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err),
|
||||
stop.
|
||||
|
||||
@ -423,6 +425,7 @@ do_route(From, To, #xmlel{} = Packet) ->
|
||||
#jid{user = User, server = Server,
|
||||
luser = LUser, lserver = LServer, lresource = LResource} = To,
|
||||
#xmlel{name = Name, attrs = Attrs} = Packet,
|
||||
Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs),
|
||||
case LResource of
|
||||
<<"">> ->
|
||||
case Name of
|
||||
@ -496,8 +499,9 @@ do_route(From, To, #xmlel{} = Packet) ->
|
||||
<<"headline">> -> route_message(From, To, Packet, headline);
|
||||
<<"error">> -> ok;
|
||||
<<"groupchat">> ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
ErrTxt = <<"Incorrect message type">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, ErrTxt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
_ ->
|
||||
route_message(From, To, Packet, normal)
|
||||
@ -517,8 +521,10 @@ do_route(From, To, #xmlel{} = Packet) ->
|
||||
<<"">> -> route_message(From, To, Packet, normal);
|
||||
<<"error">> -> ok;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
ErrTxt = <<"Incorrect message type">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet,
|
||||
?ERRT_SERVICE_UNAVAILABLE(Lang, ErrTxt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
<<"iq">> ->
|
||||
@ -526,8 +532,10 @@ do_route(From, To, #xmlel{} = Packet) ->
|
||||
<<"error">> -> ok;
|
||||
<<"result">> -> ok;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
ErrTxt = <<"User session not found">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet,
|
||||
?ERRT_SERVICE_UNAVAILABLE(Lang, ErrTxt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
_ -> ?DEBUG("packet dropped~n", [])
|
||||
@ -684,7 +692,7 @@ get_max_user_sessions(LUser, Host) ->
|
||||
process_iq(From, To, Packet) ->
|
||||
IQ = jlib:iq_query_info(Packet),
|
||||
case IQ of
|
||||
#iq{xmlns = XMLNS} ->
|
||||
#iq{xmlns = XMLNS, lang = Lang} ->
|
||||
Host = To#jid.lserver,
|
||||
case ets:lookup(sm_iqtable, {XMLNS, Host}) of
|
||||
[{_, Module, Function}] ->
|
||||
@ -697,8 +705,10 @@ process_iq(From, To, Packet) ->
|
||||
gen_iq_handler:handle(Host, Module, Function, Opts,
|
||||
From, To, IQ);
|
||||
[] ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
Txt = <<"No module is handling this query">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet,
|
||||
?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
reply -> ok;
|
||||
|
@ -233,7 +233,7 @@ process_sm_iq(From, To, IQ) ->
|
||||
process_adhoc_request(From, To, IQ, adhoc_sm_commands).
|
||||
|
||||
process_adhoc_request(From, To,
|
||||
#iq{sub_el = SubEl} = IQ, Hook) ->
|
||||
#iq{sub_el = SubEl, lang = Lang} = IQ, Hook) ->
|
||||
?DEBUG("About to parse ~p...", [IQ]),
|
||||
case adhoc:parse_request(IQ) of
|
||||
{error, Error} ->
|
||||
@ -245,8 +245,9 @@ process_adhoc_request(From, To,
|
||||
of
|
||||
ignore -> ignore;
|
||||
empty ->
|
||||
Txt = <<"No hook has processed this command">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]};
|
||||
sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]};
|
||||
{error, Error} ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, Error]};
|
||||
Command -> IQ#iq{type = result, sub_el = [Command]}
|
||||
@ -277,7 +278,9 @@ ping_command(_Acc, _From, _To,
|
||||
[{<<"info">>,
|
||||
translate:translate(Lang,
|
||||
<<"Pong">>)}]});
|
||||
true -> {error, ?ERR_BAD_REQUEST}
|
||||
true ->
|
||||
Txt = <<"Incorrect value of 'action' attribute">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end;
|
||||
ping_command(Acc, _From, _To, _Request) -> Acc.
|
||||
|
||||
|
@ -211,15 +211,15 @@ disco_identity(Acc, _From, _To, Node, Lang) ->
|
||||
|
||||
%%-------------------------------------------------------------------------
|
||||
|
||||
-define(INFO_RESULT(Allow, Feats),
|
||||
-define(INFO_RESULT(Allow, Feats, Lang),
|
||||
case Allow of
|
||||
deny ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
allow ->
|
||||
{result, Feats}
|
||||
end).
|
||||
|
||||
disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, _Lang) ->
|
||||
disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, Lang) ->
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -229,13 +229,14 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, _Lang)
|
||||
case {acl:match_rule(LServer, Access1, From),
|
||||
acl:match_rule(global, Access2, From)} of
|
||||
{deny, deny} ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
Txt = <<"Denied by ACL">>,
|
||||
{error, ?ERRT_FORBIDDEN(Lang, Txt)};
|
||||
_ ->
|
||||
{result, []}
|
||||
end
|
||||
end;
|
||||
|
||||
disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
|
||||
disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -246,25 +247,25 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
|
||||
AllowGlobal = acl:match_rule(global, AccessGlobal, From),
|
||||
case Node of
|
||||
?NS_ADMIN_ANNOUNCE ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_ANNOUNCE_ALL ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_SET_MOTD ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_EDIT_MOTD ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_DELETE_MOTD ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_ANNOUNCE_ALLHOSTS ->
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS ->
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_SET_MOTD_ALLHOSTS ->
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_EDIT_MOTD_ALLHOSTS ->
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMIN_DELETE_MOTD_ALLHOSTS ->
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
@ -283,10 +284,10 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
|
||||
}
|
||||
)).
|
||||
|
||||
-define(ITEMS_RESULT(Allow, Items),
|
||||
-define(ITEMS_RESULT(Allow, Items, Lang),
|
||||
case Allow of
|
||||
deny ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
allow ->
|
||||
{result, Items}
|
||||
end).
|
||||
@ -320,7 +321,7 @@ disco_items(Acc, From, #jid{lserver = LServer} = To, <<"announce">>, Lang) ->
|
||||
announce_items(Acc, From, To, Lang)
|
||||
end;
|
||||
|
||||
disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
|
||||
disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -331,25 +332,25 @@ disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
|
||||
AllowGlobal = acl:match_rule(global, AccessGlobal, From),
|
||||
case Node of
|
||||
?NS_ADMIN_ANNOUNCE ->
|
||||
?ITEMS_RESULT(Allow, []);
|
||||
?ITEMS_RESULT(Allow, [], Lang);
|
||||
?NS_ADMIN_ANNOUNCE_ALL ->
|
||||
?ITEMS_RESULT(Allow, []);
|
||||
?ITEMS_RESULT(Allow, [], Lang);
|
||||
?NS_ADMIN_SET_MOTD ->
|
||||
?ITEMS_RESULT(Allow, []);
|
||||
?ITEMS_RESULT(Allow, [], Lang);
|
||||
?NS_ADMIN_EDIT_MOTD ->
|
||||
?ITEMS_RESULT(Allow, []);
|
||||
?ITEMS_RESULT(Allow, [], Lang);
|
||||
?NS_ADMIN_DELETE_MOTD ->
|
||||
?ITEMS_RESULT(Allow, []);
|
||||
?ITEMS_RESULT(Allow, [], Lang);
|
||||
?NS_ADMIN_ANNOUNCE_ALLHOSTS ->
|
||||
?ITEMS_RESULT(AllowGlobal, []);
|
||||
?ITEMS_RESULT(AllowGlobal, [], Lang);
|
||||
?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS ->
|
||||
?ITEMS_RESULT(AllowGlobal, []);
|
||||
?ITEMS_RESULT(AllowGlobal, [], Lang);
|
||||
?NS_ADMIN_SET_MOTD_ALLHOSTS ->
|
||||
?ITEMS_RESULT(AllowGlobal, []);
|
||||
?ITEMS_RESULT(AllowGlobal, [], Lang);
|
||||
?NS_ADMIN_EDIT_MOTD_ALLHOSTS ->
|
||||
?ITEMS_RESULT(AllowGlobal, []);
|
||||
?ITEMS_RESULT(AllowGlobal, [], Lang);
|
||||
?NS_ADMIN_DELETE_MOTD_ALLHOSTS ->
|
||||
?ITEMS_RESULT(AllowGlobal, []);
|
||||
?ITEMS_RESULT(AllowGlobal, [], Lang);
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
@ -396,7 +397,8 @@ announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang)
|
||||
commands_result(Allow, From, To, Request) ->
|
||||
case Allow of
|
||||
deny ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
Lang = Request#adhoc_request.lang,
|
||||
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
allow ->
|
||||
announce_commands(From, To, Request)
|
||||
end.
|
||||
@ -463,12 +465,13 @@ announce_commands(From, To,
|
||||
%% User returns form.
|
||||
case jlib:parse_xdata_submit(XData) of
|
||||
invalid ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
|
||||
Fields ->
|
||||
handle_adhoc_form(From, To, Request, Fields)
|
||||
end;
|
||||
true ->
|
||||
{error, ?ERR_BAD_REQUEST}
|
||||
Txt = <<"Incorrect action or data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end.
|
||||
|
||||
-define(VVALUE(Val),
|
||||
@ -688,7 +691,9 @@ announce_all(From, To, Packet) ->
|
||||
Access = get_access(Host),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
Local = jid:make(<<>>, To#jid.server, <<>>),
|
||||
@ -703,7 +708,9 @@ announce_all_hosts_all(From, To, Packet) ->
|
||||
Access = get_access(global),
|
||||
case acl:match_rule(global, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
Local = jid:make(<<>>, To#jid.server, <<>>),
|
||||
@ -719,7 +726,9 @@ announce_online(From, To, Packet) ->
|
||||
Access = get_access(Host),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_online1(ejabberd_sm:get_vh_session_list(Host),
|
||||
@ -731,7 +740,9 @@ announce_all_hosts_online(From, To, Packet) ->
|
||||
Access = get_access(global),
|
||||
case acl:match_rule(global, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_online1(ejabberd_sm:dirty_get_sessions_list(),
|
||||
@ -752,7 +763,9 @@ announce_motd(From, To, Packet) ->
|
||||
Access = get_access(Host),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_motd(Host, Packet)
|
||||
@ -762,7 +775,9 @@ announce_all_hosts_motd(From, To, Packet) ->
|
||||
Access = get_access(global),
|
||||
case acl:match_rule(global, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
Hosts = ?MYHOSTS,
|
||||
@ -815,7 +830,9 @@ announce_motd_update(From, To, Packet) ->
|
||||
Access = get_access(Host),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_motd_update(Host, Packet)
|
||||
@ -825,7 +842,9 @@ announce_all_hosts_motd_update(From, To, Packet) ->
|
||||
Access = get_access(global),
|
||||
case acl:match_rule(global, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
Hosts = ?MYHOSTS,
|
||||
@ -861,7 +880,9 @@ announce_motd_delete(From, To, Packet) ->
|
||||
Access = get_access(Host),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_motd_delete(Host)
|
||||
@ -871,7 +892,9 @@ announce_all_hosts_motd_delete(From, To, Packet) ->
|
||||
Access = get_access(global),
|
||||
case acl:match_rule(global, Access, From) of
|
||||
deny ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"Denied by ACL">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
Hosts = ?MYHOSTS,
|
||||
|
@ -64,29 +64,33 @@ process_iq(_From, _To, IQ) ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}.
|
||||
|
||||
process_iq_get(_, From, _To,
|
||||
#iq{xmlns = ?NS_BLOCKING,
|
||||
#iq{xmlns = ?NS_BLOCKING, lang = Lang,
|
||||
sub_el = #xmlel{name = <<"blocklist">>}},
|
||||
_) ->
|
||||
#jid{luser = LUser, lserver = LServer} = From,
|
||||
{stop, process_blocklist_get(LUser, LServer)};
|
||||
{stop, process_blocklist_get(LUser, LServer, Lang)};
|
||||
process_iq_get(Acc, _, _, _, _) -> Acc.
|
||||
|
||||
process_iq_set(_, From, _To,
|
||||
#iq{xmlns = ?NS_BLOCKING,
|
||||
#iq{xmlns = ?NS_BLOCKING, lang = Lang,
|
||||
sub_el =
|
||||
#xmlel{name = SubElName, children = SubEls}}) ->
|
||||
#jid{luser = LUser, lserver = LServer} = From,
|
||||
Res = case {SubElName, fxml:remove_cdata(SubEls)} of
|
||||
{<<"block">>, []} -> {error, ?ERR_BAD_REQUEST};
|
||||
{<<"block">>, []} ->
|
||||
Txt = <<"No items found in this query">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{<<"block">>, Els} ->
|
||||
JIDs = parse_blocklist_items(Els, []),
|
||||
process_blocklist_block(LUser, LServer, JIDs);
|
||||
process_blocklist_block(LUser, LServer, JIDs, Lang);
|
||||
{<<"unblock">>, []} ->
|
||||
process_blocklist_unblock_all(LUser, LServer);
|
||||
process_blocklist_unblock_all(LUser, LServer, Lang);
|
||||
{<<"unblock">>, Els} ->
|
||||
JIDs = parse_blocklist_items(Els, []),
|
||||
process_blocklist_unblock(LUser, LServer, JIDs);
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
process_blocklist_unblock(LUser, LServer, JIDs, Lang);
|
||||
_ ->
|
||||
Txt = <<"Unknown blocking command">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end,
|
||||
{stop, Res};
|
||||
process_iq_set(Acc, _, _, _) -> Acc.
|
||||
@ -125,7 +129,7 @@ parse_blocklist_items([#xmlel{name = <<"item">>,
|
||||
parse_blocklist_items([_ | Els], JIDs) ->
|
||||
parse_blocklist_items(Els, JIDs).
|
||||
|
||||
process_blocklist_block(LUser, LServer, JIDs) ->
|
||||
process_blocklist_block(LUser, LServer, JIDs, Lang) ->
|
||||
Filter = fun (List) ->
|
||||
AlreadyBlocked = list_to_blocklist_jids(List, []),
|
||||
lists:foldr(fun (JID, List1) ->
|
||||
@ -143,8 +147,8 @@ process_blocklist_block(LUser, LServer, JIDs) ->
|
||||
end,
|
||||
List, JIDs)
|
||||
end,
|
||||
case process_blocklist_block(LUser, LServer, Filter,
|
||||
gen_mod:db_type(LServer, mod_privacy))
|
||||
case process_blocklist_block_db(LUser, LServer, Filter,
|
||||
gen_mod:db_type(LServer, mod_privacy))
|
||||
of
|
||||
{atomic, {ok, Default, List}} ->
|
||||
UserList = make_userlist(Default, List),
|
||||
@ -155,11 +159,11 @@ process_blocklist_block(LUser, LServer, JIDs) ->
|
||||
{result, [], UserList};
|
||||
_Err ->
|
||||
?ERROR_MSG("Error processing ~p: ~p", [{LUser, LServer, JIDs}, _Err]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
|
||||
end.
|
||||
|
||||
process_blocklist_block(LUser, LServer, Filter,
|
||||
mnesia) ->
|
||||
process_blocklist_block_db(LUser, LServer, Filter,
|
||||
mnesia) ->
|
||||
F = fun () ->
|
||||
case mnesia:wread({privacy, {LUser, LServer}}) of
|
||||
[] ->
|
||||
@ -185,8 +189,8 @@ process_blocklist_block(LUser, LServer, Filter,
|
||||
{ok, NewDefault, NewList}
|
||||
end,
|
||||
mnesia:transaction(F);
|
||||
process_blocklist_block(LUser, LServer, Filter,
|
||||
riak) ->
|
||||
process_blocklist_block_db(LUser, LServer, Filter,
|
||||
riak) ->
|
||||
{atomic,
|
||||
begin
|
||||
case ejabberd_riak:get(privacy, mod_privacy:privacy_schema(),
|
||||
@ -218,7 +222,7 @@ process_blocklist_block(LUser, LServer, Filter,
|
||||
Err
|
||||
end
|
||||
end};
|
||||
process_blocklist_block(LUser, LServer, Filter, odbc) ->
|
||||
process_blocklist_block_db(LUser, LServer, Filter, odbc) ->
|
||||
F = fun () ->
|
||||
Default = case
|
||||
mod_privacy:sql_get_default_privacy_list_t(LUser)
|
||||
@ -246,7 +250,7 @@ process_blocklist_block(LUser, LServer, Filter, odbc) ->
|
||||
end,
|
||||
ejabberd_odbc:sql_transaction(LServer, F).
|
||||
|
||||
process_blocklist_unblock_all(LUser, LServer) ->
|
||||
process_blocklist_unblock_all(LUser, LServer, Lang) ->
|
||||
Filter = fun (List) ->
|
||||
lists:filter(fun (#listitem{action = A}) -> A =/= deny
|
||||
end,
|
||||
@ -263,10 +267,10 @@ process_blocklist_unblock_all(LUser, LServer) ->
|
||||
{result, [], UserList};
|
||||
_Err ->
|
||||
?ERROR_MSG("Error processing ~p: ~p", [{LUser, LServer}, _Err]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
|
||||
end.
|
||||
|
||||
process_blocklist_unblock(LUser, LServer, JIDs) ->
|
||||
process_blocklist_unblock(LUser, LServer, JIDs, Lang) ->
|
||||
Filter = fun (List) ->
|
||||
lists:filter(fun (#listitem{action = deny, type = jid,
|
||||
value = JID}) ->
|
||||
@ -287,7 +291,7 @@ process_blocklist_unblock(LUser, LServer, JIDs) ->
|
||||
{result, [], UserList};
|
||||
_Err ->
|
||||
?ERROR_MSG("Error processing ~p: ~p", [{LUser, LServer, JIDs}, _Err]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
|
||||
end.
|
||||
|
||||
unblock_by_filter(LUser, LServer, Filter, mnesia) ->
|
||||
@ -375,11 +379,12 @@ broadcast_blocklist_event(LUser, LServer, Event) ->
|
||||
ejabberd_sm:route(JID, JID,
|
||||
{broadcast, {blocking, Event}}).
|
||||
|
||||
process_blocklist_get(LUser, LServer) ->
|
||||
case process_blocklist_get(LUser, LServer,
|
||||
gen_mod:db_type(LServer, mod_privacy))
|
||||
process_blocklist_get(LUser, LServer, Lang) ->
|
||||
case process_blocklist_get_db(LUser, LServer,
|
||||
gen_mod:db_type(LServer, mod_privacy))
|
||||
of
|
||||
error -> {error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
error ->
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
|
||||
List ->
|
||||
JIDs = list_to_blocklist_jids(List, []),
|
||||
Items = lists:map(fun (JID) ->
|
||||
@ -397,7 +402,7 @@ process_blocklist_get(LUser, LServer) ->
|
||||
children = Items}]}
|
||||
end.
|
||||
|
||||
process_blocklist_get(LUser, LServer, mnesia) ->
|
||||
process_blocklist_get_db(LUser, LServer, mnesia) ->
|
||||
case catch mnesia:dirty_read(privacy, {LUser, LServer})
|
||||
of
|
||||
{'EXIT', _Reason} -> error;
|
||||
@ -408,7 +413,7 @@ process_blocklist_get(LUser, LServer, mnesia) ->
|
||||
_ -> []
|
||||
end
|
||||
end;
|
||||
process_blocklist_get(LUser, LServer, riak) ->
|
||||
process_blocklist_get_db(LUser, LServer, riak) ->
|
||||
case ejabberd_riak:get(privacy, mod_privacy:privacy_schema(),
|
||||
{LUser, LServer}) of
|
||||
{ok, #privacy{default = Default, lists = Lists}} ->
|
||||
@ -421,7 +426,7 @@ process_blocklist_get(LUser, LServer, riak) ->
|
||||
{error, _} ->
|
||||
error
|
||||
end;
|
||||
process_blocklist_get(LUser, LServer, odbc) ->
|
||||
process_blocklist_get_db(LUser, LServer, odbc) ->
|
||||
case catch
|
||||
mod_privacy:sql_get_default_privacy_list(LUser, LServer)
|
||||
of
|
||||
|
@ -102,7 +102,9 @@ iq_handler2(From, To, IQ) ->
|
||||
iq_handler1(From, To, IQ) ->
|
||||
iq_handler(From, To, IQ, ?NS_CARBONS_1).
|
||||
|
||||
iq_handler(From, _To, #iq{type=set, sub_el = #xmlel{name = Operation, children = []}} = IQ, CC)->
|
||||
iq_handler(From, _To,
|
||||
#iq{type=set, lang = Lang,
|
||||
sub_el = #xmlel{name = Operation} = SubEl} = IQ, CC)->
|
||||
?DEBUG("carbons IQ received: ~p", [IQ]),
|
||||
{U, S, R} = jid:tolower(From),
|
||||
Result = case Operation of
|
||||
@ -118,12 +120,14 @@ iq_handler(From, _To, #iq{type=set, sub_el = #xmlel{name = Operation, children
|
||||
?DEBUG("carbons IQ result: ok", []),
|
||||
IQ#iq{type=result, sub_el=[]};
|
||||
{error,_Error} ->
|
||||
?WARNING_MSG("Error enabling / disabling carbons: ~p", [Result]),
|
||||
IQ#iq{type=error,sub_el = [?ERR_BAD_REQUEST]}
|
||||
?ERROR_MSG("Error enabling / disabling carbons: ~p", [Result]),
|
||||
Txt = <<"Database failure">>,
|
||||
IQ#iq{type=error,sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}
|
||||
end;
|
||||
|
||||
iq_handler(_From, _To, IQ, _CC)->
|
||||
IQ#iq{type=error, sub_el = [?ERR_NOT_ALLOWED]}.
|
||||
iq_handler(_From, _To, #iq{lang = Lang, sub_el = SubEl} = IQ, _CC)->
|
||||
Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type=error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}.
|
||||
|
||||
user_send_packet(Packet, _C2SState, From, To) ->
|
||||
check_and_forward(From, To, Packet, sent).
|
||||
|
@ -198,81 +198,81 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
|
||||
|
||||
%%%-----------------------------------------------------------------------
|
||||
|
||||
-define(INFO_RESULT(Allow, Feats),
|
||||
-define(INFO_RESULT(Allow, Feats, Lang),
|
||||
case Allow of
|
||||
deny -> {error, ?ERR_FORBIDDEN};
|
||||
deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
allow -> {result, Feats}
|
||||
end).
|
||||
|
||||
get_sm_features(Acc, From,
|
||||
#jid{lserver = LServer} = _To, Node, _Lang) ->
|
||||
#jid{lserver = LServer} = _To, Node, Lang) ->
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false -> Acc;
|
||||
_ ->
|
||||
Allow = acl:match_rule(LServer, configure, From),
|
||||
case Node of
|
||||
<<"config">> -> ?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
<<"config">> -> ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
_ -> Acc
|
||||
end
|
||||
end.
|
||||
|
||||
get_local_features(Acc, From,
|
||||
#jid{lserver = LServer} = _To, Node, _Lang) ->
|
||||
#jid{lserver = LServer} = _To, Node, Lang) ->
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false -> Acc;
|
||||
_ ->
|
||||
LNode = tokenize(Node),
|
||||
Allow = acl:match_rule(LServer, configure, From),
|
||||
case LNode of
|
||||
[<<"config">>] -> ?INFO_RESULT(Allow, []);
|
||||
[<<"user">>] -> ?INFO_RESULT(Allow, []);
|
||||
[<<"online users">>] -> ?INFO_RESULT(Allow, []);
|
||||
[<<"all users">>] -> ?INFO_RESULT(Allow, []);
|
||||
[<<"config">>] -> ?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"user">>] -> ?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"online users">>] -> ?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"all users">>] -> ?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"all users">>, <<$@, _/binary>>] ->
|
||||
?INFO_RESULT(Allow, []);
|
||||
[<<"outgoing s2s">> | _] -> ?INFO_RESULT(Allow, []);
|
||||
[<<"running nodes">>] -> ?INFO_RESULT(Allow, []);
|
||||
[<<"stopped nodes">>] -> ?INFO_RESULT(Allow, []);
|
||||
?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"outgoing s2s">> | _] -> ?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"running nodes">>] -> ?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"stopped nodes">>] -> ?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"running nodes">>, _ENode] ->
|
||||
?INFO_RESULT(Allow, [?NS_STATS]);
|
||||
?INFO_RESULT(Allow, [?NS_STATS], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"DB">>] ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"modules">>] ->
|
||||
?INFO_RESULT(Allow, []);
|
||||
?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"modules">>, _] ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"backup">>] ->
|
||||
?INFO_RESULT(Allow, []);
|
||||
?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"backup">>, _] ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"import">>] ->
|
||||
?INFO_RESULT(Allow, []);
|
||||
?INFO_RESULT(Allow, [], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"import">>, _] ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"restart">>] ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
[<<"running nodes">>, _ENode, <<"shutdown">>] ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
[<<"config">>, _] ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"add-user">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"delete-user">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"end-user-session">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"get-user-password">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"change-user-password">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"get-user-lastlogin">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"user-stats">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"get-registered-users-num">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
?NS_ADMINL(<<"get-online-users-num">>) ->
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS]);
|
||||
?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
|
||||
_ -> Acc
|
||||
end
|
||||
end.
|
||||
@ -318,7 +318,8 @@ get_sm_items(Acc, From,
|
||||
{result,
|
||||
Items ++ Nodes ++ get_user_resources(User, Server)};
|
||||
{allow, <<"config">>} -> {result, []};
|
||||
{_, <<"config">>} -> {error, ?ERR_FORBIDDEN};
|
||||
{_, <<"config">>} ->
|
||||
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
_ -> Acc
|
||||
end
|
||||
end.
|
||||
@ -448,63 +449,64 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To,
|
||||
_ ->
|
||||
LNode = tokenize(Node),
|
||||
Allow = acl:match_rule(LServer, configure, From),
|
||||
Err = ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>),
|
||||
case LNode of
|
||||
[<<"config">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"user">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"online users">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"all users">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"all users">>, <<$@, _/binary>>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"outgoing s2s">> | _] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"stopped nodes">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"DB">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"modules">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"modules">>, _] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"backup">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"backup">>, _] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"import">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"import">>, _] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"restart">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"running nodes">>, _ENode, <<"shutdown">>] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
[<<"config">>, _] ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"add-user">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"delete-user">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"end-user-session">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"get-user-password">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"change-user-password">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"get-user-lastlogin">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"user-stats">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"get-registered-users-num">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
?NS_ADMINL(<<"get-online-users-num">>) ->
|
||||
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
|
||||
?ITEMS_RESULT(Allow, LNode, {error, Err});
|
||||
_ -> Acc
|
||||
end
|
||||
end.
|
||||
@ -562,33 +564,29 @@ get_local_items({_, Host}, [<<"all users">>], _Server,
|
||||
get_local_items({_, Host},
|
||||
[<<"all users">>, <<$@, Diap/binary>>], _Server,
|
||||
_Lang) ->
|
||||
case catch ejabberd_auth:get_vh_registered_users(Host)
|
||||
of
|
||||
{'EXIT', _Reason} -> ?ERR_INTERNAL_SERVER_ERROR;
|
||||
Users ->
|
||||
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
||||
case catch begin
|
||||
[S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
|
||||
N1 = jlib:binary_to_integer(S1),
|
||||
N2 = jlib:binary_to_integer(S2),
|
||||
Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
|
||||
lists:map(fun ({S, U}) ->
|
||||
#xmlel{name = <<"item">>,
|
||||
attrs =
|
||||
[{<<"jid">>,
|
||||
<<U/binary, "@",
|
||||
S/binary>>},
|
||||
{<<"name">>,
|
||||
<<U/binary, "@",
|
||||
S/binary>>}],
|
||||
children = []}
|
||||
end,
|
||||
Sub)
|
||||
end
|
||||
of
|
||||
{'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE;
|
||||
Res -> {result, Res}
|
||||
end
|
||||
Users = ejabberd_auth:get_vh_registered_users(Host),
|
||||
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
||||
case catch begin
|
||||
[S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
|
||||
N1 = jlib:binary_to_integer(S1),
|
||||
N2 = jlib:binary_to_integer(S2),
|
||||
Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
|
||||
lists:map(fun ({S, U}) ->
|
||||
#xmlel{name = <<"item">>,
|
||||
attrs =
|
||||
[{<<"jid">>,
|
||||
<<U/binary, "@",
|
||||
S/binary>>},
|
||||
{<<"name">>,
|
||||
<<U/binary, "@",
|
||||
S/binary>>}],
|
||||
children = []}
|
||||
end,
|
||||
Sub)
|
||||
end
|
||||
of
|
||||
{'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE;
|
||||
Res -> {result, Res}
|
||||
end;
|
||||
get_local_items({_, Host}, [<<"outgoing s2s">>],
|
||||
_Server, Lang) ->
|
||||
@ -826,33 +824,33 @@ get_stopped_nodes(_Lang) ->
|
||||
%%-------------------------------------------------------------------------
|
||||
|
||||
-define(COMMANDS_RESULT(LServerOrGlobal, From, To,
|
||||
Request),
|
||||
Request, Lang),
|
||||
case acl:match_rule(LServerOrGlobal, configure, From) of
|
||||
deny -> {error, ?ERR_FORBIDDEN};
|
||||
deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
allow -> adhoc_local_commands(From, To, Request)
|
||||
end).
|
||||
|
||||
adhoc_local_commands(Acc, From,
|
||||
#jid{lserver = LServer} = To,
|
||||
#adhoc_request{node = Node} = Request) ->
|
||||
#adhoc_request{node = Node, lang = Lang} = Request) ->
|
||||
LNode = tokenize(Node),
|
||||
case LNode of
|
||||
[<<"running nodes">>, _ENode, <<"DB">>] ->
|
||||
?COMMANDS_RESULT(global, From, To, Request);
|
||||
?COMMANDS_RESULT(global, From, To, Request, Lang);
|
||||
[<<"running nodes">>, _ENode, <<"modules">>, _] ->
|
||||
?COMMANDS_RESULT(LServer, From, To, Request);
|
||||
?COMMANDS_RESULT(LServer, From, To, Request, Lang);
|
||||
[<<"running nodes">>, _ENode, <<"backup">>, _] ->
|
||||
?COMMANDS_RESULT(global, From, To, Request);
|
||||
?COMMANDS_RESULT(global, From, To, Request, Lang);
|
||||
[<<"running nodes">>, _ENode, <<"import">>, _] ->
|
||||
?COMMANDS_RESULT(global, From, To, Request);
|
||||
?COMMANDS_RESULT(global, From, To, Request, Lang);
|
||||
[<<"running nodes">>, _ENode, <<"restart">>] ->
|
||||
?COMMANDS_RESULT(global, From, To, Request);
|
||||
?COMMANDS_RESULT(global, From, To, Request, Lang);
|
||||
[<<"running nodes">>, _ENode, <<"shutdown">>] ->
|
||||
?COMMANDS_RESULT(global, From, To, Request);
|
||||
?COMMANDS_RESULT(global, From, To, Request, Lang);
|
||||
[<<"config">>, _] ->
|
||||
?COMMANDS_RESULT(LServer, From, To, Request);
|
||||
?COMMANDS_RESULT(LServer, From, To, Request, Lang);
|
||||
?NS_ADMINL(_) ->
|
||||
?COMMANDS_RESULT(LServer, From, To, Request);
|
||||
?COMMANDS_RESULT(LServer, From, To, Request, Lang);
|
||||
_ -> Acc
|
||||
end.
|
||||
|
||||
@ -882,7 +880,8 @@ adhoc_local_commands(From,
|
||||
end;
|
||||
XData /= false, ActionIsExecute ->
|
||||
case jlib:parse_xdata_submit(XData) of
|
||||
invalid -> {error, ?ERR_BAD_REQUEST};
|
||||
invalid ->
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
|
||||
Fields ->
|
||||
case catch set_form(From, LServer, LNode, Lang, Fields)
|
||||
of
|
||||
@ -898,7 +897,8 @@ adhoc_local_commands(From,
|
||||
{error, Error} -> {error, Error}
|
||||
end
|
||||
end;
|
||||
true -> {error, ?ERR_BAD_REQUEST}
|
||||
true ->
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect action or data form">>)}
|
||||
end.
|
||||
|
||||
-define(TVFIELD(Type, Var, Val),
|
||||
@ -980,10 +980,14 @@ adhoc_local_commands(From,
|
||||
get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>],
|
||||
Lang) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
|
||||
{badrpc, _Reason} ->
|
||||
{badrpc, Reason} ->
|
||||
?ERROR_MSG("RPC call mnesia:system_info(tables) on node "
|
||||
"~s failed: ~p", [Node, Reason]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
Tables ->
|
||||
STables = lists:sort(Tables),
|
||||
@ -1023,10 +1027,14 @@ get_form(Host,
|
||||
[<<"running nodes">>, ENode, <<"modules">>, <<"stop">>],
|
||||
Lang) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
case ejabberd_cluster:call(Node, gen_mod, loaded_modules, [Host]) of
|
||||
{badrpc, _Reason} ->
|
||||
{badrpc, Reason} ->
|
||||
?ERROR_MSG("RPC call gen_mod:loaded_modules(~s) on node "
|
||||
"~s failed: ~p", [Host, Node, Reason]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
Modules ->
|
||||
SModules = lists:sort(Modules),
|
||||
@ -1562,9 +1570,11 @@ get_form(_Host, _, _Lang) ->
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
||||
|
||||
set_form(_From, _Host,
|
||||
[<<"running nodes">>, ENode, <<"DB">>], _Lang, XData) ->
|
||||
[<<"running nodes">>, ENode, <<"DB">>], Lang, XData) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
lists:foreach(fun ({SVar, SVals}) ->
|
||||
Table = jlib:binary_to_atom(SVar),
|
||||
@ -1596,9 +1606,11 @@ set_form(_From, _Host,
|
||||
end;
|
||||
set_form(_From, Host,
|
||||
[<<"running nodes">>, ENode, <<"modules">>, <<"stop">>],
|
||||
_Lang, XData) ->
|
||||
Lang, XData) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
lists:foreach(fun ({Var, Vals}) ->
|
||||
case Vals of
|
||||
@ -1615,12 +1627,16 @@ set_form(_From, Host,
|
||||
set_form(_From, Host,
|
||||
[<<"running nodes">>, ENode, <<"modules">>,
|
||||
<<"start">>],
|
||||
_Lang, XData) ->
|
||||
Lang, XData) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
case lists:keysearch(<<"modules">>, 1, XData) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'modules' found in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{value, {_, Strings}} ->
|
||||
String = lists:foldl(fun (S, Res) ->
|
||||
<<Res/binary, S/binary, "\n">>
|
||||
@ -1637,98 +1653,143 @@ set_form(_From, Host,
|
||||
end,
|
||||
Modules),
|
||||
{result, []};
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
|
||||
end
|
||||
end
|
||||
end;
|
||||
set_form(_From, _Host,
|
||||
[<<"running nodes">>, ENode, <<"backup">>,
|
||||
<<"backup">>],
|
||||
_Lang, XData) ->
|
||||
Lang, XData) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
case lists:keysearch(<<"path">>, 1, XData) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'path' found in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{value, {_, [String]}} ->
|
||||
case ejabberd_cluster:call(Node, mnesia, backup, [String]) of
|
||||
{badrpc, _Reason} ->
|
||||
{badrpc, Reason} ->
|
||||
?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
|
||||
"failed: ~p", [String, Node, Reason]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
|
||||
"failed: ~p", [String, Node, Reason]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
_ -> {result, []}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Incorrect value of 'path' in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end
|
||||
end;
|
||||
set_form(_From, _Host,
|
||||
[<<"running nodes">>, ENode, <<"backup">>,
|
||||
<<"restore">>],
|
||||
_Lang, XData) ->
|
||||
Lang, XData) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
case lists:keysearch(<<"path">>, 1, XData) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'path' found in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{value, {_, [String]}} ->
|
||||
case ejabberd_cluster:call(Node, ejabberd_admin, restore, [String])
|
||||
of
|
||||
{badrpc, _Reason} ->
|
||||
{badrpc, Reason} ->
|
||||
?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
|
||||
"~s failed: ~p", [String, Node, Reason]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
|
||||
"~s failed: ~p", [String, Node, Reason]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
_ -> {result, []}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Incorrect value of 'path' in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end
|
||||
end;
|
||||
set_form(_From, _Host,
|
||||
[<<"running nodes">>, ENode, <<"backup">>,
|
||||
<<"textfile">>],
|
||||
_Lang, XData) ->
|
||||
Lang, XData) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
case lists:keysearch(<<"path">>, 1, XData) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'path' found in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{value, {_, [String]}} ->
|
||||
case ejabberd_cluster:call(Node, ejabberd_admin, dump_to_textfile,
|
||||
[String])
|
||||
of
|
||||
{badrpc, _Reason} ->
|
||||
{badrpc, Reason} ->
|
||||
?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
|
||||
"to node ~s failed: ~p", [String, Node, Reason]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
|
||||
"to node ~s failed: ~p", [String, Node, Reason]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
_ -> {result, []}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Incorrect value of 'path' in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end
|
||||
end;
|
||||
set_form(_From, _Host,
|
||||
[<<"running nodes">>, ENode, <<"import">>, <<"file">>],
|
||||
_Lang, XData) ->
|
||||
Lang, XData) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
case lists:keysearch(<<"path">>, 1, XData) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'path' found in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{value, {_, [String]}} ->
|
||||
ejabberd_cluster:call(Node, jd2ejd, import_file, [String]),
|
||||
{result, []};
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Incorrect value of 'path' in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end
|
||||
end;
|
||||
set_form(_From, _Host,
|
||||
[<<"running nodes">>, ENode, <<"import">>, <<"dir">>],
|
||||
_Lang, XData) ->
|
||||
Lang, XData) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
case lists:keysearch(<<"path">>, 1, XData) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'path' found in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{value, {_, [String]}} ->
|
||||
ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]),
|
||||
{result, []};
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Incorrect value of 'path' in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end
|
||||
end;
|
||||
set_form(From, Host,
|
||||
@ -1739,7 +1800,7 @@ set_form(From, Host,
|
||||
[<<"running nodes">>, ENode, <<"shutdown">>], _Lang,
|
||||
XData) ->
|
||||
stop_node(From, Host, ENode, stop, XData);
|
||||
set_form(_From, Host, [<<"config">>, <<"acls">>], _Lang,
|
||||
set_form(_From, Host, [<<"config">>, <<"acls">>], Lang,
|
||||
XData) ->
|
||||
case lists:keysearch(<<"acls">>, 1, XData) of
|
||||
{value, {_, Strings}} ->
|
||||
@ -1753,14 +1814,16 @@ set_form(_From, Host, [<<"config">>, <<"acls">>], _Lang,
|
||||
{ok, ACLs} ->
|
||||
acl:add_list(Host, ACLs, true),
|
||||
{result, []};
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"No 'acls' found in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end;
|
||||
set_form(_From, Host, [<<"config">>, <<"access">>],
|
||||
_Lang, XData) ->
|
||||
Lang, XData) ->
|
||||
SetAccess = fun (Rs) ->
|
||||
mnesia:transaction(fun () ->
|
||||
Os = mnesia:select(local_config,
|
||||
@ -1803,11 +1866,13 @@ set_form(_From, Host, [<<"config">>, <<"access">>],
|
||||
{atomic, _} -> {result, []};
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"No 'access' found in data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end;
|
||||
set_form(From, Host, ?NS_ADMINL(<<"add-user">>), _Lang,
|
||||
XData) ->
|
||||
@ -2052,7 +2117,7 @@ adhoc_sm_commands(_Acc, From,
|
||||
action = Action, xdata = XData} =
|
||||
Request) ->
|
||||
case acl:match_rule(LServer, configure, From) of
|
||||
deny -> {error, ?ERR_FORBIDDEN};
|
||||
deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
allow ->
|
||||
ActionIsExecute = lists:member(Action,
|
||||
[<<"">>, <<"execute">>,
|
||||
@ -2071,11 +2136,15 @@ adhoc_sm_commands(_Acc, From,
|
||||
end;
|
||||
XData /= false, ActionIsExecute ->
|
||||
case jlib:parse_xdata_submit(XData) of
|
||||
invalid -> {error, ?ERR_BAD_REQUEST};
|
||||
invalid ->
|
||||
Txt = <<"Incorrect data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
Fields ->
|
||||
set_sm_form(User, Server, <<"config">>, Request, Fields)
|
||||
end;
|
||||
true -> {error, ?ERR_BAD_REQUEST}
|
||||
true ->
|
||||
Txt = <<"Incorrect action or data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end
|
||||
end;
|
||||
adhoc_sm_commands(Acc, _From, _To, _Request) -> Acc.
|
||||
@ -2135,12 +2204,16 @@ set_sm_form(User, Server, <<"config">>,
|
||||
{value, {_, [Password]}} ->
|
||||
ejabberd_auth:set_password(User, Server, Password),
|
||||
adhoc:produce_response(Response);
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ ->
|
||||
Txt = <<"No 'password' found in data form">>,
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
|
||||
end;
|
||||
{value, {_, [<<"remove">>]}} ->
|
||||
catch ejabberd_auth:remove_user(User, Server),
|
||||
adhoc:produce_response(Response);
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ ->
|
||||
Txt = <<"Incorrect value of 'action' in data form">>,
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
|
||||
end;
|
||||
set_sm_form(_User, _Server, _Node, _Request, _Fields) ->
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
||||
|
@ -56,15 +56,17 @@ stop(Host) ->
|
||||
?NS_ECONFIGURE).
|
||||
|
||||
process_local_iq(From, To,
|
||||
#iq{type = Type, lang = _Lang, sub_el = SubEl} = IQ) ->
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case acl:match_rule(To#jid.lserver, configure, From) of
|
||||
deny ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Denied by ACL">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
allow ->
|
||||
case Type of
|
||||
set ->
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]};
|
||||
sub_el = [SubEl, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)]};
|
||||
%%case fxml:get_tag_attr_s("type", SubEl) of
|
||||
%% "cancel" ->
|
||||
%% IQ#iq{type = result,
|
||||
@ -98,7 +100,7 @@ process_local_iq(From, To,
|
||||
%% sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
|
||||
%%end;
|
||||
get ->
|
||||
case process_get(SubEl) of
|
||||
case process_get(SubEl, Lang) of
|
||||
{result, Res} -> IQ#iq{type = result, sub_el = [Res]};
|
||||
{error, Error} ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, Error]}
|
||||
@ -106,7 +108,7 @@ process_local_iq(From, To,
|
||||
end
|
||||
end.
|
||||
|
||||
process_get(#xmlel{name = <<"info">>}) ->
|
||||
process_get(#xmlel{name = <<"info">>}, _Lang) ->
|
||||
S2SConns = ejabberd_s2s:dirty_get_connections(),
|
||||
TConns = lists:usort([element(2, C) || C <- S2SConns]),
|
||||
Attrs = [{<<"registered-users">>,
|
||||
@ -130,7 +132,7 @@ process_get(#xmlel{name = <<"info">>}) ->
|
||||
attrs = [{<<"xmlns">>, ?NS_ECONFIGURE} | Attrs],
|
||||
children = []}};
|
||||
process_get(#xmlel{name = <<"welcome-message">>,
|
||||
attrs = Attrs}) ->
|
||||
attrs = Attrs}, _Lang) ->
|
||||
{Subj, Body} = ejabberd_config:get_option(
|
||||
welcome_message,
|
||||
fun({Subj, Body}) ->
|
||||
@ -146,7 +148,7 @@ process_get(#xmlel{name = <<"welcome-message">>,
|
||||
#xmlel{name = <<"body">>, attrs = [],
|
||||
children = [{xmlcdata, Body}]}]}};
|
||||
process_get(#xmlel{name = <<"registration-watchers">>,
|
||||
attrs = Attrs}) ->
|
||||
attrs = Attrs}, _Lang) ->
|
||||
SubEls = ejabberd_config:get_option(
|
||||
registration_watchers,
|
||||
fun(JIDs) when is_list(JIDs) ->
|
||||
@ -160,14 +162,14 @@ process_get(#xmlel{name = <<"registration-watchers">>,
|
||||
{result,
|
||||
#xmlel{name = <<"registration_watchers">>,
|
||||
attrs = Attrs, children = SubEls}};
|
||||
process_get(#xmlel{name = <<"acls">>, attrs = Attrs}) ->
|
||||
process_get(#xmlel{name = <<"acls">>, attrs = Attrs}, _Lang) ->
|
||||
Str = iolist_to_binary(io_lib:format("~p.",
|
||||
[ets:tab2list(acl)])),
|
||||
{result,
|
||||
#xmlel{name = <<"acls">>, attrs = Attrs,
|
||||
children = [{xmlcdata, Str}]}};
|
||||
process_get(#xmlel{name = <<"access">>,
|
||||
attrs = Attrs}) ->
|
||||
attrs = Attrs}, _Lang) ->
|
||||
Str = iolist_to_binary(io_lib:format("~p.",
|
||||
[ets:select(local_config,
|
||||
[{{local_config, {access, '$1'},
|
||||
@ -178,13 +180,14 @@ process_get(#xmlel{name = <<"access">>,
|
||||
{result,
|
||||
#xmlel{name = <<"access">>, attrs = Attrs,
|
||||
children = [{xmlcdata, Str}]}};
|
||||
process_get(#xmlel{name = <<"last">>, attrs = Attrs}) ->
|
||||
process_get(#xmlel{name = <<"last">>, attrs = Attrs}, Lang) ->
|
||||
case catch mnesia:dirty_select(last_activity,
|
||||
[{{last_activity, '_', '$1', '_'}, [],
|
||||
['$1']}])
|
||||
of
|
||||
{'EXIT', _Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
Txt = <<"Database failure">>,
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)};
|
||||
Vals ->
|
||||
TimeStamp = p1_time_compat:system_time(seconds),
|
||||
Str = list_to_binary(
|
||||
@ -196,7 +199,7 @@ process_get(#xmlel{name = <<"last">>, attrs = Attrs}) ->
|
||||
end;
|
||||
%%process_get({xmlelement, Name, Attrs, SubEls}) ->
|
||||
%% {result, };
|
||||
process_get(_) -> {error, ?ERR_BAD_REQUEST}.
|
||||
process_get(_, _) -> {error, ?ERR_BAD_REQUEST}.
|
||||
|
||||
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
|
||||
mod_opt_type(_) -> [iqdisc].
|
||||
|
@ -150,7 +150,8 @@ process_local_iq_items(From, To,
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
Node = fxml:get_tag_attr_s(<<"node">>, SubEl),
|
||||
Host = To#jid.lserver,
|
||||
@ -177,7 +178,8 @@ process_local_iq_info(From, To,
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
Host = To#jid.lserver,
|
||||
Node = fxml:get_tag_attr_s(<<"node">>, SubEl),
|
||||
@ -229,10 +231,12 @@ get_local_features(Acc, _From, To, <<>>, _Lang) ->
|
||||
ets:select(disco_features,
|
||||
[{{{'_', Host}}, [], ['$_']}])
|
||||
++ Feats};
|
||||
get_local_features(Acc, _From, _To, _Node, _Lang) ->
|
||||
get_local_features(Acc, _From, _To, _Node, Lang) ->
|
||||
case Acc of
|
||||
{result, _Features} -> Acc;
|
||||
empty -> {error, ?ERR_ITEM_NOT_FOUND}
|
||||
empty ->
|
||||
Txt = <<"No features available">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)}
|
||||
end.
|
||||
|
||||
features_to_xml(FeatureList) ->
|
||||
@ -271,8 +275,8 @@ get_local_services(Acc, _From, To, <<>>, _Lang) ->
|
||||
get_local_services({result, _} = Acc, _From, _To, _Node,
|
||||
_Lang) ->
|
||||
Acc;
|
||||
get_local_services(empty, _From, _To, _Node, _Lang) ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}.
|
||||
get_local_services(empty, _From, _To, _Node, Lang) ->
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, <<"No services available">>)}.
|
||||
|
||||
get_vh_services(Host) ->
|
||||
Hosts = lists:sort(fun (H1, H2) ->
|
||||
@ -300,7 +304,8 @@ process_sm_iq_items(From, To,
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
case is_presence_subscribed(From, To) of
|
||||
true ->
|
||||
@ -325,8 +330,9 @@ process_sm_iq_items(From, To,
|
||||
IQ#iq{type = error, sub_el = [SubEl, Error]}
|
||||
end;
|
||||
false ->
|
||||
Txt = <<"Not subscribed">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}
|
||||
sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -347,12 +353,14 @@ get_sm_items(Acc, From,
|
||||
get_sm_items({result, _} = Acc, _From, _To, _Node,
|
||||
_Lang) ->
|
||||
Acc;
|
||||
get_sm_items(empty, From, To, _Node, _Lang) ->
|
||||
get_sm_items(empty, From, To, _Node, Lang) ->
|
||||
#jid{luser = LFrom, lserver = LSFrom} = From,
|
||||
#jid{luser = LTo, lserver = LSTo} = To,
|
||||
case {LFrom, LSFrom} of
|
||||
{LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
_ -> {error, ?ERR_NOT_ALLOWED}
|
||||
_ ->
|
||||
Txt = <<"Query to another users is forbidden">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
|
||||
end.
|
||||
|
||||
is_presence_subscribed(#jid{luser = User, lserver = Server},
|
||||
@ -373,7 +381,8 @@ process_sm_iq_info(From, To,
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
case is_presence_subscribed(From, To) of
|
||||
true ->
|
||||
@ -405,8 +414,9 @@ process_sm_iq_info(From, To,
|
||||
IQ#iq{type = error, sub_el = [SubEl, Error]}
|
||||
end;
|
||||
false ->
|
||||
Txt = <<"Not subscribed">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}
|
||||
sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -423,12 +433,14 @@ get_sm_identity(Acc, _From,
|
||||
_ -> []
|
||||
end.
|
||||
|
||||
get_sm_features(empty, From, To, _Node, _Lang) ->
|
||||
get_sm_features(empty, From, To, _Node, Lang) ->
|
||||
#jid{luser = LFrom, lserver = LSFrom} = From,
|
||||
#jid{luser = LTo, lserver = LSTo} = To,
|
||||
case {LFrom, LSFrom} of
|
||||
{LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
_ -> {error, ?ERR_NOT_ALLOWED}
|
||||
_ ->
|
||||
Txt = <<"Query to another users is forbidden">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
|
||||
end;
|
||||
get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc.
|
||||
|
||||
|
@ -118,7 +118,10 @@ handle_cast(_Msg, State) -> {noreply, State}.
|
||||
handle_info({route, From, To, Packet}, State) ->
|
||||
Packet2 = case From#jid.user of
|
||||
<<"">> ->
|
||||
jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST);
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
Txt = <<"User part of JID in 'from' is empty">>,
|
||||
jlib:make_error_reply(
|
||||
Packet, ?ERRT_BAD_REQUEST(Lang, Txt));
|
||||
_ -> Packet
|
||||
end,
|
||||
do_client_version(disabled, To, From),
|
||||
|
@ -569,7 +569,8 @@ process_iq(From,
|
||||
deny ->
|
||||
?DEBUG("Denying HTTP upload slot request from ~s",
|
||||
[jid:to_string(From)]),
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
|
||||
Txt = <<"Denied by ACL">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
|
||||
end;
|
||||
process_iq(_From, #iq{sub_el = SubEl} = IQ, _State) ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
@ -601,7 +602,8 @@ parse_request(#xmlel{name = <<"request">>, attrs = Attrs} = Request, Lang) ->
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Text)}
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_BAD_REQUEST}
|
||||
Text = <<"No or invalid XML namespace">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Text)}
|
||||
end;
|
||||
parse_request(_El, _Lang) -> {error, ?ERR_BAD_REQUEST}.
|
||||
|
||||
@ -639,7 +641,7 @@ create_slot(#state{service_url = undefined,
|
||||
end;
|
||||
create_slot(#state{service_url = ServiceURL},
|
||||
#jid{luser = U, lserver = S} = JID, File, Size, ContentType,
|
||||
_Lang) ->
|
||||
Lang) ->
|
||||
Options = [{body_format, binary}, {full_result, false}],
|
||||
HttpOptions = [{timeout, ?SERVICE_REQUEST_TIMEOUT}],
|
||||
SizeStr = jlib:integer_to_binary(Size),
|
||||
@ -659,7 +661,8 @@ create_slot(#state{service_url = ServiceURL},
|
||||
Lines ->
|
||||
?ERROR_MSG("Can't parse data received for ~s from <~s>: ~p",
|
||||
[jid:to_string(JID), ServiceURL, Lines]),
|
||||
{error, ?ERR_SERVICE_UNAVAILABLE}
|
||||
Txt = <<"Failed to parse HTTP response">>,
|
||||
{error, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)}
|
||||
end;
|
||||
{ok, {402, _Body}} ->
|
||||
?INFO_MSG("Got status code 402 for ~s from <~s>",
|
||||
|
@ -304,8 +304,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
|
||||
Lang)}]},
|
||||
Res = jlib:iq_to_xml(ResIQ);
|
||||
_ ->
|
||||
Res = jlib:make_error_reply(Packet,
|
||||
?ERR_ITEM_NOT_FOUND)
|
||||
Txt = <<"Node not found">>,
|
||||
Res = jlib:make_error_reply(
|
||||
Packet, ?ERRT_ITEM_NOT_FOUND(Lang, Txt))
|
||||
end,
|
||||
ejabberd_router:route(To, From, Res);
|
||||
#iq{xmlns = ?NS_REGISTER} = IQ ->
|
||||
@ -319,7 +320,7 @@ do_route1(Host, ServerHost, From, To, Packet) ->
|
||||
attrs = [{<<"xmlns">>, XMLNS}],
|
||||
children = iq_get_vcard(Lang)}]},
|
||||
ejabberd_router:route(To, From, jlib:iq_to_xml(Res));
|
||||
#iq{type = set, xmlns = ?NS_COMMANDS, lang = _Lang,
|
||||
#iq{type = set, xmlns = ?NS_COMMANDS, lang = Lang,
|
||||
sub_el = SubEl} =
|
||||
IQ ->
|
||||
Request = adhoc:parse_request(IQ),
|
||||
@ -348,8 +349,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
|
||||
true -> ok
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_ITEM_NOT_FOUND),
|
||||
Txt = <<"Node not found">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
#iq{} = _IQ ->
|
||||
@ -407,12 +409,14 @@ do_route1(Host, ServerHost, From, To, Packet) ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
case str:tokens(ChanServ, <<"!">>) of
|
||||
[<<_, _/binary>> = Nick, <<_, _/binary>> = Server] ->
|
||||
case ets:lookup(irc_connection, {From, Server, Host}) of
|
||||
[] ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
Txt = <<"IRC connection not found">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
[R] ->
|
||||
Pid = R#irc_connection.pid,
|
||||
@ -421,7 +425,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
|
||||
Txt = <<"Failed to parse chanserv">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end
|
||||
end
|
||||
@ -532,8 +538,9 @@ process_irc_register(ServerHost, Host, From, _To,
|
||||
XDataEl = find_xdata_el(SubEl),
|
||||
case XDataEl of
|
||||
false ->
|
||||
Txt1 = <<"No data form found">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]};
|
||||
sub_el = [SubEl, ?ERRT_NOT_ACCEPTABLE(Lang, Txt1)]};
|
||||
#xmlel{attrs = Attrs} ->
|
||||
case fxml:get_attr_s(<<"type">>, Attrs) of
|
||||
<<"cancel">> ->
|
||||
@ -546,8 +553,9 @@ process_irc_register(ServerHost, Host, From, _To,
|
||||
XData = jlib:parse_xdata_submit(XDataEl),
|
||||
case XData of
|
||||
invalid ->
|
||||
Txt2 = <<"Incorrect data form">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_BAD_REQUEST]};
|
||||
sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt2)]};
|
||||
_ ->
|
||||
Node = str:tokens(fxml:get_tag_attr_s(<<"node">>,
|
||||
SubEl),
|
||||
@ -567,7 +575,9 @@ process_irc_register(ServerHost, Host, From, _To,
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
||||
Txt3 = <<"Incorrect value of 'type' attribute">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt3)]}
|
||||
end
|
||||
end;
|
||||
get ->
|
||||
@ -629,7 +639,9 @@ get_form(ServerHost, Host, From, [], Lang) ->
|
||||
#jid{user = User, server = Server} = From,
|
||||
DefaultEncoding = get_default_encoding(Host),
|
||||
Customs = case get_data(ServerHost, Host, From) of
|
||||
error -> {error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
error ->
|
||||
Txt1 = <<"Database failure">>,
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt1)};
|
||||
empty -> {User, []};
|
||||
Data -> get_username_and_connection_params(Data)
|
||||
end,
|
||||
@ -763,7 +775,7 @@ set_data(LServer, Host, From, Data, odbc) ->
|
||||
end,
|
||||
ejabberd_odbc:sql_transaction(LServer, F).
|
||||
|
||||
set_form(ServerHost, Host, From, [], _Lang, XData) ->
|
||||
set_form(ServerHost, Host, From, [], Lang, XData) ->
|
||||
case {lists:keysearch(<<"username">>, 1, XData),
|
||||
lists:keysearch(<<"connections_params">>, 1, XData)}
|
||||
of
|
||||
@ -781,11 +793,11 @@ set_form(ServerHost, Host, From, [], _Lang, XData) ->
|
||||
{connections_params, ConnectionsParams}])
|
||||
of
|
||||
{atomic, _} -> {result, []};
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Database failure">>)}
|
||||
end;
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Parse error">>)}
|
||||
end;
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Scan error">>)}
|
||||
end;
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
end;
|
||||
@ -909,7 +921,9 @@ adhoc_join(From, To,
|
||||
elements = [Form]});
|
||||
true ->
|
||||
case jlib:parse_xdata_submit(XData) of
|
||||
invalid -> {error, ?ERR_BAD_REQUEST};
|
||||
invalid ->
|
||||
Txt1 = <<"Incorrect data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt1)};
|
||||
Fields ->
|
||||
Channel = case lists:keysearch(<<"channel">>, 1, Fields)
|
||||
of
|
||||
@ -998,7 +1012,8 @@ adhoc_register(ServerHost, From, To,
|
||||
true ->
|
||||
case jlib:parse_xdata_submit(XData) of
|
||||
invalid ->
|
||||
Error = {error, ?ERR_BAD_REQUEST},
|
||||
Txt1 = <<"Incorrect data form">>,
|
||||
Error = {error, ?ERRT_BAD_REQUEST(Lang, Txt1)},
|
||||
Username = false,
|
||||
ConnectionsParams = false;
|
||||
Fields ->
|
||||
@ -1021,7 +1036,9 @@ adhoc_register(ServerHost, From, To,
|
||||
{atomic, _} ->
|
||||
adhoc:produce_response(Request,
|
||||
#adhoc_response{status = completed});
|
||||
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
_ ->
|
||||
Txt2 = <<"Database failure">>,
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt2)}
|
||||
end;
|
||||
true ->
|
||||
Form = generate_adhoc_register_form(Lang, Username,
|
||||
|
@ -86,10 +86,11 @@ stop(Host) ->
|
||||
%%%
|
||||
|
||||
process_local_iq(_From, _To,
|
||||
#iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
Sec = get_node_uptime(),
|
||||
IQ#iq{type = result,
|
||||
@ -123,10 +124,11 @@ now_to_seconds({MegaSecs, Secs, _MicroSecs}) ->
|
||||
%%%
|
||||
|
||||
process_sm_iq(From, To,
|
||||
#iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
User = To#jid.luser,
|
||||
Server = To#jid.lserver,
|
||||
@ -153,7 +155,8 @@ process_sm_iq(From, To,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
|
||||
end;
|
||||
true ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
|
||||
Txt = <<"Not subscribed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -193,16 +196,18 @@ get_last(LUser, LServer, odbc) ->
|
||||
Reason -> {error, {invalid_result, Reason}}
|
||||
end.
|
||||
|
||||
get_last_iq(IQ, SubEl, LUser, LServer) ->
|
||||
get_last_iq(#iq{lang = Lang} = IQ, SubEl, LUser, LServer) ->
|
||||
case ejabberd_sm:get_user_resources(LUser, LServer) of
|
||||
[] ->
|
||||
case get_last(LUser, LServer) of
|
||||
{error, _Reason} ->
|
||||
Txt = <<"Database failure">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
|
||||
sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]};
|
||||
not_found ->
|
||||
Txt = <<"No info about last activity found">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
|
||||
sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]};
|
||||
{ok, TimeStamp, Status} ->
|
||||
TimeStamp2 = p1_time_compat:system_time(seconds),
|
||||
Sec = TimeStamp2 - TimeStamp,
|
||||
|
@ -447,7 +447,7 @@ process_iq(LServer, #iq{sub_el = #xmlel{attrs = Attrs}} = IQ) ->
|
||||
% Preference setting (both v0.2 & v0.3)
|
||||
process_iq(#jid{luser = LUser, lserver = LServer},
|
||||
#jid{lserver = LServer},
|
||||
#iq{type = set, sub_el = #xmlel{name = <<"prefs">>} = SubEl} = IQ) ->
|
||||
#iq{type = set, lang = Lang, sub_el = #xmlel{name = <<"prefs">>} = SubEl} = IQ) ->
|
||||
try {case fxml:get_tag_attr_s(<<"default">>, SubEl) of
|
||||
<<"always">> -> always;
|
||||
<<"never">> -> never;
|
||||
@ -469,8 +469,9 @@ process_iq(#jid{luser = LUser, lserver = LServer},
|
||||
NewPrefs = prefs_el(Default, Always, Never, IQ#iq.xmlns),
|
||||
IQ#iq{type = result, sub_el = [NewPrefs]};
|
||||
_Err ->
|
||||
Txt = <<"Database failure">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
|
||||
sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}
|
||||
end
|
||||
catch _:_ ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
||||
|
@ -132,8 +132,9 @@ process_iq(From, To,
|
||||
{error, Err} ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, Err]}
|
||||
end;
|
||||
process_iq(_From, _To, #iq{sub_el = SubEl} = IQ) ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}.
|
||||
process_iq(_From, _To, #iq{sub_el = SubEl, lang = Lang} = IQ) ->
|
||||
Txt = <<"Unsupported MIX query">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% gen_server callbacks
|
||||
|
@ -1056,7 +1056,9 @@ iq_set_register_info(ServerHost, Host, From, Nick,
|
||||
ErrText = <<"That nickname is registered by another "
|
||||
"person">>,
|
||||
{error, ?ERRT_CONFLICT(Lang, ErrText)};
|
||||
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
_ ->
|
||||
Txt = <<"Database failure">>,
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)}
|
||||
end.
|
||||
|
||||
process_iq_register_set(ServerHost, Host, From, SubEl,
|
||||
@ -1073,7 +1075,9 @@ process_iq_register_set(ServerHost, Host, From, SubEl,
|
||||
{?NS_XDATA, <<"submit">>} ->
|
||||
XData = jlib:parse_xdata_submit(XEl),
|
||||
case XData of
|
||||
invalid -> {error, ?ERR_BAD_REQUEST};
|
||||
invalid ->
|
||||
Txt = <<"Incorrect data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
_ ->
|
||||
case lists:keysearch(<<"nick">>, 1, XData) of
|
||||
{value, {_, [Nick]}} when Nick /= <<"">> ->
|
||||
|
@ -252,7 +252,7 @@ normal_state({route, From, <<"">>,
|
||||
IsVoiceApprovement = is_voice_approvement(Els) and
|
||||
not is_visitor(From, StateData),
|
||||
if IsInvitation ->
|
||||
case catch check_invitation(From, Els, Lang, StateData)
|
||||
case catch check_invitation(From, Packet, Lang, StateData)
|
||||
of
|
||||
{error, Error} ->
|
||||
Err = jlib:make_error_reply(Packet, Error),
|
||||
@ -433,9 +433,11 @@ normal_state({route, From, <<"">>,
|
||||
process_iq_owner(From, Type, Lang, SubEl, StateData);
|
||||
?NS_DISCO_INFO ->
|
||||
case fxml:get_attr(<<"node">>, Attrs) of
|
||||
false -> process_iq_disco_info(From, Type, Lang, StateData);
|
||||
{value, _} -> {error, ?ERR_SERVICE_UNAVAILABLE}
|
||||
end;
|
||||
false -> process_iq_disco_info(From, Type, Lang, StateData);
|
||||
{value, _} ->
|
||||
Txt = <<"Disco info is not available for this node">>,
|
||||
{error, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)}
|
||||
end;
|
||||
?NS_DISCO_ITEMS ->
|
||||
process_iq_disco_items(From, Type, Lang, StateData);
|
||||
?NS_VCARD ->
|
||||
@ -817,8 +819,9 @@ handle_info({captcha_failed, From}, normal_state,
|
||||
of
|
||||
{ok, {Nick, Packet}} ->
|
||||
Robots = (?DICT):erase(From, StateData#state.robots),
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_NOT_AUTHORIZED),
|
||||
Txt = <<"The CAPTCHA verification has failed">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_NOT_AUTHORIZED(?MYLANG, Txt)),
|
||||
ejabberd_router:route % TODO: s/Nick/""/
|
||||
(jid:replace_resource(StateData#state.jid,
|
||||
Nick),
|
||||
@ -1807,6 +1810,22 @@ add_new_user(From, Nick,
|
||||
StateData#state.host, From, Nick),
|
||||
get_default_role(Affiliation, StateData)}
|
||||
of
|
||||
{false, _, _, _} when NUsers >= MaxUsers orelse NUsers >= MaxAdminUsers ->
|
||||
Txt = <<"Too many users in this conference">>,
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)),
|
||||
ejabberd_router:route % TODO: s/Nick/""/
|
||||
(jid:replace_resource(StateData#state.jid, Nick),
|
||||
From, Err),
|
||||
StateData;
|
||||
{false, _, _, _} when NConferences >= MaxConferences ->
|
||||
Txt = <<"You have joined too many conferences">>,
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)),
|
||||
ejabberd_router:route % TODO: s/Nick/""/
|
||||
(jid:replace_resource(StateData#state.jid, Nick),
|
||||
From, Err),
|
||||
StateData;
|
||||
{false, _, _, _} ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
@ -2555,14 +2574,18 @@ process_iq_admin(From, set, Lang, SubEl, StateData) ->
|
||||
process_admin_items_set(From, Items, Lang, StateData);
|
||||
process_iq_admin(From, get, Lang, SubEl, StateData) ->
|
||||
case fxml:get_subtag(SubEl, <<"item">>) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'item' element found">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
Item ->
|
||||
FAffiliation = get_affiliation(From, StateData),
|
||||
FRole = get_role(From, StateData),
|
||||
case fxml:get_tag_attr(<<"role">>, Item) of
|
||||
false ->
|
||||
case fxml:get_tag_attr(<<"affiliation">>, Item) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'affiliation' attribute found">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{value, StrAffiliation} ->
|
||||
case catch list_to_affiliation(StrAffiliation) of
|
||||
{'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
|
||||
@ -2583,7 +2606,9 @@ process_iq_admin(From, get, Lang, SubEl, StateData) ->
|
||||
end;
|
||||
{value, StrRole} ->
|
||||
case catch list_to_role(StrRole) of
|
||||
{'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
|
||||
{'EXIT', _} ->
|
||||
Txt = <<"Incorrect value of 'role' attribute">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
SRole ->
|
||||
if FRole == moderator ->
|
||||
Items = items_with_role(SRole, StateData),
|
||||
@ -2780,7 +2805,9 @@ find_changed_items(UJID, UAffiliation, URole,
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
|
||||
J -> {value, J}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt1 = <<"No 'nick' attribute found">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt1)}
|
||||
end
|
||||
end,
|
||||
case TJID of
|
||||
@ -2790,7 +2817,9 @@ find_changed_items(UJID, UAffiliation, URole,
|
||||
case fxml:get_attr(<<"role">>, Attrs) of
|
||||
false ->
|
||||
case fxml:get_attr(<<"affiliation">>, Attrs) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt2 = <<"No 'affiliation' attribute found">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt2)};
|
||||
{value, StrAffiliation} ->
|
||||
case catch list_to_affiliation(StrAffiliation) of
|
||||
{'EXIT', _} ->
|
||||
@ -2839,7 +2868,9 @@ find_changed_items(UJID, UAffiliation, URole,
|
||||
find_changed_items(UJID, UAffiliation, URole,
|
||||
Items, Lang, StateData,
|
||||
[MoreRes | Res]);
|
||||
false -> {error, ?ERR_NOT_ALLOWED}
|
||||
false ->
|
||||
Txt3 = <<"Changing role/affiliation is not allowed">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt3)}
|
||||
end
|
||||
end
|
||||
end;
|
||||
@ -2885,7 +2916,9 @@ find_changed_items(UJID, UAffiliation, URole,
|
||||
find_changed_items(UJID, UAffiliation, URole, Items,
|
||||
Lang, StateData,
|
||||
[MoreRes | Res]);
|
||||
_ -> {error, ?ERR_NOT_ALLOWED}
|
||||
_ ->
|
||||
Txt4 = <<"Changing role/affiliation is not allowed">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt4)}
|
||||
end
|
||||
end
|
||||
end;
|
||||
@ -3143,10 +3176,12 @@ process_iq_owner(From, set, Lang, SubEl, StateData) ->
|
||||
andalso
|
||||
is_password_settings_correct(XEl, StateData)
|
||||
of
|
||||
true -> set_config(XEl, StateData);
|
||||
true -> set_config(XEl, StateData, Lang);
|
||||
false -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Incorrect data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end;
|
||||
[#xmlel{name = <<"destroy">>} = SubEl1] ->
|
||||
?INFO_MSG("Destroyed MUC room ~s by the owner ~s",
|
||||
@ -3170,7 +3205,9 @@ process_iq_owner(From, get, Lang, SubEl, StateData) ->
|
||||
[] -> get_config(Lang, StateData, From);
|
||||
[Item] ->
|
||||
case fxml:get_tag_attr(<<"affiliation">>, Item) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false ->
|
||||
Txt = <<"No 'affiliation' attribute found">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
{value, StrAffiliation} ->
|
||||
case catch list_to_affiliation(StrAffiliation) of
|
||||
{'EXIT', _} ->
|
||||
@ -3642,10 +3679,10 @@ get_config(Lang, StateData, From) ->
|
||||
children = Res}],
|
||||
StateData}.
|
||||
|
||||
set_config(XEl, StateData) ->
|
||||
set_config(XEl, StateData, Lang) ->
|
||||
XData = jlib:parse_xdata_submit(XEl),
|
||||
case XData of
|
||||
invalid -> {error, ?ERR_BAD_REQUEST};
|
||||
invalid -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
|
||||
_ ->
|
||||
case set_xoption(XData, StateData#state.config) of
|
||||
#config{} = Config ->
|
||||
@ -3675,14 +3712,20 @@ set_config(XEl, StateData) ->
|
||||
<<"1">> -> set_xoption(Opts, Config#config{Opt = true});
|
||||
<<"true">> ->
|
||||
set_xoption(Opts, Config#config{Opt = true});
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Value of '~s' should be boolean">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}
|
||||
end).
|
||||
|
||||
-define(SET_NAT_XOPT(Opt, Val),
|
||||
case catch jlib:binary_to_integer(Val) of
|
||||
I when is_integer(I), I > 0 ->
|
||||
set_xoption(Opts, Config#config{Opt = I});
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Value of '~s' should be integer">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}
|
||||
end).
|
||||
|
||||
-define(SET_STRING_XOPT(Opt, Val),
|
||||
@ -3735,7 +3778,10 @@ set_xoption([{<<"allow_private_messages_from_visitors">>,
|
||||
<<"nobody">> ->
|
||||
?SET_STRING_XOPT(allow_private_messages_from_visitors,
|
||||
nobody);
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Value of 'allow_private_messages_from_visitors' "
|
||||
"should be anyone|moderators|nobody">>,
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
|
||||
end;
|
||||
set_xoption([{<<"muc#roomconfig_allowvisitorstatus">>,
|
||||
[Val]}
|
||||
@ -3803,7 +3849,10 @@ set_xoption([{<<"muc#roomconfig_presencebroadcast">>, Vals} | Opts],
|
||||
end
|
||||
end, {false, false, false}, Vals),
|
||||
case Roles of
|
||||
error -> {error, ?ERR_BAD_REQUEST};
|
||||
error ->
|
||||
Txt = <<"Value of 'muc#roomconfig_presencebroadcast' should "
|
||||
"be moderator|participant|visitor">>,
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
|
||||
{M, P, V} ->
|
||||
Res =
|
||||
if M -> [moderator]; true -> [] end ++
|
||||
@ -3831,7 +3880,10 @@ set_xoption([{<<"muc#roomconfig_whois">>, [Val]}
|
||||
<<"anyone">> ->
|
||||
?SET_BOOL_XOPT(anonymous,
|
||||
(iolist_to_binary(integer_to_list(0))));
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ ->
|
||||
Txt = <<"Value of 'muc#roomconfig_whois' should be "
|
||||
"moderators|anyone">>,
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
|
||||
end;
|
||||
set_xoption([{<<"muc#roomconfig_maxusers">>, [Val]}
|
||||
| Opts],
|
||||
@ -3854,8 +3906,10 @@ set_xoption([{<<"muc#roomconfig_captcha_whitelist">>,
|
||||
?SET_JIDMULTI_XOPT(captcha_whitelist, JIDs);
|
||||
set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config) ->
|
||||
set_xoption(Opts, Config);
|
||||
set_xoption([_ | _Opts], _Config) ->
|
||||
{error, ?ERR_BAD_REQUEST}.
|
||||
set_xoption([{Opt, _Vals} | _Opts], _Config) ->
|
||||
Txt = <<"Unknown option '~s'">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}.
|
||||
|
||||
change_config(Config, StateData) ->
|
||||
send_config_change_info(Config, StateData),
|
||||
@ -4128,8 +4182,9 @@ destroy_room(DEl, StateData) ->
|
||||
false -> ?FEATURE(Fiffalse)
|
||||
end).
|
||||
|
||||
process_iq_disco_info(_From, set, _Lang, _StateData) ->
|
||||
{error, ?ERR_NOT_ALLOWED};
|
||||
process_iq_disco_info(_From, set, Lang, _StateData) ->
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
|
||||
process_iq_disco_info(_From, get, Lang, StateData) ->
|
||||
Config = StateData#state.config,
|
||||
{result,
|
||||
@ -4199,9 +4254,10 @@ iq_disco_info_extras(Lang, StateData) ->
|
||||
<<"muc#roominfo_occupants">>,
|
||||
(iolist_to_binary(integer_to_list(Len))))]}].
|
||||
|
||||
process_iq_disco_items(_From, set, _Lang, _StateData) ->
|
||||
{error, ?ERR_NOT_ALLOWED};
|
||||
process_iq_disco_items(From, get, _Lang, StateData) ->
|
||||
process_iq_disco_items(_From, set, Lang, _StateData) ->
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
|
||||
process_iq_disco_items(From, get, Lang, StateData) ->
|
||||
case (StateData#state.config)#config.public_list of
|
||||
true ->
|
||||
{result, get_mucroom_disco_items(StateData), StateData};
|
||||
@ -4209,18 +4265,26 @@ process_iq_disco_items(From, get, _Lang, StateData) ->
|
||||
case is_occupant_or_admin(From, StateData) of
|
||||
true ->
|
||||
{result, get_mucroom_disco_items(StateData), StateData};
|
||||
_ -> {error, ?ERR_FORBIDDEN}
|
||||
_ ->
|
||||
Txt = <<"Only occupants or administrators can perform this query">>,
|
||||
{error, ?ERRT_FORBIDDEN(Lang, Txt)}
|
||||
end
|
||||
end.
|
||||
|
||||
process_iq_captcha(_From, get, _Lang, _SubEl,
|
||||
process_iq_captcha(_From, get, Lang, _SubEl,
|
||||
_StateData) ->
|
||||
{error, ?ERR_NOT_ALLOWED};
|
||||
process_iq_captcha(_From, set, _Lang, SubEl,
|
||||
Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
|
||||
process_iq_captcha(_From, set, Lang, SubEl,
|
||||
StateData) ->
|
||||
case ejabberd_captcha:process_reply(SubEl) of
|
||||
ok -> {result, [], StateData};
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
{error, malformed} ->
|
||||
Txt = <<"Incorrect CAPTCHA submit">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
_ ->
|
||||
Txt = <<"The CAPTCHA verification has failed">>,
|
||||
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
|
||||
end.
|
||||
|
||||
process_iq_vcard(_From, get, _Lang, _SubEl, StateData) ->
|
||||
@ -4442,33 +4506,38 @@ is_invitation(Els) ->
|
||||
end,
|
||||
false, Els).
|
||||
|
||||
check_invitation(From, Els, Lang, StateData) ->
|
||||
check_invitation(From, Packet, Lang, StateData) ->
|
||||
FAffiliation = get_affiliation(From, StateData),
|
||||
CanInvite =
|
||||
(StateData#state.config)#config.allow_user_invites
|
||||
orelse
|
||||
FAffiliation == admin orelse FAffiliation == owner,
|
||||
InviteEl = case fxml:remove_cdata(Els) of
|
||||
[#xmlel{name = <<"x">>, children = Els1} = XEl] ->
|
||||
case fxml:get_tag_attr_s(<<"xmlns">>, XEl) of
|
||||
?NS_MUC_USER -> ok;
|
||||
_ -> throw({error, ?ERR_BAD_REQUEST})
|
||||
end,
|
||||
case fxml:remove_cdata(Els1) of
|
||||
[#xmlel{name = <<"invite">>} = InviteEl1] -> InviteEl1;
|
||||
_ -> throw({error, ?ERR_BAD_REQUEST})
|
||||
end;
|
||||
_ -> throw({error, ?ERR_BAD_REQUEST})
|
||||
InviteEl = case fxml:get_subtag_with_xmlns(Packet, <<"x">>, ?NS_MUC_USER) of
|
||||
false ->
|
||||
Txt1 = <<"No 'x' element found">>,
|
||||
throw({error, ?ERRT_BAD_REQUEST(Lang, Txt1)});
|
||||
XEl ->
|
||||
case fxml:get_subtag(XEl, <<"invite">>) of
|
||||
false ->
|
||||
Txt2 = <<"No 'invite' element found">>,
|
||||
throw({error, ?ERRT_BAD_REQUEST(Lang, Txt2)});
|
||||
InviteEl1 ->
|
||||
InviteEl1
|
||||
end
|
||||
end,
|
||||
JID = case
|
||||
jid:from_string(fxml:get_tag_attr_s(<<"to">>,
|
||||
InviteEl))
|
||||
of
|
||||
error -> throw({error, ?ERR_JID_MALFORMED});
|
||||
error ->
|
||||
Txt = <<"Incorrect value of 'to' attribute">>,
|
||||
throw({error, ?ERRT_JID_MALFORMED(Lang, Txt)});
|
||||
JID1 -> JID1
|
||||
end,
|
||||
case CanInvite of
|
||||
false -> throw({error, ?ERR_NOT_ALLOWED});
|
||||
false ->
|
||||
Txt3 = <<"Invitations are not allowed in this conference">>,
|
||||
throw({error, ?ERRT_NOT_ALLOWED(Lang, Txt3)});
|
||||
true ->
|
||||
Reason = fxml:get_path_s(InviteEl,
|
||||
[{elem, <<"reason">>}, cdata]),
|
||||
|
@ -387,8 +387,9 @@ handle_offline_query(#jid{luser = U, lserver = S} = From,
|
||||
end
|
||||
end,
|
||||
IQ#iq{type = result, sub_el = []};
|
||||
handle_offline_query(_From, _To, #iq{sub_el = SubEl} = IQ) ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}.
|
||||
handle_offline_query(_From, _To, #iq{sub_el = SubEl, lang = Lang} = IQ) ->
|
||||
Txt = <<"Query to another users is forbidden">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}.
|
||||
|
||||
handle_offline_items_view(JID, #xmlel{children = Items}) ->
|
||||
{U, S, R} = jid:tolower(JID),
|
||||
|
@ -204,13 +204,14 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
||||
%% Hook callbacks
|
||||
%%====================================================================
|
||||
iq_ping(_From, _To,
|
||||
#iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
#iq{type = Type, sub_el = SubEl, lang = Lang} = IQ) ->
|
||||
case {Type, SubEl} of
|
||||
{get, #xmlel{name = <<"ping">>}} ->
|
||||
IQ#iq{type = result, sub_el = []};
|
||||
_ ->
|
||||
Txt = <<"Ping query is incorrect">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]}
|
||||
sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
|
||||
end.
|
||||
|
||||
user_online(_SID, JID, _Info) ->
|
||||
|
@ -105,27 +105,29 @@ process_iq(_From, _To, IQ) ->
|
||||
SubEl = IQ#iq.sub_el,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}.
|
||||
|
||||
process_iq_get(_, From, _To, #iq{sub_el = SubEl},
|
||||
process_iq_get(_, From, _To, #iq{lang = Lang, sub_el = SubEl},
|
||||
#userlist{name = Active}) ->
|
||||
#jid{luser = LUser, lserver = LServer} = From,
|
||||
#xmlel{children = Els} = SubEl,
|
||||
case fxml:remove_cdata(Els) of
|
||||
[] -> process_lists_get(LUser, LServer, Active);
|
||||
[] -> process_lists_get(LUser, LServer, Active, Lang);
|
||||
[#xmlel{name = Name, attrs = Attrs}] ->
|
||||
case Name of
|
||||
<<"list">> ->
|
||||
ListName = fxml:get_attr(<<"name">>, Attrs),
|
||||
process_list_get(LUser, LServer, ListName);
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
process_list_get(LUser, LServer, ListName, Lang);
|
||||
_ ->
|
||||
Txt = <<"Unsupported tag name">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
_ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Too many elements">>)}
|
||||
end.
|
||||
|
||||
process_lists_get(LUser, LServer, Active) ->
|
||||
case process_lists_get(LUser, LServer, Active,
|
||||
process_lists_get(LUser, LServer, Active, Lang) ->
|
||||
case process_lists_get_db(LUser, LServer, Active,
|
||||
gen_mod:db_type(LServer, ?MODULE))
|
||||
of
|
||||
error -> {error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
error -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
|
||||
{_Default, []} ->
|
||||
{result,
|
||||
[#xmlel{name = <<"query">>,
|
||||
@ -151,7 +153,7 @@ process_lists_get(LUser, LServer, Active) ->
|
||||
children = ADItems}]}
|
||||
end.
|
||||
|
||||
process_lists_get(LUser, LServer, _Active, mnesia) ->
|
||||
process_lists_get_db(LUser, LServer, _Active, mnesia) ->
|
||||
case catch mnesia:dirty_read(privacy, {LUser, LServer})
|
||||
of
|
||||
{'EXIT', _Reason} -> error;
|
||||
@ -165,7 +167,7 @@ process_lists_get(LUser, LServer, _Active, mnesia) ->
|
||||
Lists),
|
||||
{Default, LItems}
|
||||
end;
|
||||
process_lists_get(LUser, LServer, _Active, riak) ->
|
||||
process_lists_get_db(LUser, LServer, _Active, riak) ->
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, #privacy{default = Default, lists = Lists}} ->
|
||||
LItems = lists:map(fun ({N, _}) ->
|
||||
@ -180,7 +182,7 @@ process_lists_get(LUser, LServer, _Active, riak) ->
|
||||
{error, _} ->
|
||||
error
|
||||
end;
|
||||
process_lists_get(LUser, LServer, _Active, odbc) ->
|
||||
process_lists_get_db(LUser, LServer, _Active, odbc) ->
|
||||
Default = case catch sql_get_default_privacy_list(LUser, LServer) of
|
||||
{selected, []} -> none;
|
||||
{selected, [{DefName}]} -> DefName;
|
||||
@ -198,11 +200,11 @@ process_lists_get(LUser, LServer, _Active, odbc) ->
|
||||
_ -> error
|
||||
end.
|
||||
|
||||
process_list_get(LUser, LServer, {value, Name}) ->
|
||||
case process_list_get(LUser, LServer, Name,
|
||||
process_list_get(LUser, LServer, {value, Name}, Lang) ->
|
||||
case process_list_get_db(LUser, LServer, Name,
|
||||
gen_mod:db_type(LServer, ?MODULE))
|
||||
of
|
||||
error -> {error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
error -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
|
||||
not_found -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
Items ->
|
||||
LItems = lists:map(fun item_to_xml/1, Items),
|
||||
@ -213,10 +215,10 @@ process_list_get(LUser, LServer, {value, Name}) ->
|
||||
[#xmlel{name = <<"list">>, attrs = [{<<"name">>, Name}],
|
||||
children = LItems}]}]}
|
||||
end;
|
||||
process_list_get(_LUser, _LServer, false) ->
|
||||
process_list_get(_LUser, _LServer, false, _Lang) ->
|
||||
{error, ?ERR_BAD_REQUEST}.
|
||||
|
||||
process_list_get(LUser, LServer, Name, mnesia) ->
|
||||
process_list_get_db(LUser, LServer, Name, mnesia) ->
|
||||
case catch mnesia:dirty_read(privacy, {LUser, LServer})
|
||||
of
|
||||
{'EXIT', _Reason} -> error;
|
||||
@ -227,7 +229,7 @@ process_list_get(LUser, LServer, Name, mnesia) ->
|
||||
_ -> not_found
|
||||
end
|
||||
end;
|
||||
process_list_get(LUser, LServer, Name, riak) ->
|
||||
process_list_get_db(LUser, LServer, Name, riak) ->
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, #privacy{lists = Lists}} ->
|
||||
case lists:keysearch(Name, 1, Lists) of
|
||||
@ -239,7 +241,7 @@ process_list_get(LUser, LServer, Name, riak) ->
|
||||
{error, _} ->
|
||||
error
|
||||
end;
|
||||
process_list_get(LUser, LServer, Name, odbc) ->
|
||||
process_list_get_db(LUser, LServer, Name, odbc) ->
|
||||
case catch sql_get_privacy_list_id(LUser, LServer, Name) of
|
||||
{selected, []} -> not_found;
|
||||
{selected, [{ID}]} ->
|
||||
@ -332,7 +334,7 @@ list_to_action(S) ->
|
||||
<<"deny">> -> deny
|
||||
end.
|
||||
|
||||
process_iq_set(_, From, _To, #iq{sub_el = SubEl}) ->
|
||||
process_iq_set(_, From, _To, #iq{lang = Lang, sub_el = SubEl}) ->
|
||||
#jid{luser = LUser, lserver = LServer} = From,
|
||||
#xmlel{children = Els} = SubEl,
|
||||
case fxml:remove_cdata(Els) of
|
||||
@ -342,27 +344,30 @@ process_iq_set(_, From, _To, #iq{sub_el = SubEl}) ->
|
||||
case Name of
|
||||
<<"list">> ->
|
||||
process_list_set(LUser, LServer, ListName,
|
||||
fxml:remove_cdata(SubEls));
|
||||
fxml:remove_cdata(SubEls), Lang);
|
||||
<<"active">> ->
|
||||
process_active_set(LUser, LServer, ListName);
|
||||
<<"default">> ->
|
||||
process_default_set(LUser, LServer, ListName);
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
process_default_set(LUser, LServer, ListName, Lang);
|
||||
_ ->
|
||||
Txt = <<"Unsupported tag name">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end;
|
||||
_ -> {error, ?ERR_BAD_REQUEST}
|
||||
end.
|
||||
|
||||
process_default_set(LUser, LServer, Value) ->
|
||||
case process_default_set(LUser, LServer, Value,
|
||||
process_default_set(LUser, LServer, Value, Lang) ->
|
||||
case process_default_set_db(LUser, LServer, Value,
|
||||
gen_mod:db_type(LServer, ?MODULE))
|
||||
of
|
||||
{atomic, error} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{atomic, error} ->
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
|
||||
{atomic, not_found} -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
{atomic, ok} -> {result, []};
|
||||
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
end.
|
||||
|
||||
process_default_set(LUser, LServer, {value, Name},
|
||||
process_default_set_db(LUser, LServer, {value, Name},
|
||||
mnesia) ->
|
||||
F = fun () ->
|
||||
case mnesia:read({privacy, {LUser, LServer}}) of
|
||||
@ -378,7 +383,7 @@ process_default_set(LUser, LServer, {value, Name},
|
||||
end
|
||||
end,
|
||||
mnesia:transaction(F);
|
||||
process_default_set(LUser, LServer, {value, Name}, riak) ->
|
||||
process_default_set_db(LUser, LServer, {value, Name}, riak) ->
|
||||
{atomic,
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, #privacy{lists = Lists} = P} ->
|
||||
@ -393,7 +398,7 @@ process_default_set(LUser, LServer, {value, Name}, riak) ->
|
||||
{error, _} ->
|
||||
not_found
|
||||
end};
|
||||
process_default_set(LUser, LServer, {value, Name},
|
||||
process_default_set_db(LUser, LServer, {value, Name},
|
||||
odbc) ->
|
||||
F = fun () ->
|
||||
case sql_get_privacy_list_names_t(LUser) of
|
||||
@ -406,7 +411,7 @@ process_default_set(LUser, LServer, {value, Name},
|
||||
end
|
||||
end,
|
||||
odbc_queries:sql_transaction(LServer, F);
|
||||
process_default_set(LUser, LServer, false, mnesia) ->
|
||||
process_default_set_db(LUser, LServer, false, mnesia) ->
|
||||
F = fun () ->
|
||||
case mnesia:read({privacy, {LUser, LServer}}) of
|
||||
[] -> ok;
|
||||
@ -414,7 +419,7 @@ process_default_set(LUser, LServer, false, mnesia) ->
|
||||
end
|
||||
end,
|
||||
mnesia:transaction(F);
|
||||
process_default_set(LUser, LServer, false, riak) ->
|
||||
process_default_set_db(LUser, LServer, false, riak) ->
|
||||
{atomic,
|
||||
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
|
||||
{ok, R} ->
|
||||
@ -422,7 +427,7 @@ process_default_set(LUser, LServer, false, riak) ->
|
||||
{error, _} ->
|
||||
ok
|
||||
end};
|
||||
process_default_set(LUser, LServer, false, odbc) ->
|
||||
process_default_set_db(LUser, LServer, false, odbc) ->
|
||||
case catch sql_unset_default_privacy_list(LUser,
|
||||
LServer)
|
||||
of
|
||||
@ -588,14 +593,16 @@ set_privacy_list(LUser, LServer, Name, List, odbc) ->
|
||||
end,
|
||||
odbc_queries:sql_transaction(LServer, F).
|
||||
|
||||
process_list_set(LUser, LServer, {value, Name}, Els) ->
|
||||
process_list_set(LUser, LServer, {value, Name}, Els, Lang) ->
|
||||
case parse_items(Els) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
remove ->
|
||||
case remove_privacy_list(LUser, LServer, Name,
|
||||
gen_mod:db_type(LServer, ?MODULE))
|
||||
of
|
||||
{atomic, conflict} -> {error, ?ERR_CONFLICT};
|
||||
{atomic, conflict} ->
|
||||
Txt = <<"Cannot remove default list">>,
|
||||
{error, ?ERRT_CONFLICT(Lang, Txt)};
|
||||
{atomic, ok} ->
|
||||
ejabberd_sm:route(jid:make(LUser, LServer,
|
||||
<<"">>),
|
||||
@ -605,7 +612,7 @@ process_list_set(LUser, LServer, {value, Name}, Els) ->
|
||||
list = []},
|
||||
Name}}),
|
||||
{result, []};
|
||||
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
_ -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
|
||||
end;
|
||||
List ->
|
||||
case set_privacy_list(LUser, LServer, Name, List,
|
||||
@ -622,10 +629,10 @@ process_list_set(LUser, LServer, {value, Name}, Els) ->
|
||||
needdb = NeedDb},
|
||||
Name}}),
|
||||
{result, []};
|
||||
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
_ -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
|
||||
end
|
||||
end;
|
||||
process_list_set(_LUser, _LServer, false, _Els) ->
|
||||
process_list_set(_LUser, _LServer, false, _Els, _Lang) ->
|
||||
{error, ?ERR_BAD_REQUEST}.
|
||||
|
||||
parse_items([]) -> remove;
|
||||
|
@ -73,52 +73,58 @@ stop(Host) ->
|
||||
?NS_PRIVATE).
|
||||
|
||||
process_sm_iq(#jid{luser = LUser, lserver = LServer},
|
||||
#jid{luser = LUser, lserver = LServer}, IQ)
|
||||
#jid{luser = LUser, lserver = LServer}, #iq{lang = Lang} = IQ)
|
||||
when IQ#iq.type == set ->
|
||||
case IQ#iq.sub_el of
|
||||
#xmlel{name = <<"query">>, children = Xmlels} ->
|
||||
case filter_xmlels(Xmlels) of
|
||||
[] ->
|
||||
Txt = <<"No private data found in this query">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [IQ#iq.sub_el, ?ERR_NOT_ACCEPTABLE]};
|
||||
sub_el = [IQ#iq.sub_el, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)]};
|
||||
Data ->
|
||||
set_data(LUser, LServer, Data),
|
||||
IQ#iq{type = result, sub_el = []}
|
||||
end;
|
||||
_ ->
|
||||
Txt = <<"No query found">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [IQ#iq.sub_el, ?ERR_NOT_ACCEPTABLE]}
|
||||
sub_el = [IQ#iq.sub_el, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)]}
|
||||
end;
|
||||
%%
|
||||
process_sm_iq(#jid{luser = LUser, lserver = LServer},
|
||||
#jid{luser = LUser, lserver = LServer}, IQ)
|
||||
#jid{luser = LUser, lserver = LServer}, #iq{lang = Lang} = IQ)
|
||||
when IQ#iq.type == get ->
|
||||
case IQ#iq.sub_el of
|
||||
#xmlel{name = <<"query">>, attrs = Attrs,
|
||||
children = Xmlels} ->
|
||||
case filter_xmlels(Xmlels) of
|
||||
[] ->
|
||||
Txt = <<"No private data found in this query">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [IQ#iq.sub_el, ?ERR_BAD_FORMAT]};
|
||||
sub_el = [IQ#iq.sub_el, ?ERRT_BAD_FORMAT(Lang, Txt)]};
|
||||
Data ->
|
||||
case catch get_data(LUser, LServer, Data) of
|
||||
{'EXIT', _Reason} ->
|
||||
Txt = <<"Database failure">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el =
|
||||
[IQ#iq.sub_el, ?ERR_INTERNAL_SERVER_ERROR]};
|
||||
[IQ#iq.sub_el, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]};
|
||||
Storage_Xmlels ->
|
||||
IQ#iq{type = result,
|
||||
sub_el = [?Xmlel_Query(Attrs, Storage_Xmlels)]}
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
Txt = <<"No query found">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [IQ#iq.sub_el, ?ERR_BAD_FORMAT]}
|
||||
sub_el = [IQ#iq.sub_el, ?ERRT_BAD_FORMAT(Lang, Txt)]}
|
||||
end;
|
||||
%%
|
||||
process_sm_iq(_From, _To, IQ) ->
|
||||
process_sm_iq(_From, _To, #iq{lang = Lang} = IQ) ->
|
||||
Txt = <<"Query to another users is forbidden">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [IQ#iq.sub_el, ?ERR_FORBIDDEN]}.
|
||||
sub_el = [IQ#iq.sub_el, ?ERRT_FORBIDDEN(Lang, Txt)]}.
|
||||
|
||||
filter_xmlels(Xmlels) -> filter_xmlels(Xmlels, []).
|
||||
|
||||
|
@ -150,7 +150,7 @@ process_iq(_,
|
||||
children = iq_vcard(Lang)}]};
|
||||
%% bytestreams info request
|
||||
process_iq(JID,
|
||||
#iq{type = get, sub_el = SubEl,
|
||||
#iq{type = get, sub_el = SubEl, lang = Lang,
|
||||
xmlns = ?NS_BYTESTREAMS} =
|
||||
IQ,
|
||||
#state{acl = ACL, stream_addr = StreamAddr,
|
||||
@ -165,11 +165,12 @@ process_iq(JID,
|
||||
attrs = [{<<"xmlns">>, ?NS_BYTESTREAMS}],
|
||||
children = StreamHostEl}]};
|
||||
deny ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
|
||||
Txt = <<"Denied by ACL">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
|
||||
end;
|
||||
%% bytestream activation request
|
||||
process_iq(InitiatorJID,
|
||||
#iq{type = set, sub_el = SubEl,
|
||||
#iq{type = set, sub_el = SubEl, lang = Lang,
|
||||
xmlns = ?NS_BYTESTREAMS} =
|
||||
IQ,
|
||||
#state{acl = ACL, serverhost = ServerHost}) ->
|
||||
@ -194,22 +195,27 @@ process_iq(InitiatorJID,
|
||||
of
|
||||
ok -> IQ#iq{type = result, sub_el = []};
|
||||
false ->
|
||||
Txt = <<"Failed to activate bytestream">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]};
|
||||
sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]};
|
||||
limit ->
|
||||
Txt = <<"Too many active bytestreams">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_RESOURCE_CONSTRAINT]};
|
||||
sub_el = [SubEl, ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)]};
|
||||
conflict ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_CONFLICT]};
|
||||
Txt = <<"Bytestream already activated">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_CONFLICT(Lang, Txt)]};
|
||||
_ ->
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
|
||||
end;
|
||||
_ ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
||||
Txt = <<"Malformed JID">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
|
||||
end;
|
||||
deny ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
|
||||
Txt = <<"Denied by ACL">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
|
||||
end;
|
||||
%% Unknown "set" or "get" request
|
||||
process_iq(_, #iq{type = Type, sub_el = SubEl} = IQ, _)
|
||||
|
@ -1034,7 +1034,10 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
|
||||
none ->
|
||||
ok;
|
||||
invalid ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
|
||||
Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs),
|
||||
Txt = <<"Incorrect authorization response">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
XFields ->
|
||||
handle_authorization_response(Host, From, To, Packet, XFields)
|
||||
@ -1418,13 +1421,14 @@ adhoc_request(Host, _ServerHost, Owner,
|
||||
send_pending_node_form(Host, Owner, Lang, Plugins);
|
||||
adhoc_request(Host, _ServerHost, Owner,
|
||||
#adhoc_request{node = ?NS_PUBSUB_GET_PENDING,
|
||||
action = <<"execute">>, xdata = XData},
|
||||
action = <<"execute">>, xdata = XData, lang = Lang},
|
||||
_Access, _Plugins) ->
|
||||
ParseOptions = case XData of
|
||||
#xmlel{name = <<"x">>} = XEl ->
|
||||
case jlib:parse_xdata_submit(XEl) of
|
||||
invalid ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
Txt = <<"Incorrect data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
XData2 ->
|
||||
case set_xoption(Host, XData2, []) of
|
||||
NewOpts when is_list(NewOpts) -> {result, NewOpts};
|
||||
@ -1432,8 +1436,8 @@ adhoc_request(Host, _ServerHost, Owner,
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
?INFO_MSG("Bad XForm: ~p", [XData]),
|
||||
{error, ?ERR_BAD_REQUEST}
|
||||
Txt = <<"No data form found">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end,
|
||||
case ParseOptions of
|
||||
{result, XForm} ->
|
||||
@ -1463,7 +1467,9 @@ send_pending_node_form(Host, Owner, _Lang, Plugins) ->
|
||||
end,
|
||||
case lists:filter(Filter, Plugins) of
|
||||
[] ->
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED};
|
||||
Err = extended_error(?ERR_FEATURE_NOT_IMPLEMENTED,
|
||||
unsupported, <<"get-pending">>),
|
||||
{error, Err};
|
||||
Ps ->
|
||||
XOpts = [#xmlel{name = <<"option">>, attrs = [],
|
||||
children = [#xmlel{name = <<"value">>,
|
||||
@ -1504,10 +1510,11 @@ send_pending_auth_events(Host, Node, Owner) ->
|
||||
true ->
|
||||
case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of
|
||||
{result, owner} -> node_call(Host, Type, get_node_subscriptions, [Nidx]);
|
||||
_ -> {error, ?ERR_FORBIDDEN}
|
||||
_ -> {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
|
||||
end;
|
||||
false ->
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}
|
||||
{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED,
|
||||
unsupported, <<"get-pending">>)}
|
||||
end
|
||||
end,
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
@ -1644,6 +1651,7 @@ send_authorization_approval(Host, JID, SNode, Subscription) ->
|
||||
ejabberd_router:route(service_jid(Host), JID, Stanza).
|
||||
|
||||
handle_authorization_response(Host, From, To, Packet, XFields) ->
|
||||
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
|
||||
case {lists:keysearch(<<"pubsub#node">>, 1, XFields),
|
||||
lists:keysearch(<<"pubsub#subscriber_jid">>, 1, XFields),
|
||||
lists:keysearch(<<"pubsub#allow">>, 1, XFields)}
|
||||
@ -1665,7 +1673,7 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
|
||||
{result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]),
|
||||
update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs);
|
||||
false ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
{error, ?ERRT_FORBIDDEN(Lang, <<"You're not an owner">>)}
|
||||
end
|
||||
end,
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
@ -1680,7 +1688,8 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
_ ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ACCEPTABLE),
|
||||
Txt = <<"Incorrect data form">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end.
|
||||
|
||||
@ -1691,7 +1700,7 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) ->
|
||||
end,
|
||||
Subs),
|
||||
case Sub of
|
||||
[{pending, SubId}] ->
|
||||
[{pending, SubId}|_] ->
|
||||
NewSub = case Allow of
|
||||
true -> subscribed;
|
||||
false -> none
|
||||
@ -1700,7 +1709,8 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) ->
|
||||
send_authorization_approval(Host, Subscriber, Node, NewSub),
|
||||
{result, ok};
|
||||
_ ->
|
||||
{error, ?ERR_UNEXPECTED_REQUEST}
|
||||
Txt = <<"No pending subscriptions found">>,
|
||||
{error, ?ERRT_UNEXPECTED_REQUEST(?MYLANG, Txt)}
|
||||
end.
|
||||
|
||||
-define(XFIELD(Type, Label, Var, Val),
|
||||
@ -1830,7 +1840,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
[#xmlel{name = <<"x">>} = XEl] ->
|
||||
case jlib:parse_xdata_submit(XEl) of
|
||||
invalid ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
Txt = <<"Incorrect data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
|
||||
XData ->
|
||||
case set_xoption(Host, XData, node_options(Host, Type)) of
|
||||
NewOpts when is_list(NewOpts) -> {result, NewOpts};
|
||||
@ -1839,7 +1850,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
end;
|
||||
_ ->
|
||||
?INFO_MSG("Node ~p; bad configuration: ~p", [Node, Configuration]),
|
||||
{error, ?ERR_BAD_REQUEST}
|
||||
Txt = <<"No data form found">>,
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
|
||||
end,
|
||||
case ParseOptions of
|
||||
{result, NodeOptions} ->
|
||||
@ -1876,7 +1888,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
Error
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
Txt1 = <<"You're not allowed to create nodes">>,
|
||||
{error, ?ERRT_FORBIDDEN(?MYLANG, Txt1)}
|
||||
end
|
||||
end,
|
||||
Reply = [#xmlel{name = <<"pubsub">>,
|
||||
@ -1926,7 +1939,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
| {error, xmlel()}
|
||||
).
|
||||
delete_node(_Host, <<>>, _Owner) ->
|
||||
{error, ?ERR_NOT_ALLOWED};
|
||||
{error, ?ERRT_NOT_ALLOWED(?MYLANG, <<"No node specified">>)};
|
||||
delete_node(Host, Node, Owner) ->
|
||||
Action = fun (#pubsub_node{type = Type, id = Nidx}) ->
|
||||
case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of
|
||||
@ -1938,7 +1951,7 @@ delete_node(Host, Node, Owner) ->
|
||||
Error -> Error
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
{error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
|
||||
end
|
||||
end,
|
||||
Reply = [],
|
||||
@ -2247,22 +2260,28 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, Access) ->
|
||||
{result, Reply};
|
||||
{result, {_, Result}} ->
|
||||
{result, Result};
|
||||
{error, ?ERR_ITEM_NOT_FOUND} ->
|
||||
Type = select_type(ServerHost, Host, Node),
|
||||
case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of
|
||||
{error, _} = Error ->
|
||||
case is_item_not_found(Error) of
|
||||
true ->
|
||||
case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of
|
||||
{result,
|
||||
[#xmlel{name = <<"pubsub">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_PUBSUB}],
|
||||
children = [#xmlel{name = <<"create">>,
|
||||
attrs = [{<<"node">>, NewNode}]}]}]} ->
|
||||
publish_item(Host, ServerHost, NewNode, Publisher, ItemId, Payload);
|
||||
_ ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
Type = select_type(ServerHost, Host, Node),
|
||||
case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of
|
||||
true ->
|
||||
case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of
|
||||
{result,
|
||||
[#xmlel{name = <<"pubsub">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_PUBSUB}],
|
||||
children = [#xmlel{name = <<"create">>,
|
||||
attrs = [{<<"node">>, NewNode}]}]}]} ->
|
||||
publish_item(Host, ServerHost, NewNode, Publisher, ItemId, Payload);
|
||||
_ ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
end;
|
||||
false ->
|
||||
Txt = <<"Automatic node creation is not enabled">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, Txt)}
|
||||
end;
|
||||
false ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
Error
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
@ -2416,7 +2435,9 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIds, RSM) ->
|
||||
end;
|
||||
true ->
|
||||
case catch jlib:binary_to_integer(SMaxItems) of
|
||||
{'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
|
||||
{'EXIT', _} ->
|
||||
Txt = <<"Value of 'max_items' should be integer">>,
|
||||
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
|
||||
Val -> Val
|
||||
end
|
||||
end,
|
||||
@ -2639,7 +2660,7 @@ get_affiliations(Host, Node, JID) ->
|
||||
{error,
|
||||
extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"modify-affiliations">>)};
|
||||
Affiliation /= owner ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)};
|
||||
true ->
|
||||
node_call(Host, Type, get_node_affiliations, [Nidx])
|
||||
end
|
||||
@ -2732,7 +2753,7 @@ set_affiliations(Host, Node, From, EntitiesEls) ->
|
||||
FilteredEntities),
|
||||
{result, []};
|
||||
_ ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
{error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
|
||||
end
|
||||
end,
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
@ -2948,7 +2969,7 @@ get_subscriptions(Host, Node, JID) ->
|
||||
{error,
|
||||
extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"manage-subscriptions">>)};
|
||||
Affiliation /= owner ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)};
|
||||
true ->
|
||||
node_call(Host, Type, get_node_subscriptions, [Nidx])
|
||||
end
|
||||
@ -3059,10 +3080,10 @@ set_subscriptions(Host, Node, From, EntitiesEls) ->
|
||||
[], Entities),
|
||||
case Result of
|
||||
[] -> {result, []};
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
[{error, E}|_] -> {error, E}
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
{error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
|
||||
end
|
||||
end,
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
@ -3606,7 +3627,7 @@ get_configure(Host, ServerHost, Node, From, Lang) ->
|
||||
children =
|
||||
get_configure_xfields(Type, Options, Lang, Groups)}]}]}]};
|
||||
_ ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
{error, ?ERRT_FORBIDDEN(Lang, <<"You're not an owner">>)}
|
||||
end
|
||||
end,
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
@ -3820,7 +3841,8 @@ set_configure(Host, Node, From, Els, Lang) ->
|
||||
{result, owner} ->
|
||||
case jlib:parse_xdata_submit(XEl) of
|
||||
invalid ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
Txt = <<"Incorrect data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
|
||||
XData ->
|
||||
OldOpts = case Options of
|
||||
[] -> node_options(Host, Type);
|
||||
@ -3840,7 +3862,8 @@ set_configure(Host, Node, From, Els, Lang) ->
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
Txt = <<"You're not an owner">>,
|
||||
{error, ?ERRT_FORBIDDEN(Lang, Txt)}
|
||||
end
|
||||
end,
|
||||
case transaction(Host, Node, Action, transaction) of
|
||||
@ -3854,10 +3877,12 @@ set_configure(Host, Node, From, Els, Lang) ->
|
||||
Other
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_BAD_REQUEST}
|
||||
Txt = <<"Incorrect data form">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_BAD_REQUEST}
|
||||
Txt = <<"No data form found">>,
|
||||
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
|
||||
end.
|
||||
|
||||
add_opt(Key, Value, Opts) ->
|
||||
@ -3872,7 +3897,10 @@ add_opt(Key, Value, Opts) ->
|
||||
_ -> error
|
||||
end,
|
||||
case BoolVal of
|
||||
error -> {error, ?ERR_NOT_ACCEPTABLE};
|
||||
error ->
|
||||
Txt = <<"Value of '~s' should be boolean">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)};
|
||||
_ -> set_xoption(Host, Opts, add_opt(Opt, BoolVal, NewOpts))
|
||||
end).
|
||||
|
||||
@ -3885,10 +3913,14 @@ add_opt(Key, Value, Opts) ->
|
||||
if (Max =:= undefined) orelse (IVal =< Max) ->
|
||||
set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts));
|
||||
true ->
|
||||
{error, ?ERR_NOT_ACCEPTABLE}
|
||||
Txt = <<"Incorrect value of '~s'">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_NOT_ACCEPTABLE}
|
||||
Txt = <<"Value of '~s' should be integer">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
|
||||
end).
|
||||
|
||||
-define(SET_ALIST_XOPT(Opt, Val, Vals),
|
||||
@ -3896,7 +3928,9 @@ add_opt(Key, Value, Opts) ->
|
||||
true ->
|
||||
set_xoption(Host, Opts, add_opt(Opt, jlib:binary_to_atom(Val), NewOpts));
|
||||
false ->
|
||||
{error, ?ERR_NOT_ACCEPTABLE}
|
||||
Txt = <<"Incorrect value of '~s'">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
|
||||
end).
|
||||
|
||||
-define(SET_LIST_XOPT(Opt, Val),
|
||||
@ -4139,8 +4173,9 @@ features(Host, Node) when is_binary(Node) ->
|
||||
tree_call({_User, Server, _Resource}, Function, Args) ->
|
||||
tree_call(Server, Function, Args);
|
||||
tree_call(Host, Function, Args) ->
|
||||
?DEBUG("tree_call ~p ~p ~p", [Host, Function, Args]),
|
||||
catch apply(tree(Host), Function, Args).
|
||||
Tree = tree(Host),
|
||||
?DEBUG("tree_call apply(~s, ~s, ~p) @ ~s", [Tree, Function, Args, Host]),
|
||||
catch apply(Tree, Function, Args).
|
||||
|
||||
tree_action(Host, Function, Args) ->
|
||||
?DEBUG("tree_action ~p ~p ~p", [Host, Function, Args]),
|
||||
@ -4267,6 +4302,13 @@ extended_error(#xmlel{name = Error, attrs = Attrs, children = SubEls}, Ext, ExtA
|
||||
#xmlel{name = Error, attrs = Attrs,
|
||||
children = lists:reverse([#xmlel{name = Ext, attrs = ExtAttrs} | SubEls])}.
|
||||
|
||||
is_item_not_found({error, ErrEl}) ->
|
||||
case fxml:get_subtag_with_xmlns(
|
||||
ErrEl, <<"item-not-found">>, ?NS_STANZAS) of
|
||||
#xmlel{} -> true;
|
||||
_ -> false
|
||||
end.
|
||||
|
||||
string_to_ljid(JID) ->
|
||||
case jid:from_string(JID) of
|
||||
error ->
|
||||
|
@ -151,21 +151,28 @@ process_iq(From, To,
|
||||
%% modules. lists:foreach can
|
||||
%% only return ok:
|
||||
not_allowed ->
|
||||
Txt = <<"Removal is not allowed">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
sub_el = [SubEl,
|
||||
?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
not_exists ->
|
||||
Txt = <<"No such user">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el =
|
||||
[SubEl, ?ERR_ITEM_NOT_FOUND]};
|
||||
_ ->
|
||||
[SubEl,
|
||||
?ERRT_ITEM_NOT_FOUND(Lang, Txt)]};
|
||||
Err ->
|
||||
?ERROR_MSG("failed to remove user ~s@~s: ~p",
|
||||
[User, Server, Err]),
|
||||
IQ#iq{type = error,
|
||||
sub_el =
|
||||
[SubEl,
|
||||
?ERR_INTERNAL_SERVER_ERROR]}
|
||||
end;
|
||||
true ->
|
||||
Txt = <<"No password in this query">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
||||
sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
|
||||
end
|
||||
end;
|
||||
(UTag == false) and (RTag /= false) and AllowRemove ->
|
||||
@ -182,7 +189,9 @@ process_iq(From, To,
|
||||
ejabberd_auth:remove_user(User, Server),
|
||||
ignore;
|
||||
_ ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
|
||||
Txt = <<"The query is only allowed from local users">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}
|
||||
end;
|
||||
(UTag /= false) and (PTag /= false) ->
|
||||
User = fxml:get_tag_cdata(UTag),
|
||||
@ -200,11 +209,14 @@ process_iq(From, To,
|
||||
SubEl, Source, Lang,
|
||||
true);
|
||||
_ ->
|
||||
Txt = <<"Incorrect data form">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
||||
sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
|
||||
end;
|
||||
{error, malformed} ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]};
|
||||
Txt = <<"Incorrect CAPTCHA submit">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]};
|
||||
_ ->
|
||||
ErrText = <<"The CAPTCHA verification has failed">>,
|
||||
IQ#iq{type = error,
|
||||
@ -344,7 +356,8 @@ try_register_or_set_password(User, Server, Password,
|
||||
IQ#iq{type = error, sub_el = [SubEl, Error]}
|
||||
end;
|
||||
deny ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
|
||||
Txt = <<"Denied by ACL">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
|
||||
end;
|
||||
_ ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
|
||||
@ -359,13 +372,17 @@ try_set_password(User, Server, Password, IQ, SubEl,
|
||||
of
|
||||
ok -> IQ#iq{type = result, sub_el = []};
|
||||
{error, empty_password} ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]};
|
||||
Txt = <<"Empty password">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]};
|
||||
{error, not_allowed} ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Chaning password is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
{error, invalid_jid} ->
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]};
|
||||
_ ->
|
||||
sub_el = [SubEl, ?ERR_JID_MALFORMED]};
|
||||
Err ->
|
||||
?ERROR_MSG("failed to register user ~s@~s: ~p",
|
||||
[User, Server, Err]),
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
|
||||
end;
|
||||
@ -377,7 +394,7 @@ try_set_password(User, Server, Password, IQ, SubEl,
|
||||
|
||||
try_register(User, Server, Password, SourceRaw, Lang) ->
|
||||
case jid:is_nodename(User) of
|
||||
false -> {error, ?ERR_BAD_REQUEST};
|
||||
false -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Malformed username">>)};
|
||||
_ ->
|
||||
JID = jid:make(User, Server, <<"">>),
|
||||
Access = gen_mod:get_module_opt(Server, ?MODULE, access,
|
||||
@ -387,8 +404,8 @@ try_register(User, Server, Password, SourceRaw, Lang) ->
|
||||
case {acl:match_rule(Server, Access, JID),
|
||||
check_ip_access(SourceRaw, IPAccess)}
|
||||
of
|
||||
{deny, _} -> {error, ?ERR_FORBIDDEN};
|
||||
{_, deny} -> {error, ?ERR_FORBIDDEN};
|
||||
{deny, _} -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
{_, deny} -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
|
||||
{allow, allow} ->
|
||||
Source = may_remove_resource(SourceRaw),
|
||||
case check_timeout(Source) of
|
||||
@ -406,14 +423,20 @@ try_register(User, Server, Password, SourceRaw, Lang) ->
|
||||
Error ->
|
||||
remove_timeout(Source),
|
||||
case Error of
|
||||
{atomic, exists} -> {error, ?ERR_CONFLICT};
|
||||
{atomic, exists} ->
|
||||
Txt = <<"User already exists">>,
|
||||
{error, ?ERRT_CONFLICT(Lang, Txt)};
|
||||
{error, invalid_jid} ->
|
||||
{error, ?ERR_JID_MALFORMED};
|
||||
{error, not_allowed} ->
|
||||
{error, ?ERR_NOT_ALLOWED};
|
||||
{error, too_many_users} ->
|
||||
{error, ?ERR_NOT_ALLOWED};
|
||||
{error, _Reason} ->
|
||||
Txt = <<"Too many users registered">>,
|
||||
{error, ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)};
|
||||
{error, _} ->
|
||||
?ERROR_MSG("failed to register user "
|
||||
"~s@~s: ~p",
|
||||
[User, Server, Error]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
end
|
||||
end;
|
||||
|
@ -137,13 +137,14 @@ process_iq(From, To, IQ) when ((From#jid.luser == <<"">>) andalso (From#jid.reso
|
||||
process_iq_manager(From, To, IQ);
|
||||
|
||||
process_iq(From, To, IQ) ->
|
||||
#iq{sub_el = SubEl} = IQ,
|
||||
#iq{sub_el = SubEl, lang = Lang} = IQ,
|
||||
#jid{lserver = LServer} = From,
|
||||
case lists:member(LServer, ?MYHOSTS) of
|
||||
true -> process_local_iq(From, To, IQ);
|
||||
_ ->
|
||||
Txt = <<"The query is only allowed from local users">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
|
||||
sub_el = [SubEl, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]}
|
||||
end.
|
||||
|
||||
process_local_iq(From, To, #iq{type = Type} = IQ) ->
|
||||
@ -479,12 +480,13 @@ get_roster_by_jid_t(LUser, LServer, LJID, riak) ->
|
||||
exit(Err)
|
||||
end.
|
||||
|
||||
try_process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
|
||||
try_process_iq_set(From, To, #iq{sub_el = SubEl, lang = Lang} = IQ) ->
|
||||
#jid{server = Server} = From,
|
||||
Access = gen_mod:get_module_opt(Server, ?MODULE, access, fun(A) when is_atom(A) -> A end, all),
|
||||
case acl:match_rule(Server, Access, From) of
|
||||
deny ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Denied by ACL">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
allow ->
|
||||
process_iq_set(From, To, IQ)
|
||||
end.
|
||||
@ -1616,8 +1618,9 @@ process_iq_manager(From, To, IQ) ->
|
||||
true ->
|
||||
process_iq_manager2(MatchDomain, To, IQ);
|
||||
false ->
|
||||
#iq{sub_el = SubEl} = IQ,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
||||
#iq{sub_el = SubEl, lang = Lang} = IQ,
|
||||
Txt = <<"Roster management is not allowed from this domain">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
|
||||
end.
|
||||
|
||||
process_iq_manager2(MatchDomain, To, IQ) ->
|
||||
|
@ -60,8 +60,9 @@ process_local_iq(#jid{user = User, server = Server,
|
||||
_To, #iq{type = get, sub_el = _SubEl} = IQ) ->
|
||||
get_ip({User, Server, Resource}, IQ);
|
||||
process_local_iq(_From, _To,
|
||||
#iq{type = set, sub_el = SubEl} = IQ) ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}.
|
||||
#iq{type = set, sub_el = SubEl, lang = Lang} = IQ) ->
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}.
|
||||
|
||||
process_sm_iq(#jid{user = User, server = Server,
|
||||
resource = Resource},
|
||||
@ -69,14 +70,17 @@ process_sm_iq(#jid{user = User, server = Server,
|
||||
#iq{type = get, sub_el = _SubEl} = IQ) ->
|
||||
get_ip({User, Server, Resource}, IQ);
|
||||
process_sm_iq(_From, _To,
|
||||
#iq{type = get, sub_el = SubEl} = IQ) ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]};
|
||||
#iq{type = get, sub_el = SubEl, lang = Lang} = IQ) ->
|
||||
Txt = <<"Query to another users is forbidden">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]};
|
||||
process_sm_iq(_From, _To,
|
||||
#iq{type = set, sub_el = SubEl} = IQ) ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}.
|
||||
#iq{type = set, sub_el = SubEl, lang = Lang} = IQ) ->
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}.
|
||||
|
||||
get_ip({User, Server, Resource},
|
||||
#iq{sub_el =
|
||||
#iq{lang = Lang,
|
||||
sub_el =
|
||||
#xmlel{name = Name, attrs = Attrs} = SubEl} =
|
||||
IQ) ->
|
||||
case ejabberd_sm:get_user_ip(User, Server, Resource) of
|
||||
@ -88,8 +92,9 @@ get_ip({User, Server, Resource},
|
||||
[{xmlcdata,
|
||||
iolist_to_binary(jlib:ip_to_list(IP))}]}]};
|
||||
_ ->
|
||||
Txt = <<"User session not found">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
|
||||
sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}
|
||||
end.
|
||||
|
||||
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
|
||||
|
@ -50,17 +50,18 @@ stop(Host) ->
|
||||
|
||||
process_local_iq(_From, To,
|
||||
#iq{id = _ID, type = Type, xmlns = XMLNS,
|
||||
sub_el = SubEl} =
|
||||
sub_el = SubEl, lang = Lang} =
|
||||
IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
#xmlel{children = Els} = SubEl,
|
||||
Node = str:tokens(fxml:get_tag_attr_s(<<"node">>, SubEl),
|
||||
<<"/">>),
|
||||
Names = get_names(Els, []),
|
||||
case get_local_stats(To#jid.server, Node, Names) of
|
||||
case get_local_stats(To#jid.server, Node, Names, Lang) of
|
||||
{result, Res} ->
|
||||
IQ#iq{type = result,
|
||||
sub_el =
|
||||
@ -87,18 +88,18 @@ get_names([_ | Els], Res) -> get_names(Els, Res).
|
||||
#xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}],
|
||||
children = []}).
|
||||
|
||||
get_local_stats(_Server, [], []) ->
|
||||
get_local_stats(_Server, [], [], _Lang) ->
|
||||
{result,
|
||||
[?STAT(<<"users/online">>), ?STAT(<<"users/total">>),
|
||||
?STAT(<<"users/all-hosts/online">>),
|
||||
?STAT(<<"users/all-hosts/total">>)]};
|
||||
get_local_stats(Server, [], Names) ->
|
||||
get_local_stats(Server, [], Names, _Lang) ->
|
||||
{result,
|
||||
lists:map(fun (Name) -> get_local_stat(Server, [], Name)
|
||||
end,
|
||||
Names)};
|
||||
get_local_stats(_Server, [<<"running nodes">>, _],
|
||||
[]) ->
|
||||
[], _Lang) ->
|
||||
{result,
|
||||
[?STAT(<<"time/uptime">>), ?STAT(<<"time/cputime">>),
|
||||
?STAT(<<"users/online">>),
|
||||
@ -107,16 +108,19 @@ get_local_stats(_Server, [<<"running nodes">>, _],
|
||||
?STAT(<<"transactions/restarted">>),
|
||||
?STAT(<<"transactions/logged">>)]};
|
||||
get_local_stats(_Server, [<<"running nodes">>, ENode],
|
||||
Names) ->
|
||||
Names, Lang) ->
|
||||
case search_running_node(ENode) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false ->
|
||||
Txt = <<"No running node found">>,
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
|
||||
Node ->
|
||||
{result,
|
||||
lists:map(fun (Name) -> get_node_stat(Node, Name) end,
|
||||
Names)}
|
||||
end;
|
||||
get_local_stats(_Server, _, _) ->
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}.
|
||||
get_local_stats(_Server, _, _, Lang) ->
|
||||
Txt = <<"No statistics found for this item">>,
|
||||
{error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)}.
|
||||
|
||||
-define(STATVAL(Val, Unit),
|
||||
#xmlel{name = <<"stat">>,
|
||||
|
@ -51,10 +51,11 @@ stop(Host) ->
|
||||
?NS_TIME).
|
||||
|
||||
process_local_iq(_From, _To,
|
||||
#iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
#iq{type = Type, sub_el = SubEl, lang = Lang} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
Now_universal = calendar:universal_time(),
|
||||
Now_local = calendar:universal_time_to_local_time(Now_universal),
|
||||
|
@ -152,7 +152,8 @@ process_local_iq(_From, _To,
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
IQ#iq{type = result,
|
||||
sub_el =
|
||||
@ -176,7 +177,7 @@ process_local_iq(_From, _To,
|
||||
end.
|
||||
|
||||
process_sm_iq(From, To,
|
||||
#iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
#jid{user = User, lserver = LServer} = From,
|
||||
@ -185,14 +186,16 @@ process_sm_iq(From, To,
|
||||
set_vcard(User, LServer, SubEl),
|
||||
IQ#iq{type = result, sub_el = []};
|
||||
false ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
|
||||
Txt = <<"The query is only allowed from local users">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}
|
||||
end;
|
||||
get ->
|
||||
#jid{luser = LUser, lserver = LServer} = To,
|
||||
case get_vcard(LUser, LServer) of
|
||||
error ->
|
||||
Txt = <<"Database failure">>,
|
||||
IQ#iq{type = error,
|
||||
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
|
||||
sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]};
|
||||
[] ->
|
||||
IQ#iq{type = result,
|
||||
sub_el = [#xmlel{name = <<"vCard">>,
|
||||
@ -422,15 +425,17 @@ do_route(ServerHost, From, To, Packet) ->
|
||||
XDataEl = find_xdata_el(SubEl),
|
||||
case XDataEl of
|
||||
false ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_BAD_REQUEST),
|
||||
Txt = <<"Data form not found">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
_ ->
|
||||
XData = jlib:parse_xdata_submit(XDataEl),
|
||||
case XData of
|
||||
invalid ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_BAD_REQUEST),
|
||||
Txt = <<"Incorrect data form">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
_ ->
|
||||
ResIQ = IQ#iq{type = result,
|
||||
@ -470,7 +475,8 @@ do_route(ServerHost, From, To, Packet) ->
|
||||
#iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} ->
|
||||
case Type of
|
||||
set ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
|
||||
@ -516,10 +522,11 @@ do_route(ServerHost, From, To, Packet) ->
|
||||
++ Info}]},
|
||||
ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ))
|
||||
end;
|
||||
#iq{type = Type, xmlns = ?NS_DISCO_ITEMS} ->
|
||||
#iq{type = Type, lang = Lang, xmlns = ?NS_DISCO_ITEMS} ->
|
||||
case Type of
|
||||
set ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
ResIQ = IQ#iq{type = result,
|
||||
|
@ -206,7 +206,8 @@ process_local_iq(_From, _To,
|
||||
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
IQ#iq{type = result,
|
||||
sub_el =
|
||||
@ -240,10 +241,11 @@ process_sm_iq(_From, #jid{lserver = LServer} = To,
|
||||
|
||||
process_vcard_ldap(To, IQ, Server) ->
|
||||
{ok, State} = eldap_utils:get_state(Server, ?PROCNAME),
|
||||
#iq{type = Type, sub_el = SubEl} = IQ,
|
||||
#iq{type = Type, sub_el = SubEl, lang = Lang} = IQ,
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
#jid{luser = LUser} = To,
|
||||
LServer = State#state.serverhost,
|
||||
@ -455,15 +457,17 @@ route(State, From, To, Packet) ->
|
||||
XDataEl = find_xdata_el(SubEl),
|
||||
case XDataEl of
|
||||
false ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_BAD_REQUEST),
|
||||
Txt = <<"Data form not found">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
_ ->
|
||||
XData = jlib:parse_xdata_submit(XDataEl),
|
||||
case XData of
|
||||
invalid ->
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERR_BAD_REQUEST),
|
||||
Txt = <<"Incorrect data form">>,
|
||||
Err = jlib:make_error_reply(
|
||||
Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
_ ->
|
||||
ResIQ = IQ#iq{type = result,
|
||||
@ -505,7 +509,8 @@ route(State, From, To, Packet) ->
|
||||
#iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} ->
|
||||
case Type of
|
||||
set ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
Info = ejabberd_hooks:run_fold(disco_info, ServerHost,
|
||||
@ -545,10 +550,11 @@ route(State, From, To, Packet) ->
|
||||
++ Info}]},
|
||||
ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ))
|
||||
end;
|
||||
#iq{type = Type, xmlns = ?NS_DISCO_ITEMS} ->
|
||||
#iq{type = Type, lang = Lang, xmlns = ?NS_DISCO_ITEMS} ->
|
||||
case Type of
|
||||
set ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ALLOWED(Lang, Txt)),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
ResIQ = IQ#iq{type = result,
|
||||
|
@ -52,11 +52,12 @@ stop(Host) ->
|
||||
|
||||
process_local_iq(_From, To,
|
||||
#iq{id = _ID, type = Type, xmlns = _XMLNS,
|
||||
sub_el = SubEl} =
|
||||
sub_el = SubEl, lang = Lang} =
|
||||
IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
|
||||
get ->
|
||||
Host = To#jid.lserver,
|
||||
OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os,
|
||||
|
@ -77,8 +77,9 @@ publish_item(Nidx, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
#pubsub_node{options = Options} ->
|
||||
case find_opt(node_type, Options) of
|
||||
collection ->
|
||||
Txt = <<"Publishing items to collection node is not allowed">>,
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"publish">>)};
|
||||
?ERR_EXTENDED(?ERRT_NOT_ALLOWED(?MYLANG, Txt), <<"publish">>)};
|
||||
_ ->
|
||||
node_hometree:publish_item(Nidx, Publisher, Model,
|
||||
MaxItems, ItemId, Payload)
|
||||
|
@ -800,8 +800,10 @@ get_item(Nidx, ItemId) ->
|
||||
{selected,
|
||||
[<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], [RItem]} ->
|
||||
{result, raw_to_item(Nidx, RItem)};
|
||||
_ ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
{selected, _, []} ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
{'EXIT', _} ->
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)}
|
||||
end.
|
||||
|
||||
get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
|
||||
|
@ -69,13 +69,13 @@ create_node(Key, Node, Type, Owner, Options, Parents) ->
|
||||
Other -> Other
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_CONFLICT}
|
||||
{error, ?ERRT_CONFLICT(?MYLANG, <<"Node already exists">>)}
|
||||
end.
|
||||
|
||||
delete_node(Key, Node) ->
|
||||
case find_node(Key, Node) of
|
||||
false ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)};
|
||||
Record ->
|
||||
lists:foreach(fun (#pubsub_node{options = Opts} = Child) ->
|
||||
NewOpts = remove_config_parent(Node, Opts),
|
||||
@ -99,7 +99,7 @@ get_node(Host, Node, _From) ->
|
||||
|
||||
get_node(Host, Node) ->
|
||||
case find_node(Host, Node) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false -> {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)};
|
||||
Record -> Record
|
||||
end.
|
||||
|
||||
@ -115,7 +115,7 @@ get_nodes(Key) ->
|
||||
get_parentnodes(Host, Node, _From) ->
|
||||
case find_node(Host, Node) of
|
||||
false ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)};
|
||||
#pubsub_node{parents = Parents} ->
|
||||
Q = qlc:q([N
|
||||
|| #pubsub_node{nodeid = {NHost, NNode}} = N
|
||||
@ -139,7 +139,7 @@ get_subnodes(Host, <<>>) ->
|
||||
get_subnodes_helper(Host, <<>>);
|
||||
get_subnodes(Host, Node) ->
|
||||
case find_node(Host, Node) of
|
||||
false -> {error, ?ERR_ITEM_NOT_FOUND};
|
||||
false -> {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)};
|
||||
_ -> get_subnodes_helper(Host, Node)
|
||||
end.
|
||||
|
||||
@ -238,7 +238,7 @@ validate_parentage(Key, Owners, [<<>> | T]) ->
|
||||
validate_parentage(Key, Owners, [ParentID | T]) ->
|
||||
case find_node(Key, ParentID) of
|
||||
false ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)};
|
||||
#pubsub_node{owners = POwners, options = POptions} ->
|
||||
NodeType = find_opt(node_type, ?DEFAULT_NODETYPE, POptions),
|
||||
MutualOwners = [O || O <- Owners, PO <- POwners, O == PO],
|
||||
|
@ -74,15 +74,15 @@ get_node(Host, Node, _From) ->
|
||||
get_node(Host, Node).
|
||||
|
||||
get_node(Host, Node) ->
|
||||
case catch mnesia:read({pubsub_node, {Host, Node}}) of
|
||||
case mnesia:read({pubsub_node, {Host, Node}}) of
|
||||
[Record] when is_record(Record, pubsub_node) -> Record;
|
||||
_ -> {error, ?ERR_ITEM_NOT_FOUND}
|
||||
_ -> {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}
|
||||
end.
|
||||
|
||||
get_node(Nidx) ->
|
||||
case catch mnesia:index_read(pubsub_node, Nidx, #pubsub_node.id) of
|
||||
case mnesia:index_read(pubsub_node, Nidx, #pubsub_node.id) of
|
||||
[Record] when is_record(Record, pubsub_node) -> Record;
|
||||
_ -> {error, ?ERR_ITEM_NOT_FOUND}
|
||||
_ -> {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}
|
||||
end.
|
||||
|
||||
get_nodes(Host, _From) ->
|
||||
@ -147,7 +147,7 @@ get_subnodes_tree(Host, Node) ->
|
||||
|
||||
create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
BJID = jid:tolower(jid:remove_resource(Owner)),
|
||||
case catch mnesia:read({pubsub_node, {Host, Node}}) of
|
||||
case mnesia:read({pubsub_node, {Host, Node}}) of
|
||||
[] ->
|
||||
ParentExists = case Host of
|
||||
{_U, _S, _R} ->
|
||||
@ -183,7 +183,7 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
end;
|
||||
_ ->
|
||||
{error, ?ERR_CONFLICT}
|
||||
{error, ?ERRT_CONFLICT(?MYLANG, <<"Node already exists">>)}
|
||||
end.
|
||||
|
||||
delete_node(Host, Node) ->
|
||||
|
@ -93,7 +93,8 @@ set_node(Record) when is_record(Record, pubsub_node) ->
|
||||
end,
|
||||
case Nidx of
|
||||
none ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
Txt = <<"Node index not found">>,
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, Txt)};
|
||||
_ ->
|
||||
lists:foreach(fun ({Key, Value}) ->
|
||||
SKey = iolist_to_binary(atom_to_list(Key)),
|
||||
@ -125,9 +126,9 @@ get_node(Host, Node) ->
|
||||
[<<"node">>, <<"parent">>, <<"type">>, <<"nodeid">>], [RItem]} ->
|
||||
raw_to_node(Host, RItem);
|
||||
{'EXIT', _Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)};
|
||||
_ ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}
|
||||
end.
|
||||
|
||||
get_node(Nidx) ->
|
||||
@ -140,9 +141,9 @@ get_node(Nidx) ->
|
||||
[<<"host">>, <<"node">>, <<"parent">>, <<"type">>], [[Host, Node, Parent, Type]]} ->
|
||||
raw_to_node(Host, [Node, Parent, Type, Nidx]);
|
||||
{'EXIT', _Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)};
|
||||
_ ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
{error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, <<"Node not found">>)}
|
||||
end.
|
||||
|
||||
get_nodes(Host, _From) ->
|
||||
@ -211,7 +212,7 @@ get_subnodes_tree(Host, Node) ->
|
||||
create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
BJID = jid:tolower(jid:remove_resource(Owner)),
|
||||
case nodeidx(Host, Node) of
|
||||
{error, ?ERR_ITEM_NOT_FOUND} ->
|
||||
{error, not_found} ->
|
||||
ParentExists = case Host of
|
||||
{_U, _S, _R} ->
|
||||
%% This is special case for PEP handling
|
||||
@ -248,9 +249,9 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
end;
|
||||
{result, _} ->
|
||||
{error, ?ERR_CONFLICT};
|
||||
Error ->
|
||||
Error
|
||||
{error, ?ERRT_CONFLICT(?MYLANG, <<"Node already exists">>)};
|
||||
{error, db_fail} ->
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)}
|
||||
end.
|
||||
|
||||
delete_node(Host, Node) ->
|
||||
@ -303,9 +304,9 @@ nodeidx(Host, Node) ->
|
||||
{selected, [<<"nodeid">>], [[Nidx]]} ->
|
||||
{result, Nidx};
|
||||
{'EXIT', _Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, db_fail};
|
||||
_ ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
{error, not_found}
|
||||
end.
|
||||
|
||||
nodeowners(Nidx) ->
|
||||
|
@ -237,31 +237,40 @@ var_xfield(?PUBSUB_SUBSCRIPTION_TYPE) -> subscription_type;
|
||||
var_xfield(?PUBSUB_SUBSCRIPTION_DEPTH) -> subscription_depth;
|
||||
var_xfield(_) -> {error, badarg}.
|
||||
|
||||
val_xfield(deliver, [Val]) -> xopt_to_bool(Val);
|
||||
val_xfield(digest, [Val]) -> xopt_to_bool(Val);
|
||||
val_xfield(digest_frequency, [Val]) ->
|
||||
val_xfield(deliver = Opt, [Val]) -> xopt_to_bool(Opt, Val);
|
||||
val_xfield(digest = Opt, [Val]) -> xopt_to_bool(Opt, Val);
|
||||
val_xfield(digest_frequency = Opt, [Val]) ->
|
||||
case catch jlib:binary_to_integer(Val) of
|
||||
N when is_integer(N) -> N;
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ ->
|
||||
Txt = <<"Value of '~s' should be integer">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
|
||||
end;
|
||||
val_xfield(expire, [Val]) -> jlib:datetime_string_to_timestamp(Val);
|
||||
val_xfield(include_body, [Val]) -> xopt_to_bool(Val);
|
||||
val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val);
|
||||
val_xfield(show_values, Vals) -> Vals;
|
||||
val_xfield(subscription_type, [<<"items">>]) -> items;
|
||||
val_xfield(subscription_type, [<<"nodes">>]) -> nodes;
|
||||
val_xfield(subscription_depth, [<<"all">>]) -> all;
|
||||
val_xfield(subscription_depth, [Depth]) ->
|
||||
val_xfield(subscription_depth = Opt, [Depth]) ->
|
||||
case catch jlib:binary_to_integer(Depth) of
|
||||
N when is_integer(N) -> N;
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ ->
|
||||
Txt = <<"Value of '~s' should be integer">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
|
||||
end.
|
||||
|
||||
%% Convert XForm booleans to Erlang booleans.
|
||||
xopt_to_bool(<<"0">>) -> false;
|
||||
xopt_to_bool(<<"1">>) -> true;
|
||||
xopt_to_bool(<<"false">>) -> false;
|
||||
xopt_to_bool(<<"true">>) -> true;
|
||||
xopt_to_bool(_) -> {error, ?ERR_NOT_ACCEPTABLE}.
|
||||
xopt_to_bool(_, <<"0">>) -> false;
|
||||
xopt_to_bool(_, <<"1">>) -> true;
|
||||
xopt_to_bool(_, <<"false">>) -> false;
|
||||
xopt_to_bool(_, <<"true">>) -> true;
|
||||
xopt_to_bool(Option, _) ->
|
||||
Txt = <<"Value of '~s' should be boolean">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Option])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}.
|
||||
|
||||
-spec(get_option_xfield/3 ::
|
||||
(
|
||||
|
@ -200,31 +200,40 @@ var_xfield(?PUBSUB_SUBSCRIPTION_TYPE) -> subscription_type;
|
||||
var_xfield(?PUBSUB_SUBSCRIPTION_DEPTH) -> subscription_depth;
|
||||
var_xfield(_) -> {error, badarg}.
|
||||
|
||||
val_xfield(deliver, [Val]) -> xopt_to_bool(Val);
|
||||
val_xfield(digest, [Val]) -> xopt_to_bool(Val);
|
||||
val_xfield(digest_frequency, [Val]) ->
|
||||
val_xfield(deliver = Opt, [Val]) -> xopt_to_bool(Opt, Val);
|
||||
val_xfield(digest = Opt, [Val]) -> xopt_to_bool(Opt, Val);
|
||||
val_xfield(digest_frequency = Opt, [Val]) ->
|
||||
case catch jlib:binary_to_integer(Val) of
|
||||
N when is_integer(N) -> N;
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ ->
|
||||
Txt = <<"Value of '~s' should be integer">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
|
||||
end;
|
||||
val_xfield(expire, [Val]) -> jlib:datetime_string_to_timestamp(Val);
|
||||
val_xfield(include_body, [Val]) -> xopt_to_bool(Val);
|
||||
val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val);
|
||||
val_xfield(show_values, Vals) -> Vals;
|
||||
val_xfield(subscription_type, [<<"items">>]) -> items;
|
||||
val_xfield(subscription_type, [<<"nodes">>]) -> nodes;
|
||||
val_xfield(subscription_depth, [<<"all">>]) -> all;
|
||||
val_xfield(subscription_depth, [Depth]) ->
|
||||
val_xfield(subscription_depth = Opt, [Depth]) ->
|
||||
case catch jlib:binary_to_integer(Depth) of
|
||||
N when is_integer(N) -> N;
|
||||
_ -> {error, ?ERR_NOT_ACCEPTABLE}
|
||||
_ ->
|
||||
Txt = <<"Value of '~s' should be integer">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
|
||||
end.
|
||||
|
||||
%% Convert XForm booleans to Erlang booleans.
|
||||
xopt_to_bool(<<"0">>) -> false;
|
||||
xopt_to_bool(<<"1">>) -> true;
|
||||
xopt_to_bool(<<"false">>) -> false;
|
||||
xopt_to_bool(<<"true">>) -> true;
|
||||
xopt_to_bool(_) -> {error, ?ERR_NOT_ACCEPTABLE}.
|
||||
xopt_to_bool(_, <<"0">>) -> false;
|
||||
xopt_to_bool(_, <<"1">>) -> true;
|
||||
xopt_to_bool(_, <<"false">>) -> false;
|
||||
xopt_to_bool(_, <<"true">>) -> true;
|
||||
xopt_to_bool(Option, _) ->
|
||||
Txt = <<"Value of '~s' should be boolean">>,
|
||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Option])),
|
||||
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}.
|
||||
|
||||
%% Return a field for an XForm for Key, with data filled in, if
|
||||
%% applicable, from Options.
|
||||
|
Loading…
Reference in New Issue
Block a user