mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-30 16:36:29 +01:00
fix dializer warnings (thanks to Karim Gemayel)
This commit is contained in:
parent
349c44fcc0
commit
ee861e650d
@ -57,119 +57,408 @@
|
|||||||
path_to_node/1]).
|
path_to_node/1]).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(init/3 ::
|
||||||
|
(
|
||||||
|
Host :: string(),
|
||||||
|
ServerHost :: string(),
|
||||||
|
Opts :: [{Key::atom(), Value::term()}])
|
||||||
|
-> 'ok'
|
||||||
|
).
|
||||||
|
|
||||||
init(Host, ServerHost, Opts) ->
|
init(Host, ServerHost, Opts) ->
|
||||||
node_flat:init(Host, ServerHost, Opts).
|
node_flat:init(Host, ServerHost, Opts).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(terminate/2 ::
|
||||||
|
(
|
||||||
|
Host :: string(),
|
||||||
|
ServerHost :: string())
|
||||||
|
-> 'ok'
|
||||||
|
).
|
||||||
|
|
||||||
terminate(Host, ServerHost) ->
|
terminate(Host, ServerHost) ->
|
||||||
node_flat:terminate(Host, ServerHost).
|
node_flat:terminate(Host, ServerHost).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(options/0 :: () -> [nodeOption()]).
|
||||||
|
|
||||||
options() ->
|
options() ->
|
||||||
[{node_type, leaf} | node_flat:options()].
|
[{'node_type', 'leaf'} | node_flat:options()].
|
||||||
|
|
||||||
|
|
||||||
|
-spec(features/0 :: () -> [Feature::string()]).
|
||||||
|
|
||||||
features() ->
|
features() ->
|
||||||
["multi-collection" | node_flat:features()].
|
["multi-collection" | node_flat:features()].
|
||||||
|
|
||||||
create_node_permission(_Host, _ServerHost, _Node, _ParentNode,
|
|
||||||
_Owner, _Access) ->
|
-spec(create_node_permission/6 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
ServerHost :: string(),
|
||||||
|
NodeId :: nodeId(),
|
||||||
|
ParentNodeId :: nodeId(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
Access :: atom())
|
||||||
|
-> {'result', 'true'}
|
||||||
|
).
|
||||||
|
|
||||||
|
create_node_permission(_Host, _ServerHost, _NodeId, _ParentNodeId,
|
||||||
|
_JID, _Access) ->
|
||||||
{result, true}.
|
{result, true}.
|
||||||
|
|
||||||
create_node(NodeId, Owner) ->
|
|
||||||
node_flat:create_node(NodeId, Owner).
|
|
||||||
|
|
||||||
delete_node(Removed) ->
|
-spec(create_node/2 ::
|
||||||
node_flat:delete_node(Removed).
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> {'result', {'default', 'broadcast'}}
|
||||||
|
).
|
||||||
|
|
||||||
subscribe_node(NodeId, Sender, Subscriber, AccessModel,
|
create_node(NodeIdx, JID) ->
|
||||||
|
node_flat:create_node(NodeIdx, JID).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(delete_node/1 ::
|
||||||
|
(
|
||||||
|
Nodes :: [Node::pubsubNode()])
|
||||||
|
-> {result, {'default', 'broadcast',
|
||||||
|
Reply :: [{Node :: pubsubNode(),
|
||||||
|
[{Owner :: bareUsr(),
|
||||||
|
Subscriptions :: [{Subscription :: subscription(),
|
||||||
|
SubId :: subId()}]}]}]}}
|
||||||
|
).
|
||||||
|
|
||||||
|
delete_node(Nodes) ->
|
||||||
|
node_flat:delete_node(Nodes).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(subscribe_node/8 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
Subscriber :: jidEntity(),
|
||||||
|
AccessModel :: accessModel(),
|
||||||
|
SendLast :: atom(),
|
||||||
|
PresenceSubscription :: boolean(),
|
||||||
|
RosterGroup :: boolean(),
|
||||||
|
Options :: [nodeOption()])
|
||||||
|
-> {'result', {'default',
|
||||||
|
Subscription :: 'subscribed',
|
||||||
|
SubId :: subId()}}
|
||||||
|
| {'result', {'default',
|
||||||
|
Subscription :: 'subscribed',
|
||||||
|
SubId :: subId(),
|
||||||
|
SendLast ::' send_last'}}
|
||||||
|
| {'result', {'default',
|
||||||
|
Subscription :: 'pending',
|
||||||
|
SubId :: subId()}}
|
||||||
|
| {'error', _} %% TODO add all error cases
|
||||||
|
).
|
||||||
|
|
||||||
|
subscribe_node(NodeIdx, JID, Subscriber, AccessModel,
|
||||||
SendLast, PresenceSubscription, RosterGroup, Options) ->
|
SendLast, PresenceSubscription, RosterGroup, Options) ->
|
||||||
node_flat:subscribe_node(NodeId, Sender, Subscriber, AccessModel,
|
node_flat:subscribe_node(NodeIdx, JID, Subscriber, AccessModel,
|
||||||
SendLast, PresenceSubscription, RosterGroup,
|
SendLast, PresenceSubscription, RosterGroup,
|
||||||
Options).
|
Options).
|
||||||
|
|
||||||
unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
|
||||||
node_flat:unsubscribe_node(NodeId, Sender, Subscriber, SubId).
|
|
||||||
|
|
||||||
publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) ->
|
-spec(unsubscribe_node/4 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
Subscriber :: jidEntity(),
|
||||||
|
SubId :: subId())
|
||||||
|
-> {'result', 'default'} | {'error', _} %% TODO : add all error cases
|
||||||
|
).
|
||||||
|
|
||||||
|
unsubscribe_node(NodeIdx, JID, Subscriber, SubId) ->
|
||||||
|
node_flat:unsubscribe_node(NodeIdx, JID, Subscriber, SubId).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(publish_item/6 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
PublishModel :: atom(), %% TODO : make a generic publishMod() type
|
||||||
|
MaxItems :: 'unlimited' | integer(),
|
||||||
|
ItemId :: itemId(),
|
||||||
|
Payload :: payload())
|
||||||
|
-> {'result', {'default', 'broadcast', ItemIds :: [] | [itemId()]}}
|
||||||
|
| {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
publish_item(NodeIdx, JID, PublishModel, MaxItems, ItemId, Payload) ->
|
||||||
%% TODO: should look up the NodeTree plugin here. There's no
|
%% TODO: should look up the NodeTree plugin here. There's no
|
||||||
%% access to the Host of the request at this level, so for now we
|
%% access to the Host of the request at this level, so for now we
|
||||||
%% just use nodetree_dag.
|
%% just use nodetree_dag.
|
||||||
case nodetree_dag:get_node(NodeId) of
|
case nodetree_dag:get_node(NodeIdx) of
|
||||||
#pubsub_node{options = Options} ->
|
#pubsub_node{options = Options} ->
|
||||||
case find_opt(node_type, Options) of
|
case find_opt('node_type', Options) of
|
||||||
collection ->
|
'collection' ->
|
||||||
{error, mod_pubsub:extended_error('not-allowed', "publish")};
|
{error, mod_pubsub:extended_error('not-allowed', "publish")};
|
||||||
_ ->
|
_ ->
|
||||||
node_flat:publish_item(NodeId, Publisher, Model,
|
node_flat:publish_item(NodeIdx, JID, PublishModel,
|
||||||
MaxItems, ItemId, Payload)
|
MaxItems, ItemId, Payload)
|
||||||
end;
|
end;
|
||||||
Err ->
|
Error ->
|
||||||
Err
|
Error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
-spec(find_opt/2 ::
|
||||||
|
(
|
||||||
|
Key :: atom(),
|
||||||
|
Options :: [] | [Option::nodeOption()])
|
||||||
|
-> Value :: 'false' | term()
|
||||||
|
).
|
||||||
|
|
||||||
find_opt(_, []) -> false;
|
find_opt(_, []) -> false;
|
||||||
find_opt(Option, [{Option, Value} | _]) -> Value;
|
find_opt(Key, [{Key, Value} | _]) -> Value;
|
||||||
find_opt(Option, [_ | T]) -> find_opt(Option, T).
|
find_opt(Key, [_ | Options]) -> find_opt(Key, Options).
|
||||||
|
|
||||||
remove_extra_items(NodeId, MaxItems, ItemIds) ->
|
|
||||||
node_flat:remove_extra_items(NodeId, MaxItems, ItemIds).
|
|
||||||
|
|
||||||
delete_item(NodeId, Publisher, PublishModel, ItemId) ->
|
-spec(remove_extra_items/3 ::
|
||||||
node_flat:delete_item(NodeId, Publisher, PublishModel, ItemId).
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
MaxItems :: 'unlimited' | integer(),
|
||||||
|
ItemsIds :: [ItemId::itemId()])
|
||||||
|
-> {'result',
|
||||||
|
{OldItems :: [] | [ItemId::itemId()],
|
||||||
|
NewItems :: [] | [ItemId::itemId()]}}
|
||||||
|
).
|
||||||
|
|
||||||
purge_node(NodeId, Owner) ->
|
remove_extra_items(NodeIdx, MaxItems, ItemIds) ->
|
||||||
node_flat:purge_node(NodeId, Owner).
|
node_flat:remove_extra_items(NodeIdx, MaxItems, ItemIds).
|
||||||
|
|
||||||
get_entity_affiliations(Host, Owner) ->
|
|
||||||
node_flat:get_entity_affiliations(Host, Owner).
|
|
||||||
|
|
||||||
get_node_affiliations(NodeId) ->
|
-spec(delete_item/4 ::
|
||||||
node_flat:get_node_affiliations(NodeId).
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
PublishModel :: atom(),
|
||||||
|
ItemId :: itemId())
|
||||||
|
-> {'result', {'default', 'broadcast'}} | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
get_affiliation(NodeId, Owner) ->
|
delete_item(NodeIdx, JID, PublishModel, ItemId) ->
|
||||||
node_flat:get_affiliation(NodeId, Owner).
|
node_flat:delete_item(NodeIdx, JID, PublishModel, ItemId).
|
||||||
|
|
||||||
set_affiliation(NodeId, Owner, Affiliation) ->
|
|
||||||
node_flat:set_affiliation(NodeId, Owner, Affiliation).
|
|
||||||
|
|
||||||
get_entity_subscriptions(Host, Owner) ->
|
-spec(purge_node/2 ::
|
||||||
node_flat:get_entity_subscriptions(Host, Owner).
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> {'result', {'default', 'broadcast'}} | {'error', 'forbidden'}
|
||||||
|
).
|
||||||
|
|
||||||
get_node_subscriptions(NodeId) ->
|
purge_node(NodeIdx, JID) ->
|
||||||
node_flat:get_node_subscriptions(NodeId).
|
node_flat:purge_node(NodeIdx, JID).
|
||||||
|
|
||||||
get_subscriptions(NodeId, Owner) ->
|
|
||||||
node_flat:get_subscriptions(NodeId, Owner).
|
|
||||||
|
|
||||||
set_subscriptions(NodeId, Owner, Subscription, SubId) ->
|
-spec(get_entity_affiliations/2 ::
|
||||||
node_flat:set_subscriptions(NodeId, Owner, Subscription, SubId).
|
(
|
||||||
|
Host :: binary(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> {'result', Reply :: [] | [{Node::pubsubNode(), Affiliation::affiliation()}]}
|
||||||
|
).
|
||||||
|
|
||||||
get_pending_nodes(Host, Owner) ->
|
get_entity_affiliations(Host, JID) ->
|
||||||
node_flat:get_pending_nodes(Host, Owner).
|
node_flat:get_entity_affiliations(Host, JID).
|
||||||
|
|
||||||
get_states(NodeId) ->
|
|
||||||
node_flat:get_states(NodeId).
|
|
||||||
|
|
||||||
get_state(NodeId, JID) ->
|
-spec(get_node_affiliations/1 ::
|
||||||
node_flat:get_state(NodeId, JID).
|
(
|
||||||
|
NodeIdx :: nodeIdx())
|
||||||
|
-> {'result', [] | [{Entity::fullUsr(), Affiliation::affiliation()}]}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_node_affiliations(NodeIdx) ->
|
||||||
|
node_flat:get_node_affiliations(NodeIdx).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_affiliation/2 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> {'result', Affiliation::affiliation()}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_affiliation(NodeIdx, JID) ->
|
||||||
|
node_flat:get_affiliation(NodeIdx, JID).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(set_affiliation/3 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
Affiliation :: affiliation())
|
||||||
|
-> 'ok' | {error, 'internal-server-error'}
|
||||||
|
).
|
||||||
|
|
||||||
|
set_affiliation(NodeIdx, JID, Affiliation) ->
|
||||||
|
node_flat:set_affiliation(NodeIdx, JID, Affiliation).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_entity_subscriptions/2 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> {'result', []
|
||||||
|
| [{Node :: pubsubNode(),
|
||||||
|
Subscription :: subscription(),
|
||||||
|
SubId :: subId(),
|
||||||
|
Entity :: fullUsr()}]}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_entity_subscriptions(Host, JID) ->
|
||||||
|
node_flat:get_entity_subscriptions(Host, JID).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_node_subscriptions/1 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx())
|
||||||
|
-> {'result', []
|
||||||
|
| [{Entity::fullUsr(), 'none'}]
|
||||||
|
| [{Entity::fullUsr(), Subscription::subscription(), SubId::subId()}]}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_node_subscriptions(NodeIdx) ->
|
||||||
|
node_flat:get_node_subscriptions(NodeIdx).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_subscriptions/2 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> {'result', Subscriptions :: [] | [{Subscription::subscription(), SubId::subId()}]}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_subscriptions(NodeIdx, JID) ->
|
||||||
|
node_flat:get_subscriptions(NodeIdx, JID).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(set_subscriptions/4 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
Subscription :: subscription(),
|
||||||
|
SubId :: subId())
|
||||||
|
-> 'ok'
|
||||||
|
| {Subscription::subscription(), SubId::subId()}
|
||||||
|
| {error, _}
|
||||||
|
).
|
||||||
|
|
||||||
|
set_subscriptions(NodeIdx, JID, Subscription, SubId) ->
|
||||||
|
node_flat:set_subscriptions(NodeIdx, JID, Subscription, SubId).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_pending_nodes/2 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> 'false' | {'value', NodeId::nodeId()}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_pending_nodes(Host, JID) ->
|
||||||
|
node_flat:get_pending_nodes(Host, JID).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_states/1 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx())
|
||||||
|
-> {'result', States :: [] | [State::pubsubState()]}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_states(NodeIdx) ->
|
||||||
|
node_flat:get_states(NodeIdx).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_state/2 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
Entity :: fullUsr())
|
||||||
|
-> State::pubsubState()
|
||||||
|
).
|
||||||
|
|
||||||
|
get_state(NodeIdx, Entity) ->
|
||||||
|
node_flat:get_state(NodeIdx, Entity).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(set_state/1 ::
|
||||||
|
(
|
||||||
|
State :: pubsubState())
|
||||||
|
-> 'ok' | {error, 'internal-server-error'}
|
||||||
|
).
|
||||||
|
|
||||||
set_state(State) ->
|
set_state(State) ->
|
||||||
node_flat:set_state(State).
|
node_flat:set_state(State).
|
||||||
|
|
||||||
get_items(NodeId, From) ->
|
|
||||||
node_flat:get_items(NodeId, From).
|
|
||||||
|
|
||||||
get_items(NodeId, JID, AccessModel, PresenceSubscription,
|
-spec(get_items/2 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
Entity :: fullUsr())
|
||||||
|
-> {'result', Items :: [] | [Item::pubsubItem()]}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_items(NodeIdx, Entity) ->
|
||||||
|
node_flat:get_items(NodeIdx, Entity).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_items/6 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
AccessModel :: accessModel(),
|
||||||
|
PresenceSubscription :: boolean(),
|
||||||
|
RosterGroup :: boolean(),
|
||||||
|
SubId :: subId())
|
||||||
|
-> {'result', Items :: [] | [Item::pubsubItem()]}
|
||||||
|
| {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_items(NodeIdx, JID, AccessModel, PresenceSubscription,
|
||||||
RosterGroup, SubId) ->
|
RosterGroup, SubId) ->
|
||||||
node_flat:get_items(NodeId, JID, AccessModel, PresenceSubscription,
|
node_flat:get_items(NodeIdx, JID, AccessModel, PresenceSubscription,
|
||||||
RosterGroup, SubId).
|
RosterGroup, SubId).
|
||||||
|
|
||||||
get_item(NodeId, ItemId) ->
|
|
||||||
node_flat:get_item(NodeId, ItemId).
|
|
||||||
|
|
||||||
get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription,
|
-spec(get_item/2 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
ItemId :: itemId())
|
||||||
|
-> {'result', Item::pubsubItem()} | {'error', 'item-not-found'}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_item(NodeIdx, ItemId) ->
|
||||||
|
node_flat:get_item(NodeIdx, ItemId).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_item/7 ::
|
||||||
|
(
|
||||||
|
NodeIdx :: nodeIdx(),
|
||||||
|
ItemId :: itemId(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
AccessModel :: accessModel(),
|
||||||
|
PresenceSubscription :: boolean(),
|
||||||
|
RosterGroup :: boolean(),
|
||||||
|
SubId :: subId())
|
||||||
|
-> {'result', Item::pubsubItem()} | {'error', 'item-not-found'}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_item(NodeIdx, ItemId, JID, AccessModel, PresenceSubscription,
|
||||||
RosterGroup, SubId) ->
|
RosterGroup, SubId) ->
|
||||||
node_flat:get_item(NodeId, ItemId, JID, AccessModel,
|
node_flat:get_item(NodeIdx, ItemId, JID, AccessModel,
|
||||||
PresenceSubscription, RosterGroup, SubId).
|
PresenceSubscription, RosterGroup, SubId).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(set_item/1 ::
|
||||||
|
(
|
||||||
|
Item :: pubsubItem())
|
||||||
|
-> 'ok' | {error, 'internal-server-error'}
|
||||||
|
).
|
||||||
|
|
||||||
set_item(Item) ->
|
set_item(Item) ->
|
||||||
node_flat:set_item(Item).
|
node_flat:set_item(Item).
|
||||||
|
|
||||||
|
@ -51,128 +51,265 @@
|
|||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% API
|
%% API
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
|
-spec(init/3 ::
|
||||||
|
(
|
||||||
|
Host :: string(),
|
||||||
|
ServerHost :: string(),
|
||||||
|
Opts :: [{Key::atom(), Value::term()}])
|
||||||
|
-> 'ok'
|
||||||
|
).
|
||||||
|
|
||||||
init(Host, ServerHost, Opts) ->
|
init(Host, ServerHost, Opts) ->
|
||||||
nodetree_tree:init(Host, ServerHost, Opts).
|
nodetree_tree:init(Host, ServerHost, Opts).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(terminate/2 ::
|
||||||
|
(
|
||||||
|
Host :: string(),
|
||||||
|
ServerHost :: string())
|
||||||
|
-> 'ok'
|
||||||
|
).
|
||||||
|
|
||||||
terminate(Host, ServerHost) ->
|
terminate(Host, ServerHost) ->
|
||||||
nodetree_tree:terminate(Host, ServerHost).
|
nodetree_tree:terminate(Host, ServerHost).
|
||||||
|
|
||||||
create_node(Key, Node, Type, Owner, Options, Parents) ->
|
|
||||||
OwnerJID = jlib:short_prepd_bare_jid(Owner),
|
-spec(create_node/6 ::
|
||||||
case find_node(Key, Node) of
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
NodeId :: nodeId(),
|
||||||
|
Type :: nodeType(),
|
||||||
|
JID :: jidEntity(),
|
||||||
|
Options :: [nodeOption()],
|
||||||
|
ParentNodeIds :: [] | [nodeId()])
|
||||||
|
-> {'ok', NodeIdx::nodeIdx()} | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
create_node(Host, NodeId, Type, #jid{node = U, domain = S} = _JID, Options, ParentNodeIds) ->
|
||||||
|
case find_node(Host, NodeId) of
|
||||||
false ->
|
false ->
|
||||||
Nidx = pubsub_index:new(node),
|
NodeIdx = pubsub_index:new(node),
|
||||||
N = #pubsub_node{id = oid(Key, Node),
|
Node = #pubsub_node{id = {Host, NodeId},
|
||||||
idx = Nidx,
|
idx = NodeIdx,
|
||||||
type = Type,
|
type = Type,
|
||||||
parents = Parents,
|
parents = ParentNodeIds,
|
||||||
owners = [OwnerJID],
|
owners = [_Owner = {U,S,undefined}],
|
||||||
options = Options},
|
options = Options},
|
||||||
case set_node(N) of
|
case set_node(Node) of
|
||||||
ok -> {ok, Nidx};
|
ok -> {ok, NodeIdx};
|
||||||
Other -> Other
|
Other -> Other
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'conflict')}
|
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'conflict')}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
set_node(#pubsub_node{id = {Key, _},
|
|
||||||
|
-spec(set_node/1 ::
|
||||||
|
(
|
||||||
|
Node :: pubsubNode())
|
||||||
|
-> 'ok' | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
set_node(#pubsub_node{id = {Host, _},
|
||||||
owners = Owners,
|
owners = Owners,
|
||||||
options = Options} = Node) ->
|
options = Options} = Node) ->
|
||||||
Parents = find_opt(collection, ?DEFAULT_PARENTS, Options),
|
ParentNodeIds = find_opt('collection', ?DEFAULT_PARENTS, Options),
|
||||||
case validate_parentage(Key, Owners, Parents) of
|
case validate_parentage(Host, Owners, ParentNodeIds) of
|
||||||
true ->
|
true ->
|
||||||
%% Update parents whenever the config changes.
|
%% Update parents whenever the config changes.
|
||||||
mnesia:write(Node#pubsub_node{parents = Parents});
|
mnesia:write(Node#pubsub_node{parents = ParentNodeIds});
|
||||||
Other ->
|
Other ->
|
||||||
Other
|
Other
|
||||||
end.
|
end.
|
||||||
|
|
||||||
delete_node(Key, Node) ->
|
|
||||||
case find_node(Key, Node) of
|
-spec(delete_node/2 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
NodeId :: nodeId())
|
||||||
|
-> [pubsubNode()] | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
delete_node(Host, NodeId) ->
|
||||||
|
case find_node(Host, NodeId) of
|
||||||
false ->
|
false ->
|
||||||
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
||||||
Record ->
|
ParentNode ->
|
||||||
%% Find all of N's children, update their configs to
|
%% Find all of N's children, update their configs to
|
||||||
%% remove N from the collection setting.
|
%% remove N from the collection setting.
|
||||||
lists:foreach(fun (#pubsub_node{options = Opts} = Child) ->
|
lists:foreach(fun (#pubsub_node{options = Options} = Node) ->
|
||||||
NewOpts = remove_config_parent(Node, Opts),
|
NewOptions = remove_config_parent(NodeId, Options),
|
||||||
Parents = find_opt(collection, ?DEFAULT_PARENTS, NewOpts),
|
Parents = find_opt('collection', ?DEFAULT_PARENTS, NewOptions),
|
||||||
ok = mnesia:write(pubsub_node,
|
ok = mnesia:write(pubsub_node,
|
||||||
Child#pubsub_node{
|
Node#pubsub_node{
|
||||||
parents = Parents,
|
parents = Parents,
|
||||||
options = NewOpts},
|
options = NewOptions},
|
||||||
write)
|
write)
|
||||||
end, get_subnodes(Key, Node)),
|
end, get_subnodes(Host, NodeId)),
|
||||||
|
|
||||||
%% Remove and return the requested node.
|
%% Remove and return the requested node.
|
||||||
pubsub_index:free(node, Record#pubsub_node.idx),
|
pubsub_index:free(node, ParentNode#pubsub_node.idx),
|
||||||
mnesia:delete_object(pubsub_node, Record, write),
|
mnesia:delete_object(pubsub_node, ParentNode, write),
|
||||||
[Record]
|
[ParentNode]
|
||||||
end.
|
end.
|
||||||
|
|
||||||
options() ->
|
|
||||||
nodetree_tree:options().
|
|
||||||
|
|
||||||
get_node(Host, Node, _From) ->
|
-spec(options/0 :: () -> Options::[Option::nodeOption()]).
|
||||||
get_node(Host, Node).
|
%Options::[{'virtual_tree', 'false'}])
|
||||||
|
|
||||||
get_node(Host, Node) ->
|
options() -> nodetree_tree:options().
|
||||||
case find_node(Host, Node) of
|
|
||||||
|
|
||||||
|
-spec(get_node/3 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
NodeId :: nodeId(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> pubsubNode() | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_node(Host, NodeId, _JID) ->
|
||||||
|
get_node(Host, NodeId).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_node/2 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
NodeId :: nodeId())
|
||||||
|
-> pubsubNode() | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_node(Host, NodeId) ->
|
||||||
|
case find_node(Host, NodeId) of
|
||||||
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
||||||
Record -> Record
|
Node -> Node
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_node(Node) ->
|
|
||||||
nodetree_tree:get_node(Node).
|
|
||||||
|
|
||||||
get_nodes(Key, From) ->
|
-spec(get_node/1 ::
|
||||||
nodetree_tree:get_nodes(Key, From).
|
(
|
||||||
|
NodeIdx :: nodeIdx())
|
||||||
|
-> pubsubNode() | {'error', 'item-not-found'}
|
||||||
|
).
|
||||||
|
|
||||||
get_nodes(Key) ->
|
get_node(NodeIdx) ->
|
||||||
nodetree_tree:get_nodes(Key).
|
nodetree_tree:get_node(NodeIdx).
|
||||||
|
|
||||||
get_parentnodes(Host, Node, _From) ->
|
|
||||||
case find_node(Host, Node) of
|
-spec(get_nodes/2 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> Nodes :: [] | [Node::pubsubNode()]
|
||||||
|
).
|
||||||
|
|
||||||
|
get_nodes(Host, JID) ->
|
||||||
|
nodetree_tree:get_nodes(Host, JID).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_nodes/1 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub())
|
||||||
|
-> Nodes :: [] | [Node::pubsubNode()]
|
||||||
|
).
|
||||||
|
|
||||||
|
get_nodes(Host) ->
|
||||||
|
nodetree_tree:get_nodes(Host).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(get_parentnodes/3 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
NodeId :: nodeId(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> ParentNodes :: [] | [ParentNode::pubsubNode()]
|
||||||
|
).
|
||||||
|
|
||||||
|
get_parentnodes(Host, NodeId, _JID) ->
|
||||||
|
case find_node(Host, NodeId) of
|
||||||
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
||||||
#pubsub_node{parents = Parents} ->
|
#pubsub_node{parents = ParentNodeIds} ->
|
||||||
Q = qlc:q([N || #pubsub_node{id = {NHost, NNode}} = N <- mnesia:table(pubsub_node),
|
Q = qlc:q([Node || #pubsub_node{id = {NHost, NNodeId}} = Node
|
||||||
Parent <- Parents,
|
<- mnesia:table(pubsub_node),
|
||||||
|
ParentNodeId <- ParentNodeIds,
|
||||||
Host == NHost,
|
Host == NHost,
|
||||||
Parent == NNode]),
|
ParentNodeId == NNodeId]),
|
||||||
qlc:e(Q)
|
qlc:e(Q)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_parentnodes_tree(Host, Node, _From) ->
|
|
||||||
|
-spec(get_parentnodes_tree/3 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
NodeId :: nodeId(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> [] | [{Depth::integer(), Nodes :: [] | [Node::pubsubNode()]}]
|
||||||
|
).
|
||||||
|
|
||||||
|
get_parentnodes_tree(Host, NodeId, _JID) ->
|
||||||
Pred = fun (Name, #pubsub_node{id = {_, NodeName}}) -> Name == NodeName end,
|
Pred = fun (Name, #pubsub_node{id = {_, NodeName}}) -> Name == NodeName end,
|
||||||
Tr = fun (#pubsub_node{parents = Parents}) -> Parents end,
|
Tr = fun (#pubsub_node{parents = Parents}) -> Parents end,
|
||||||
traversal_helper(Pred, Tr, Host, [Node]).
|
traversal_helper(Pred, Tr, Host, [NodeId]).
|
||||||
|
|
||||||
get_subnodes(Host, Node, _From) ->
|
|
||||||
|
-spec(get_subnodes/3 ::
|
||||||
|
(
|
||||||
|
ParentNodeHost :: hostPubsub(),
|
||||||
|
ParentNodeId :: nodeId(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> [] | [Node::pubsubNode()] | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_subnodes(Host, Node, _JID) ->
|
||||||
get_subnodes(Host, Node).
|
get_subnodes(Host, Node).
|
||||||
|
|
||||||
get_subnodes(Host, <<>>) ->
|
|
||||||
get_subnodes_helper(Host, <<>>);
|
-spec(get_subnodes/2 ::
|
||||||
get_subnodes(Host, Node) ->
|
(
|
||||||
case find_node(Host, Node) of
|
ParentNodeHost :: hostPubsub(),
|
||||||
|
ParentNodeId :: nodeId())
|
||||||
|
-> [] | [Node::pubsubNode()] | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
get_subnodes(ParentNodeHost, <<>>) ->
|
||||||
|
get_subnodes_helper(ParentNodeHost, <<>>);
|
||||||
|
get_subnodes(ParentNodeHost, ParentNodeId) ->
|
||||||
|
case find_node(ParentNodeHost, ParentNodeId) of
|
||||||
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item-not-found')};
|
||||||
_ -> get_subnodes_helper(Host, Node)
|
_ -> get_subnodes_helper(ParentNodeHost, ParentNodeId)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_subnodes_helper(Host, Node) ->
|
|
||||||
Q = qlc:q([Record || #pubsub_node{id = {NHost, _},
|
-spec(get_subnodes_helper/2 ::
|
||||||
parents = Parents} = Record <- mnesia:table(pubsub_node),
|
(
|
||||||
Host == NHost,
|
ParentNodeHost :: hostPubsub(),
|
||||||
lists:member(Node, Parents)]),
|
ParentNodeId :: nodeId())
|
||||||
|
-> SubNodes :: [] | [Node::pubsubNode()]
|
||||||
|
).
|
||||||
|
|
||||||
|
get_subnodes_helper(ParentNodeHost, ParentNodeId) ->
|
||||||
|
Q = qlc:q([Node || #pubsub_node{id = {Host, _},
|
||||||
|
parents = ParentNodeIds} = Node <- mnesia:table(pubsub_node),
|
||||||
|
ParentNodeHost == Host,
|
||||||
|
lists:member(ParentNodeId, ParentNodeIds)]),
|
||||||
qlc:e(Q).
|
qlc:e(Q).
|
||||||
|
|
||||||
get_subnodes_tree(Host, Node, From) ->
|
|
||||||
Pred = fun (N, #pubsub_node{parents = Parents}) ->
|
-spec(get_subnodes_tree/3 ::
|
||||||
lists:member(N, Parents)
|
(
|
||||||
|
ParentNodeHost :: hostPubsub(),
|
||||||
|
ParentNodeId :: nodeId(),
|
||||||
|
JID :: jidEntity())
|
||||||
|
-> [] | [{Depth::integer(), Nodes :: [] | [Node::pubsubNode()]}]
|
||||||
|
).
|
||||||
|
|
||||||
|
get_subnodes_tree(Host, ParentNodeId, JID) ->
|
||||||
|
Pred = fun(NodeId, #pubsub_node{parents = ParentNodeIds}) ->
|
||||||
|
lists:member(NodeId, ParentNodeIds)
|
||||||
end,
|
end,
|
||||||
Tr = fun (#pubsub_node{id = {_, N}}) -> [N] end,
|
Tr = fun (#pubsub_node{id = {_, NodeId}}) -> [NodeId] end,
|
||||||
traversal_helper(Pred, Tr, 1, Host, [Node],
|
traversal_helper(Pred, Tr, 1, Host, [ParentNodeId],
|
||||||
[{0, [get_node(Host, Node, From)]}]).
|
[{0, [get_node(Host, ParentNodeId, JID)]}]).
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
@ -181,8 +318,15 @@ oid(Key, Name) -> {Key, Name}.
|
|||||||
|
|
||||||
%% Key = jlib:jid() | host()
|
%% Key = jlib:jid() | host()
|
||||||
%% Node = string()
|
%% Node = string()
|
||||||
find_node(Key, Node) ->
|
-spec(find_node/2 ::
|
||||||
case mnesia:read(pubsub_node, oid(Key, Node), read) of
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
NodeId :: nodeId())
|
||||||
|
-> pubsubNode() | 'false'
|
||||||
|
).
|
||||||
|
|
||||||
|
find_node(Host, NodeId) ->
|
||||||
|
case mnesia:read({pubsub_node, {Host, NodeId}}) of
|
||||||
[] -> false;
|
[] -> false;
|
||||||
[Node] -> Node
|
[Node] -> Node
|
||||||
end.
|
end.
|
||||||
@ -190,53 +334,109 @@ find_node(Key, Node) ->
|
|||||||
%% Key = jlib:jid() | host()
|
%% Key = jlib:jid() | host()
|
||||||
%% Default = term()
|
%% Default = term()
|
||||||
%% Options = [{Key = atom(), Value = term()}]
|
%% Options = [{Key = atom(), Value = term()}]
|
||||||
|
-spec(find_opt/3 ::
|
||||||
|
(
|
||||||
|
Key :: atom(),
|
||||||
|
Default :: term(),
|
||||||
|
Options :: [Option::nodeOption()])
|
||||||
|
-> Value::term()
|
||||||
|
).
|
||||||
|
|
||||||
find_opt(Key, Default, Options) ->
|
find_opt(Key, Default, Options) ->
|
||||||
case lists:keysearch(Key, 1, Options) of
|
case lists:keysearch(Key, 1, Options) of
|
||||||
{value, {Key, Val}} -> Val;
|
{value, {Key, Value}} -> Value;
|
||||||
_ -> Default
|
_ -> Default
|
||||||
end.
|
end.
|
||||||
|
|
||||||
traversal_helper(Pred, Tr, Host, Nodes) ->
|
|
||||||
traversal_helper(Pred, Tr, 0, Host, Nodes, []).
|
-spec(traversal_helper/4 ::
|
||||||
|
(
|
||||||
|
Pred :: fun(),
|
||||||
|
Tr :: fun(),
|
||||||
|
ParentNodeHost :: hostPubsub(),
|
||||||
|
ParentNodeIds :: [] | [ParentNodeId::nodeId()])
|
||||||
|
-> [] | [{Depth::integer(), Nodes :: [] | [Node::pubsubNode()]}]
|
||||||
|
).
|
||||||
|
|
||||||
|
traversal_helper(Pred, Tr, ParentNodeHost, ParentNodeIds) ->
|
||||||
|
traversal_helper(Pred, Tr, 0, ParentNodeHost, ParentNodeIds, []).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(traversal_helper/6 ::
|
||||||
|
(
|
||||||
|
Pred :: fun(),
|
||||||
|
Tr :: fun(),
|
||||||
|
Depth :: integer(),
|
||||||
|
ParentNodeHost :: hostPubsub(),
|
||||||
|
ParentNodeIds :: [] | [ParentNodeId::nodeId()],
|
||||||
|
Acc :: [] | [{Depth::integer(), Nodes :: [] | [Node::pubsubNode()]}])
|
||||||
|
-> [] | [{Depth::integer(), Nodes :: [] | [Node::pubsubNode()]}]
|
||||||
|
).
|
||||||
|
|
||||||
traversal_helper(_Pred, _Tr, _Depth, _Host, [], Acc) ->
|
traversal_helper(_Pred, _Tr, _Depth, _Host, [], Acc) ->
|
||||||
Acc;
|
Acc;
|
||||||
traversal_helper(Pred, Tr, Depth, Host, Nodes, Acc) ->
|
traversal_helper(Pred, Tr, Depth, ParentNodeHost, ParentNodeIds, Acc) ->
|
||||||
Q = qlc:q([Record || #pubsub_node{id = {NHost, _}} = Record <- mnesia:table(pubsub_node),
|
Q = qlc:q([Node || #pubsub_node{id = {Host, _}} = Node <- mnesia:table(pubsub_node),
|
||||||
Node <- Nodes,
|
ParentNodeId <- ParentNodeIds,
|
||||||
Host == NHost,
|
ParentNodeHost == Host,
|
||||||
Pred(Node, Node)]),
|
Pred(ParentNodeId, Node)]),
|
||||||
Nodes = qlc:e(Q),
|
Nodes = qlc:e(Q),
|
||||||
Names = lists:flatmap(Tr, Nodes),
|
Ids = lists:flatmap(Tr, Nodes),
|
||||||
traversal_helper(Pred, Tr, Depth + 1, Host, Names, [{Depth, Nodes} | Acc]).
|
traversal_helper(Pred, Tr, Depth + 1, ParentNodeHost, Ids, [{Depth, Nodes} | Acc]).
|
||||||
|
|
||||||
remove_config_parent(Node, Options) ->
|
|
||||||
remove_config_parent(Node, Options, []).
|
|
||||||
|
|
||||||
remove_config_parent(_Node, [], Acc) ->
|
-spec(remove_config_parent/2 ::
|
||||||
|
(
|
||||||
|
NodeId :: nodeId(),
|
||||||
|
Options :: [Option::nodeOption()])
|
||||||
|
-> [Option::nodeOption()]
|
||||||
|
).
|
||||||
|
|
||||||
|
remove_config_parent(NodeId, Options) ->
|
||||||
|
remove_config_parent(NodeId, Options, []).
|
||||||
|
|
||||||
|
|
||||||
|
-spec(remove_config_parent/3 ::
|
||||||
|
(
|
||||||
|
NodeId :: nodeId(),
|
||||||
|
Options :: [] | [Option::nodeOption()],
|
||||||
|
Acc :: [Option::nodeOption()])
|
||||||
|
-> [Option::nodeOption()]
|
||||||
|
).
|
||||||
|
|
||||||
|
remove_config_parent(_NodeId, [], Acc) ->
|
||||||
lists:reverse(Acc);
|
lists:reverse(Acc);
|
||||||
remove_config_parent(Node, [{collection, Parents} | T], Acc) ->
|
remove_config_parent(NodeId, [{'collection', ParentNodeIds} | Options], Acc) ->
|
||||||
remove_config_parent(Node, T,
|
remove_config_parent(NodeId, Options,
|
||||||
[{collection, lists:delete(Node, Parents)} | Acc]);
|
[{'collection', lists:delete(NodeId, ParentNodeIds)} | Acc]);
|
||||||
remove_config_parent(Node, [H | T], Acc) ->
|
remove_config_parent(NodeId, [Option | Options], Acc) ->
|
||||||
remove_config_parent(Node, T, [H | Acc]).
|
remove_config_parent(NodeId, Options, [Option | Acc]).
|
||||||
|
|
||||||
validate_parentage(_Key, _Owners, []) ->
|
|
||||||
|
-spec(validate_parentage/3 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub(),
|
||||||
|
Owners :: [Owner::bareUsr()],
|
||||||
|
ParentNodeIds :: [] | [ParentNodeId::nodeId()] | [ParentNodeId :: nodeId() | []])
|
||||||
|
-> 'true' | {'error', _}
|
||||||
|
).
|
||||||
|
|
||||||
|
validate_parentage(_Host, _Owners, []) ->
|
||||||
true;
|
true;
|
||||||
validate_parentage(Key, Owners, [[] | T]) ->
|
validate_parentage(Host, Owners, [[] | ParentNodeIds]) ->
|
||||||
validate_parentage(Key, Owners, T);
|
validate_parentage(Host, Owners, ParentNodeIds);
|
||||||
validate_parentage(Key, Owners, [<<>> | T]) ->
|
validate_parentage(Host, Owners, [<<>> | ParentNodeIds]) ->
|
||||||
validate_parentage(Key, Owners, T);
|
validate_parentage(Host, Owners, ParentNodeIds);
|
||||||
validate_parentage(Key, Owners, [ParentId | T]) ->
|
validate_parentage(Host, Owners, [ParentNodeId | ParentNodeIds]) ->
|
||||||
case find_node(Key, ParentId) of
|
case find_node(Host, ParentNodeId) of
|
||||||
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item_not_found')};
|
false -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'item_not_found')};
|
||||||
#pubsub_node{owners = POwners, options = POptions} ->
|
#pubsub_node{owners = ParentNodeOwners, options = Options} ->
|
||||||
NodeType = find_opt(node_type, ?DEFAULT_NODETYPE, POptions),
|
NodeType = find_opt('node_type', ?DEFAULT_NODETYPE, Options),
|
||||||
MutualOwners = [O || O <- Owners, PO <- POwners,
|
MutualOwners = [Owner || Owner <- Owners, ParentNodeOwner <- ParentNodeOwners,
|
||||||
O == PO],
|
Owner == ParentNodeOwner],
|
||||||
case {MutualOwners, NodeType} of
|
case {MutualOwners, NodeType} of
|
||||||
{[], _} -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'forbidden')};
|
{[], _} -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'forbidden')};
|
||||||
{_, collection} -> validate_parentage(Key, Owners, T);
|
{_, 'collection'} -> validate_parentage(Host, Owners, ParentNodeIds);
|
||||||
{_, _} -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'not-allowed')}
|
{_, _} -> {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'not-allowed')}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
@ -244,6 +444,12 @@ validate_parentage(Key, Owners, [ParentId | T]) ->
|
|||||||
%% @spec (Host) -> jid()
|
%% @spec (Host) -> jid()
|
||||||
%% Host = host()
|
%% Host = host()
|
||||||
%% @doc <p>Generate pubsub service JID.</p>
|
%% @doc <p>Generate pubsub service JID.</p>
|
||||||
|
-spec(service_jid/1 ::
|
||||||
|
(
|
||||||
|
Host :: hostPubsub())
|
||||||
|
-> ServiceJID :: jidContact() | jidComponent() %% should only return jidContact()
|
||||||
|
).
|
||||||
|
|
||||||
service_jid(Host) ->
|
service_jid(Host) ->
|
||||||
case Host of
|
case Host of
|
||||||
{U,S,_} -> exmpp_jid:make(U, S);
|
{U,S,_} -> exmpp_jid:make(U, S);
|
||||||
|
@ -157,7 +157,7 @@ get_node(Host, NodeId) ->
|
|||||||
-spec(get_node/1 ::
|
-spec(get_node/1 ::
|
||||||
(
|
(
|
||||||
NodeIdx :: nodeIdx())
|
NodeIdx :: nodeIdx())
|
||||||
-> pubsubNode() | {error, 'item-not-found'} | any()
|
-> pubsubNode() | {'error', 'item-not-found'}
|
||||||
).
|
).
|
||||||
|
|
||||||
get_node(NodeIdx) ->
|
get_node(NodeIdx) ->
|
||||||
|
Loading…
Reference in New Issue
Block a user