]> granicus.if.org Git - ejabberd/commitdiff
several pubsub/pep bugfix
authorChristophe Romain <christophe.romain@process-one.net>
Sat, 22 Dec 2007 00:04:05 +0000 (00:04 +0000)
committerChristophe Romain <christophe.romain@process-one.net>
Sat, 22 Dec 2007 00:04:05 +0000 (00:04 +0000)
SVN Revision: 1096

ChangeLog
src/ejabberd_c2s.erl
src/ejabberd_sm.erl
src/mod_pubsub/mod_pubsub.erl
src/mod_pubsub/node_default.erl
src/mod_pubsub/pubsub.hrl

index 87f6e6f1c5a5b5a2e99f4473e277ee6c68f7a4c0..e0e127f71155ecbbd55264e695bb11de00940f78 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-12-22  Christophe Romain <christophe.romain@process-one.net>
+
+       * src/ejabberd_sm.erl: change incoming_presence_hook to
+       presence_probe_hook
+       * src/ejabberd_c2s.erl: Likewise
+
+       * src/mod_pubsub/mod_pubsub.erl: send last pep item bugfix and
+       broadcast optimization (EJAB-468) (EJAB-467) (EJAB-460)
+       * src/mod_pubsub/pubsub.hrl: Likewise
+       * src/mod_pubsub/node_default.erl: Likewise
+
 2007-12-22  Badlop  <badlop@process-one.net>
 
        * src/mod_caps.erl: Bugfix in timeout checking. Check for timeout
index 7954f0586b8ed19c3385707b25112aaf04e616fa..8a449a8c8c89fd26c3b8a90e081e5c165d7e4683 100644 (file)
@@ -1385,6 +1385,7 @@ process_presence_probe(From, To, StateData) ->
                        deny ->
                            ok;
                        allow ->
+                           ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [From, To, Packet]),
                            ejabberd_router:route(To, From, Packet)
                    end;
                Cond2 ->
index 9dca35290ef5a6d4c502c72e05801833684ce65b..025b6de6826b0aecfb8d9738ef733034cff68d06 100644 (file)
@@ -386,9 +386,7 @@ do_route(From, To, Packet) ->
                                        From,
                                        jlib:jid_replace_resource(To, R),
                                        Packet)
-                             end, PResources),
-                           ejabberd_hooks:run(incoming_presence_hook, LServer,
-                                              [From, To, Packet]);
+                             end, PResources);
                       true ->
                            ok
                    end;
index fcb1468215698b778bf81c9405674c9803893a7b..96f1f288089af0ce6e13f4ce54bc291cfe7cbeb1 100644 (file)
@@ -23,7 +23,6 @@
 
 %%% TODO
 %%% plugin: generate Reply (do not use broadcast atom anymore)
-%%% to be implemented: deliver_notifications
 
 -module(mod_pubsub).
 -version('1.10-01').
@@ -40,9 +39,7 @@
 -define(PEPNODE, "pep").
 
 %% exports for hooks
--export([set_presence/4,
-        unset_presence/4,
-        incoming_presence/3,
+-export([presence_probe/3,
         remove_user/2,
         disco_local_identity/5,
         disco_local_features/5,
@@ -142,9 +139,6 @@ init([ServerHost, Opts]) ->
     Host = gen_mod:get_opt_host(ServerHost, Opts, "pubsub.@HOST@"),
     ServedHosts = gen_mod:get_opt(served_hosts, Opts, []),
     Access = gen_mod:get_opt(access_createnode, Opts, all),
-    mnesia:create_table(pubsub_presence,
-                       [{disc_copies, [node()]},
-                        {attributes, record_info(fields, pubsub_presence)}]),
     mod_disco:register_feature(ServerHost, ?NS_PUBSUB),
     ejabberd_hooks:add(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75),
     ejabberd_hooks:add(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75),
@@ -152,9 +146,7 @@ init([ServerHost, Opts]) ->
     ejabberd_hooks:add(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
     ejabberd_hooks:add(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
     ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75),
-    ejabberd_hooks:add(incoming_presence_hook, ServerHost, ?MODULE, incoming_presence, 50),
-    %%ejabberd_hooks:add(set_presence_hook, ServerHost, ?MODULE, set_presence, 50),
-    %%ejabberd_hooks:add(unset_presence_hook, ServerHost, ?MODULE, unset_presence, 50),
+    ejabberd_hooks:add(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 50),
     ejabberd_hooks:add(remove_user, ServerHost, ?MODULE, remove_user, 50),
     IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
     lists:foreach(
@@ -218,12 +210,12 @@ terminate_plugins(Host, ServerHost, Plugins, TreePlugin) ->
     ok.
 
 init_nodes(Host, ServerHost, ServedHosts) ->
-    create_node(Host, ServerHost, ["pubsub"], ?PUBSUB_JID, ?STDNODE),
-    create_node(Host, ServerHost, ["pubsub", "nodes"], ?PUBSUB_JID, ?STDNODE),
-    create_node(Host, ServerHost, ["home"], ?PUBSUB_JID, ?STDNODE),
+    create_node(Host, ServerHost, ["pubsub"], service_jid(Host), ?STDNODE),
+    create_node(Host, ServerHost, ["pubsub", "nodes"], service_jid(Host), ?STDNODE),
+    create_node(Host, ServerHost, ["home"], service_jid(Host), ?STDNODE),
     lists:foreach(
       fun(H) ->
-             create_node(Host, ServerHost, ["home", H], ?PUBSUB_JID, ?STDNODE)
+             create_node(Host, ServerHost, ["home", H], service_jid(Host), ?STDNODE)
       end, [ServerHost | ServedHosts]),
     ok.
 
@@ -390,13 +382,7 @@ disco_sm_items(Acc, _From, To, Node, _Lang) ->
 %% presence hooks handling functions
 %%
 
-set_presence(User, Server, Resource, Presence) ->
-    Proc = gen_mod:get_module_proc(Server, ?PROCNAME),
-    gen_server:cast(Proc, {set_presence, User, Server, Resource, Presence}).
-unset_presence(User, Server, Resource, Status) ->
-    Proc = gen_mod:get_module_proc(Server, ?PROCNAME),
-    gen_server:cast(Proc, {unset_presence, User, Server, Resource, Status}).
-incoming_presence(From, #jid{lserver = Host} = To, Packet) ->
+presence_probe(#jid{lserver = Host} = From, To, Packet) ->
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
     gen_server:cast(Proc, {presence, From, To, Packet}).
 
@@ -438,102 +424,70 @@ handle_call(stop, _From, State) ->
 %%--------------------------------------------------------------------
 %% @private
 handle_cast({presence, From, To, Packet}, State) ->
-    Plugins = State#state.plugins,
-    Key = {To#jid.lserver, From#jid.luser, From#jid.lserver},
-    Record = #pubsub_presence{key = Key, resource = From#jid.lresource},
-    Priority = case xml:get_subtag(Packet, "priority") of
-                  false -> 0;
-                  SubEl ->
-                      case catch list_to_integer(xml:get_tag_cdata(SubEl)) of
-                          P when is_integer(P) -> P;
-                          _ -> 0
-                      end
-              end,
-    PresenceType = case xml:get_tag_attr_s("type", Packet) of
-                      "" ->
-                          if Priority < 0 -> unavailable;
-                             true -> available
-                          end;
-                      "unavailable" -> unavailable;
-                      "error" -> unavailable;
-                      _ -> none
-                  end,
-    PreviouslyAvailable =
-       lists:member(From#jid.lresource,
-                    lists:map(fun(#pubsub_presence{resource = R}) -> R end,
-                              case catch mnesia:dirty_read(pubsub_presence, Key) of
-                                  Result when is_list(Result) -> Result;
-                                  _ -> []
-                              end)),
-    case PresenceType of
-       available -> mnesia:dirty_write(Record);
-       unavailable -> mnesia:dirty_delete_object(Record);
-       _ -> ok
-    end,
-    if PreviouslyAvailable == false,
-       PresenceType == available ->
-           %% A new resource is available. Loop through all subscriptions
-           %% and if the node is so configured, send the last item.
-           JID = jlib:jid_tolower(From),
-           Host = State#state.host,
-           ServerHost = State#state.server_host,
+    %% A new resource is available. send last published items
+    JID = jlib:jid_tolower(From),
+    Host = State#state.host,
+    ServerHost = State#state.server_host,
+    if From == To ->
+       %% for each node From is subscribed to
+       %% and if the node is so configured, send the last published item to From
+       lists:foreach(fun(Type) ->
+           {result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, From]),
            lists:foreach(
-               fun(Type) ->
-                   {result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, From]),
-                   Options = node_options(Type),
-                   SendLast = get_option(Options, send_last_published_item),
-                   AccessModel = get_option(Options, access_model),
-                   AllowedGroups = get_option(Options, roster_groups_allowed),
-                   lists:foreach(
-                       fun({Node, Subscription}) ->
-                           if
-                               Subscription /= none, Subscription /= pending, SendLast == on_sub_and_presence ->
+               fun({Node, subscribed}) -> 
+                   case tree_action(Host, get_node, [Host, Node]) of
+                       #pubsub_node{options = Options} ->
+                           case get_option(Options, send_last_published_item) of
+                               on_sub_and_presence ->
                                    send_last_item(Host, Node, JID);
-                               SendLast == on_sub_and_presence ->
-                                   {PresenceSubscription, RosterGroup} = get_roster_info(
-                                                                           To#jid.luser, To#jid.lserver, JID, AllowedGroups),
-                                   Features = case catch mod_caps:get_features(ServerHost, mod_caps:read_caps(element(4, Packet))) of
-                                                   F when is_list(F) -> F;
-                                                   _ -> []
-                                               end,
-                                   case lists:member(Node ++ "+notify", Features) of
-                                       true ->
-                                           MaySubscribe =
-                                               case AccessModel of
-                                                   open -> true;
-                                                   presence -> PresenceSubscription;
-                                                   whitelist -> false; % subscribers are added manually
-                                                   authorize -> false; % likewise
-                                                   roster -> RosterGroup
-                                               end,
-                                           if MaySubscribe ->
-                                                   send_last_item(Host, Node, JID);
-                                               true ->
-                                                   ok
-                                           end;
-                                       false ->
-                                           ok
-                                   end;
-                               true ->
+                               _ ->
                                    ok
                            end;
-                       (_) ->
+                       _ ->
                            ok
-                   end, Subscriptions)
-               end, Plugins),
-           {noreply, State};
-       true ->
-           {noreply, State}
-    end;
-
-handle_cast({set_presence, _User, _Server, _Resource, _Presence}, State) ->
-    {noreply, State};
-handle_cast({unset_presence, _User, _Server, _Resource, _Status}, State) ->
+                   end;
+                  (_) ->
+                   ok
+               end, Subscriptions)
+       end, State#state.plugins);
+    true ->
+       ok
+    end,
+    %% and send to From last PEP events published by To
+    PepKey = jlib:jid_tolower(jlib:jid_remove_resource(To)),
+    Caps = mod_caps:read_caps(element(4, Packet)),
+    lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, options = Options}) ->
+       case get_option(Options, send_last_published_item) of
+           on_sub_and_presence ->
+               case is_caps_notify(ServerHost, Node, Caps) of
+                   true ->
+                       AllowedGroups = get_option(Options, roster_groups_allowed),
+                       {PresenceSubscription, RosterGroup} = get_roster_info(
+                                       To#jid.luser, To#jid.lserver, JID, AllowedGroups),
+                       Subscribed = case get_option(Options, access_model) of
+                           open -> true;
+                           presence -> PresenceSubscription;
+                           whitelist -> false; % subscribers are added manually
+                           authorize -> false; % likewise
+                           roster -> RosterGroup
+                       end,
+                       if Subscribed ->
+                           send_last_item(PepKey, Node, JID);
+                       true ->
+                           ok
+                       end;
+                   false ->
+                       ok
+               end;
+           _ ->
+               ok
+       end
+    end, tree_action(Host, get_nodes, [PepKey])),
     {noreply, State};
 
 handle_cast({remove, User, Server}, State) ->
     Owner = jlib:make_jid(User, Server, ""),
-    delete_nodes(Server, Owner, State#state.plugins),
+    delete_nodes(Server, Owner),
     {noreply, State};
 
 handle_cast(_Msg, State) ->
@@ -578,9 +532,7 @@ terminate(_Reason, #state{host = Host,
     ejabberd_hooks:delete(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
     ejabberd_hooks:delete(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
     ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75),
-    ejabberd_hooks:delete(incoming_presence_hook, ServerHost, ?MODULE, incoming_presence, 50),
-    %%ejabberd_hooks:delete(set_presence_hook, ServerHost, ?MODULE, set_presence, 50),
-    %%ejabberd_hooks:delete(unset_presence_hook, ServerHost, ?MODULE, unset_presence, 50),
+    ejabberd_hooks:delete(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 50),
     ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE, remove_user, 50),
     lists:foreach(fun({NS,Mod}) ->
                          gen_iq_handler:remove_iq_handler(Mod, ServerHost, NS)
@@ -666,9 +618,7 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
                            Res = IQ#iq{type = result,
                                        sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}],
                                                   iq_get_vcard(Lang)}]},
-                           ejabberd_router:route(To,
-                                                 From,
-                                                 jlib:iq_to_xml(Res));
+                           ejabberd_router:route(To, From, jlib:iq_to_xml(Res));
                        #iq{} ->
                            Err = jlib:make_error_reply(
                                    Packet,
@@ -678,7 +628,7 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
                            ok
                    end;
                "presence" ->
-                   incoming_presence(From, To, Packet),
+                   presence_probe(From, To, Packet),
                    ok;
                "message" ->
                    case xml:get_attr_s("type", Attrs) of
@@ -1022,8 +972,7 @@ send_authorization_request(Host, Node, Subscriber) ->
        #pubsub_node{owners = Owners} ->
            lists:foreach(
              fun(Owner) ->
-                     ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(Owner),
-                                           Stanza)
+                     ejabberd_router ! {route, service_jid(Host), jlib:make_jid(Owner), Stanza}
              end, Owners),
            ok;
        _ ->
@@ -1096,8 +1045,9 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
                     end,
            case transaction(Host, Node, Action, sync_dirty) of
                {error, Error} ->
-                   ejabberd_router:route(To, From,
-                                         jlib:make_error_reply(Packet, Error));
+                   ejabberd_router:route(
+                    To, From,
+                    jlib:make_error_reply(Packet, Error));
                {result, _NewSubscription} ->
                    %% XXX: notify about subscription state change, section 12.11
                    ok;
@@ -1312,25 +1262,12 @@ delete_node(Host, Node, Owner) ->
        {result, Result} ->
            {result, Result}
     end.
-delete_nodes(Host, Owner, Plugins) ->
+delete_nodes(Host, Owner) ->
     %% This removes only PEP nodes when user is removed
     OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
     lists:foreach(fun(#pubsub_node{nodeid={NodeKey, NodeName}}) ->
        delete_node(NodeKey, NodeName, Owner)
     end, tree_action(Host, get_nodes, [OwnerKey])).
-%   TODO: may be best to use the generic following code
-%   lists:foreach(fun(Type) ->
-%          {result, Affiliations} = node_action(Type, get_entity_affiliations, [Host, Owner]),
-%          NodeKey = case Type of
-%          ?PEPNODE -> OwnerKey;
-%          _ -> Host
-%          end,
-%          lists:foreach(
-%              fun({NodeId, owner}) -> delete_node(NodeKey, NodeId, Owner);
-%                 (_) -> ok
-%              end
-%          end, Affiliations)
-%      end, Plugins),
 
 %% @spec (Host, Node, From, JID) ->
 %%               {error, Reason::stanzaError()} |
@@ -1407,7 +1344,6 @@ subscribe_node(Host, Node, From, JID) ->
        {error, Error} ->
            {error, Error};
        {result, {Result, subscribed, send_last}} ->
-           %% TODO was send_last_published_item
            send_all_items(Host, Node, Subscriber),
            case Result of
                default -> {result, Reply(subscribed)};
@@ -1505,7 +1441,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
                             node_call(Type, publish_item, [Host, Node, Publisher, Model, MaxItems, ItemId, Payload])
                     end
             end,
-    %%ejabberd_hooks:run(pubsub_publish_item, Host, [Host, Node, JID, ?PUBSUB_JID, ItemId, Payload]),
+    %%ejabberd_hooks:run(pubsub_publish_item, Host, [Host, Node, JID, service_jid(Host), ItemId, Payload]),
     Reply = [],
     case transaction(Host, Node, Action, sync_dirty) of
        {error, ?ERR_ITEM_NOT_FOUND} ->
@@ -1741,7 +1677,7 @@ send_items(Host, Node, LJID, Number) ->
              [{xmlelement, "x", [{"xmlns", ?NS_PUBSUB_EVENT}],
                [{xmlelement, "items", [{"node", node_to_string(Node)}],
                  ItemsEls}]}]},
-    ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(LJID), Stanza).
+    ejabberd_router ! {route, service_jid(Host), jlib:make_jid(LJID), Stanza}.
 
 %% @spec (Host, JID, Plugins) -> {error, Reason} | {result, Response}
 %%      Host = host()
@@ -2055,18 +1991,30 @@ node_to_string(Node) ->
 string_to_node(SNode) ->
     string:tokens(SNode, "/").
 
-%% @spec (Host, JID, PresenceDelivery) -> boolean()
+%% @spec (Host) -> jid()
 %%     Host = host()
-%%     JID = jid()
+%% @doc <p>Generate pubsub service JID.</p>
+service_jid(Host) ->
+    case Host of 
+    {U,S,_} -> {jid, U, S, "", U, S, ""}; 
+    _ -> {jid, "", Host, "", "", Host, ""}
+    end.
+
+%% @spec (LJID, PresenceDelivery) -> boolean()
+%%     LJID = jid()
+%%     Subscription = atom()
 %%     PresenceDelivery = boolean()
 %% @doc <p>Check if a notification must be delivered or not
-to_be_delivered(_Host, _JID, false) -> 
-    % default is true
-    true;
-to_be_delivered(Host, JID, true) ->
-    case mnesia:dirty_read(pubsub_presence, {Host, element(1, JID), element(2, JID)}) of
-    [_] -> true;
-    [] -> false
+is_to_delivered(_, none, _) -> false;
+is_to_delivered(_, pending, _) -> false;
+is_to_delivered(_, _, false) -> true;
+is_to_delivered({User, Server, _}, _, true) ->
+    case mnesia:dirty_match_object({session, '_', '_', {User, Server}, '_', '_'}) of
+    [] -> false;
+    Ss ->
+       lists:foldl(fun({session, _, _, _, undefined, _}, Acc) -> Acc;
+                      ({session, _, _, _, _Priority, _}, _Acc) -> true
+       end, false, Ss)
     end.
 
 %%%%%% broadcast functions
@@ -2094,22 +2042,19 @@ broadcast_publish_item(Host, Node, ItemId, _From, Payload) ->
                                       [{xmlelement, "items", [{"node", node_to_string(Node)}],
                                         [{xmlelement, "item", ItemAttrs, Content}]}]}]},
                        lists:foreach(
-                         fun(#pubsub_state{stateid = {JID, _},
+                         fun(#pubsub_state{stateid = {LJID, _},
                                            subscription = Subscription}) ->
-                               ToBeSent = to_be_delivered(Host, JID, PresenceDelivery),
-                               if
-                                   (Subscription /= none) and
-                                   (Subscription /= pending) and
-                                   ToBeSent ->
+                               case is_to_delivered(LJID, Subscription, PresenceDelivery) of
+                                   true ->
                                        DestJIDs = case BroadcastAll of
-                                           true -> ejabberd_sm:get_user_resources(element(1, JID), element(2, JID));
-                                           false -> [JID]
+                                           true -> ejabberd_sm:get_user_resources(element(1, LJID), element(2, LJID));
+                                           false -> [LJID]
                                        end,
                                        lists:foreach(
                                            fun(DestJID) ->
-                                               ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(DestJID), Stanza)
+                                               ejabberd_router ! {route, service_jid(Host), jlib:make_jid(DestJID), Stanza}
                                            end, DestJIDs);
-                                   true ->
+                                   false ->
                                        ok
                                end
                          end, States),
@@ -2148,7 +2093,7 @@ broadcast_retract_item(Host, Node, ItemId, ForceNotify) ->
                                                    subscription = Subscription}) ->
                                        if (Subscription /= none) and
                                           (Subscription /= pending) ->
-                                           ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(JID), Stanza);
+                                           ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza};
                                           true ->
                                            ok
                                        end
@@ -2181,7 +2126,7 @@ broadcast_purge_node(Host, Node) ->
                                                    subscription = Subscription}) ->
                                        if (Subscription /= none) and
                                           (Subscription /= pending) ->
-                                               ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(JID), Stanza);
+                                               ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza};
                                           true ->
                                            ok
                                        end
@@ -2213,7 +2158,7 @@ broadcast_removed_node(Host, Removed) ->
                                                subscription = Subscription}) ->
                                            if (Subscription /= none) and
                                               (Subscription /= pending) ->
-                                               ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(JID), Stanza);
+                                               ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza};
                                               true ->
                                                ok
                                            end
@@ -2253,14 +2198,12 @@ broadcast_config_notification(Host, Node, Lang) ->
                                               [{xmlelement, "item", [{"id", "configuration"}],
                                                 Content}]}]}]},
                                lists:foreach(
-                                 fun(#pubsub_state{stateid = {JID, _},
+                                 fun(#pubsub_state{stateid = {LJID, _},
                                                    subscription = Subscription}) ->
-                                       ToBeSent = to_be_delivered(Host, JID, PresenceDelivery),
-                                       if (Subscription /= none) and
-                                          (Subscription /= pending) and
-                                          ToBeSent ->
-                                               ejabberd_router:route(?PUBSUB_JID, jlib:make_jid(JID), Stanza);
-                                          true ->
+                                       case is_to_delivered(LJID, Subscription, PresenceDelivery) of
+                                           true ->
+                                               ejabberd_router ! {route, service_jid(Host), jlib:make_jid(LJID), Stanza};
+                                           false ->
                                                ok
                                        end
                                  end, States),
@@ -2298,11 +2241,10 @@ broadcast_config_notification(Host, Node, Lang) ->
 broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
     ?DEBUG("looking for pid of ~p@~p/~p", [LUser, LServer, LResource]),
     %% We need to know the resource, so we can ask for presence data.
-    SenderResources = ejabberd_sm:get_user_resources(LUser, LServer),
     SenderResource = case LResource of
                         "" ->
                             %% If we don't know the resource, just pick one.
-                            case SenderResources of
+                            case ejabberd_sm:get_user_resources(LUser, LServer) of
                                 [R|_] ->
                                     R;
                                 [] ->
@@ -2322,36 +2264,19 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
            case catch ejabberd_c2s:get_subscribed_and_online(C2SPid) of
                ContactsWithCaps when is_list(ContactsWithCaps) ->
                    ?DEBUG("found contacts with caps: ~p", [ContactsWithCaps]),
-                   LookingFor = Node ++ "+notify",
                    lists:foreach(
                      fun({JID, Caps}) ->
-                             case catch mod_caps:get_features(LServer, Caps) of
-                                 Features when is_list(Features) ->
-                                     case lists:member(LookingFor, Features) of
-                                         true ->
-                                             To = jlib:make_jid(JID),
-                                             ejabberd_router:route(Sender, To, Stanza);
-                                         _ ->
-                                             ok
-                                     end;
-                                 _ ->
-                                     %% couldn't get entity capabilities.
-                                     %% nothing to do about that...
-                                     ok
-                             end
+                           case is_caps_notify(LServer, Node, Caps) of
+                               true ->
+                                   To = jlib:make_jid(JID),
+                                   ejabberd_router ! {route, Sender, To, Stanza};
+                               false ->
+                                   ok
+                           end
                      end, ContactsWithCaps);
                _ ->
                    ok
            end,
-       %% also send a notification to any
-       %% of the account owner's available resources.
-       %% See: XEP-0163 1.1 section 3
-       %% Note: ejabberd_c2s:get_subscribed_and_online already returns owner online resources
-       %%       this loop should be deleted
-       %    lists:foreach(fun(Resource) ->
-       %                         To = jlib:make_jid(LUser, LServer, Resource),
-       %                         ejabberd_router:route(Sender, To, Stanza)
-       %                 end, SenderResources),
            ok;
        _ ->
            ok
@@ -2359,6 +2284,12 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
 broadcast_by_caps(_, _, _, _) ->
     ok.
 
+is_caps_notify(Host, Node, Caps) ->
+    case catch mod_caps:get_features(Host, Caps) of
+       Features when is_list(Features) -> lists:member(Node ++ "+notify", Features);
+       _ -> false
+    end.
+
 %%%%%%% Configuration handling
 
 %%<p>There are several reasons why the default node configuration options request might fail:</p>
index b5e8d9f67c886466a2412d79dfbc45a2f5745eb7..b02eb6c0f203661a52a37cba7be6ad0f86f7d717 100644 (file)
@@ -177,21 +177,21 @@ create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
     LOwner = jlib:jid_tolower(Owner),
     {User, Server, _Resource} = LOwner,
     Allowed = case acl:match_rule(ServerHost, Access, LOwner) of
-                 allow ->
-                     if Server == Host ->  %% Server == ServerHost ??
-                             true;
-                        true ->
-                             case Node of
-                                 ["home", Server, User | _] -> true;
-                                 _ -> false
-                             end
-                     end;
-                 _ ->
-                     case Owner of
-                         ?PUBSUB_JID -> true;
-                         _ -> false
-                     end
-             end,
+               allow ->
+                   if Server == Host ->  %% Server == ServerHost ??
+                       true;
+                   true ->
+                       case Node of
+                           ["home", Server, User | _] -> true;
+                           _ -> false
+                       end
+                   end;
+               _ ->
+                   case Owner of
+                       {jid, "", _, "", "", _, ""} -> true;
+                       _ -> false
+                   end
+           end,
     ChildOK = true, %% TODO test with ParentNode
     {result, Allowed and ChildOK}.
 
index 199a8dd2e8bd437209e5c76fc1586d3ab773f51f..7755f8a96c257b240570d277d32652d883e0b1cc 100644 (file)
@@ -1,12 +1,11 @@
 %%% ====================================================================
-%%% This software is copyright 2006, Process-one.
+%%% This software is copyright 2007, Process-one.
 %%%
 %%% This file contains pubsub types definition.
 %%% ====================================================================
 
 %% -------------------------------
 %% Pubsub constants
--define(PUBSUB_JID, {jid, "", Host, "", "", Host, ""}).
 -define(ERR_EXTENDED(E,C), mod_pubsub:extended_error(E,C)).
 
 %% this is currently a hard limit.