]> granicus.if.org Git - ejabberd/commitdiff
fix owners cache and fix unsubscribe permissions (EJAB-840)
authorChristophe Romain <christophe.romain@process-one.net>
Sun, 11 Jan 2009 01:41:22 +0000 (01:41 +0000)
committerChristophe Romain <christophe.romain@process-one.net>
Sun, 11 Jan 2009 01:41:22 +0000 (01:41 +0000)
SVN Revision: 1798

ChangeLog
src/mod_pubsub/mod_pubsub.erl
src/mod_pubsub/node_default.erl

index 3ba623f370f8cc166dcad37688226eb25026be28..b23db51fb45f614ec40236f26d197e2097087339 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-01-11  Christophe Romain <christophe.romain@process-one.net>
+
+       * src/mod_pubsub/mod_pubsub.erl: fix owners cache and fix unsubscribe
+       permissions (thanks to Andy Skelton)(EJAB-840)
+       * src/mod_pubsub/node_default.erl: Likewise
+
 2009-01-10  Christophe Romain <christophe.romain@process-one.net>
 
        * src/mod_pubsub/node_default.erl: fix unsubscription of full jid
index d7b05d32fc0461a417aba0ad78a3d6fe526f575e..682a1aed8f060748a3b30962bb2483a635acfaa9 100644 (file)
@@ -1875,19 +1875,34 @@ set_affiliations(Host, Node, From, EntitiesEls) ->
        error ->
            {error, ?ERR_BAD_REQUEST};
        _ ->
-           Action = fun(#pubsub_node{type = Type, owners = Owners}) ->
-                            case lists:member(Owner, Owners) of
-                                true ->
-                                    lists:foreach(
-                                      fun({JID, Affiliation}) ->
-                                              node_call(
-                                                Type, set_affiliation,
-                                                [Host, Node, JID, Affiliation])
-                                      end, Entities),
-                                    {result, []};
-                                _ ->
-                                    {error, ?ERR_FORBIDDEN}
-                            end
+           Action = fun(#pubsub_node{type = Type, owners = Owners}=N) ->
+                       case lists:member(Owner, Owners) of
+                           true ->
+                               lists:foreach(
+                                   fun({JID, Affiliation}) ->
+                                       node_call(Type, set_affiliation, [Host, Node, JID, Affiliation]),
+                                       case Affiliation of
+                                           owner ->
+                                               NewOwner = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
+                                               NewOwners = [NewOwner|Owners],
+                                               tree_call(Host, set_node, [N#pubsub_node{owners = NewOwners}]);
+                                           none ->
+                                               OldOwner = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
+                                               case lists:member(OldOwner, Owners) of
+                                                   true ->
+                                                       NewOwners = Owners--[OldOwner],
+                                                       tree_call(Host, set_node, [N#pubsub_node{owners = NewOwners}]);
+                                                   _ ->
+                                                       ok
+                                               end;
+                                           _ ->
+                                               ok
+                                       end
+                                   end, Entities),
+                               {result, []};
+                           _ ->
+                               {error, ?ERR_FORBIDDEN}
+                       end
                     end,
            transaction(Host, Node, Action, sync_dirty)
     end.
index c1434087dc715a465deda3fc3503149a1826e49e..87b97dec3267b052239bb96bdf387e836162f1aa 100644 (file)
@@ -275,22 +275,27 @@ subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
               SendLast, PresenceSubscription, RosterGroup) ->
     SubKey = jlib:jid_tolower(Subscriber),
     GenKey = jlib:jid_remove_resource(SubKey),
-    Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == GenKey),
+    SenderKey = jlib:jid_tolower(jlib:jid_remove_resource(Sender)),
     GenState = get_state(Host, Node, GenKey),
     SubState = case SubKey of
        GenKey -> GenState;
        _ -> get_state(Host, Node, SubKey)
        end,
-    Affiliation = GenState#pubsub_state.affiliation,
-    Subscription = SubState#pubsub_state.subscription,
+    Authorized = case SenderKey of
+       GenKey ->
+           true;
+       _ ->
+           SenderState = get_state(Host, Node, SenderKey),
+           SenderState#pubsub_state.affiliation == owner
+       end,
     if
        not Authorized ->
            %% JIDs do not match
            {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "invalid-jid")};
-       Affiliation == outcast ->
+       GenState#pubsub_state.affiliation == outcast ->
            %% Requesting entity is blocked
            {error, ?ERR_FORBIDDEN};
-       Subscription == pending ->
+       SubState#pubsub_state.subscription == pending ->
            %% Requesting entity has pending subscription
            {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "pending-subscription")};
        (AccessModel == presence) and (not PresenceSubscription) ->
@@ -345,14 +350,19 @@ subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
 unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
     SubKey = jlib:jid_tolower(Subscriber),
     GenKey = jlib:jid_remove_resource(SubKey),
-    Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == GenKey),
+    SenderKey = jlib:jid_tolower(jlib:jid_remove_resource(Sender)),
     GenState = get_state(Host, Node, GenKey),
     SubState = case SubKey of
        GenKey -> GenState;
        _ -> get_state(Host, Node, SubKey)
        end,
-    Affiliation = GenState#pubsub_state.affiliation,
-    Subscription = SubState#pubsub_state.subscription,
+    Authorized = case SenderKey of
+       GenKey ->
+           true;
+       _ ->
+           SenderState = get_state(Host, Node, SenderKey),
+           SenderState#pubsub_state.affiliation == owner
+       end,
     if
        %% Entity did not specify SubID
        %%SubID == "", ?? ->
@@ -361,10 +371,10 @@ unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
        %%InvalidSubID ->
        %%      {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
        %% Requesting entity is not a subscriber
-       Subscription == none ->
+       SubState#pubsub_state.subscription == none ->
            {error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST, "not-subscribed")};
        %% Requesting entity is prohibited from unsubscribing entity
-       (not Authorized) and (Affiliation =/= owner) ->
+       not Authorized ->
            {error, ?ERR_FORBIDDEN};
        %% Was just subscriber, remove the record
        SubState#pubsub_state.affiliation == none ->
@@ -576,7 +586,12 @@ set_affiliation(Host, Node, Owner, Affiliation) ->
     SubKey = jlib:jid_tolower(Owner),
     GenKey = jlib:jid_remove_resource(SubKey),
     GenState = get_state(Host, Node, GenKey),
-    set_state(GenState#pubsub_state{affiliation = Affiliation}),
+    case {Affiliation, GenState#pubsub_state.subscription} of
+       {none, none} ->
+           del_state(GenState#pubsub_state.stateid);
+       _ ->
+           set_state(GenState#pubsub_state{affiliation = Affiliation})
+    end,
     ok.
 
 %% @spec (Host, Ownner) -> [{Node,Subscription}]
@@ -619,7 +634,12 @@ get_subscription(Host, Node, Owner) ->
 set_subscription(Host, Node, Owner, Subscription) ->
     SubKey = jlib:jid_tolower(Owner),
     SubState = get_state(Host, Node, SubKey),
-    set_state(SubState#pubsub_state{subscription = Subscription}),
+    case {Subscription, SubState#pubsub_state.affiliation} of
+       {none, none} ->
+           del_state(SubState#pubsub_state.stateid);
+       _ ->
+           set_state(SubState#pubsub_state{subscription = Subscription})
+    end,
     ok.
 
 %% @spec (Host, Node) -> [States] | []
@@ -690,7 +710,6 @@ get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubI
     SubKey = jlib:jid_tolower(JID),
     GenKey = jlib:jid_remove_resource(SubKey),
     GenState = get_state(Host, Node, GenKey),
-    Affiliation = GenState#pubsub_state.affiliation,
     if
        %%SubID == "", ?? ->
            %% Entity has multiple subscriptions to the node but does not specify a subscription ID
@@ -698,7 +717,7 @@ get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubI
        %%InvalidSubID ->
            %% Entity is subscribed but specifies an invalid subscription ID
            %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
-       Affiliation == outcast ->
+       GenState#pubsub_state.affiliation == outcast ->
            %% Requesting entity is blocked
            {error, ?ERR_FORBIDDEN};
        (AccessModel == presence) and (not PresenceSubscription) ->
@@ -737,7 +756,6 @@ get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup
     SubKey = jlib:jid_tolower(JID),
     GenKey = jlib:jid_remove_resource(SubKey),
     GenState = get_state(Host, Node, GenKey),
-    Affiliation = GenState#pubsub_state.affiliation,
     if
        %%SubID == "", ?? ->
            %% Entity has multiple subscriptions to the node but does not specify a subscription ID
@@ -745,7 +763,7 @@ get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup
        %%InvalidSubID ->
            %% Entity is subscribed but specifies an invalid subscription ID
            %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
-       Affiliation == outcast ->
+       GenState#pubsub_state.affiliation == outcast ->
            %% Requesting entity is blocked
            {error, ?ERR_FORBIDDEN};
        (AccessModel == presence) and (not PresenceSubscription) ->