mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-24 17:29:28 +01:00
Support XEP-0157: Contact Addresses for XMPP Services (EJAB-235)
SVN Revision: 2368
This commit is contained in:
parent
2729285977
commit
9df5639974
@ -1958,6 +1958,7 @@ disabled for instances of <TT>ejabberd</TT> with hundreds of thousands users.</P
|
||||
|
||||
|
||||
|
||||
|
||||
</P><P>This module adds support for Service Discovery (<A HREF="http://www.xmpp.org/extensions/xep-0030.html">XEP-0030</A>). With
|
||||
this module enabled, services on your server can be discovered by
|
||||
Jabber clients. Note that <TT>ejabberd</TT> has no modules with support
|
||||
@ -1969,8 +1970,16 @@ the services you offer.</P><P>Options:
|
||||
<B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
the processing discipline for Service Discovery (<TT>http://jabber.org/protocol/disco#items</TT> and
|
||||
<TT>http://jabber.org/protocol/disco#info</TT>) IQ queries (see section <A HREF="#modiqdiscoption">3.3.2</A>).
|
||||
</DD><DT CLASS="dt-description"><B><TT>extra_domains</TT></B></DT><DD CLASS="dd-description"> With this option,
|
||||
extra domains can be added to the Service Discovery item list.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{extra_domains, [ Domain ]}</TT></B></DT><DD CLASS="dd-description"> With this option,
|
||||
you can specify a list of extra domains that are added to the Service Discovery item list.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{server_info, [ {Modules, Field, [Value]} ]}</TT></B></DT><DD CLASS="dd-description">
|
||||
Specify additional information about the server,
|
||||
as described in Contact Addresses for XMPP Services (<A HREF="http://www.xmpp.org/extensions/xep-0157.html">XEP-0157</A>).
|
||||
<TT>Modules</TT> can be the keyword ‘all’,
|
||||
in which case the information is reported in all the services;
|
||||
or a list of <TT>ejabberd</TT> modules,
|
||||
in which case the information is only specified for the services provided by those modules.
|
||||
Any arbitrary <TT>Field</TT> and <TT>Value</TT> can be specified, not only contact addresses.
|
||||
</DD></DL><P>Examples:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
To serve a link to the Jabber User Directory on <TT>jabber.org</TT>:
|
||||
@ -1996,6 +2005,28 @@ To serve a link to the Jabber User Directory on <TT>jabber.org</TT>:
|
||||
"example.com"]}]},
|
||||
...
|
||||
]}.
|
||||
</PRE></LI><LI CLASS="li-itemize">With this configuration, all services show abuse addresses,
|
||||
feedback address on the main server,
|
||||
and admin addresses for both the main server and the vJUD service:
|
||||
<PRE CLASS="verbatim">{modules,
|
||||
[
|
||||
...
|
||||
{mod_disco, [{server_info, [
|
||||
{all,
|
||||
"abuse-addresses",
|
||||
["mailto:abuse@shakespeare.lit"]},
|
||||
{[mod_muc],
|
||||
"Web chatroom logs",
|
||||
["http://www.example.org/muc-logs"]},
|
||||
{[mod_disco],
|
||||
"feedback-addresses",
|
||||
["http://shakespeare.lit/feedback.php", "mailto:feedback@shakespeare.lit", "xmpp:feedback@shakespeare.lit"]},
|
||||
{[mod_disco, mod_vcard],
|
||||
"admin-addresses",
|
||||
["mailto:xmpp@shakespeare.lit", "xmpp:admins@shakespeare.lit"]}
|
||||
]}]},
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modecho"></A> </P><!--TOC subsection <TT>mod_echo</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc42">3.3.5</A>  <A HREF="#modecho"><TT>mod_echo</TT></A></H3><!--SEC END --><P> <A NAME="modecho"></A>
|
||||
</P><P>This module simply echoes any Jabber
|
||||
@ -3275,6 +3306,10 @@ Starts the Erlang system detached from the system console.
|
||||
Maximum number of Erlang processes.
|
||||
</DD><DT CLASS="dt-description"><B><TT>-remsh ejabberd@localhost</TT></B></DT><DD CLASS="dd-description">
|
||||
Open an Erlang shell in a remote Erlang node.
|
||||
</DD><DT CLASS="dt-description"><B><TT>-hidden</TT></B></DT><DD CLASS="dd-description">
|
||||
The connections to other nodes are hidden (not published).
|
||||
The result is that this node is not considered part of the cluster.
|
||||
This is important when starting a temporary <TT>ctl</TT> or <TT>debug</TT> node.
|
||||
</DD></DL><P>
|
||||
Note that some characters need to be escaped when used in shell scripts, for instance <CODE>"</CODE> and <CODE>{}</CODE>.
|
||||
You can find other options in the Erlang manual page (<TT>erl -man erl</TT>).</P><P> <A NAME="eja-commands"></A> </P><!--TOC section <TT>ejabberd</TT> Commands-->
|
||||
|
@ -2600,6 +2600,7 @@ disabled for instances of \ejabberd{} with hundreds of thousands users.
|
||||
\ind{protocols!XEP-0030: Service Discovery}
|
||||
\ind{protocols!XEP-0011: Jabber Browsing}
|
||||
\ind{protocols!XEP-0094: Agent Information}
|
||||
\ind{protocols!XEP-0157: Contact Addresses for XMPP Services}
|
||||
|
||||
This module adds support for Service Discovery (\xepref{0030}). With
|
||||
this module enabled, services on your server can be discovered by
|
||||
@ -2613,8 +2614,16 @@ Options:
|
||||
\begin{description}
|
||||
\iqdiscitem{Service Discovery (\ns{http://jabber.org/protocol/disco\#items} and
|
||||
\ns{http://jabber.org/protocol/disco\#info})}
|
||||
\titem{extra\_domains} \ind{options!extra\_domains}With this option,
|
||||
extra domains can be added to the Service Discovery item list.
|
||||
\titem{\{extra\_domains, [ Domain ]\}} \ind{options!extra\_domains}With this option,
|
||||
you can specify a list of extra domains that are added to the Service Discovery item list.
|
||||
\titem{\{server\_info, [ \{Modules, Field, [Value]\} ]\}} \ind{options!server\_info}
|
||||
Specify additional information about the server,
|
||||
as described in Contact Addresses for XMPP Services (\xepref{0157}).
|
||||
\term{Modules} can be the keyword `all',
|
||||
in which case the information is reported in all the services;
|
||||
or a list of \ejabberd{} modules,
|
||||
in which case the information is only specified for the services provided by those modules.
|
||||
Any arbitrary \term{Field} and \term{Value} can be specified, not only contact addresses.
|
||||
\end{description}
|
||||
|
||||
Examples:
|
||||
@ -2648,9 +2657,32 @@ Examples:
|
||||
...
|
||||
]}.
|
||||
\end{verbatim}
|
||||
\item With this configuration, all services show abuse addresses,
|
||||
feedback address on the main server,
|
||||
and admin addresses for both the main server and the vJUD service:
|
||||
\begin{verbatim}
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_disco, [{server_info, [
|
||||
{all,
|
||||
"abuse-addresses",
|
||||
["mailto:abuse@shakespeare.lit"]},
|
||||
{[mod_muc],
|
||||
"Web chatroom logs",
|
||||
["http://www.example.org/muc-logs"]},
|
||||
{[mod_disco],
|
||||
"feedback-addresses",
|
||||
["http://shakespeare.lit/feedback.php", "mailto:feedback@shakespeare.lit", "xmpp:feedback@shakespeare.lit"]},
|
||||
{[mod_disco, mod_vcard],
|
||||
"admin-addresses",
|
||||
["mailto:xmpp@shakespeare.lit", "xmpp:admins@shakespeare.lit"]}
|
||||
]}]},
|
||||
...
|
||||
]}.
|
||||
\end{verbatim}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\makesubsection{modecho}{\modecho{}}
|
||||
\ind{modules!\modecho{}}\ind{debugging}
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
-define(NS_COMMANDS, "http://jabber.org/protocol/commands").
|
||||
-define(NS_BYTESTREAMS, "http://jabber.org/protocol/bytestreams").
|
||||
-define(NS_ADMIN, "http://jabber.org/protocol/admin").
|
||||
-define(NS_SERVERINFO, "http://jabber.org/network/serverinfo").
|
||||
|
||||
-define(NS_RSM, "http://jabber.org/protocol/rsm").
|
||||
-define(NS_EJABBERD_CONFIG, "ejabberd:config").
|
||||
|
@ -1,7 +1,7 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : mod_disco.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose : Service Discovery (JEP-0030) support
|
||||
%%% Purpose : Service Discovery (XEP-0030) support
|
||||
%%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
@ -41,6 +41,7 @@
|
||||
get_sm_identity/5,
|
||||
get_sm_features/5,
|
||||
get_sm_items/5,
|
||||
get_info/5,
|
||||
register_feature/2,
|
||||
unregister_feature/2,
|
||||
register_extra_domain/2,
|
||||
@ -79,6 +80,7 @@ start(Host, Opts) ->
|
||||
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 100),
|
||||
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 100),
|
||||
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100),
|
||||
ejabberd_hooks:add(disco_info, Host, ?MODULE, get_info, 100),
|
||||
ok.
|
||||
|
||||
stop(Host) ->
|
||||
@ -88,6 +90,7 @@ stop(Host) ->
|
||||
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
|
||||
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 100),
|
||||
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_services, 100),
|
||||
ejabberd_hooks:delete(disco_info, Host, ?MODULE, get_info, 100),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
|
||||
@ -153,6 +156,8 @@ process_local_iq_info(From, To, #iq{type = Type, lang = Lang,
|
||||
Host,
|
||||
[],
|
||||
[From, To, Node, Lang]),
|
||||
Info = ejabberd_hooks:run_fold(disco_info, Host, [],
|
||||
[Host, ?MODULE, Node, Lang]),
|
||||
case ejabberd_hooks:run_fold(disco_local_features,
|
||||
Host,
|
||||
empty,
|
||||
@ -166,6 +171,7 @@ process_local_iq_info(From, To, #iq{type = Type, lang = Lang,
|
||||
sub_el = [{xmlelement, "query",
|
||||
[{"xmlns", ?NS_DISCO_INFO} | ANode],
|
||||
Identity ++
|
||||
Info ++
|
||||
lists:map(fun feature_to_xml/1, Features)
|
||||
}]};
|
||||
{error, Error} ->
|
||||
@ -362,3 +368,60 @@ get_user_resources(User, Server) ->
|
||||
[{"jid", User ++ "@" ++ Server ++ "/" ++ R},
|
||||
{"name", User}], []}
|
||||
end, lists:sort(Rs)).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%%% Support for: XEP-0157 Contact Addresses for XMPP Services
|
||||
|
||||
get_info(_A, Host, Module, Node, _Lang) when Node == [] ->
|
||||
Serverinfo_fields = get_fields_xml(Host, Module),
|
||||
[{xmlelement, "x",
|
||||
[{"xmlns", ?NS_XDATA}, {"type", "result"}],
|
||||
[{xmlelement, "field",
|
||||
[{"var", "FORM_TYPE"}, {"type", "hidden"}],
|
||||
[{xmlelement, "value",
|
||||
[],
|
||||
[{xmlcdata, ?NS_SERVERINFO}]
|
||||
}]
|
||||
}]
|
||||
++ Serverinfo_fields
|
||||
}];
|
||||
|
||||
get_info(_, _, _, _Node, _) ->
|
||||
[].
|
||||
|
||||
get_fields_xml(Host, Module) ->
|
||||
Fields = gen_mod:get_module_opt(Host, ?MODULE, server_info, []),
|
||||
|
||||
%% filter, and get only the ones allowed for this module
|
||||
Fields_good = lists:filter(
|
||||
fun({Modules, _, _}) ->
|
||||
case Modules of
|
||||
all -> true;
|
||||
Modules -> lists:member(Module, Modules)
|
||||
end
|
||||
end,
|
||||
Fields),
|
||||
|
||||
fields_to_xml(Fields_good).
|
||||
|
||||
fields_to_xml(Fields) ->
|
||||
[ field_to_xml(Field) || Field <- Fields].
|
||||
|
||||
field_to_xml({_, Var, Values}) ->
|
||||
Values_xml = values_to_xml(Values),
|
||||
{xmlelement, "field",
|
||||
[{"var", Var}],
|
||||
Values_xml
|
||||
}.
|
||||
|
||||
values_to_xml(Values) ->
|
||||
lists:map(
|
||||
fun(Value) ->
|
||||
{xmlelement, "value",
|
||||
[],
|
||||
[{xmlcdata, Value}]
|
||||
}
|
||||
end,
|
||||
Values
|
||||
).
|
||||
|
@ -214,6 +214,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
|
||||
#iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
|
||||
sub_el = SubEl, lang = Lang} = IQ ->
|
||||
Node = xml:get_tag_attr_s("node", SubEl),
|
||||
Info = ejabberd_hooks:run_fold(
|
||||
disco_info, ServerHost, [],
|
||||
[ServerHost, ?MODULE, "", ""]),
|
||||
case iq_disco(Node, Lang) of
|
||||
[] ->
|
||||
Res = IQ#iq{type = result,
|
||||
@ -227,7 +230,7 @@ do_route1(Host, ServerHost, From, To, Packet) ->
|
||||
Res = IQ#iq{type = result,
|
||||
sub_el = [{xmlelement, "query",
|
||||
[{"xmlns", XMLNS}],
|
||||
DiscoInfo}]},
|
||||
DiscoInfo ++ Info}]},
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
jlib:iq_to_xml(Res))
|
||||
|
@ -353,10 +353,14 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
|
||||
case jlib:iq_query_info(Packet) of
|
||||
#iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
|
||||
sub_el = _SubEl, lang = Lang} = IQ ->
|
||||
Info = ejabberd_hooks:run_fold(
|
||||
disco_info, ServerHost, [],
|
||||
[ServerHost, ?MODULE, "", ""]),
|
||||
Res = IQ#iq{type = result,
|
||||
sub_el = [{xmlelement, "query",
|
||||
[{"xmlns", XMLNS}],
|
||||
iq_disco_info(Lang)}]},
|
||||
iq_disco_info(Lang)
|
||||
++Info}]},
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
jlib:iq_to_xml(Res));
|
||||
|
@ -120,9 +120,13 @@ delete_listener(Host) ->
|
||||
%%%------------------------
|
||||
|
||||
%% disco#info request
|
||||
process_iq(_, #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} = IQ, #state{name=Name}) ->
|
||||
process_iq(_, #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} = IQ,
|
||||
#state{name=Name, serverhost=ServerHost}) ->
|
||||
Info = ejabberd_hooks:run_fold(
|
||||
disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]),
|
||||
IQ#iq{type = result, sub_el =
|
||||
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}], iq_disco_info(Lang, Name)}]};
|
||||
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}],
|
||||
iq_disco_info(Name, Lang) ++ Info}]};
|
||||
|
||||
%% disco#items request
|
||||
process_iq(_, #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ, _) ->
|
||||
|
@ -888,12 +888,15 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
|
||||
sub_el = SubEl, lang = Lang} = IQ ->
|
||||
{xmlelement, _, QAttrs, _} = SubEl,
|
||||
Node = xml:get_attr_s("node", QAttrs),
|
||||
Info = ejabberd_hooks:run_fold(
|
||||
disco_info, ServerHost, [],
|
||||
[ServerHost, ?MODULE, "", ""]),
|
||||
Res = case iq_disco_info(Host, Node, From, Lang) of
|
||||
{result, IQRes} ->
|
||||
jlib:iq_to_xml(
|
||||
IQ#iq{type = result,
|
||||
sub_el = [{xmlelement, "query",
|
||||
QAttrs, IQRes}]});
|
||||
QAttrs, IQRes++Info}]});
|
||||
{error, Error} ->
|
||||
jlib:make_error_reply(Packet, Error)
|
||||
end,
|
||||
|
@ -367,6 +367,9 @@ do_route(ServerHost, From, To, Packet) ->
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
Info = ejabberd_hooks:run_fold(
|
||||
disco_info, ServerHost, [],
|
||||
[ServerHost, ?MODULE, "", ""]),
|
||||
ResIQ =
|
||||
IQ#iq{type = result,
|
||||
sub_el = [{xmlelement,
|
||||
@ -384,7 +387,7 @@ do_route(ServerHost, From, To, Packet) ->
|
||||
[{"var", ?NS_SEARCH}], []},
|
||||
{xmlelement, "feature",
|
||||
[{"var", ?NS_VCARD}], []}
|
||||
]
|
||||
] ++ Info
|
||||
}]},
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
|
@ -406,6 +406,7 @@ do_route(State, From, To, Packet) ->
|
||||
|
||||
route(State, From, To, Packet) ->
|
||||
#jid{user = User, resource = Resource} = To,
|
||||
ServerHost = State#state.serverhost,
|
||||
if
|
||||
(User /= "") or (Resource /= "") ->
|
||||
Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
|
||||
@ -467,6 +468,9 @@ route(State, From, To, Packet) ->
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
Info = ejabberd_hooks:run_fold(
|
||||
disco_info, ServerHost, [],
|
||||
[ServerHost, ?MODULE, "", ""]),
|
||||
ResIQ =
|
||||
IQ#iq{type = result,
|
||||
sub_el = [{xmlelement,
|
||||
@ -482,7 +486,7 @@ route(State, From, To, Packet) ->
|
||||
[{"var", ?NS_SEARCH}], []},
|
||||
{xmlelement, "feature",
|
||||
[{"var", ?NS_VCARD}], []}
|
||||
]
|
||||
] ++ Info
|
||||
}]},
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
|
@ -344,6 +344,9 @@ do_route(ServerHost, From, To, Packet) ->
|
||||
Packet, ?ERR_NOT_ALLOWED),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
get ->
|
||||
Info = ejabberd_hooks:run_fold(
|
||||
disco_info, ServerHost, [],
|
||||
[ServerHost, ?MODULE, "", ""]),
|
||||
ResIQ =
|
||||
IQ#iq{type = result,
|
||||
sub_el = [{xmlelement,
|
||||
@ -359,7 +362,7 @@ do_route(ServerHost, From, To, Packet) ->
|
||||
[{"var", ?NS_SEARCH}], []},
|
||||
{xmlelement, "feature",
|
||||
[{"var", ?NS_VCARD}], []}
|
||||
]
|
||||
] ++ Info
|
||||
}]},
|
||||
ejabberd_router:route(To,
|
||||
From,
|
||||
|
Loading…
Reference in New Issue
Block a user