From b661bee4b161119d8d52174d0f97e7b3581d3ab9 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Tue, 12 Dec 2017 01:04:14 +0100 Subject: [PATCH] Support pubsub#publish-options PRECONDITIONs Support PubSub publishing options that are specified as PRECONDITIONs as per XEP-0060 v1.14. --- src/mod_pubsub.erl | 21 ++++++++++++++++++--- src/node_flat.erl | 1 + src/node_mb.erl | 1 + src/node_pep.erl | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index bc816b519..d3f82c990 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -82,8 +82,9 @@ err_jid_required/0, err_max_items_exceeded/0, err_max_nodes_exceeded/0, err_nodeid_required/0, err_not_in_roster_group/0, err_not_subscribed/0, err_payload_too_big/0, err_payload_required/0, - err_pending_subscription/0, err_presence_subscription_required/0, - err_subid_required/0, err_too_many_subscriptions/0, err_unsupported/1, + err_pending_subscription/0, err_precondition_not_met/0, + err_presence_subscription_required/0, err_subid_required/0, + err_too_many_subscriptions/0, err_unsupported/1, err_unsupported_access_model/0]). %% API and gen_server callbacks @@ -1773,9 +1774,13 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, PubOpts, Access PayloadCount = payload_xmlelements(Payload), PayloadSize = byte_size(term_to_binary(Payload)) - 2, PayloadMaxSize = get_option(Options, max_payload_size), + PreconditionsMet = preconditions_met(PubOpts, Options), if not PublishFeature -> {error, extended_error(xmpp:err_feature_not_implemented(), err_unsupported(publish))}; + not PreconditionsMet -> + {error, extended_error(xmpp:err_conflict(), + err_precondition_not_met())}; PayloadSize > PayloadMaxSize -> {error, extended_error(xmpp:err_not_acceptable(), err_payload_too_big())}; @@ -1844,7 +1849,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, PubOpts, Access Type = select_type(ServerHost, Host, Node), case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of true -> - case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of + case create_node(Host, ServerHost, Node, Publisher, Type, Access, PubOpts) of {result, #pubsub{create = NewNode}} -> publish_item(Host, ServerHost, NewNode, Publisher, ItemId, Payload, PubOpts, Access); @@ -2513,6 +2518,11 @@ get_roster_info(OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, _}, A get_roster_info(OwnerUser, OwnerServer, JID, AllowedGroups) -> get_roster_info(OwnerUser, OwnerServer, jid:tolower(JID), AllowedGroups). +-spec preconditions_met(pubsub_publish_options:result(), + pubsub_node_config:result()) -> boolean(). +preconditions_met(PubOpts, NodeOpts) -> + lists:all(fun(Opt) -> lists:member(Opt, NodeOpts) end, PubOpts). + -spec service_jid(jid() | ljid() | binary()) -> jid(). service_jid(#jid{} = Jid) -> Jid; service_jid({U, S, R}) -> jid:make(U, S, R); @@ -3459,6 +3469,7 @@ features() -> <<"presence-subscribe">>, % RECOMMENDED <<"publisher-affiliation">>, % RECOMMENDED <<"publish-only-affiliation">>, % OPTIONAL + <<"publish-options">>, % OPTIONAL <<"retrieve-default">>, <<"shim">>]. % RECOMMENDED @@ -3690,6 +3701,10 @@ err_payload_required() -> err_pending_subscription() -> #ps_error{type = 'pending-subscription'}. +-spec err_precondition_not_met() -> ps_error(). +err_precondition_not_met() -> + #ps_error{type = 'precondition-not-met'}. + -spec err_presence_subscription_required() -> ps_error(). err_presence_subscription_required() -> #ps_error{type = 'presence-subscription-required'}. diff --git a/src/node_flat.erl b/src/node_flat.erl index bc529e145..c23a1ebef 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -105,6 +105,7 @@ features() -> <<"persistent-items">>, <<"publish">>, <<"publish-only-affiliation">>, + <<"publish-options">>, <<"purge-nodes">>, <<"retract-items">>, <<"retrieve-affiliations">>, diff --git a/src/node_mb.erl b/src/node_mb.erl index 132060319..7e0b24597 100644 --- a/src/node_mb.erl +++ b/src/node_mb.erl @@ -93,6 +93,7 @@ features() -> <<"outcast-affiliation">>, <<"persistent-items">>, <<"publish">>, + <<"publish-options">>, <<"purge-nodes">>, <<"retract-items">>, <<"retrieve-affiliations">>, diff --git a/src/node_pep.erl b/src/node_pep.erl index 08c84ce9a..3bea659dc 100644 --- a/src/node_pep.erl +++ b/src/node_pep.erl @@ -87,6 +87,7 @@ features() -> <<"outcast-affiliation">>, <<"persistent-items">>, <<"publish">>, + <<"publish-options">>, <<"purge-nodes">>, <<"retract-items">>, <<"retrieve-affiliations">>,