]> granicus.if.org Git - ejabberd/commitdiff
PubSub: enforce controls on publish and delete
authorChristophe Romain <christophe.romain@process-one.net>
Wed, 27 Sep 2017 15:37:38 +0000 (17:37 +0200)
committerChristophe Romain <christophe.romain@process-one.net>
Wed, 27 Sep 2017 15:37:38 +0000 (17:37 +0200)
src/node_flat.erl
src/node_flat_sql.erl

index 160f6d27c7823ebfc45d19ef497674886218e0e8..7347747e8e3535dc8804c5cf30e8475b9c5e7c4b 100644 (file)
@@ -376,23 +376,26 @@ publish_item(Nidx, Publisher, PublishModel, MaxItems, ItemId, Payload,
        true ->
            if MaxItems > 0 ->
                    Now = p1_time_compat:timestamp(),
-                   PubId = {Now, SubKey},
-                   Item = case get_item(Nidx, ItemId) of
-                       {result, OldItem} ->
-                           OldItem#pubsub_item{modification = PubId,
-                               payload = Payload};
+                   case get_item(Nidx, ItemId) of
+                       {result, #pubsub_item{creation = {_, GenKey}} = OldItem} ->
+                           set_item(OldItem#pubsub_item{
+                                       modification = {Now, SubKey},
+                                       payload = Payload}),
+                           {result, {default, broadcast, []}};
+                       {result, _} ->
+                           {error, xmpp:err_forbidden()};
                        _ ->
-                           #pubsub_item{itemid = {ItemId, Nidx},
-                               nodeidx = Nidx,
-                               creation = {Now, GenKey},
-                               modification = PubId,
-                               payload = Payload}
-                   end,
-                   Items = [ItemId | GenState#pubsub_state.items -- [ItemId]],
-                   {result, {NI, OI}} = remove_extra_items(Nidx, MaxItems, Items),
-                   set_item(Item),
-                   set_state(GenState#pubsub_state{items = NI}),
-                   {result, {default, broadcast, OI}};
+                           Items = [ItemId | GenState#pubsub_state.items],
+                           {result, {NI, OI}} = remove_extra_items(Nidx, MaxItems, Items),
+                           set_state(GenState#pubsub_state{items = NI}),
+                           set_item(#pubsub_item{
+                                       itemid = {ItemId, Nidx},
+                                       nodeidx = Nidx,
+                                       creation = {Now, GenKey},
+                                       modification = {Now, SubKey},
+                                       payload = Payload}),
+                           {result, {default, broadcast, OI}}
+                   end;
                true ->
                    {result, {default, broadcast, []}}
            end
index 97f49c92c572c0355bb4b186b6e989bf102b50dd..2ea5b0babd19d6393fd4ae2ab7e09c99057be3d5 100644 (file)
@@ -243,20 +243,31 @@ publish_item(Nidx, Publisher, PublishModel, MaxItems, ItemId, Payload,
     if not ((PublishModel == open) or
                    (PublishModel == publishers) and
                    ((Affiliation == owner)
-                        or (Affiliation == publisher)
-                        or (Affiliation == publish_only))
+                       or (Affiliation == publisher)
+                       or (Affiliation == publish_only))
                    or (Subscribed == true)) ->
            {error, xmpp:err_forbidden()};
        true ->
            if MaxItems > 0 ->
-                   PubId = {p1_time_compat:timestamp(), SubKey},
-                   set_item(#pubsub_item{itemid = {ItemId, Nidx},
-                           creation = {p1_time_compat:timestamp(), GenKey},
-                           modification = PubId,
-                           payload = Payload}),
-                   Items = [ItemId | itemids(Nidx, GenKey) -- [ItemId]],
-                   {result, {_, OI}} = remove_extra_items(Nidx, MaxItems, Items),
-                   {result, {default, broadcast, OI}};
+                   Now = p1_time_compat:timestamp(),
+                   case get_item(Nidx, ItemId) of
+                       {result, #pubsub_item{creation = {_, GenKey}} = OldItem} ->
+                           set_item(OldItem#pubsub_item{
+                                       modification = {Now, SubKey},
+                                       payload = Payload}),
+                           {result, {default, broadcast, []}};
+                       {result, _} ->
+                           {error, xmpp:err_forbidden()};
+                       _ ->
+                           Items = [ItemId | itemids(Nidx, GenKey)],
+                           {result, {_NI, OI}} = remove_extra_items(Nidx, MaxItems, Items),
+                           set_item(#pubsub_item{
+                                       itemid = {ItemId, Nidx},
+                                       creation = {Now, GenKey},
+                                       modification = {Now, SubKey},
+                                       payload = Payload}),
+                           {result, {default, broadcast, OI}}
+                   end;
                true ->
                    {result, {default, broadcast, []}}
            end
@@ -284,9 +295,23 @@ delete_item(Nidx, Publisher, PublishModel, ItemId) ->
     if not Allowed ->
            {error, xmpp:err_forbidden()};
        true ->
-           case del_item(Nidx, ItemId) of
-               {updated, 1} -> {result, {default, broadcast}};
-               _ -> {error, xmpp:err_item_not_found()}
+           Items = itemids(Nidx, GenKey),
+           case lists:member(ItemId, Items) of
+               true ->
+                   case del_item(Nidx, ItemId) of
+                       {updated, 1} -> {result, {default, broadcast}};
+                       _ -> {error, xmpp:err_item_not_found()}
+                   end;
+               false ->
+                   case Affiliation of
+                       owner ->
+                           case del_item(Nidx, ItemId) of
+                               {updated, 1} -> {result, {default, broadcast}};
+                               _ -> {error, xmpp:err_item_not_found()}
+                           end;
+                       _ ->
+                           {error, xmpp:err_forbidden()}
+                   end
            end
     end.