mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-26 16:26:24 +01:00
Improve handling of PEP sent to external contacts (EJAB-825)
SVN Revision: 1751
This commit is contained in:
parent
978adbbd94
commit
214ef31053
@ -1,3 +1,9 @@
|
|||||||
|
2008-12-23 Christophe Romain <christophe.romain@process-one.net>
|
||||||
|
|
||||||
|
* src/mod_pubsub/mod_pubsub.erl: Improve handling of PEP sent to
|
||||||
|
external contacts (EJAB-825)
|
||||||
|
* src/mod_caps.erl: Likewise
|
||||||
|
|
||||||
2008-12-19 Christophe Romain <christophe.romain@process-one.net>
|
2008-12-19 Christophe Romain <christophe.romain@process-one.net>
|
||||||
|
|
||||||
* src/mod_pubsub/mod_pubsub.erl: Fix send_last_published_item issue
|
* src/mod_pubsub/mod_pubsub.erl: Fix send_last_published_item issue
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
note_caps/3,
|
note_caps/3,
|
||||||
clear_caps/1,
|
clear_caps/1,
|
||||||
get_features/2,
|
get_features/2,
|
||||||
|
get_user_resource/2,
|
||||||
handle_disco_response/3]).
|
handle_disco_response/3]).
|
||||||
|
|
||||||
%% gen_mod callbacks
|
%% gen_mod callbacks
|
||||||
@ -61,6 +62,7 @@
|
|||||||
-record(caps, {node, version, exts}).
|
-record(caps, {node, version, exts}).
|
||||||
-record(caps_features, {node_pair, features}).
|
-record(caps_features, {node_pair, features}).
|
||||||
-record(user_caps, {jid, caps}).
|
-record(user_caps, {jid, caps}).
|
||||||
|
-record(user_caps_default, {uid, resource}).
|
||||||
-record(state, {host,
|
-record(state, {host,
|
||||||
disco_requests = ?DICT:new(),
|
disco_requests = ?DICT:new(),
|
||||||
feature_queries = []}).
|
feature_queries = []}).
|
||||||
@ -84,8 +86,9 @@ read_caps([], Result) ->
|
|||||||
Result.
|
Result.
|
||||||
|
|
||||||
%% get_caps reads user caps from database
|
%% get_caps reads user caps from database
|
||||||
get_caps(JID) ->
|
get_caps({U, S, R}) ->
|
||||||
case catch mnesia:dirty_read({user_caps, list_to_binary(exmpp_jid:jid_to_list(JID))}) of
|
BJID = exmpp_jlib:jid_to_binary(U, S, R),
|
||||||
|
case catch mnesia:dirty_read({user_caps, BJID}) of
|
||||||
[#user_caps{caps=Caps}] ->
|
[#user_caps{caps=Caps}] ->
|
||||||
Caps;
|
Caps;
|
||||||
_ ->
|
_ ->
|
||||||
@ -93,8 +96,26 @@ get_caps(JID) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%% clear_caps removes user caps from database
|
%% clear_caps removes user caps from database
|
||||||
clear_caps(JID) ->
|
clear_caps({U, S, R}) ->
|
||||||
catch mnesia:dirty_delete({user_caps, list_to_binary(exmpp_jid:jid_to_list(JID))}).
|
BJID = exmpp_jlib:jid_to_binary(U, S, R),
|
||||||
|
BUID = exmpp_jlib:jid_to_binary(U, S),
|
||||||
|
catch mnesia:dirty_delete({user_caps, BJID}),
|
||||||
|
case catch mnesia:dirty_read({user_caps_default, BUID}) of
|
||||||
|
[#user_caps_default{resource=R}] ->
|
||||||
|
catch mnesia:dirty_delete({user_caps_default, BUID});
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% give default user resource
|
||||||
|
get_user_resource(U, S) ->
|
||||||
|
BUID = exmpp_jlib:bare_jid_to_binary(U, S),
|
||||||
|
case catch mnesia:dirty_read({user_caps_default, BUID}) of
|
||||||
|
[#user_caps_default{resource=R}] ->
|
||||||
|
R;
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
%% note_caps should be called to make the module request disco
|
%% note_caps should be called to make the module request disco
|
||||||
%% information. Host is the host that asks, From is the full JID that
|
%% information. Host is the host that asks, From is the full JID that
|
||||||
@ -113,7 +134,8 @@ note_caps(Host, From, Caps) ->
|
|||||||
%% timeout error.
|
%% timeout error.
|
||||||
get_features(Host, Caps) ->
|
get_features(Host, Caps) ->
|
||||||
case Caps of
|
case Caps of
|
||||||
nothing -> [];
|
nothing ->
|
||||||
|
[];
|
||||||
#caps{} ->
|
#caps{} ->
|
||||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
gen_server:call(Proc, {get_features, Caps})
|
gen_server:call(Proc, {get_features, Caps})
|
||||||
@ -149,6 +171,9 @@ init([Host, _Opts]) ->
|
|||||||
mnesia:create_table(user_caps,
|
mnesia:create_table(user_caps,
|
||||||
[{disc_copies, [node()]},
|
[{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, user_caps)}]),
|
{attributes, record_info(fields, user_caps)}]),
|
||||||
|
mnesia:create_table(user_caps_default,
|
||||||
|
[{disc_copies, [node()]},
|
||||||
|
{attributes, record_info(fields, user_caps_default)}]),
|
||||||
{ok, #state{host = Host}}.
|
{ok, #state{host = Host}}.
|
||||||
|
|
||||||
maybe_get_features(#caps{node = Node, version = Version, exts = Exts}) ->
|
maybe_get_features(#caps{node = Node, version = Version, exts = Exts}) ->
|
||||||
@ -200,8 +225,17 @@ handle_cast({note_caps, From,
|
|||||||
#state{host = Host, disco_requests = Requests} = State) ->
|
#state{host = Host, disco_requests = Requests} = State) ->
|
||||||
%% XXX: this leads to race conditions where ejabberd will send
|
%% XXX: this leads to race conditions where ejabberd will send
|
||||||
%% lots of caps disco requests.
|
%% lots of caps disco requests.
|
||||||
mnesia:dirty_write(#user_caps{jid = list_to_binary(exmpp_jid:jid_to_list(From)),
|
#jid{node = U, domain = S, resource = R} = From,
|
||||||
caps = Caps}),
|
BJID = exmpp_jlib:jid_to_binary(From),
|
||||||
|
mnesia:dirty_write(#user_caps{jid = BJID, caps = Caps}),
|
||||||
|
case ejabberd_sm:get_user_resources(U, S) of
|
||||||
|
[] ->
|
||||||
|
ok;
|
||||||
|
_ ->
|
||||||
|
% only store default resource of external contacts
|
||||||
|
BUID = exmpp_jlib:bare_jid_to_binary(From),
|
||||||
|
mnesia:dirty_write(#user_caps_default{uid = BUID, resource = R})
|
||||||
|
end,
|
||||||
SubNodes = [Version | Exts],
|
SubNodes = [Version | Exts],
|
||||||
%% Now, find which of these are not already in the database.
|
%% Now, find which of these are not already in the database.
|
||||||
Fun = fun() ->
|
Fun = fun() ->
|
||||||
|
@ -2389,20 +2389,15 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
|
|||||||
%%ReplyTo = jlib:make_jid(LUser, LServer, SenderResource), % This has to be used
|
%%ReplyTo = jlib:make_jid(LUser, LServer, SenderResource), % This has to be used
|
||||||
case catch ejabberd_c2s:get_subscribed(C2SPid) of
|
case catch ejabberd_c2s:get_subscribed(C2SPid) of
|
||||||
Contacts when is_list(Contacts) ->
|
Contacts when is_list(Contacts) ->
|
||||||
Online = lists:foldl(fun({U, S, R}, Acc) ->
|
|
||||||
case user_resource(U, S, R) of
|
|
||||||
[] -> Acc;
|
|
||||||
OR -> [{U, S, OR}|Acc]
|
|
||||||
end
|
|
||||||
end, [], Contacts),
|
|
||||||
lists:foreach(fun({U, S, R}) ->
|
lists:foreach(fun({U, S, R}) ->
|
||||||
case is_caps_notify(LServer, Node, {U, S, R}) of
|
OR = user_resource(U, S, R),
|
||||||
|
case is_caps_notify(LServer, Node, {U, S, OR}) of
|
||||||
true ->
|
true ->
|
||||||
ejabberd_router ! {route, Sender, exmpp_jid:make_jid(U, S, R), Stanza};
|
ejabberd_router ! {route, Sender, exmpp_jid:make_jid(U, S, OR), Stanza};
|
||||||
false ->
|
false ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
end, Online);
|
end, Contacts);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
@ -2414,20 +2409,27 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
|
|||||||
broadcast_by_caps(_, _, _, _) ->
|
broadcast_by_caps(_, _, _, _) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
%% If we don't know the resource, just pick first if any
|
||||||
|
%% If no resource available, check if caps anyway (remote online)
|
||||||
user_resource(LUser, LServer, []) ->
|
user_resource(LUser, LServer, []) ->
|
||||||
%% If we don't know the resource, just pick first if any
|
|
||||||
case ejabberd_sm:get_user_resources(LUser, LServer) of
|
case ejabberd_sm:get_user_resources(LUser, LServer) of
|
||||||
[R|_] -> R;
|
[R|_] ->
|
||||||
[] -> []
|
R;
|
||||||
|
[] ->
|
||||||
|
mod_caps:get_user_resource(LUser, LServer)
|
||||||
end;
|
end;
|
||||||
user_resource(_, _, LResource) ->
|
user_resource(_, _, LResource) ->
|
||||||
LResource.
|
LResource.
|
||||||
|
|
||||||
is_caps_notify(Host, Node, LJID) ->
|
is_caps_notify(Host, Node, LJID) ->
|
||||||
Caps = mod_caps:get_caps(LJID),
|
case mod_caps:get_caps(LJID) of
|
||||||
case catch mod_caps:get_features(Host, Caps) of
|
nothing ->
|
||||||
Features when is_list(Features) -> lists:member(Node ++ "+notify", Features);
|
false;
|
||||||
_ -> false
|
Caps ->
|
||||||
|
case catch mod_caps:get_features(Host, Caps) of
|
||||||
|
Features when is_list(Features) -> lists:member(Node ++ "+notify", Features);
|
||||||
|
_ -> false
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%%%%%% Configuration handling
|
%%%%%%% Configuration handling
|
||||||
|
Loading…
Reference in New Issue
Block a user