25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-10-19 15:32:08 +02:00

fix EJAB-701 and EJAB-836

SVN Revision: 1779
This commit is contained in:
Christophe Romain 2009-01-08 14:06:35 +00:00
parent 14bc7cf77f
commit 967bbe7f03
3 changed files with 104 additions and 71 deletions

View File

@ -1,3 +1,12 @@
2009-01-08 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: completely support subscription using
full JID (EJAB-701)
* src/mod_pubsub/node_default.erl: Likewise
* src/mod_pubsub/node_default.erl: any entity can retrieve item when
node access model is "open" (thanks to Myers Carpenter)(EJAB-836)
2009-01-07 Badlop <badlop@process-one.net> 2009-01-07 Badlop <badlop@process-one.net>
* src/mod_roster.erl: Show hyperlinks to local contacts when * src/mod_roster.erl: Show hyperlinks to local contacts when

View File

@ -465,12 +465,12 @@ handle_cast({presence, JID, Pid}, State) ->
lists:foreach(fun(Type) -> lists:foreach(fun(Type) ->
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, JID]), {result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, JID]),
lists:foreach( lists:foreach(
fun({Node, subscribed}) -> fun({Node, subscribed, SubJID}) ->
case tree_action(Host, get_node, [Host, Node, JID]) of case tree_action(Host, get_node, [Host, Node, JID]) of
#pubsub_node{options = Options} -> #pubsub_node{options = Options} ->
case get_option(Options, send_last_published_item) of case get_option(Options, send_last_published_item) of
on_sub_and_presence -> on_sub_and_presence ->
send_last_item(Host, Node, LJID); send_last_item(Host, Node, SubJID);
_ -> _ ->
ok ok
end; end;
@ -522,13 +522,11 @@ handle_cast({presence, JID, Pid}, State) ->
handle_cast({remove_user, LUser, LServer}, State) -> handle_cast({remove_user, LUser, LServer}, State) ->
Host = State#state.host, Host = State#state.host,
Owner = jlib:make_jid(LUser, LServer, ""), Owner = jlib:make_jid(LUser, LServer, ""),
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
%% remove user's subscriptions %% remove user's subscriptions
lists:foreach(fun(Type) -> lists:foreach(fun(Type) ->
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, Owner]), {result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, Owner]),
lists:foreach(fun lists:foreach(fun
({Node, subscribed}) -> ({Node, subscribed, JID}) ->
JID = jlib:jid_to_string(Owner),
unsubscribe_node(Host, Node, Owner, JID, all); unsubscribe_node(Host, Node, Owner, JID, all);
(_) -> (_) ->
ok ok
@ -537,7 +535,7 @@ handle_cast({remove_user, LUser, LServer}, State) ->
%% remove user's PEP nodes %% remove user's PEP nodes
lists:foreach(fun(#pubsub_node{nodeid={NodeKey, NodeName}}) -> lists:foreach(fun(#pubsub_node{nodeid={NodeKey, NodeName}}) ->
delete_node(NodeKey, NodeName, Owner) delete_node(NodeKey, NodeName, Owner)
end, tree_action(Host, get_nodes, [OwnerKey])), end, tree_action(Host, get_nodes, [jlib:jid_tolower(Owner)])),
%% remove user's nodes %% remove user's nodes
delete_node(Host, ["home", LServer, LUser], Owner), delete_node(Host, ["home", LServer, LUser], Owner),
{noreply, State}; {noreply, State};
@ -1453,11 +1451,13 @@ subscribe_node(Host, Node, From, JID) ->
%%<li>The node does not exist.</li> %%<li>The node does not exist.</li>
%%<li>The request specifies a subscription ID that is not valid or current.</li> %%<li>The request specifies a subscription ID that is not valid or current.</li>
%%</ul> %%</ul>
unsubscribe_node(Host, Node, From, JID, SubId) -> unsubscribe_node(Host, Node, From, JID, SubId) when is_list(JID) ->
Subscriber = case jlib:string_to_jid(JID) of Subscriber = case jlib:string_to_jid(JID) of
error -> {"", "", ""}; error -> {"", "", ""};
J -> jlib:jid_tolower(J) J -> jlib:jid_tolower(J)
end, end,
unsubscribe_node(Host, Node, From, Subscriber, SubId);
unsubscribe_node(Host, Node, From, Subscriber, SubId) ->
case node_action(Host, Node, unsubscribe_node, case node_action(Host, Node, unsubscribe_node,
[Host, Node, From, Subscriber, SubId]) of [Host, Node, From, Subscriber, SubId]) of
{error, Error} -> {error, Error} ->
@ -1934,7 +1934,8 @@ get_subscriptions(Host, JID, Plugins) when is_list(Plugins) ->
%% Service does not support retreive subscriptions %% Service does not support retreive subscriptions
{{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-subscriptions")}, Acc}; {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-subscriptions")}, Acc};
true -> true ->
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, JID]), Subscriber = jlib:jid_remove_resource(JID),
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, Subscriber]),
{Status, [Subscriptions|Acc]} {Status, [Subscriptions|Acc]}
end end
end, {ok, []}, Plugins), end, {ok, []}, Plugins),
@ -2298,7 +2299,7 @@ broadcast_config_notification(Host, Node, Lang) ->
broadcast_stanza(Host, NodeOpts, States, Stanza) -> broadcast_stanza(Host, NodeOpts, States, Stanza) ->
PresenceDelivery = get_option(NodeOpts, presence_based_delivery), PresenceDelivery = get_option(NodeOpts, presence_based_delivery),
BroadcastAll = get_option(NodeOpts, broadcast_all_resources), BroadcastAll = get_option(NodeOpts, broadcast_all_resources), %% XXX this is not standard
From = service_jid(Host), From = service_jid(Host),
lists:foreach(fun(#pubsub_state{stateid = {LJID, _}, subscription = Subs}) -> lists:foreach(fun(#pubsub_state{stateid = {LJID, _}, subscription = Subs}) ->
case is_to_deliver(LJID, Subs, PresenceDelivery) of case is_to_deliver(LJID, Subs, PresenceDelivery) of

View File

@ -277,11 +277,16 @@ delete_node(Host, Removed) ->
%% <p>In the default plugin module, the record is unchanged.</p> %% <p>In the default plugin module, the record is unchanged.</p>
subscribe_node(Host, Node, Sender, Subscriber, AccessModel, subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
SendLast, PresenceSubscription, RosterGroup) -> SendLast, PresenceSubscription, RosterGroup) ->
SubscriberKey = jlib:jid_tolower(jlib:jid_remove_resource(Subscriber)), SubKey = jlib:jid_tolower(Subscriber),
Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == SubscriberKey), GenKey = jlib:jid_remove_resource(SubKey),
State = get_state(Host, Node, SubscriberKey), Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == GenKey),
#pubsub_state{affiliation = Affiliation, GenState = get_state(Host, Node, GenKey),
subscription = Subscription} = State, SubState = case SubKey of
GenKey -> GenState;
_ -> get_state(Host, Node, SubKey)
end,
Affiliation = GenState#pubsub_state.affiliation,
Subscription = SubState#pubsub_state.subscription,
Whitelisted = lists:member(Affiliation, [member, publisher, owner]), Whitelisted = lists:member(Affiliation, [member, publisher, owner]),
if if
not Authorized -> not Authorized ->
@ -321,7 +326,7 @@ subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
true -> true ->
subscribed subscribed
end, end,
set_state(State#pubsub_state{subscription = NewSubscription}), set_state(SubState#pubsub_state{subscription = NewSubscription}),
case NewSubscription of case NewSubscription of
subscribed -> subscribed ->
case SendLast of case SendLast of
@ -343,9 +348,16 @@ subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
%% Reason = mod_pubsub:stanzaError() %% Reason = mod_pubsub:stanzaError()
%% @doc <p>Unsubscribe the <tt>Subscriber</tt> from the <tt>Node</tt>.</p> %% @doc <p>Unsubscribe the <tt>Subscriber</tt> from the <tt>Node</tt>.</p>
unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) -> unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
SubscriberKey = jlib:jid_tolower(jlib:jid_remove_resource(Subscriber)), SubKey = jlib:jid_tolower(Subscriber),
Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == SubscriberKey), GenKey = jlib:jid_remove_resource(SubKey),
State = get_state(Host, Node, SubscriberKey), Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == GenKey),
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,
if if
%% Entity did not specify SubID %% Entity did not specify SubID
%%SubID == "", ?? -> %%SubID == "", ?? ->
@ -354,17 +366,18 @@ unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
%%InvalidSubID -> %%InvalidSubID ->
%% {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; %% {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
%% Requesting entity is not a subscriber %% Requesting entity is not a subscriber
State#pubsub_state.subscription == none -> Subscription == none ->
{error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST, "not-subscribed")}; {error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST, "not-subscribed")};
%% Requesting entity is prohibited from unsubscribing entity %% Requesting entity is prohibited from unsubscribing entity
(not Authorized) and (State#pubsub_state.affiliation =/= owner) -> (not Authorized) and (Affiliation =/= owner) ->
{error, ?ERR_FORBIDDEN}; {error, ?ERR_FORBIDDEN};
%% Was just subscriber, remove the record %% Was just subscriber, remove the record
State#pubsub_state.affiliation == none -> Affiliation == none ->
del_state(State#pubsub_state.stateid), del_state(SubState#pubsub_state.stateid),
{result, default}; {result, default};
true -> true ->
set_state(State#pubsub_state{subscription = none}), %% TODO, may require better clean
set_state(SubState#pubsub_state{subscription = none}),
{result, default} {result, default}
end. end.
@ -408,10 +421,15 @@ unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
%% </p> %% </p>
%% <p>In the default plugin module, the record is unchanged.</p> %% <p>In the default plugin module, the record is unchanged.</p>
publish_item(Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload) -> publish_item(Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
PublisherKey = jlib:jid_tolower(jlib:jid_remove_resource(Publisher)), SubKey = jlib:jid_tolower(Publisher),
State = get_state(Host, Node, PublisherKey), GenKey = jlib:jid_remove_resource(SubKey),
#pubsub_state{affiliation = Affiliation, GenState = get_state(Host, Node, GenKey),
subscription = Subscription} = State, SubState = case SubKey of
GenKey -> GenState;
_ -> get_state(Host, Node, SubKey)
end,
Affiliation = GenState#pubsub_state.affiliation,
Subscription = SubState#pubsub_state.subscription,
if if
not ((PublishModel == open) not ((PublishModel == open)
or ((PublishModel == publishers) or ((PublishModel == publishers)
@ -421,7 +439,7 @@ publish_item(Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
%% Entity does not have sufficient privileges to publish to node %% Entity does not have sufficient privileges to publish to node
{error, ?ERR_FORBIDDEN}; {error, ?ERR_FORBIDDEN};
true -> true ->
PubId = {PublisherKey, now()}, %% TODO, uses {now(),PublisherKey} for sorting (EJAB-824) PubId = {SubKey, now()}, %% TODO, uses {now(),PublisherKey} for sorting (EJAB-824)
%% TODO: check creation, presence, roster (EJAB-663) %% TODO: check creation, presence, roster (EJAB-663)
Item = case get_item(Host, Node, ItemId) of Item = case get_item(Host, Node, ItemId) of
{result, OldItem} -> {result, OldItem} ->
@ -429,17 +447,17 @@ publish_item(Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
payload = Payload}; payload = Payload};
_ -> _ ->
#pubsub_item{itemid = {ItemId, {Host, Node}}, #pubsub_item{itemid = {ItemId, {Host, Node}},
creation = PubId, creation = {GenKey, now()},
modification = PubId, modification = PubId,
payload = Payload} payload = Payload}
end, end,
Items = [ItemId | State#pubsub_state.items--[ItemId]], Items = [ItemId | GenState#pubsub_state.items--[ItemId]],
{result, {NI, OI}} = remove_extra_items( {result, {NI, OI}} = remove_extra_items(
Host, Node, MaxItems, Items), Host, Node, MaxItems, Items),
if MaxItems > 0 -> set_item(Item); if MaxItems > 0 -> set_item(Item);
true -> ok true -> ok
end, end,
set_state(State#pubsub_state{items = NI}), set_state(GenState#pubsub_state{items = NI}),
{result, {default, broadcast, OI}} {result, {default, broadcast, OI}}
end. end.
@ -480,12 +498,13 @@ remove_extra_items(Host, Node, MaxItems, ItemIds) ->
%% <p>Default plugin: The user performing the deletion must be the node owner %% <p>Default plugin: The user performing the deletion must be the node owner
%% or a publisher.</p> %% or a publisher.</p>
delete_item(Host, Node, Publisher, ItemId) -> delete_item(Host, Node, Publisher, ItemId) ->
PublisherKey = jlib:jid_tolower(jlib:jid_remove_resource(Publisher)), SubKey = jlib:jid_tolower(Publisher),
State = get_state(Host, Node, PublisherKey), GenKey = jlib:jid_remove_resource(SubKey),
#pubsub_state{affiliation = Affiliation, items = Items} = State, GenState = get_state(Host, Node, GenKey),
#pubsub_state{affiliation = Affiliation, items = Items} = GenState,
Allowed = (Affiliation == publisher) orelse (Affiliation == owner) Allowed = (Affiliation == publisher) orelse (Affiliation == owner)
orelse case get_item(Host, Node, ItemId) of orelse case get_item(Host, Node, ItemId) of
{result, #pubsub_item{creation = {PublisherKey, _}}} -> true; {result, #pubsub_item{creation = {GenKey, _}}} -> true;
_ -> false _ -> false
end, end,
if if
@ -497,7 +516,7 @@ delete_item(Host, Node, Publisher, ItemId) ->
{result, _} -> {result, _} ->
del_item(Host, Node, ItemId), del_item(Host, Node, ItemId),
NewItems = lists:delete(ItemId, Items), NewItems = lists:delete(ItemId, Items),
set_state(State#pubsub_state{items = NewItems}), set_state(GenState#pubsub_state{items = NewItems}),
{result, {default, broadcast}}; {result, {default, broadcast}};
_ -> _ ->
%% Non-existent node or item %% Non-existent node or item
@ -512,8 +531,10 @@ delete_item(Host, Node, Publisher, ItemId) ->
%% Node = mod_pubsub:pubsubNode() %% Node = mod_pubsub:pubsubNode()
%% Owner = mod_pubsub:jid() %% Owner = mod_pubsub:jid()
purge_node(Host, Node, Owner) -> purge_node(Host, Node, Owner) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), SubKey = jlib:jid_tolower(Owner),
case get_state(Host, Node, OwnerKey) of GenKey = jlib:jid_remove_resource(SubKey),
GenState = get_state(Host, Node, GenKey),
case GenState of
#pubsub_state{items = Items, affiliation = owner} -> #pubsub_state{items = Items, affiliation = owner} ->
del_items(Host, Node, Items), del_items(Host, Node, Items),
{result, {default, broadcast}}; {result, {default, broadcast}};
@ -533,9 +554,10 @@ purge_node(Host, Node, Owner) ->
%% that will be added to the affiliation stored in the main %% that will be added to the affiliation stored in the main
%% <tt>pubsub_state</tt> table.</p> %% <tt>pubsub_state</tt> table.</p>
get_entity_affiliations(Host, Owner) -> get_entity_affiliations(Host, Owner) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), SubKey = jlib:jid_tolower(Owner),
GenKey = jlib:jid_remove_resource(SubKey),
States = mnesia:match_object( States = mnesia:match_object(
#pubsub_state{stateid = {OwnerKey, {Host, '_'}}, _ = '_'}), #pubsub_state{stateid = {GenKey, {Host, '_'}}, _ = '_'}),
Tr = fun(#pubsub_state{stateid = {_, {_, N}}, affiliation = A}) -> Tr = fun(#pubsub_state{stateid = {_, {_, N}}, affiliation = A}) ->
{N, A} {N, A}
end, end,
@ -550,14 +572,16 @@ get_node_affiliations(Host, Node) ->
{result, lists:map(Tr, States)}. {result, lists:map(Tr, States)}.
get_affiliation(Host, Node, Owner) -> get_affiliation(Host, Node, Owner) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), SubKey = jlib:jid_tolower(Owner),
State = get_state(Host, Node, OwnerKey), GenKey = jlib:jid_remove_resource(SubKey),
{result, State#pubsub_state.affiliation}. GenState = get_state(Host, Node, GenKey),
{result, GenState#pubsub_state.affiliation}.
set_affiliation(Host, Node, Owner, Affiliation) -> set_affiliation(Host, Node, Owner, Affiliation) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), SubKey = jlib:jid_tolower(Owner),
State = get_state(Host, Node, OwnerKey), GenKey = jlib:jid_remove_resource(SubKey),
set_state(State#pubsub_state{affiliation = Affiliation}), GenState = get_state(Host, Node, GenKey),
set_state(GenState#pubsub_state{affiliation = Affiliation}),
ok. ok.
%% @spec (Host, Owner) -> [{Node,Subscription}] %% @spec (Host, Owner) -> [{Node,Subscription}]
@ -572,11 +596,16 @@ set_affiliation(Host, Node, Owner, Affiliation) ->
%% that will be added to the affiliation stored in the main %% that will be added to the affiliation stored in the main
%% <tt>pubsub_state</tt> table.</p> %% <tt>pubsub_state</tt> table.</p>
get_entity_subscriptions(Host, Owner) -> get_entity_subscriptions(Host, Owner) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), States = case jlib:jid_tolower(Owner) of
States = mnesia:match_object( {U, D, ""} -> mnesia:match_object(
#pubsub_state{stateid = {OwnerKey, {Host, '_'}}, _ = '_'}), #pubsub_state{stateid = {{U, D, '_'}, {Host, '_'}}, _ = '_'});
Tr = fun(#pubsub_state{stateid = {_, {_, N}}, subscription = S}) -> {U, D, R} -> mnesia:match_object(
{N, S} #pubsub_state{stateid = {{U, D, ""}, {Host, '_'}}, _ = '_'})
++ mnesia:match_object(
#pubsub_state{stateid = {{U, D, R}, {Host, '_'}}, _ = '_'})
end,
Tr = fun(#pubsub_state{stateid = {J, {_, N}}, subscription = S}) ->
{N, S, J}
end, end,
{result, lists:map(Tr, States)}. {result, lists:map(Tr, States)}.
@ -589,14 +618,14 @@ get_node_subscriptions(Host, Node) ->
{result, lists:map(Tr, States)}. {result, lists:map(Tr, States)}.
get_subscription(Host, Node, Owner) -> get_subscription(Host, Node, Owner) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), SubKey = jlib:jid_tolower(Owner),
State = get_state(Host, Node, OwnerKey), SubState = get_state(Host, Node, SubKey),
{result, State#pubsub_state.subscription}. {result, SubState#pubsub_state.subscription}.
set_subscription(Host, Node, Owner, Subscription) -> set_subscription(Host, Node, Owner, Subscription) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), SubKey = jlib:jid_tolower(Owner),
State = get_state(Host, Node, OwnerKey), SubState = get_state(Host, Node, SubKey),
set_state(State#pubsub_state{subscription = Subscription}), set_state(SubState#pubsub_state{subscription = Subscription}),
ok. ok.
%% @spec (Host, Node) -> [States] | [] %% @spec (Host, Node) -> [States] | []
@ -664,10 +693,10 @@ get_items(Host, Node, _From) ->
#pubsub_item{itemid = {'_', {Host, Node}}, _ = '_'}), #pubsub_item{itemid = {'_', {Host, Node}}, _ = '_'}),
{result, Items}. {result, Items}.
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
State = get_state(Host, Node, jlib:jid_tolower(jlib:jid_remove_resource(JID))), SubKey = jlib:jid_tolower(JID),
#pubsub_state{affiliation = Affiliation, GenKey = jlib:jid_remove_resource(SubKey),
subscription = Subscription} = State, GenState = get_state(Host, Node, GenKey),
Subscribed = not ((Subscription == none) or (Subscription == pending)), Affiliation = GenState#pubsub_state.affiliation,
Whitelisted = lists:member(Affiliation, [member, publisher, owner]), Whitelisted = lists:member(Affiliation, [member, publisher, owner]),
if if
%%SubID == "", ?? -> %%SubID == "", ?? ->
@ -679,9 +708,6 @@ get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubI
Affiliation == outcast -> Affiliation == outcast ->
%% Requesting entity is blocked %% Requesting entity is blocked
{error, ?ERR_FORBIDDEN}; {error, ?ERR_FORBIDDEN};
(AccessModel == open) and (not Subscribed) ->
%% Entity is not subscribed
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-subscribed")};
(AccessModel == presence) and (not PresenceSubscription) -> (AccessModel == presence) and (not PresenceSubscription) ->
%% Entity is not authorized to create a subscription (presence subscription required) %% Entity is not authorized to create a subscription (presence subscription required)
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")}; {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
@ -715,10 +741,10 @@ get_item(Host, Node, ItemId) ->
{error, ?ERR_ITEM_NOT_FOUND} {error, ?ERR_ITEM_NOT_FOUND}
end. end.
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
State = get_state(Host, Node, jlib:jid_tolower(jlib:jid_remove_resource(JID))), SubKey = jlib:jid_tolower(JID),
#pubsub_state{affiliation = Affiliation, GenKey = jlib:jid_remove_resource(SubKey),
subscription = Subscription} = State, GenState = get_state(Host, Node, GenKey),
Subscribed = not ((Subscription == none) or (Subscription == pending)), Affiliation = GenState#pubsub_state.affiliation,
Whitelisted = lists:member(Affiliation, [member, publisher, owner]), Whitelisted = lists:member(Affiliation, [member, publisher, owner]),
if if
%%SubID == "", ?? -> %%SubID == "", ?? ->
@ -730,9 +756,6 @@ get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup
Affiliation == outcast -> Affiliation == outcast ->
%% Requesting entity is blocked %% Requesting entity is blocked
{error, ?ERR_FORBIDDEN}; {error, ?ERR_FORBIDDEN};
(AccessModel == open) and (not Subscribed) ->
%% Entity is not subscribed
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-subscribed")};
(AccessModel == presence) and (not PresenceSubscription) -> (AccessModel == presence) and (not PresenceSubscription) ->
%% Entity is not authorized to create a subscription (presence subscription required) %% Entity is not authorized to create a subscription (presence subscription required)
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")}; {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};