mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Rewrite mod_pubsub to use XML codec
This commit is contained in:
parent
31faa4eb9a
commit
45eb49125b
@ -5,6 +5,47 @@
|
||||
hash :: binary()}).
|
||||
-type vcard_xupdate() :: #vcard_xupdate{}.
|
||||
|
||||
-record(ps_affiliation, {xmlns = <<>> :: binary(),
|
||||
node = <<>> :: binary(),
|
||||
type :: member | none | outcast |
|
||||
owner | publisher | 'publish-only',
|
||||
jid :: jid:jid()}).
|
||||
-type ps_affiliation() :: #ps_affiliation{}.
|
||||
|
||||
-type ps_error_type() :: 'closed-node' | 'configuration-required' |
|
||||
'invalid-jid' | 'invalid-options' |
|
||||
'invalid-payload' | 'invalid-subid' |
|
||||
'item-forbidden' | 'item-required' | 'jid-required' |
|
||||
'max-items-exceeded' | 'max-nodes-exceeded' |
|
||||
'nodeid-required' | 'not-in-roster-group' |
|
||||
'not-subscribed' | 'payload-too-big' |
|
||||
'payload-required' | 'pending-subscription' |
|
||||
'presence-subscription-required' | 'subid-required' |
|
||||
'too-many-subscriptions' | 'unsupported' |
|
||||
'unsupported-access-model'.
|
||||
-type ps_error_feature() :: 'access-authorize' | 'access-open' |
|
||||
'access-presence' | 'access-roster' |
|
||||
'access-whitelist' | 'auto-create' |
|
||||
'auto-subscribe' | 'collections' | 'config-node' |
|
||||
'create-and-configure' | 'create-nodes' |
|
||||
'delete-items' | 'delete-nodes' |
|
||||
'filtered-notifications' | 'get-pending' |
|
||||
'instant-nodes' | 'item-ids' | 'last-published' |
|
||||
'leased-subscription' | 'manage-subscriptions' |
|
||||
'member-affiliation' | 'meta-data' |
|
||||
'modify-affiliations' | 'multi-collection' |
|
||||
'multi-subscribe' | 'outcast-affiliation' |
|
||||
'persistent-items' | 'presence-notifications' |
|
||||
'presence-subscribe' | 'publish' |
|
||||
'publish-options' | 'publish-only-affiliation' |
|
||||
'publisher-affiliation' | 'purge-nodes' |
|
||||
'retract-items' | 'retrieve-affiliations' |
|
||||
'retrieve-default' | 'retrieve-items' |
|
||||
'retrieve-subscriptions' | 'subscribe' |
|
||||
'subscription-options' | 'subscription-notifications'.
|
||||
-record(ps_error, {type :: ps_error_type(), feature :: ps_error_feature()}).
|
||||
-type ps_error() :: #ps_error{}.
|
||||
|
||||
-record(chatstate, {type :: active | composing | gone | inactive | paused}).
|
||||
-type chatstate() :: #chatstate{}.
|
||||
|
||||
@ -77,10 +118,10 @@
|
||||
-record(muc_unsubscribe, {}).
|
||||
-type muc_unsubscribe() :: #muc_unsubscribe{}.
|
||||
|
||||
-record(pubsub_unsubscribe, {node = <<>> :: binary(),
|
||||
jid :: jid:jid(),
|
||||
subid = <<>> :: binary()}).
|
||||
-type pubsub_unsubscribe() :: #pubsub_unsubscribe{}.
|
||||
-record(ps_unsubscribe, {node = <<>> :: binary(),
|
||||
jid :: jid:jid(),
|
||||
subid = <<>> :: binary()}).
|
||||
-type ps_unsubscribe() :: #ps_unsubscribe{}.
|
||||
|
||||
-record(mix_leave, {}).
|
||||
-type mix_leave() :: #mix_leave{}.
|
||||
@ -105,10 +146,6 @@
|
||||
height :: non_neg_integer()}).
|
||||
-type thumbnail() :: #thumbnail{}.
|
||||
|
||||
-record(pubsub_affiliation, {node = <<>> :: binary(),
|
||||
type :: 'member' | 'none' | 'outcast' | 'owner' | 'publish-only' | 'publisher'}).
|
||||
-type pubsub_affiliation() :: #pubsub_affiliation{}.
|
||||
|
||||
-record(muc_decline, {reason = <<>> :: binary(),
|
||||
from :: jid:jid(),
|
||||
to :: jid:jid()}).
|
||||
@ -195,13 +232,16 @@
|
||||
-record(feature_sm, {xmlns = <<>> :: binary()}).
|
||||
-type feature_sm() :: #feature_sm{}.
|
||||
|
||||
-record(pubsub_item, {id = <<>> :: binary(),
|
||||
xml_els = [] :: [fxml:xmlel()]}).
|
||||
-type pubsub_item() :: #pubsub_item{}.
|
||||
-record(ps_item, {xmlns = <<>> :: binary(),
|
||||
id = <<>> :: binary(),
|
||||
xml_els = [] :: [fxml:xmlel()],
|
||||
node = <<>> :: binary(),
|
||||
publisher = <<>> :: binary()}).
|
||||
-type ps_item() :: #ps_item{}.
|
||||
|
||||
-record(pubsub_publish, {node = <<>> :: binary(),
|
||||
items = [] :: [#pubsub_item{}]}).
|
||||
-type pubsub_publish() :: #pubsub_publish{}.
|
||||
-record(ps_publish, {node = <<>> :: binary(),
|
||||
items = [] :: [#ps_item{}]}).
|
||||
-type ps_publish() :: #ps_publish{}.
|
||||
|
||||
-record(roster_item, {jid :: jid:jid(),
|
||||
name = <<>> :: binary(),
|
||||
@ -214,12 +254,6 @@
|
||||
ver :: binary()}).
|
||||
-type roster_query() :: #roster_query{}.
|
||||
|
||||
-record(pubsub_event_item, {id = <<>> :: binary(),
|
||||
node = <<>> :: binary(),
|
||||
publisher = <<>> :: binary(),
|
||||
xml_els = [] :: [fxml:xmlel()]}).
|
||||
-type pubsub_event_item() :: #pubsub_event_item{}.
|
||||
|
||||
-record(sm_r, {xmlns = <<>> :: binary()}).
|
||||
-type sm_r() :: #sm_r{}.
|
||||
|
||||
@ -263,14 +297,6 @@
|
||||
xmlns = <<>> :: binary()}).
|
||||
-type sm_enabled() :: #sm_enabled{}.
|
||||
|
||||
-record(pubsub_event_items, {node = <<>> :: binary(),
|
||||
retract = [] :: [binary()],
|
||||
items = [] :: [#pubsub_event_item{}]}).
|
||||
-type pubsub_event_items() :: #pubsub_event_items{}.
|
||||
|
||||
-record(pubsub_event, {items = [] :: [#pubsub_event_items{}]}).
|
||||
-type pubsub_event() :: #pubsub_event{}.
|
||||
|
||||
-record(muc_unique, {name = <<>> :: binary()}).
|
||||
-type muc_unique() :: #muc_unique{}.
|
||||
|
||||
@ -283,9 +309,9 @@
|
||||
resource :: binary()}).
|
||||
-type legacy_auth() :: #legacy_auth{}.
|
||||
|
||||
-record(pubsub_subscribe, {node = <<>> :: binary(),
|
||||
jid :: jid:jid()}).
|
||||
-type pubsub_subscribe() :: #pubsub_subscribe{}.
|
||||
-record(ps_subscribe, {node = <<>> :: binary(),
|
||||
jid :: jid:jid()}).
|
||||
-type ps_subscribe() :: #ps_subscribe{}.
|
||||
|
||||
-record(message, {id = <<>> :: binary(),
|
||||
type = normal :: 'chat' | 'error' | 'groupchat' | 'headline' | 'normal',
|
||||
@ -325,11 +351,13 @@
|
||||
-record(muc_subscriptions, {list = [] :: [jid:jid()]}).
|
||||
-type muc_subscriptions() :: #muc_subscriptions{}.
|
||||
|
||||
-record(pubsub_subscription, {jid :: jid:jid(),
|
||||
node = <<>> :: binary(),
|
||||
subid = <<>> :: binary(),
|
||||
type :: 'none' | 'pending' | 'subscribed' | 'unconfigured'}).
|
||||
-type pubsub_subscription() :: #pubsub_subscription{}.
|
||||
-record(ps_subscription, {xmlns = <<>> :: binary(),
|
||||
jid :: jid:jid(),
|
||||
type :: 'none' | 'pending' | 'subscribed' | 'unconfigured',
|
||||
node = <<>> :: binary(),
|
||||
subid = <<>> :: binary(),
|
||||
expiry :: erlang:timestamp()}).
|
||||
-type ps_subscription() :: #ps_subscription{}.
|
||||
|
||||
-record(bob_data, {cid = <<>> :: binary(),
|
||||
'max-age' :: non_neg_integer(),
|
||||
@ -375,11 +403,13 @@
|
||||
node = <<>> :: binary()}).
|
||||
-type stats() :: #stats{}.
|
||||
|
||||
-record(pubsub_items, {node = <<>> :: binary(),
|
||||
max_items :: non_neg_integer(),
|
||||
subid = <<>> :: binary(),
|
||||
items = [] :: [#pubsub_item{}]}).
|
||||
-type pubsub_items() :: #pubsub_items{}.
|
||||
-record(ps_items, {xmlns = <<>> :: binary(),
|
||||
node = <<>> :: binary(),
|
||||
items = [] :: [#ps_item{}],
|
||||
max_items :: non_neg_integer(),
|
||||
subid = <<>> :: binary(),
|
||||
retract :: binary()}).
|
||||
-type ps_items() :: #ps_items{}.
|
||||
|
||||
-record(presence, {id = <<>> :: binary(),
|
||||
type = available :: 'available' | 'error' | 'probe' | 'subscribe' | 'subscribed' | 'unavailable' | 'unsubscribe' | 'unsubscribed',
|
||||
@ -438,10 +468,10 @@
|
||||
-record(carbons_received, {forwarded :: #forwarded{}}).
|
||||
-type carbons_received() :: #carbons_received{}.
|
||||
|
||||
-record(pubsub_retract, {node = <<>> :: binary(),
|
||||
notify = false :: boolean(),
|
||||
items = [] :: [#pubsub_item{}]}).
|
||||
-type pubsub_retract() :: #pubsub_retract{}.
|
||||
-record(ps_retract, {node = <<>> :: binary(),
|
||||
notify = false :: boolean(),
|
||||
items = [] :: [#ps_item{}]}).
|
||||
-type ps_retract() :: #ps_retract{}.
|
||||
|
||||
-record(upload_slot, {get :: binary(),
|
||||
put :: binary(),
|
||||
@ -707,22 +737,46 @@
|
||||
xdata :: #xdata{}}).
|
||||
-type mam_query() :: #mam_query{}.
|
||||
|
||||
-record(pubsub_options, {node = <<>> :: binary(),
|
||||
jid :: jid:jid(),
|
||||
subid = <<>> :: binary(),
|
||||
xdata :: #xdata{}}).
|
||||
-type pubsub_options() :: #pubsub_options{}.
|
||||
-record(pubsub_owner, {affiliations :: {binary(),[#ps_affiliation{}]},
|
||||
configure :: {binary(),'undefined' | #xdata{}},
|
||||
default :: {binary(),'undefined' | #xdata{}},
|
||||
delete :: {binary(),binary()},
|
||||
purge :: binary(),
|
||||
subscriptions :: {binary(),[#ps_subscription{}]}}).
|
||||
-type pubsub_owner() :: #pubsub_owner{}.
|
||||
|
||||
-record(pubsub, {subscriptions :: {binary(),[#pubsub_subscription{}]},
|
||||
affiliations :: [#pubsub_affiliation{}],
|
||||
publish :: #pubsub_publish{},
|
||||
subscribe :: #pubsub_subscribe{},
|
||||
unsubscribe :: #pubsub_unsubscribe{},
|
||||
options :: #pubsub_options{},
|
||||
items :: #pubsub_items{},
|
||||
retract :: #pubsub_retract{}}).
|
||||
-record(ps_options, {node = <<>> :: binary(),
|
||||
jid :: jid:jid(),
|
||||
subid = <<>> :: binary(),
|
||||
xdata :: #xdata{}}).
|
||||
-type ps_options() :: #ps_options{}.
|
||||
|
||||
-record(pubsub, {subscriptions :: {binary(),[#ps_subscription{}]},
|
||||
subscription :: #ps_subscription{},
|
||||
affiliations :: {binary(),[#ps_affiliation{}]},
|
||||
publish :: #ps_publish{},
|
||||
publish_options :: #xdata{},
|
||||
subscribe :: #ps_subscribe{},
|
||||
unsubscribe :: #ps_unsubscribe{},
|
||||
options :: #ps_options{},
|
||||
items :: #ps_items{},
|
||||
retract :: #ps_retract{},
|
||||
create :: binary(),
|
||||
configure :: {binary(),'undefined' | #xdata{}},
|
||||
default :: {binary(),'undefined' | #xdata{}},
|
||||
delete :: {binary(),binary()},
|
||||
purge :: binary(),
|
||||
rsm :: #rsm_set{}}).
|
||||
-type pubsub() :: #pubsub{}.
|
||||
|
||||
-record(ps_event, {items :: #ps_items{},
|
||||
purge :: binary(),
|
||||
subscription :: #ps_subscription{},
|
||||
delete :: {binary(),binary()},
|
||||
create :: binary(),
|
||||
configuration :: {binary(),'undefined' | #xdata{}}}).
|
||||
-type ps_event() :: #ps_event{}.
|
||||
|
||||
-record(register, {registered = false :: boolean(),
|
||||
remove = false :: boolean(),
|
||||
instructions :: binary(),
|
||||
@ -852,21 +906,27 @@
|
||||
|
||||
-type xmpp_element() :: muc_admin() |
|
||||
compression() |
|
||||
pubsub_subscription() |
|
||||
ps_subscription() |
|
||||
xdata_option() |
|
||||
version() |
|
||||
pubsub_affiliation() |
|
||||
ps_affiliation() |
|
||||
mam_fin() |
|
||||
sm_a() |
|
||||
bob_data() |
|
||||
media() |
|
||||
stanza_id() |
|
||||
starttls_proceed() |
|
||||
client_id() |
|
||||
sm_resumed() |
|
||||
forwarded() |
|
||||
xevent() |
|
||||
privacy_list() |
|
||||
carbons_sent() |
|
||||
mam_archived() |
|
||||
p1_rebind() |
|
||||
sasl_abort() |
|
||||
db_result() |
|
||||
carbons_received() |
|
||||
pubsub_retract() |
|
||||
upload_slot() |
|
||||
mix_participant() |
|
||||
compressed() |
|
||||
@ -875,31 +935,20 @@
|
||||
'see-other-host'() |
|
||||
hint() |
|
||||
stream_start() |
|
||||
stanza_id() |
|
||||
starttls_proceed() |
|
||||
client_id() |
|
||||
sm_resumed() |
|
||||
forwarded() |
|
||||
xevent() |
|
||||
privacy_list() |
|
||||
text() |
|
||||
vcard_org() |
|
||||
shim() |
|
||||
search_item() |
|
||||
offline_item() |
|
||||
feature_sm() |
|
||||
pubsub_item() |
|
||||
roster_item() |
|
||||
pubsub_event_item() |
|
||||
muc_item() |
|
||||
vcard_temp() |
|
||||
address() |
|
||||
sasl_success() |
|
||||
addresses() |
|
||||
pubsub_event_items() |
|
||||
muc_subscriptions() |
|
||||
disco_items() |
|
||||
pubsub_options() |
|
||||
compress() |
|
||||
bytestreams() |
|
||||
adhoc_actions() |
|
||||
@ -912,9 +961,16 @@
|
||||
vcard_tel() |
|
||||
vcard_geo() |
|
||||
vcard_photo() |
|
||||
pubsub_owner() |
|
||||
pubsub() |
|
||||
muc_owner() |
|
||||
muc_actor() |
|
||||
ps_error() |
|
||||
starttls_failure() |
|
||||
sasl_challenge() |
|
||||
x_conference() |
|
||||
private() |
|
||||
sasl_failure() |
|
||||
vcard_name() |
|
||||
adhoc_note() |
|
||||
rosterver_feature() |
|
||||
@ -924,18 +980,15 @@
|
||||
bookmark_conference() |
|
||||
offline() |
|
||||
time() |
|
||||
ps_subscribe() |
|
||||
sm_enable() |
|
||||
starttls_failure() |
|
||||
sasl_challenge() |
|
||||
handshake() |
|
||||
x_conference() |
|
||||
private() |
|
||||
compress_failure() |
|
||||
sasl_failure() |
|
||||
bookmark_storage() |
|
||||
muc_decline() |
|
||||
legacy_auth() |
|
||||
search() |
|
||||
ps_publish() |
|
||||
nick() |
|
||||
p1_ack() |
|
||||
block() |
|
||||
@ -946,11 +999,12 @@
|
||||
xcaptcha() |
|
||||
streamhost() |
|
||||
bind() |
|
||||
ps_retract() |
|
||||
last() |
|
||||
redirect() |
|
||||
sm_enabled() |
|
||||
pubsub_event() |
|
||||
vcard_sound() |
|
||||
ps_event() |
|
||||
mam_result() |
|
||||
rsm_first() |
|
||||
stat() |
|
||||
@ -961,15 +1015,17 @@
|
||||
ping() |
|
||||
privacy_item() |
|
||||
disco_item() |
|
||||
ps_item() |
|
||||
mam_prefs() |
|
||||
sasl_mechanisms() |
|
||||
caps() |
|
||||
muc() |
|
||||
stream_features() |
|
||||
stats() |
|
||||
pubsub_items() |
|
||||
ps_items() |
|
||||
sic() |
|
||||
ps_options() |
|
||||
starttls() |
|
||||
mam_prefs() |
|
||||
sasl_mechanisms() |
|
||||
media_uri() |
|
||||
muc_destroy() |
|
||||
vcard_key() |
|
||||
@ -990,23 +1046,21 @@
|
||||
stream_error() |
|
||||
muc_user() |
|
||||
vcard_adr() |
|
||||
gone() |
|
||||
carbons_private() |
|
||||
mix_leave() |
|
||||
muc_subscribe() |
|
||||
muc_unique() |
|
||||
sasl_response() |
|
||||
pubsub_subscribe() |
|
||||
message() |
|
||||
presence() |
|
||||
gone() |
|
||||
sm_resume() |
|
||||
carbons_enable() |
|
||||
expire() |
|
||||
muc_unsubscribe() |
|
||||
pubsub_unsubscribe() |
|
||||
ps_unsubscribe() |
|
||||
chatstate() |
|
||||
sasl_auth() |
|
||||
p1_push() |
|
||||
oob_x() |
|
||||
pubsub_publish() |
|
||||
unblock().
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
-module(gen_pubsub_node).
|
||||
|
||||
-include("jlib.hrl").
|
||||
-include("xmpp.hrl").
|
||||
|
||||
-type(host() :: mod_pubsub:host()).
|
||||
-type(nodeId() :: mod_pubsub:nodeId()).
|
||||
@ -175,20 +175,13 @@
|
||||
ok |
|
||||
{error, xmlel()}.
|
||||
|
||||
-callback get_items(NodeIdx :: nodeIdx(),
|
||||
JID :: jid(),
|
||||
AccessModel :: accessModel(),
|
||||
Presence_Subscription :: boolean(),
|
||||
RosterGroup :: boolean(),
|
||||
SubId :: subId(),
|
||||
RSM :: none | rsm_in()) ->
|
||||
{result, {[pubsubItem()], none | rsm_out()}} |
|
||||
{error, xmlel()}.
|
||||
-callback get_items(nodeIdx(), jid(), accessModel(),
|
||||
boolean(), boolean(), binary(),
|
||||
undefined | rsm_set()) ->
|
||||
{result, {[pubsubItem()], undefined | rsm_set()}} | {error, error()}.
|
||||
|
||||
-callback get_items(NodeIdx :: nodeIdx(),
|
||||
From :: jid(),
|
||||
RSM :: none | rsm_in()) ->
|
||||
{result, {[pubsubItem()], none | rsm_out()}}.
|
||||
-callback get_items(nodeIdx(), jid(), undefined | rsm_set()) ->
|
||||
{result, {[pubsubItem()], undefined | rsm_set()}}.
|
||||
|
||||
-callback get_item(NodeIdx :: nodeIdx(),
|
||||
ItemId :: itemId(),
|
||||
|
@ -406,13 +406,15 @@ feature_response(_IQResult, Host, From, Caps,
|
||||
[_SubNode | SubNodes]) ->
|
||||
feature_request(Host, From, Caps, SubNodes).
|
||||
|
||||
-spec caps_read_fun(binary(), {binary(), binary()}) -> function().
|
||||
-spec caps_read_fun(binary(), {binary(), binary()})
|
||||
-> fun(() -> {ok, [binary()] | non_neg_integer()} | error).
|
||||
caps_read_fun(Host, Node) ->
|
||||
LServer = jid:nameprep(Host),
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
fun() -> Mod:caps_read(LServer, Node) end.
|
||||
|
||||
-spec caps_write_fun(binary(), {binary(), binary()}, [binary()]) -> function().
|
||||
-spec caps_write_fun(binary(), {binary(), binary()},
|
||||
[binary()] | non_neg_integer()) -> fun().
|
||||
caps_write_fun(Host, Node, Features) ->
|
||||
LServer = jid:nameprep(Host),
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
|
@ -287,8 +287,8 @@ get_pep_node(#message{from = #jid{luser = <<>>}}) ->
|
||||
%% It's not PEP.
|
||||
undefined;
|
||||
get_pep_node(#message{} = Msg) ->
|
||||
case xmpp:get_subtag(Msg, #pubsub_event{}) of
|
||||
#pubsub_event{items = [#pubsub_event_items{node = Node}]} ->
|
||||
case xmpp:get_subtag(Msg, #ps_event{}) of
|
||||
#ps_event{items = #ps_items{node = Node}} ->
|
||||
Node;
|
||||
_ ->
|
||||
undefined
|
||||
|
@ -4377,12 +4377,12 @@ send_wrapped(From, To, Packet, Node, State) ->
|
||||
wrap(From, To, Packet, Node) ->
|
||||
El = xmpp:encode(xmpp:set_from_to(Packet, From, To)),
|
||||
#message{
|
||||
sub_els = [#pubsub_event{
|
||||
items = [#pubsub_event_items{
|
||||
node = Node,
|
||||
items = [#pubsub_event_item{
|
||||
id = randoms:get_string(),
|
||||
xml_els = [El]}]}]}]}.
|
||||
sub_els = [#ps_event{
|
||||
items = #ps_items{
|
||||
node = Node,
|
||||
items = [#ps_item{
|
||||
id = randoms:get_string(),
|
||||
xml_els = [El]}]}}]}.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% Multicast
|
||||
|
2907
src/mod_pubsub.erl
2907
src/mod_pubsub.erl
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,7 @@
|
||||
-compile([{parse_transform, ejabberd_sql_pt}]).
|
||||
|
||||
-include("pubsub.hrl").
|
||||
-include("jlib.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
|
||||
-export([init/3, terminate/2, options/0, features/0,
|
||||
@ -81,27 +81,27 @@ create_node(Nidx, Owner) ->
|
||||
J = encode_jid(OwnerKey),
|
||||
A = encode_affiliation(owner),
|
||||
S = encode_subscriptions([]),
|
||||
catch ejabberd_sql:sql_query_t(
|
||||
?SQL("insert into pubsub_state("
|
||||
"nodeid, jid, affiliation, subscriptions) "
|
||||
"values (%(Nidx)d, %(J)s, %(A)s, %(S)s)")),
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("insert into pubsub_state("
|
||||
"nodeid, jid, affiliation, subscriptions) "
|
||||
"values (%(Nidx)d, %(J)s, %(A)s, %(S)s)")),
|
||||
{result, {default, broadcast}}.
|
||||
|
||||
delete_node(Nodes) ->
|
||||
Reply = lists:map(fun (#pubsub_node{id = Nidx} = PubsubNode) ->
|
||||
Subscriptions = case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(subscriptions)s "
|
||||
"from pubsub_state where nodeid=%(Nidx)d"))
|
||||
of
|
||||
{selected, RItems} ->
|
||||
[{decode_jid(SJID), decode_subscriptions(Subs)} ||
|
||||
{SJID, Subs} <- RItems];
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
{PubsubNode, Subscriptions}
|
||||
end, Nodes),
|
||||
Reply = lists:map(
|
||||
fun(#pubsub_node{id = Nidx} = PubsubNode) ->
|
||||
Subscriptions =
|
||||
case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(subscriptions)s "
|
||||
"from pubsub_state where nodeid=%(Nidx)d")) of
|
||||
{selected, RItems} ->
|
||||
[{decode_jid(SJID), decode_subscriptions(Subs)}
|
||||
|| {SJID, Subs} <- RItems];
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
{PubsubNode, Subscriptions}
|
||||
end, Nodes),
|
||||
{result, {default, broadcast, Reply}}.
|
||||
|
||||
subscribe_node(Nidx, Sender, Subscriber, AccessModel,
|
||||
@ -118,22 +118,25 @@ subscribe_node(Nidx, Sender, Subscriber, AccessModel,
|
||||
Subscriptions),
|
||||
Owner = Affiliation == owner,
|
||||
if not Authorized ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"invalid-jid">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_bad_request(), mod_pubsub:err_invalid_jid())};
|
||||
(Affiliation == outcast) or (Affiliation == publish_only) ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, xmpp:err_forbidden()};
|
||||
PendingSubscription ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"pending-subscription">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_authorized(),
|
||||
mod_pubsub:err_pending_subscription())};
|
||||
(AccessModel == presence) and (not PresenceSubscription) and (not Owner) ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_authorized(),
|
||||
mod_pubsub:err_presence_subscription_required())};
|
||||
(AccessModel == roster) and (not RosterGroup) and (not Owner) ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_authorized(),
|
||||
mod_pubsub:err_not_in_roster_group())};
|
||||
(AccessModel == whitelist) and (not Whitelisted) and (not Owner) ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_allowed(), mod_pubsub:err_closed_node())};
|
||||
%%MustPay ->
|
||||
%% % Payment is required for a subscription
|
||||
%% {error, ?ERR_PAYMENT_REQUIRED};
|
||||
@ -177,7 +180,7 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) ->
|
||||
if
|
||||
%% Requesting entity is prohibited from unsubscribing entity
|
||||
not Authorized ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, xmpp:err_forbidden()};
|
||||
%% Entity did not specify SubId
|
||||
%%SubId == "", ?? ->
|
||||
%% {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")};
|
||||
@ -186,8 +189,9 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) ->
|
||||
%% {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
|
||||
%% Requesting entity is not a subscriber
|
||||
Subscriptions == [] ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_UNEXPECTED_REQUEST_CANCEL), <<"not-subscribed">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_unexpected_request(),
|
||||
mod_pubsub:err_not_subscribed())};
|
||||
%% Subid supplied, so use that.
|
||||
SubIdExists ->
|
||||
Sub = first_in_list(fun
|
||||
@ -200,8 +204,9 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) ->
|
||||
delete_subscription(SubKey, Nidx, S, Affiliation, Subscriptions),
|
||||
{result, default};
|
||||
false ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_UNEXPECTED_REQUEST_CANCEL), <<"not-subscribed">>)}
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_unexpected_request(),
|
||||
mod_pubsub:err_not_subscribed())}
|
||||
end;
|
||||
%% Asking to remove all subscriptions to the given node
|
||||
SubId == all ->
|
||||
@ -214,8 +219,8 @@ unsubscribe_node(Nidx, Sender, Subscriber, SubId) ->
|
||||
{result, default};
|
||||
%% No subid and more than one possible subscription match.
|
||||
true ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"subid-required">>)}
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_bad_request(), mod_pubsub:err_subid_required())}
|
||||
end.
|
||||
|
||||
delete_subscription(SubKey, Nidx, {Subscription, SubId}, Affiliation, Subscriptions) ->
|
||||
@ -241,7 +246,7 @@ publish_item(Nidx, Publisher, PublishModel, MaxItems, ItemId, Payload,
|
||||
or (Affiliation == publisher)
|
||||
or (Affiliation == publish_only))
|
||||
or (Subscribed == true)) ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, xmpp:err_forbidden()};
|
||||
true ->
|
||||
if MaxItems > 0 ->
|
||||
PubId = {p1_time_compat:timestamp(), SubKey},
|
||||
@ -277,11 +282,11 @@ delete_item(Nidx, Publisher, PublishModel, ItemId) ->
|
||||
_ -> false
|
||||
end,
|
||||
if not Allowed ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, xmpp:err_forbidden()};
|
||||
true ->
|
||||
case del_item(Nidx, ItemId) of
|
||||
{updated, 1} -> {result, {default, broadcast}};
|
||||
_ -> {error, ?ERR_ITEM_NOT_FOUND}
|
||||
_ -> {error, xmpp:err_item_not_found()}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -299,7 +304,7 @@ purge_node(Nidx, Owner) ->
|
||||
States),
|
||||
{result, {default, broadcast}};
|
||||
_ ->
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
{error, xmpp:err_forbidden()}
|
||||
end.
|
||||
|
||||
get_entity_affiliations(Host, Owner) ->
|
||||
@ -307,48 +312,42 @@ get_entity_affiliations(Host, Owner) ->
|
||||
GenKey = jid:remove_resource(SubKey),
|
||||
H = encode_host(Host),
|
||||
J = encode_jid(GenKey),
|
||||
Reply = case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(node)s, @(type)s, @(i.nodeid)d, @(affiliation)s "
|
||||
"from pubsub_state i, pubsub_node n where "
|
||||
"i.nodeid = n.nodeid and jid=%(J)s and host=%(H)s"))
|
||||
of
|
||||
{selected, RItems} ->
|
||||
[{nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}), decode_affiliation(A)}
|
||||
|| {N, T, I, A} <- RItems];
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
{result, Reply}.
|
||||
{result,
|
||||
case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(node)s, @(type)s, @(i.nodeid)d, @(affiliation)s "
|
||||
"from pubsub_state i, pubsub_node n where "
|
||||
"i.nodeid = n.nodeid and jid=%(J)s and host=%(H)s")) of
|
||||
{selected, RItems} ->
|
||||
[{nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}),
|
||||
decode_affiliation(A)} || {N, T, I, A} <- RItems];
|
||||
_ ->
|
||||
[]
|
||||
end}.
|
||||
|
||||
get_node_affiliations(Nidx) ->
|
||||
Reply = case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(affiliation)s from pubsub_state "
|
||||
"where nodeid=%(Nidx)d"))
|
||||
of
|
||||
{selected, RItems} ->
|
||||
[{decode_jid(J), decode_affiliation(A)} || {J, A} <- RItems];
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
{result, Reply}.
|
||||
{result,
|
||||
case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(affiliation)s from pubsub_state "
|
||||
"where nodeid=%(Nidx)d")) of
|
||||
{selected, RItems} ->
|
||||
[{decode_jid(J), decode_affiliation(A)} || {J, A} <- RItems];
|
||||
_ ->
|
||||
[]
|
||||
end}.
|
||||
|
||||
get_affiliation(Nidx, Owner) ->
|
||||
SubKey = jid:tolower(Owner),
|
||||
GenKey = jid:remove_resource(SubKey),
|
||||
J = encode_jid(GenKey),
|
||||
Reply = case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(affiliation)s from pubsub_state "
|
||||
"where nodeid=%(Nidx)d and jid=%(J)s"))
|
||||
of
|
||||
{selected, [{A}]} ->
|
||||
decode_affiliation(A);
|
||||
_ ->
|
||||
none
|
||||
end,
|
||||
{result, Reply}.
|
||||
{result,
|
||||
case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(affiliation)s from pubsub_state "
|
||||
"where nodeid=%(Nidx)d and jid=%(J)s")) of
|
||||
{selected, [{A}]} ->
|
||||
decode_affiliation(A);
|
||||
_ ->
|
||||
none
|
||||
end}.
|
||||
|
||||
set_affiliation(Nidx, Owner, Affiliation) ->
|
||||
SubKey = jid:tolower(Owner),
|
||||
@ -382,26 +381,26 @@ get_entity_subscriptions(Host, Owner) ->
|
||||
"where i.nodeid = n.nodeid and"
|
||||
" jid in (%(SJ)s, %(GJ)s) and host=%(H)s")
|
||||
end,
|
||||
Reply = case catch ejabberd_sql:sql_query_t(Query) of
|
||||
{selected, RItems} ->
|
||||
lists:foldl(fun ({N, T, I, J, S}, Acc) ->
|
||||
Node = nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}),
|
||||
Jid = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Node, none, Jid} | Acc];
|
||||
Subs ->
|
||||
lists:foldl(fun ({Sub, SubId}, Acc2) ->
|
||||
[{Node, Sub, SubId, Jid} | Acc2]
|
||||
end,
|
||||
Acc, Subs)
|
||||
end
|
||||
end,
|
||||
[], RItems);
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
{result, Reply}.
|
||||
{result,
|
||||
case ejabberd_sql:sql_query_t(Query) of
|
||||
{selected, RItems} ->
|
||||
lists:foldl(
|
||||
fun({N, T, I, J, S}, Acc) ->
|
||||
Node = nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}),
|
||||
Jid = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Node, none, Jid} | Acc];
|
||||
Subs ->
|
||||
lists:foldl(
|
||||
fun({Sub, SubId}, Acc2) ->
|
||||
[{Node, Sub, SubId, Jid} | Acc2]
|
||||
end, Acc, Subs)
|
||||
end
|
||||
end, [], RItems);
|
||||
_ ->
|
||||
[]
|
||||
end}.
|
||||
|
||||
-spec get_entity_subscriptions_for_send_last(Host :: mod_pubsub:hostPubsub(),
|
||||
Owner :: jid()) ->
|
||||
@ -435,66 +434,62 @@ get_entity_subscriptions_for_send_last(Host, Owner) ->
|
||||
"and val='on_sub_and_presence' and"
|
||||
" jid in (%(SJ)s, %(GJ)s) and host=%(H)s")
|
||||
end,
|
||||
Reply = case catch ejabberd_sql:sql_query_t(Query) of
|
||||
{selected, RItems} ->
|
||||
lists:foldl(fun ({N, T, I, J, S}, Acc) ->
|
||||
Node = nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}),
|
||||
Jid = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Node, none, Jid} | Acc];
|
||||
Subs ->
|
||||
lists:foldl(fun ({Sub, SubId}, Acc2) ->
|
||||
[{Node, Sub, SubId, Jid}| Acc2]
|
||||
end,
|
||||
Acc, Subs)
|
||||
end
|
||||
end,
|
||||
[], RItems);
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
{result, Reply}.
|
||||
{result,
|
||||
case ejabberd_sql:sql_query_t(Query) of
|
||||
{selected, RItems} ->
|
||||
lists:foldl(
|
||||
fun ({N, T, I, J, S}, Acc) ->
|
||||
Node = nodetree_tree_sql:raw_to_node(Host, {N, <<"">>, T, I}),
|
||||
Jid = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Node, none, Jid} | Acc];
|
||||
Subs ->
|
||||
lists:foldl(
|
||||
fun ({Sub, SubId}, Acc2) ->
|
||||
[{Node, Sub, SubId, Jid}| Acc2]
|
||||
end, Acc, Subs)
|
||||
end
|
||||
end, [], RItems);
|
||||
_ ->
|
||||
[]
|
||||
end}.
|
||||
|
||||
get_node_subscriptions(Nidx) ->
|
||||
Reply = case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(subscriptions)s from pubsub_state "
|
||||
"where nodeid=%(Nidx)d"))
|
||||
of
|
||||
{selected, RItems} ->
|
||||
lists:foldl(fun ({J, S}, Acc) ->
|
||||
Jid = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Jid, none} | Acc];
|
||||
Subs ->
|
||||
lists:foldl(fun ({Sub, SubId}, Acc2) ->
|
||||
[{Jid, Sub, SubId} | Acc2]
|
||||
end,
|
||||
Acc, Subs)
|
||||
end
|
||||
end,
|
||||
[], RItems);
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
{result, Reply}.
|
||||
{result,
|
||||
case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(subscriptions)s from pubsub_state "
|
||||
"where nodeid=%(Nidx)d")) of
|
||||
{selected, RItems} ->
|
||||
lists:foldl(
|
||||
fun ({J, S}, Acc) ->
|
||||
Jid = decode_jid(J),
|
||||
case decode_subscriptions(S) of
|
||||
[] ->
|
||||
[{Jid, none} | Acc];
|
||||
Subs ->
|
||||
lists:foldl(
|
||||
fun ({Sub, SubId}, Acc2) ->
|
||||
[{Jid, Sub, SubId} | Acc2]
|
||||
end, Acc, Subs)
|
||||
end
|
||||
end, [], RItems);
|
||||
_ ->
|
||||
[]
|
||||
end}.
|
||||
|
||||
get_subscriptions(Nidx, Owner) ->
|
||||
SubKey = jid:tolower(Owner),
|
||||
J = encode_jid(SubKey),
|
||||
Reply = case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(subscriptions)s from pubsub_state"
|
||||
" where nodeid=%(Nidx)d and jid=%(J)s"))
|
||||
of
|
||||
{selected, [{S}]} ->
|
||||
decode_subscriptions(S);
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
{result, Reply}.
|
||||
{result,
|
||||
case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(subscriptions)s from pubsub_state"
|
||||
" where nodeid=%(Nidx)d and jid=%(J)s")) of
|
||||
{selected, [{S}]} ->
|
||||
decode_subscriptions(S);
|
||||
_ ->
|
||||
[]
|
||||
end}.
|
||||
|
||||
set_subscriptions(Nidx, Owner, Subscription, SubId) ->
|
||||
SubKey = jid:tolower(Owner),
|
||||
@ -503,8 +498,9 @@ set_subscriptions(Nidx, Owner, Subscription, SubId) ->
|
||||
{_, []} ->
|
||||
case Subscription of
|
||||
none ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"not-subscribed">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_bad_request(),
|
||||
mod_pubsub:err_not_subscribed())};
|
||||
_ ->
|
||||
new_subscription(Nidx, Owner, Subscription, SubState)
|
||||
end;
|
||||
@ -514,8 +510,9 @@ set_subscriptions(Nidx, Owner, Subscription, SubId) ->
|
||||
_ -> replace_subscription({Subscription, SID}, SubState)
|
||||
end;
|
||||
{<<>>, [_ | _]} ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_BAD_REQUEST), <<"subid-required">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_bad_request(),
|
||||
mod_pubsub:err_subid_required())};
|
||||
_ ->
|
||||
case Subscription of
|
||||
none -> unsub_with_subid(Nidx, SubId, SubState);
|
||||
@ -585,21 +582,19 @@ get_nodes_helper(NodeTree, #pubsub_state{stateid = {_, N}, subscriptions = Subs}
|
||||
end.
|
||||
|
||||
get_states(Nidx) ->
|
||||
case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(affiliation)s, @(subscriptions)s "
|
||||
"from pubsub_state where nodeid=%(Nidx)d"))
|
||||
of
|
||||
case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(affiliation)s, @(subscriptions)s "
|
||||
"from pubsub_state where nodeid=%(Nidx)d")) of
|
||||
{selected, RItems} ->
|
||||
{result,
|
||||
lists:map(fun ({SJID, Aff, Subs}) ->
|
||||
JID = decode_jid(SJID),
|
||||
#pubsub_state{stateid = {JID, Nidx},
|
||||
items = itemids(Nidx, JID),
|
||||
affiliation = decode_affiliation(Aff),
|
||||
subscriptions = decode_subscriptions(Subs)}
|
||||
end,
|
||||
RItems)};
|
||||
lists:map(
|
||||
fun({SJID, Aff, Subs}) ->
|
||||
JID = decode_jid(SJID),
|
||||
#pubsub_state{stateid = {JID, Nidx},
|
||||
items = itemids(Nidx, JID),
|
||||
affiliation = decode_affiliation(Aff),
|
||||
subscriptions = decode_subscriptions(Subs)}
|
||||
end, RItems)};
|
||||
_ ->
|
||||
{result, []}
|
||||
end.
|
||||
@ -614,16 +609,14 @@ get_state(Nidx, JID) ->
|
||||
|
||||
get_state_without_itemids(Nidx, JID) ->
|
||||
J = encode_jid(JID),
|
||||
case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(affiliation)s, @(subscriptions)s "
|
||||
"from pubsub_state "
|
||||
"where nodeid=%(Nidx)d and jid=%(J)s"))
|
||||
of
|
||||
case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(jid)s, @(affiliation)s, @(subscriptions)s "
|
||||
"from pubsub_state "
|
||||
"where nodeid=%(Nidx)d and jid=%(J)s")) of
|
||||
{selected, [{SJID, Aff, Subs}]} ->
|
||||
#pubsub_state{stateid = {decode_jid(SJID), Nidx},
|
||||
affiliation = decode_affiliation(Aff),
|
||||
subscriptions = decode_subscriptions(Subs)};
|
||||
affiliation = decode_affiliation(Aff),
|
||||
subscriptions = decode_subscriptions(Subs)};
|
||||
_ ->
|
||||
#pubsub_state{stateid = {JID, Nidx}}
|
||||
end.
|
||||
@ -653,73 +646,60 @@ del_state(Nidx, JID) ->
|
||||
" where jid=%(J)s and nodeid=%(Nidx)d")),
|
||||
ok.
|
||||
|
||||
%get_items(Nidx, _From) ->
|
||||
% case catch
|
||||
% ejabberd_sql:sql_query_t([<<"select itemid, publisher, creation, modification, payload "
|
||||
% "from pubsub_item where nodeid='">>, Nidx,
|
||||
% <<"' order by modification desc;">>])
|
||||
% of
|
||||
% {selected,
|
||||
% [<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], RItems} ->
|
||||
% {result, [raw_to_item(Nidx, RItem) || RItem <- RItems]};
|
||||
% _ ->
|
||||
% {result, []}
|
||||
% end.
|
||||
|
||||
get_items(Nidx, From, none) ->
|
||||
MaxItems = case catch
|
||||
ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(val)s from pubsub_node_option "
|
||||
"where nodeid=%(Nidx)d and name='max_items'"))
|
||||
of
|
||||
{selected, [{Value}]} ->
|
||||
jlib:expr_to_term(Value);
|
||||
_ ->
|
||||
?MAXITEMS
|
||||
end,
|
||||
get_items(Nidx, From, #rsm_in{max = MaxItems});
|
||||
get_items(Nidx, _From,
|
||||
#rsm_in{max = M, direction = Direction, id = I, index = IncIndex}) ->
|
||||
Max = ejabberd_sql:escape(jlib:i2l(M)),
|
||||
{Way, Order} = case Direction of
|
||||
aft when I == <<>> -> {<<"is not">>, <<"desc">>};
|
||||
aft -> {<<"<">>, <<"desc">>};
|
||||
before when I == <<>> -> {<<"is not">>, <<"asc">>};
|
||||
before -> {<<">">>, <<"asc">>};
|
||||
_ -> {<<"is not">>, <<"desc">>}
|
||||
end,
|
||||
get_items(Nidx, From, undefined) ->
|
||||
MaxItems = case ejabberd_sql:sql_query_t(
|
||||
?SQL("select @(val)s from pubsub_node_option "
|
||||
"where nodeid=%(Nidx)d and name='max_items'")) of
|
||||
{selected, [{Value}]} ->
|
||||
jlib:expr_to_term(Value);
|
||||
_ ->
|
||||
?MAXITEMS
|
||||
end,
|
||||
get_items(Nidx, From, #rsm_set{max = MaxItems});
|
||||
get_items(Nidx, _From, #rsm_set{max = Max, index = IncIndex,
|
||||
'after' = After, before = Before}) ->
|
||||
{Way, Order} = if After == <<>> -> {<<"is not">>, <<"desc">>};
|
||||
After /= undefined -> {<<"<">>, <<"desc">>};
|
||||
Before == <<>> -> {<<"is not">>, <<"asc">>};
|
||||
Before /= undefined -> {<<">">>, <<"asc">>};
|
||||
true -> {<<"is not">>, <<"desc">>}
|
||||
end,
|
||||
SNidx = integer_to_binary(Nidx),
|
||||
[AttrName, Id] = case I of
|
||||
undefined when IncIndex =/= undefined ->
|
||||
case catch
|
||||
ejabberd_sql:sql_query_t([<<"select modification from pubsub_item pi "
|
||||
"where exists ( select count(*) as count1 "
|
||||
"from pubsub_item where nodeid='">>, SNidx,
|
||||
I = if After /= undefined -> After;
|
||||
Before /= undefined -> Before;
|
||||
true -> undefined
|
||||
end,
|
||||
[AttrName, Id] =
|
||||
case I of
|
||||
undefined when IncIndex =/= undefined ->
|
||||
case ejabberd_sql:sql_query_t(
|
||||
[<<"select modification from pubsub_item pi "
|
||||
"where exists ( select count(*) as count1 "
|
||||
"from pubsub_item where nodeid='">>, SNidx,
|
||||
<<"' and modification > pi.modification having count1 = ">>,
|
||||
ejabberd_sql:escape(jlib:i2l(IncIndex)), <<" );">>])
|
||||
of
|
||||
{selected, [_], [[O]]} ->
|
||||
[<<"modification">>, <<"'", O/binary, "'">>];
|
||||
_ ->
|
||||
[<<"modification">>, <<"null">>]
|
||||
end;
|
||||
undefined ->
|
||||
[<<"modification">>, <<"null">>];
|
||||
<<>> ->
|
||||
[<<"modification">>, <<"null">>];
|
||||
I ->
|
||||
[A, B] = str:tokens(ejabberd_sql:escape(jlib:i2l(I)), <<"@">>),
|
||||
[A, <<"'", B/binary, "'">>]
|
||||
end,
|
||||
Count = case catch
|
||||
ejabberd_sql:sql_query_t([<<"select count(*) from pubsub_item where nodeid='">>, SNidx, <<"';">>])
|
||||
of
|
||||
{selected, [_], [[C]]} -> C;
|
||||
_ -> <<"0">>
|
||||
end,
|
||||
IncIndex, <<" );">>]) of
|
||||
{selected, [_], [[O]]} ->
|
||||
[<<"modification">>, <<"'", O/binary, "'">>];
|
||||
_ ->
|
||||
[<<"modification">>, <<"null">>]
|
||||
end;
|
||||
undefined ->
|
||||
[<<"modification">>, <<"null">>];
|
||||
<<>> ->
|
||||
[<<"modification">>, <<"null">>];
|
||||
I ->
|
||||
[A, B] = str:tokens(ejabberd_sql:escape(I), <<"@">>),
|
||||
[A, <<"'", B/binary, "'">>]
|
||||
end,
|
||||
Count = case ejabberd_sql:sql_query_t(
|
||||
[<<"select count(*) from pubsub_item where nodeid='">>,
|
||||
SNidx, <<"';">>]) of
|
||||
{selected, [_], [[C]]} -> binary_to_integer(C);
|
||||
_ -> 0
|
||||
end,
|
||||
Query = fun(mssql, _) ->
|
||||
ejabberd_sql:sql_query_t(
|
||||
[<<"select top ">>, jlib:i2l(Max),
|
||||
[<<"select top ">>, Max,
|
||||
<<" itemid, publisher, creation, modification, payload "
|
||||
"from pubsub_item where nodeid='">>, SNidx,
|
||||
<<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>,
|
||||
@ -729,32 +709,33 @@ get_items(Nidx, _From,
|
||||
[<<"select itemid, publisher, creation, modification, payload "
|
||||
"from pubsub_item where nodeid='">>, SNidx,
|
||||
<<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>,
|
||||
AttrName, <<" ">>, Order, <<" limit ">>, jlib:i2l(Max), <<" ;">>])
|
||||
AttrName, <<" ">>, Order, <<" limit ">>, Max, <<" ;">>])
|
||||
end,
|
||||
case catch ejabberd_sql:sql_query_t(Query) of
|
||||
{selected,
|
||||
[<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], RItems} ->
|
||||
case ejabberd_sql:sql_query_t(Query) of
|
||||
{selected, [<<"itemid">>, <<"publisher">>, <<"creation">>,
|
||||
<<"modification">>, <<"payload">>], RItems} ->
|
||||
case RItems of
|
||||
[[_, _, _, F, _]|_] ->
|
||||
Index = case catch
|
||||
ejabberd_sql:sql_query_t([<<"select count(*) from pubsub_item "
|
||||
"where nodeid='">>, SNidx, <<"' and ">>,
|
||||
AttrName, <<" > '">>, F, <<"';">>])
|
||||
of
|
||||
%{selected, [_], [{C}, {In}]} -> [string:strip(C, both, $"), string:strip(In, both, $")];
|
||||
{selected, [_], [[In]]} -> In;
|
||||
_ -> <<"0">>
|
||||
end,
|
||||
Index = case catch ejabberd_sql:sql_query_t(
|
||||
[<<"select count(*) from pubsub_item "
|
||||
"where nodeid='">>, SNidx, <<"' and ">>,
|
||||
AttrName, <<" > '">>, F, <<"';">>]) of
|
||||
{selected, [_], [[In]]} -> binary_to_integer(In);
|
||||
_ -> 0
|
||||
end,
|
||||
[_, _, _, L, _] = lists:last(RItems),
|
||||
RsmOut = #rsm_out{count = Count, index = Index,
|
||||
first = <<"modification@", F/binary>>,
|
||||
last = <<"modification@", (jlib:i2l(L))/binary>>},
|
||||
RsmOut = #rsm_set{count = Count,
|
||||
index = Index,
|
||||
first = #rsm_first{
|
||||
index = Index,
|
||||
data = <<"modification@", F/binary>>},
|
||||
last = <<"modification@", L/binary>>},
|
||||
{result, {[raw_to_item(Nidx, RItem) || RItem <- RItems], RsmOut}};
|
||||
[] ->
|
||||
{result, {[], #rsm_out{count = Count}}}
|
||||
{result, {[], #rsm_set{count = Count}}}
|
||||
end;
|
||||
_ ->
|
||||
{result, {[], none}}
|
||||
{result, {[], undefined}}
|
||||
end.
|
||||
|
||||
get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM) ->
|
||||
@ -769,18 +750,20 @@ get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM
|
||||
%% Entity is subscribed but specifies an invalid subscription ID
|
||||
%{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
|
||||
(Affiliation == outcast) or (Affiliation == publish_only) ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, xmpp:err_forbidden()};
|
||||
(AccessModel == presence) and not PresenceSubscription ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_authorized(),
|
||||
mod_pubsub:err_presence_subscription_required())};
|
||||
(AccessModel == roster) and not RosterGroup ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_authorized(),
|
||||
mod_pubsub:err_not_in_roster_group())};
|
||||
(AccessModel == whitelist) and not Whitelisted ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_allowed(), mod_pubsub:err_closed_node())};
|
||||
(AccessModel == authorize) and not Whitelisted ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, xmpp:err_forbidden()};
|
||||
%%MustPay ->
|
||||
%% % Payment is required for a subscription
|
||||
%% {error, ?ERR_PAYMENT_REQUIRED};
|
||||
@ -820,9 +803,9 @@ get_item(Nidx, ItemId) ->
|
||||
{selected, [RItem]} ->
|
||||
{result, raw_to_item(Nidx, RItem)};
|
||||
{selected, []} ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
{error, xmpp:err_item_not_found()};
|
||||
{'EXIT', _} ->
|
||||
{error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)}
|
||||
{error, xmpp:err_internal_server_error(<<"Database failure">>, ?MYLANG)}
|
||||
end.
|
||||
|
||||
get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
|
||||
@ -837,18 +820,20 @@ get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _Sub
|
||||
%% Entity is subscribed but specifies an invalid subscription ID
|
||||
%{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
|
||||
(Affiliation == outcast) or (Affiliation == publish_only) ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, xmpp:err_forbidden()};
|
||||
(AccessModel == presence) and not PresenceSubscription ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"presence-subscription-required">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_authorized(),
|
||||
mod_pubsub:err_presence_subscription_required())};
|
||||
(AccessModel == roster) and not RosterGroup ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_AUTHORIZED), <<"not-in-roster-group">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_authorized(),
|
||||
mod_pubsub:err_not_in_roster_group())};
|
||||
(AccessModel == whitelist) and not Whitelisted ->
|
||||
{error,
|
||||
?ERR_EXTENDED((?ERR_NOT_ALLOWED), <<"closed-node">>)};
|
||||
{error, mod_pubsub:extended_error(
|
||||
xmpp:err_not_allowed(), mod_pubsub:err_closed_node())};
|
||||
(AccessModel == authorize) and not Whitelisted ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
{error, xmpp:err_forbidden()};
|
||||
%%MustPay ->
|
||||
%% % Payment is required for a subscription
|
||||
%% {error, ?ERR_PAYMENT_REQUIRED};
|
||||
|
10
src/xmpp.erl
10
src/xmpp.erl
@ -10,7 +10,7 @@
|
||||
|
||||
%% API
|
||||
-export([make_iq_result/1, make_iq_result/2, make_error/2,
|
||||
decode/1, decode/2, decode_tags_by_ns/2, encode/1,
|
||||
decode/1, decode/2, encode/1,
|
||||
get_type/1, get_to/1, get_from/1, get_id/1,
|
||||
get_lang/1, get_error/1, get_els/1, get_ns/1,
|
||||
set_type/2, set_to/2, set_from/2, set_id/2,
|
||||
@ -252,6 +252,10 @@ decode(Pkt, _Opts) ->
|
||||
decode_els(Stanza) ->
|
||||
decode_els(Stanza, fun xmpp_codec:is_known_tag/1).
|
||||
|
||||
-type match_fun() :: fun((xmlel()) -> boolean()).
|
||||
-spec decode_els(iq(), match_fun()) -> iq();
|
||||
(message(), match_fun()) -> message();
|
||||
(presence(), match_fun()) -> presence().
|
||||
decode_els(Stanza, MatchFun) ->
|
||||
Els = lists:map(
|
||||
fun(#xmlel{} = El) ->
|
||||
@ -268,10 +272,6 @@ decode_els(Stanza, MatchFun) ->
|
||||
encode(Pkt) ->
|
||||
xmpp_codec:encode(Pkt).
|
||||
|
||||
-spec decode_tags_by_ns([xmpp_element() | xmlel()], [binary()]) -> [xmpp_element()].
|
||||
decode_tags_by_ns(Els, NSList) ->
|
||||
[xmpp_codec:decode(El) || El <- Els, lists:member(get_ns(El), NSList)].
|
||||
|
||||
format_error(Reason) ->
|
||||
xmpp_codec:format_error(Reason).
|
||||
|
||||
|
4325
src/xmpp_codec.erl
4325
src/xmpp_codec.erl
File diff suppressed because it is too large
Load Diff
@ -1646,27 +1646,40 @@
|
||||
|
||||
-xml(pubsub_subscription,
|
||||
#elem{name = <<"subscription">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_subscription, '$jid', '$node', '$subid',
|
||||
'$type'},
|
||||
attrs = [#attr{name = <<"jid">>,
|
||||
required = true,
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#owner">>,
|
||||
<<"http://jabber.org/protocol/pubsub#event">>],
|
||||
result = {ps_subscription, '$xmlns', '$jid', '$type',
|
||||
'$node', '$subid', '$expiry'},
|
||||
attrs = [#attr{name = <<"xmlns">>},
|
||||
#attr{name = <<"jid">>,
|
||||
required = true,
|
||||
dec = {dec_jid, []},
|
||||
enc = {enc_jid, []}},
|
||||
#attr{name = <<"node">>},
|
||||
#attr{name = <<"node">>},
|
||||
#attr{name = <<"subid">>},
|
||||
#attr{name = <<"subscription">>,
|
||||
label = '$type',
|
||||
dec = {dec_enum, [[none, pending, subscribed,
|
||||
unconfigured]]},
|
||||
enc = {enc_enum, []}}]}).
|
||||
enc = {enc_enum, []}},
|
||||
#attr{name = <<"expiry">>,
|
||||
dec = {dec_utc, []},
|
||||
enc = {enc_utc, []}}]}).
|
||||
|
||||
-record(ps_affiliation, {xmlns = <<>> :: binary(),
|
||||
node = <<>> :: binary(),
|
||||
type :: member | none | outcast |
|
||||
owner | publisher | 'publish-only',
|
||||
jid :: jid:jid()}).
|
||||
-type ps_affiliation() :: #ps_affiliation{}.
|
||||
|
||||
-xml(pubsub_affiliation,
|
||||
#elem{name = <<"affiliation">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_affiliation, '$node', '$type'},
|
||||
attrs = [#attr{name = <<"node">>,
|
||||
required = true},
|
||||
result = {ps_affiliation, '$xmlns', '$node', '$type', '$_'},
|
||||
attrs = [#attr{name = <<"node">>, required = true},
|
||||
#attr{name = <<"xmlns">>},
|
||||
#attr{name = <<"affiliation">>,
|
||||
label = '$type',
|
||||
required = true,
|
||||
@ -1674,24 +1687,28 @@
|
||||
publisher, 'publish-only']]},
|
||||
enc = {enc_enum, []}}]}).
|
||||
|
||||
-xml(pubsub_item,
|
||||
#elem{name = <<"item">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_item, '$id', '$_xmls'},
|
||||
attrs = [#attr{name = <<"id">>}]}).
|
||||
-xml(pubsub_owner_affiliation,
|
||||
#elem{name = <<"affiliation">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#owner">>,
|
||||
result = {ps_affiliation, '$xmlns', '$_', '$type', '$jid'},
|
||||
attrs = [#attr{name = <<"jid">>,
|
||||
required = true,
|
||||
dec = {dec_jid, []},
|
||||
enc = {enc_jid, []}},
|
||||
#attr{name = <<"xmlns">>},
|
||||
#attr{name = <<"affiliation">>,
|
||||
label = '$type',
|
||||
required = true,
|
||||
dec = {dec_enum, [[member, none, outcast, owner,
|
||||
publisher, 'publish-only']]},
|
||||
enc = {enc_enum, []}}]}).
|
||||
|
||||
-xml(pubsub_items,
|
||||
#elem{name = <<"items">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_items, '$node', '$max_items',
|
||||
'$subid', '$items'},
|
||||
attrs = [#attr{name = <<"max_items">>,
|
||||
dec = {dec_int, [0, infinity]},
|
||||
enc = {enc_int, []}},
|
||||
#attr{name = <<"node">>,
|
||||
required = true},
|
||||
#attr{name = <<"subid">>}],
|
||||
refs = [#ref{name = pubsub_item, label = '$items'}]}).
|
||||
-xml(pubsub_event_configuration,
|
||||
#elem{name = <<"configuration">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#event">>,
|
||||
result = {'$node', '$xdata'},
|
||||
attrs = [#attr{name = <<"node">>, required = true}],
|
||||
refs = [#ref{name = xdata, min = 0, max = 1}]}).
|
||||
|
||||
-xml(pubsub_event_retract,
|
||||
#elem{name = <<"retract">>,
|
||||
@ -1699,32 +1716,55 @@
|
||||
result = '$id',
|
||||
attrs = [#attr{name = <<"id">>, required = true}]}).
|
||||
|
||||
-xml(pubsub_event_item,
|
||||
-xml(pubsub_item,
|
||||
#elem{name = <<"item">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#event">>,
|
||||
result = {pubsub_event_item, '$id', '$node', '$publisher', '$_xmls'},
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#event">>],
|
||||
result = {ps_item, '$xmlns', '$id', '$_xmls', '$node', '$publisher'},
|
||||
attrs = [#attr{name = <<"id">>},
|
||||
#attr{name = <<"xmlns">>},
|
||||
#attr{name = <<"node">>},
|
||||
#attr{name = <<"publisher">>}]}).
|
||||
|
||||
-xml(pubsub_event_items,
|
||||
-xml(pubsub_items,
|
||||
#elem{name = <<"items">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#event">>,
|
||||
result = {pubsub_event_items, '$node', '$retract', '$items'},
|
||||
attrs = [#attr{name = <<"node">>,
|
||||
required = true}],
|
||||
refs = [#ref{name = pubsub_event_retract, label = '$retract'},
|
||||
#ref{name = pubsub_event_item, label = '$items'}]}).
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#event">>],
|
||||
result = {ps_items, '$xmlns', '$node', '$items', '$max_items',
|
||||
'$subid', '$retract'},
|
||||
attrs = [#attr{name = <<"xmlns">>},
|
||||
#attr{name = <<"max_items">>,
|
||||
dec = {dec_int, [0, infinity]},
|
||||
enc = {enc_int, []}},
|
||||
#attr{name = <<"node">>,
|
||||
required = true},
|
||||
#attr{name = <<"subid">>}],
|
||||
refs = [#ref{name = pubsub_event_retract, label = '$retract',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_item, label = '$items'}]}).
|
||||
|
||||
-xml(pubsub_event,
|
||||
#elem{name = <<"event">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#event">>,
|
||||
result = {pubsub_event, '$items'},
|
||||
refs = [#ref{name = pubsub_event_items, label = '$items'}]}).
|
||||
result = {ps_event, '$items', '$purge', '$subscription', '$delete',
|
||||
'$create', '$configuration'},
|
||||
refs = [#ref{name = pubsub_items, label = '$items',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_subscription, min = 0, max = 1,
|
||||
label = '$subscription'},
|
||||
#ref{name = pubsub_purge, min = 0, max = 1,
|
||||
label = '$purge'},
|
||||
#ref{name = pubsub_delete, min = 0, max = 1,
|
||||
label = '$delete'},
|
||||
#ref{name = pubsub_create, min = 0, max = 1,
|
||||
label = '$create'},
|
||||
#ref{name = pubsub_event_configuration, min = 0, max = 1,
|
||||
label = '$configuration'}]}).
|
||||
|
||||
-xml(pubsub_subscriptions,
|
||||
#elem{name = <<"subscriptions">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#owner">>],
|
||||
result = {'$node', '$subscriptions'},
|
||||
attrs = [#attr{name = <<"node">>}],
|
||||
refs = [#ref{name = pubsub_subscription, label = '$subscriptions'}]}).
|
||||
@ -1732,13 +1772,21 @@
|
||||
-xml(pubsub_affiliations,
|
||||
#elem{name = <<"affiliations">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = '$affiliations',
|
||||
result = {'$node', '$affiliations'},
|
||||
attrs = [#attr{name = <<"node">>}],
|
||||
refs = [#ref{name = pubsub_affiliation, label = '$affiliations'}]}).
|
||||
|
||||
-xml(pubsub_owner_affiliations,
|
||||
#elem{name = <<"affiliations">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#owner">>,
|
||||
result = {'$node', '$affiliations'},
|
||||
attrs = [#attr{name = <<"node">>}],
|
||||
refs = [#ref{name = pubsub_owner_affiliation, label = '$affiliations'}]}).
|
||||
|
||||
-xml(pubsub_subscribe,
|
||||
#elem{name = <<"subscribe">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_subscribe, '$node', '$jid'},
|
||||
result = {ps_subscribe, '$node', '$jid'},
|
||||
attrs = [#attr{name = <<"node">>},
|
||||
#attr{name = <<"jid">>,
|
||||
required = true,
|
||||
@ -1748,7 +1796,7 @@
|
||||
-xml(pubsub_unsubscribe,
|
||||
#elem{name = <<"unsubscribe">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_unsubscribe, '$node', '$jid', '$subid'},
|
||||
result = {ps_unsubscribe, '$node', '$jid', '$subid'},
|
||||
attrs = [#attr{name = <<"node">>},
|
||||
#attr{name = <<"subid">>},
|
||||
#attr{name = <<"jid">>,
|
||||
@ -1759,7 +1807,7 @@
|
||||
-xml(pubsub_publish,
|
||||
#elem{name = <<"publish">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_publish, '$node', '$items'},
|
||||
result = {ps_publish, '$node', '$items'},
|
||||
attrs = [#attr{name = <<"node">>,
|
||||
required = true}],
|
||||
refs = [#ref{name = pubsub_item, label = '$items'}]}).
|
||||
@ -1767,7 +1815,7 @@
|
||||
-xml(pubsub_options,
|
||||
#elem{name = <<"options">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_options, '$node', '$jid', '$subid', '$xdata'},
|
||||
result = {ps_options, '$node', '$jid', '$subid', '$xdata'},
|
||||
attrs = [#attr{name = <<"node">>},
|
||||
#attr{name = <<"subid">>},
|
||||
#attr{name = <<"jid">>,
|
||||
@ -1780,7 +1828,7 @@
|
||||
-xml(pubsub_retract,
|
||||
#elem{name = <<"retract">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub_retract, '$node', '$notify', '$items'},
|
||||
result = {ps_retract, '$node', '$notify', '$items'},
|
||||
attrs = [#attr{name = <<"node">>,
|
||||
required = true},
|
||||
#attr{name = <<"notify">>,
|
||||
@ -1789,12 +1837,69 @@
|
||||
enc = {enc_bool, []}}],
|
||||
refs = [#ref{name = pubsub_item, label = '$items'}]}).
|
||||
|
||||
-xml(pubsub_create,
|
||||
#elem{name = <<"create">>,
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#event">>],
|
||||
result = '$node',
|
||||
attrs = [#attr{name = <<"node">>}]}).
|
||||
|
||||
-xml(pubsub_configure,
|
||||
#elem{name = <<"configure">>,
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#owner">>],
|
||||
result = {'$node', '$xdata'},
|
||||
attrs = [#attr{name = <<"node">>}],
|
||||
refs = [#ref{name = xdata, min = 0, max = 1}]}).
|
||||
|
||||
-xml(pubsub_publish_options,
|
||||
#elem{name = <<"publish-options">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = '$xdata',
|
||||
refs = [#ref{name = xdata, min = 0, max = 1}]}).
|
||||
|
||||
-xml(pubsub_default,
|
||||
#elem{name = <<"default">>,
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#owner">>],
|
||||
result = {'$node', '$xdata'},
|
||||
attrs = [#attr{name = <<"node">>}],
|
||||
refs = [#ref{name = xdata, min = 0, max = 1}]}).
|
||||
|
||||
-xml(pubsub_redirect,
|
||||
#elem{name = <<"redirect">>,
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#owner">>,
|
||||
<<"http://jabber.org/protocol/pubsub#event">>],
|
||||
result = '$uri',
|
||||
attrs = [#attr{name = <<"uri">>, required = true}]}).
|
||||
|
||||
-xml(pubsub_delete,
|
||||
#elem{name = <<"delete">>,
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#owner">>,
|
||||
<<"http://jabber.org/protocol/pubsub#event">>],
|
||||
result = {'$node', '$uri'},
|
||||
attrs = [#attr{name = <<"node">>, required = true}],
|
||||
refs = [#ref{name = pubsub_redirect, min = 0, max = 1,
|
||||
label = '$uri', default = <<>>}]}).
|
||||
|
||||
-xml(pubsub_purge,
|
||||
#elem{name = <<"purge">>,
|
||||
xmlns = [<<"http://jabber.org/protocol/pubsub">>,
|
||||
<<"http://jabber.org/protocol/pubsub#owner">>,
|
||||
<<"http://jabber.org/protocol/pubsub#event">>],
|
||||
result = '$node',
|
||||
attrs = [#attr{name = <<"node">>, required = true}]}).
|
||||
|
||||
-xml(pubsub,
|
||||
#elem{name = <<"pubsub">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub">>,
|
||||
result = {pubsub, '$subscriptions', '$affiliations', '$publish',
|
||||
'$subscribe', '$unsubscribe', '$options', '$items',
|
||||
'$retract'},
|
||||
result = {pubsub, '$subscriptions', '$subscription',
|
||||
'$affiliations', '$publish', '$publish_options',
|
||||
'$subscribe', '$unsubscribe', '$options', '$items',
|
||||
'$retract', '$create', '$configure', '$default', '$delete',
|
||||
'$purge', '$rsm'},
|
||||
refs = [#ref{name = pubsub_subscriptions, label = '$subscriptions',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_affiliations, label = '$affiliations',
|
||||
@ -1809,9 +1914,209 @@
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_retract, label = '$retract',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_create, label = '$create',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_configure, label = '$configure',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_publish_options, min = 0, max = 1,
|
||||
label = '$publish_options'},
|
||||
#ref{name = pubsub_default, label = '$default',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_delete, label = '$delete',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_purge, label = '$purge',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_subscription, label = '$subscription',
|
||||
min = 0, max = 1},
|
||||
#ref{name = rsm_set, min = 0, max = 1, label = '$rsm'},
|
||||
#ref{name = pubsub_publish, label = '$publish',
|
||||
min = 0, max = 1}]}).
|
||||
|
||||
-xml(pubsub_owner,
|
||||
#elem{name = <<"pubsub">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#owner">>,
|
||||
result = {pubsub_owner, '$affiliations', '$configure', '$default',
|
||||
'$delete', '$purge', '$subscriptions'},
|
||||
refs = [#ref{name = pubsub_owner_affiliations,
|
||||
label = '$affiliations', min = 0, max = 1},
|
||||
#ref{name = pubsub_configure, label = '$configure',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_default, label = '$default',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_delete, label = '$delete',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_purge, label = '$purge',
|
||||
min = 0, max = 1},
|
||||
#ref{name = pubsub_subscriptions,
|
||||
label = '$subscriptions', min = 0, max = 1}]}).
|
||||
|
||||
-type ps_error_type() :: 'closed-node' | 'configuration-required' |
|
||||
'invalid-jid' | 'invalid-options' |
|
||||
'invalid-payload' | 'invalid-subid' |
|
||||
'item-forbidden' | 'item-required' | 'jid-required' |
|
||||
'max-items-exceeded' | 'max-nodes-exceeded' |
|
||||
'nodeid-required' | 'not-in-roster-group' |
|
||||
'not-subscribed' | 'payload-too-big' |
|
||||
'payload-required' | 'pending-subscription' |
|
||||
'presence-subscription-required' | 'subid-required' |
|
||||
'too-many-subscriptions' | 'unsupported' |
|
||||
'unsupported-access-model'.
|
||||
-type ps_error_feature() :: 'access-authorize' | 'access-open' |
|
||||
'access-presence' | 'access-roster' |
|
||||
'access-whitelist' | 'auto-create' |
|
||||
'auto-subscribe' | 'collections' | 'config-node' |
|
||||
'create-and-configure' | 'create-nodes' |
|
||||
'delete-items' | 'delete-nodes' |
|
||||
'filtered-notifications' | 'get-pending' |
|
||||
'instant-nodes' | 'item-ids' | 'last-published' |
|
||||
'leased-subscription' | 'manage-subscriptions' |
|
||||
'member-affiliation' | 'meta-data' |
|
||||
'modify-affiliations' | 'multi-collection' |
|
||||
'multi-subscribe' | 'outcast-affiliation' |
|
||||
'persistent-items' | 'presence-notifications' |
|
||||
'presence-subscribe' | 'publish' |
|
||||
'publish-options' | 'publish-only-affiliation' |
|
||||
'publisher-affiliation' | 'purge-nodes' |
|
||||
'retract-items' | 'retrieve-affiliations' |
|
||||
'retrieve-default' | 'retrieve-items' |
|
||||
'retrieve-subscriptions' | 'subscribe' |
|
||||
'subscription-options' | 'subscription-notifications'.
|
||||
-record(ps_error, {type :: ps_error_type(), feature :: ps_error_feature()}).
|
||||
-type ps_error() :: #ps_error{}.
|
||||
|
||||
-xml(pubsub_error_closed_node,
|
||||
#elem{name = <<"closed-node">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'closed-node', '$_'}}).
|
||||
-xml(pubsub_error_configuration_required,
|
||||
#elem{name = <<"configuration-required">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'configuration-required', '$_'}}).
|
||||
-xml(pubsub_error_invalid_jid,
|
||||
#elem{name = <<"invalid-jid">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'invalid-jid', '$_'}}).
|
||||
-xml(pubsub_error_invalid_options,
|
||||
#elem{name = <<"invalid-options">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'invalid-options', '$_'}}).
|
||||
-xml(pubsub_error_invalid_payload,
|
||||
#elem{name = <<"invalid-payload">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'invalid-payload', '$_'}}).
|
||||
-xml(pubsub_error_invalid_subid,
|
||||
#elem{name = <<"invalid-subid">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'invalid-subid', '$_'}}).
|
||||
-xml(pubsub_error_item_forbidden,
|
||||
#elem{name = <<"item-forbidden">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'item-forbidden', '$_'}}).
|
||||
-xml(pubsub_error_item_required,
|
||||
#elem{name = <<"item-required">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'item-required', '$_'}}).
|
||||
-xml(pubsub_error_jid_required,
|
||||
#elem{name = <<"jid-required">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'jid-required', '$_'}}).
|
||||
-xml(pubsub_error_max_items_exceeded,
|
||||
#elem{name = <<"max-items-exceeded">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'max-items-exceeded', '$_'}}).
|
||||
-xml(pubsub_error_max_nodes_exceeded,
|
||||
#elem{name = <<"max-nodes-exceeded">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'max-nodes-exceeded', '$_'}}).
|
||||
-xml(pubsub_error_nodeid_required,
|
||||
#elem{name = <<"nodeid-required">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'nodeid-required', '$_'}}).
|
||||
-xml(pubsub_error_not_in_roster_group,
|
||||
#elem{name = <<"not-in-roster-group">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'not-in-roster-group', '$_'}}).
|
||||
-xml(pubsub_error_not_subscribed,
|
||||
#elem{name = <<"not-subscribed">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'not-subscribed', '$_'}}).
|
||||
-xml(pubsub_error_payload_too_big,
|
||||
#elem{name = <<"payload-too-big">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'payload-too-big', '$_'}}).
|
||||
-xml(pubsub_error_payload_required,
|
||||
#elem{name = <<"payload-required">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'payload-required', '$_'}}).
|
||||
-xml(pubsub_error_pending_subscription,
|
||||
#elem{name = <<"pending-subscription">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'pending-subscription', '$_'}}).
|
||||
-xml(pubsub_error_presence_subscription_required,
|
||||
#elem{name = <<"presence-subscription-required">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'presence-subscription-required', '$_'}}).
|
||||
-xml(pubsub_error_subid_required,
|
||||
#elem{name = <<"subid-required">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'subid-required', '$_'}}).
|
||||
-xml(pubsub_error_too_many_subscriptions,
|
||||
#elem{name = <<"too-many-subscriptions">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'too-many-subscriptions', '$_'}}).
|
||||
-xml(pubsub_error_unsupported,
|
||||
#elem{name = <<"unsupported">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'unsupported', '$feature'},
|
||||
attrs = [#attr{name = <<"feature">>, required = true,
|
||||
dec = {dec_enum, [['access-authorize',
|
||||
'access-open',
|
||||
'access-presence',
|
||||
'access-roster',
|
||||
'access-whitelist',
|
||||
'auto-create',
|
||||
'auto-subscribe',
|
||||
'collections',
|
||||
'config-node',
|
||||
'create-and-configure',
|
||||
'create-nodes',
|
||||
'delete-items',
|
||||
'delete-nodes',
|
||||
'filtered-notifications',
|
||||
'get-pending',
|
||||
'instant-nodes',
|
||||
'item-ids',
|
||||
'last-published',
|
||||
'leased-subscription',
|
||||
'manage-subscriptions',
|
||||
'member-affiliation',
|
||||
'meta-data',
|
||||
'modify-affiliations',
|
||||
'multi-collection',
|
||||
'multi-subscribe',
|
||||
'outcast-affiliation',
|
||||
'persistent-items',
|
||||
'presence-notifications',
|
||||
'presence-subscribe',
|
||||
'publish',
|
||||
'publish-options',
|
||||
'publish-only-affiliation',
|
||||
'publisher-affiliation',
|
||||
'purge-nodes',
|
||||
'retract-items',
|
||||
'retrieve-affiliations',
|
||||
'retrieve-default',
|
||||
'retrieve-items',
|
||||
'retrieve-subscriptions',
|
||||
'subscribe',
|
||||
'subscription-options',
|
||||
'subscription-notifications']]},
|
||||
enc = {enc_enum, []}}]}).
|
||||
-xml(pubsub_error_unsupported_access_model,
|
||||
#elem{name = <<"unsupported-access-model">>,
|
||||
xmlns = <<"http://jabber.org/protocol/pubsub#errors">>,
|
||||
result = {ps_error, 'unsupported-access-model', '$_'}}).
|
||||
|
||||
-xml(shim_header,
|
||||
#elem{name = <<"header">>,
|
||||
xmlns = <<"http://jabber.org/protocol/shim">>,
|
||||
|
Loading…
Reference in New Issue
Block a user