mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
* src/mod_last.erl: Supprot for storing status from latest
unavailable presence (thanks to Sergei Golovan) * src/ejabberd_sm.erl: Likewise * src/ejabberd_c2s.erl: Likewise * src/mod_vcard.erl: Minor update (thanks to Sergei Golovan) * src/mod_register.erl: Added "access" option (thanks to Sergei Golovan) * src/mod_irc/mod_irc.erl: Likewise * src/ejabberd.cfg.example: Updated * src/win32/ejabberd.cfg: Likewise * src/mod_privacy.erl: Fixed module stopping (thanks to Sergei Golovan) * src/mod_private.erl: Likewise * src/gen_mod.erl: Added function get_module_opt/3 (thanks to Sergei Golovan) * src/ejabberd_local.erl: Minor fix (thanks to Sergei Golovan) * doc/guide.tex: Updated (thanks to Sergei Golovan) SVN Revision: 244
This commit is contained in:
parent
b64cc8f662
commit
a846fe815c
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
||||
2004-07-11 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/mod_last.erl: Supprot for storing status from latest
|
||||
unavailable presence (thanks to Sergei Golovan)
|
||||
* src/ejabberd_sm.erl: Likewise
|
||||
* src/ejabberd_c2s.erl: Likewise
|
||||
|
||||
* src/mod_vcard.erl: Minor update (thanks to Sergei Golovan)
|
||||
|
||||
* src/mod_register.erl: Added "access" option (thanks to Sergei
|
||||
Golovan)
|
||||
* src/mod_irc/mod_irc.erl: Likewise
|
||||
* src/ejabberd.cfg.example: Updated
|
||||
* src/win32/ejabberd.cfg: Likewise
|
||||
|
||||
* src/mod_privacy.erl: Fixed module stopping (thanks to Sergei
|
||||
Golovan)
|
||||
* src/mod_private.erl: Likewise
|
||||
|
||||
* src/gen_mod.erl: Added function get_module_opt/3 (thanks to
|
||||
Sergei Golovan)
|
||||
|
||||
* src/ejabberd_local.erl: Minor fix (thanks to Sergei Golovan)
|
||||
|
||||
* doc/guide.tex: Updated (thanks to Sergei Golovan)
|
||||
|
||||
2004-07-10 Alexey Shchepin <alexey@sevcom.net>
|
||||
|
||||
* src/mod_roster.erl: Removed superfluous include_lib line
|
||||
|
@ -871,7 +871,17 @@ Options:
|
||||
<B><TT>host</TT></B><DD> Defines hostname of service
|
||||
(see <A HREF="#sec:modhostoption">A.1.2</A>). If not present
|
||||
then prefix <TT>irc.</TT> is added to main <TT>ejabberd</TT> hostname.
|
||||
<DT><B><TT>access</TT></B><DD> Specifies who is allowed to use IRC transport (default value is <TT>all</TT>).
|
||||
</DL>
|
||||
Example:
|
||||
<PRE>
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_irc, [{access, all}]},
|
||||
...
|
||||
]}.
|
||||
</PRE>
|
||||
<!--TOC subsection <TT>mod_last</TT>-->
|
||||
|
||||
<H3><A NAME="htoc36">A.6</A> <TT>mod_last</TT></H3><!--SEC END -->
|
||||
@ -981,14 +991,15 @@ Example:
|
||||
<H3><A NAME="htoc42">A.12</A> <TT>mod_register</TT></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:modregister"></A>
|
||||
This module adds support for <A HREF="http://www.jabber.org/jeps/jep-0077.html">JEP-0077</A> (In-Band Registration).
|
||||
It is possible to restrict registration via ``register''
|
||||
access rule. If this rule returns ``deny'' on requested user name, then
|
||||
registration is not allowed for it.<BR>
|
||||
This module adds support for <A HREF="http://www.jabber.org/jeps/jep-0077.html">JEP-0077</A> (In-Band Registration).<BR>
|
||||
<BR>
|
||||
Options:
|
||||
<DL COMPACT=compact><DT>
|
||||
<B><TT>iqdisc</TT></B><DD> <TT>jabber:iq:register</TT> IQ queries processing
|
||||
<B><TT>access</TT></B><DD> Specifies rule to restrict registration.
|
||||
If this rule returns ``deny'' on requested user name, then
|
||||
registration is not allowed for it. (default value is <TT>all</TT>, which means
|
||||
no restrictions).
|
||||
<DT><B><TT>iqdisc</TT></B><DD> <TT>jabber:iq:register</TT> IQ queries processing
|
||||
discipline (see <A HREF="#sec:modiqdiscoption">A.1.1</A>).
|
||||
</DL>
|
||||
Example:
|
||||
@ -1004,7 +1015,7 @@ Example:
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_register, []},
|
||||
{mod_register, [{access, register}]},
|
||||
...
|
||||
]}.
|
||||
</PRE>
|
||||
|
@ -860,8 +860,19 @@ This module implements IRC transport.
|
||||
Options:
|
||||
\begin{description}
|
||||
\hostitem{irc}
|
||||
\titem{access} Specifies who is allowed to use IRC transport (default value is \term{all}).
|
||||
\end{description}
|
||||
|
||||
Example:
|
||||
\begin{verbatim}
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_irc, [{access, all}]},
|
||||
...
|
||||
]}.
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\subsection{\modlast{}}
|
||||
\label{sec:modlast}
|
||||
@ -965,12 +976,13 @@ Example:
|
||||
\label{sec:modregister}
|
||||
|
||||
This module adds support for \jepref{0077} (In-Band Registration).
|
||||
It is possible to restrict registration via ``register''
|
||||
access rule. If this rule returns ``deny'' on requested user name, then
|
||||
registration is not allowed for it.
|
||||
|
||||
Options:
|
||||
\begin{description}
|
||||
\titem{access} Specifies rule to restrict registration.
|
||||
If this rule returns ``deny'' on requested user name, then
|
||||
registration is not allowed for it. (default value is \term{all}, which means
|
||||
no restrictions).
|
||||
\iqdiscitem{\ns{jabber:iq:register}}
|
||||
\end{description}
|
||||
|
||||
@ -987,7 +999,7 @@ Example:
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_register, []},
|
||||
{mod_register, [{access, register}]},
|
||||
...
|
||||
]}.
|
||||
\end{verbatim}
|
||||
|
@ -107,7 +107,7 @@
|
||||
% Used modules:
|
||||
{modules,
|
||||
[
|
||||
{mod_register, []},
|
||||
{mod_register, [{access, register}]},
|
||||
{mod_roster, []},
|
||||
{mod_privacy, []},
|
||||
{mod_configure, []},
|
||||
|
@ -856,7 +856,8 @@ terminate(_Reason, StateName, StateData) ->
|
||||
[{xmlelement, "status", [],
|
||||
[{xmlcdata, "Replaced by new connection"}]}]},
|
||||
ejabberd_sm:unset_presence(StateData#state.user,
|
||||
StateData#state.resource),
|
||||
StateData#state.resource,
|
||||
"Replaced by new connection"),
|
||||
presence_broadcast(
|
||||
StateData, From, StateData#state.pres_a, Packet),
|
||||
presence_broadcast(
|
||||
@ -867,15 +868,26 @@ terminate(_Reason, StateName, StateData) ->
|
||||
jlib:jid_to_string(StateData#state.jid)]),
|
||||
ejabberd_sm:close_session(StateData#state.user,
|
||||
StateData#state.resource),
|
||||
|
||||
Tmp = ?SETS:new(),
|
||||
case StateData of
|
||||
#state{pres_last = undefined,
|
||||
pres_a = Tmp,
|
||||
pres_i = Tmp,
|
||||
pres_invis = false} ->
|
||||
ok;
|
||||
_ ->
|
||||
From = StateData#state.jid,
|
||||
Packet = {xmlelement, "presence",
|
||||
[{"type", "unavailable"}], []},
|
||||
ejabberd_sm:unset_presence(StateData#state.user,
|
||||
StateData#state.resource),
|
||||
StateData#state.resource,
|
||||
""),
|
||||
presence_broadcast(
|
||||
StateData, From, StateData#state.pres_a, Packet),
|
||||
presence_broadcast(
|
||||
StateData, From, StateData#state.pres_i, Packet)
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
@ -984,8 +996,15 @@ presence_update(From, Packet, StateData) ->
|
||||
{xmlelement, _Name, Attrs, _Els} = Packet,
|
||||
case xml:get_attr_s("type", Attrs) of
|
||||
"unavailable" ->
|
||||
Status = case xml:get_subtag(Packet, "status") of
|
||||
false ->
|
||||
"";
|
||||
StatusTag ->
|
||||
xml:get_tag_cdata(StatusTag)
|
||||
end,
|
||||
ejabberd_sm:unset_presence(StateData#state.user,
|
||||
StateData#state.resource),
|
||||
StateData#state.resource,
|
||||
Status),
|
||||
presence_broadcast(StateData, From, StateData#state.pres_a, Packet),
|
||||
presence_broadcast(StateData, From, StateData#state.pres_i, Packet),
|
||||
StateData#state{pres_last = undefined,
|
||||
|
@ -65,7 +65,7 @@ loop(State) ->
|
||||
catch mod_disco:unregister_feature(XMLNS),
|
||||
loop(State);
|
||||
refresh_iq_handlers ->
|
||||
lists:map(
|
||||
lists:foreach(
|
||||
fun(T) ->
|
||||
case T of
|
||||
{XMLNS, _Module, _Function, _Opts} ->
|
||||
|
@ -13,7 +13,7 @@
|
||||
-export([start_link/0, init/0, open_session/2, close_session/2,
|
||||
get_user_resources/1,
|
||||
set_presence/3,
|
||||
unset_presence/2,
|
||||
unset_presence/3,
|
||||
dirty_get_sessions_list/0,
|
||||
dirty_get_my_sessions_list/0,
|
||||
register_iq_handler/3,
|
||||
@ -317,14 +317,14 @@ set_presence(User, Resource, Priority) ->
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
unset_presence(User, Resource) ->
|
||||
unset_presence(User, Resource, Status) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
F = fun() ->
|
||||
UR = {User, Resource},
|
||||
mnesia:delete({presence, UR})
|
||||
end,
|
||||
mnesia:transaction(F),
|
||||
catch mod_last:on_presence_update(LUser).
|
||||
catch mod_last:on_presence_update(LUser, Status).
|
||||
|
||||
get_user_present_resources(LUser) ->
|
||||
case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
|
||||
|
@ -15,6 +15,7 @@
|
||||
stop_module/1,
|
||||
get_opt/2,
|
||||
get_opt/3,
|
||||
get_module_opt/3,
|
||||
loaded_modules/0]).
|
||||
|
||||
-export([behaviour_info/1]).
|
||||
@ -73,6 +74,16 @@ get_opt(Opt, Opts, Default) ->
|
||||
Val
|
||||
end.
|
||||
|
||||
get_module_opt(Module, Opt, Default) ->
|
||||
OptsList = ets:lookup(ejabberd_modules, Module),
|
||||
case OptsList of
|
||||
[] ->
|
||||
Default;
|
||||
[#ejabberd_module{opts = Opts} | _] ->
|
||||
get_opt(Opt, Opts, Default)
|
||||
end.
|
||||
|
||||
loaded_modules() ->
|
||||
ets:select(ejabberd_modules,
|
||||
[{#ejabberd_module{_ = '_', module = '$1'}, [],['$1']}]).
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/1, init/1, stop/0, closed_conection/2,
|
||||
-export([start/1, init/2, stop/0, closed_conection/2,
|
||||
get_user_and_encoding/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
@ -29,34 +29,48 @@ start(Opts) ->
|
||||
[{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, irc_custom)}]),
|
||||
Host = gen_mod:get_opt(host, Opts, "irc." ++ ?MYNAME),
|
||||
register(ejabberd_mod_irc, spawn(?MODULE, init, [Host])).
|
||||
Access = gen_mod:get_opt(access, Opts, all),
|
||||
register(ejabberd_mod_irc, spawn(?MODULE, init, [Host, Access])).
|
||||
|
||||
init(Host) ->
|
||||
init(Host, Access) ->
|
||||
catch ets:new(irc_connection, [named_table,
|
||||
public,
|
||||
{keypos, #irc_connection.userserver}]),
|
||||
ejabberd_router:register_route(Host),
|
||||
loop(Host).
|
||||
loop(Host, Access).
|
||||
|
||||
loop(Host) ->
|
||||
loop(Host, Access) ->
|
||||
receive
|
||||
{route, From, To, Packet} ->
|
||||
case catch do_route(Host, From, To, Packet) of
|
||||
case catch do_route(Host, Access, From, To, Packet) of
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("~p", [Reason]);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
loop(Host);
|
||||
loop(Host, Access);
|
||||
stop ->
|
||||
ejabberd_router:unregister_global_route(Host),
|
||||
ok;
|
||||
_ ->
|
||||
loop(Host)
|
||||
loop(Host, Access)
|
||||
end.
|
||||
|
||||
|
||||
do_route(Host, From, To, Packet) ->
|
||||
do_route(Host, Access, From, To, Packet) ->
|
||||
case acl:match_rule(Access, From) of
|
||||
allow ->
|
||||
do_route1(Host, From, To, Packet);
|
||||
_ ->
|
||||
{xmlelement, _Name, Attrs, _Els} = Packet,
|
||||
Lang = xml:get_attr_s("xml:lang", Attrs),
|
||||
ErrText = "Access denied by service policy",
|
||||
Err = jlib:make_error_reply(Packet,
|
||||
?ERRT_FORBIDDEN(Lang, ErrText)),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end.
|
||||
|
||||
do_route1(Host, From, To, Packet) ->
|
||||
#jid{user = ChanServ, resource = Resource} = To,
|
||||
{xmlelement, _Name, Attrs, _Els} = Packet,
|
||||
case ChanServ of
|
||||
|
@ -16,13 +16,13 @@
|
||||
stop/0,
|
||||
process_local_iq/3,
|
||||
process_sm_iq/3,
|
||||
on_presence_update/1,
|
||||
on_presence_update/2,
|
||||
remove_user/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(last_activity, {user, timestamp}).
|
||||
-record(last_activity, {user, timestamp, status}).
|
||||
|
||||
|
||||
start(Opts) ->
|
||||
@ -30,6 +30,7 @@ start(Opts) ->
|
||||
mnesia:create_table(last_activity,
|
||||
[{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, last_activity)}]),
|
||||
update_table(),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_LAST,
|
||||
?MODULE, process_local_iq, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_LAST,
|
||||
@ -93,7 +94,7 @@ get_last(IQ, SubEl, LUser) ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
|
||||
[] ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
|
||||
[#last_activity{timestamp = TimeStamp}] ->
|
||||
[#last_activity{timestamp = TimeStamp, status = Status}] ->
|
||||
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||
TimeStamp2 = MegaSecs * 1000000 + Secs,
|
||||
Sec = TimeStamp2 - TimeStamp,
|
||||
@ -101,17 +102,18 @@ get_last(IQ, SubEl, LUser) ->
|
||||
sub_el = [{xmlelement, "query",
|
||||
[{"xmlns", ?NS_LAST},
|
||||
{"seconds", integer_to_list(Sec)}],
|
||||
[]}]}
|
||||
[{xmlcdata, Status}]}]}
|
||||
end.
|
||||
|
||||
|
||||
|
||||
on_presence_update(LUser) ->
|
||||
on_presence_update(LUser, Status) ->
|
||||
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||
TimeStamp = MegaSecs * 1000000 + Secs,
|
||||
F = fun() ->
|
||||
mnesia:write(#last_activity{user = LUser,
|
||||
timestamp = TimeStamp})
|
||||
timestamp = TimeStamp,
|
||||
status = Status})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
@ -122,3 +124,22 @@ remove_user(User) ->
|
||||
mnesia:delete({last_activity, LUser})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
|
||||
update_table() ->
|
||||
Fields = record_info(fields, last_activity),
|
||||
case mnesia:table_info(last_activity, attributes) of
|
||||
Fields ->
|
||||
ok;
|
||||
[user, timestamp] ->
|
||||
?INFO_MSG("Converting last_activity table from {user, timestamp} format", []),
|
||||
mnesia:transform_table(
|
||||
last_activity,
|
||||
fun({_, U, T}) ->
|
||||
#last_activity{user = U, timestamp = T, status = ""}
|
||||
end, Fields);
|
||||
_ ->
|
||||
?INFO_MSG("Recreating last_activity table", []),
|
||||
mnesia:transform_table(last_activity, ignore, Fields)
|
||||
end.
|
||||
|
||||
|
@ -50,7 +50,7 @@ start(Opts) ->
|
||||
?MODULE, process_iq, IQDisc).
|
||||
|
||||
stop() ->
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_PRIVACY).
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_PRIVACY).
|
||||
|
||||
process_iq(From, _To, IQ) ->
|
||||
#iq{type = Type, sub_el = SubEl} = IQ,
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
-export([start/1,
|
||||
stop/0,
|
||||
process_local_iq/3,
|
||||
process_sm_iq/3,
|
||||
remove_user/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
@ -28,13 +28,13 @@ start(Opts) ->
|
||||
[{disc_only_copies, [node()]},
|
||||
{attributes, record_info(fields, private_storage)}]),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_PRIVATE,
|
||||
?MODULE, process_local_iq, IQDisc).
|
||||
?MODULE, process_sm_iq, IQDisc).
|
||||
|
||||
stop() ->
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_PRIVATE).
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_PRIVATE).
|
||||
|
||||
|
||||
process_local_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
process_sm_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
#jid{luser = LUser, lserver = LServer} = From,
|
||||
case ?MYNAME of
|
||||
LServer ->
|
||||
|
@ -122,7 +122,8 @@ try_register(User, Password) ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
_ ->
|
||||
JID = jlib:make_jid(User, ?MYNAME, ""),
|
||||
case acl:match_rule(register, JID) of
|
||||
Access = gen_mod:get_module_opt(?MODULE, access, all),
|
||||
case acl:match_rule(Access, JID) of
|
||||
deny ->
|
||||
{error, ?ERR_CONFLICT};
|
||||
allow ->
|
||||
|
@ -70,10 +70,10 @@ start(Opts) ->
|
||||
|
||||
init(Host, Search) ->
|
||||
case Search of
|
||||
true ->
|
||||
ejabberd_router:register_route(Host),
|
||||
false ->
|
||||
loop(Host);
|
||||
_ ->
|
||||
ejabberd_router:register_route(Host),
|
||||
loop(Host)
|
||||
end.
|
||||
|
||||
|
@ -103,7 +103,7 @@
|
||||
% Used modules:
|
||||
{modules,
|
||||
[
|
||||
{mod_register, []},
|
||||
{mod_register, [{access, register}]},
|
||||
{mod_roster, []},
|
||||
{mod_privacy, []},
|
||||
{mod_configure, []},
|
||||
|
Loading…
Reference in New Issue
Block a user