mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-26 17:38:45 +01:00
Add option to restrict max offline messages by Access and ACL (EJAB-951)
New option for mod_offline: access_max_user_messages. The old option user_max_messages is no longer supported. SVN Revision: 2163
This commit is contained in:
parent
2f6cea2be3
commit
88fd7b226a
@ -2423,11 +2423,31 @@ sent to an offline user will be stored on the server until that user comes
|
||||
online again. Thus it is very similar to how email works. Note that
|
||||
<TT>ejabberdctl</TT> has a command to delete expired messages
|
||||
(see section <A HREF="#ejabberdctl">4.1</A>).</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>user_max_messages</TT></B></DT><DD CLASS="dd-description">This option
|
||||
is use to set a max number of offline messages per user (quota). Its
|
||||
value can be either <TT>infinity</TT> or a strictly positive
|
||||
integer. The default value is <TT>infinity</TT>.
|
||||
</DD></DL><P> <A NAME="modprivacy"></A> </P><!--TOC subsection <TT>mod_privacy</TT>-->
|
||||
<B><TT>access_max_user_messages</TT></B></DT><DD CLASS="dd-description">
|
||||
This option defines which access rule will be enforced to limit
|
||||
the maximum number of offline messages that a user can have (quota).
|
||||
When a user has too many offline messages, any new messages that he receive are discarded,
|
||||
and a resource-constraint error is returned to the sender.
|
||||
The default value is <TT>max_user_offline_messages</TT>.
|
||||
Then you can define an access rule with a syntax similar to
|
||||
<TT>max_user_sessions</TT> (see <A HREF="#configmaxsessions">3.1.5</A>).
|
||||
</DD></DL><P>This example allows power users to have as much as 5000 offline messages,
|
||||
administrators up to 2000,
|
||||
and all the other users up to 100.
|
||||
</P><PRE CLASS="verbatim">{acl, admin, {user, "admin1", "localhost"}}.
|
||||
{acl, admin, {user, "admin2", "example.org"}}.
|
||||
{acl, poweruser, {user, "bob", "example.org"}}.
|
||||
{acl, poweruser, {user, "jane", "example.org"}}.
|
||||
|
||||
{access, max_user_offline_messages, [ {5000, poweruser}, {2000, admin}, {100, all} ]}.
|
||||
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_offline, [ {access_max_user_messages, max_user_offline_messages} ]},
|
||||
...
|
||||
]}.
|
||||
</PRE><P> <A NAME="modprivacy"></A> </P><!--TOC subsection <TT>mod_privacy</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc48">3.3.11</A>  <A HREF="#modprivacy"><TT>mod_privacy</TT></A></H3><!--SEC END --><P> <A NAME="modprivacy"></A>
|
||||
</P><P>This module implements Blocking Communication (also known as Privacy Rules)
|
||||
as defined in section 10 from XMPP IM. If end users have support for it in
|
||||
@ -2538,12 +2558,27 @@ is replaced at start time with the real virtual host name.
|
||||
|
||||
</DD><DT CLASS="dt-description"><B><TT>access_createnode</TT></B></DT><DD CLASS="dd-description">
|
||||
This option restricts which users are allowed to create pubsub nodes using
|
||||
ACL and ACCESS. The default value is <TT>pubsub_createnode</TT>. </DD><DT CLASS="dt-description"><B><TT>plugins</TT></B></DT><DD CLASS="dd-description"> To specify which pubsub node plugins to use. If not defined, the default
|
||||
ACL and ACCESS. The default value is <TT>pubsub_createnode</TT>. </DD><DT CLASS="dt-description"><B><TT>plugins</TT></B></DT><DD CLASS="dd-description">
|
||||
To specify which pubsub node plugins to use. If not defined, the default
|
||||
pubsub plugin is always used.
|
||||
</DD><DT CLASS="dt-description"><B><TT>nodetree</TT></B></DT><DD CLASS="dd-description"> To specify which nodetree to use. If not defined, the default pubsub
|
||||
nodetree is used. Nodetrees are default and virtual. Only one nodetree can be used
|
||||
</DD><DT CLASS="dt-description"><B><TT>nodetree</TT></B></DT><DD CLASS="dd-description">
|
||||
To specify which nodetree to use. If not defined, the default pubsub
|
||||
nodetree is used. Only one nodetree can be used per host,
|
||||
and is shared by all node plugins.
|
||||
</DD></DL><P>Example:
|
||||
</DD><DT CLASS="dt-description"><B><TT>pep_sendlast_offline</TT></B></DT><DD CLASS="dd-description">
|
||||
To specify whether or not we should get last published PEP items
|
||||
from users in our roster which are offline when we connect. Value is true or false.
|
||||
If not defined, pubsub assumes false so we only get last items of online contacts.
|
||||
</DD><DT CLASS="dt-description"><B><TT>last_item_cache</TT></B></DT><DD CLASS="dd-description">
|
||||
To specify whether or not pubsub should cache last items. Value is true
|
||||
or false. If not defined, pubsub do not cache last items. On systems with not so many nodes,
|
||||
caching last items speeds up pubsub and allows to raise user connection rate. The cost is memory
|
||||
usage, as every item is stored in memory.
|
||||
</DD><DT CLASS="dt-description"><B><TT>pep_mapping</TT></B></DT><DD CLASS="dd-description">
|
||||
This allow to define a Key-Value list to choose defined node plugins on given PEP namespace.
|
||||
The following example will use node_tune instead of node_pep for every PEP node with tune namespace:
|
||||
<PRE CLASS="verbatim"> {mod_pubsub, [{pep_mapping, [{"http://jabber.org/protocol/tune", "tune"}]}]}
|
||||
</PRE></DD></DL><P>Example:
|
||||
</P><PRE CLASS="verbatim">{modules,
|
||||
[
|
||||
...
|
||||
|
@ -3132,12 +3132,35 @@ online again. Thus it is very similar to how email works. Note that
|
||||
(see section~\ref{ejabberdctl}).
|
||||
|
||||
\begin{description}
|
||||
\titem{user\_max\_messages}\ind{options!user\_max\_messages}This option
|
||||
is use to set a max number of offline messages per user (quota). Its
|
||||
value can be either \term{infinity} or a strictly positive
|
||||
integer. The default value is \term{infinity}.
|
||||
\titem{access\_max\_user\_messages}\ind{options!access\_max\_user\_messages}
|
||||
This option defines which access rule will be enforced to limit
|
||||
the maximum number of offline messages that a user can have (quota).
|
||||
When a user has too many offline messages, any new messages that he receive are discarded,
|
||||
and a resource-constraint error is returned to the sender.
|
||||
The default value is \term{max\_user\_offline\_messages}.
|
||||
Then you can define an access rule with a syntax similar to
|
||||
\term{max\_user\_sessions} (see \ref{configmaxsessions}).
|
||||
\end{description}
|
||||
|
||||
This example allows power users to have as much as 5000 offline messages,
|
||||
administrators up to 2000,
|
||||
and all the other users up to 100.
|
||||
\begin{verbatim}
|
||||
{acl, admin, {user, "admin1", "localhost"}}.
|
||||
{acl, admin, {user, "admin2", "example.org"}}.
|
||||
{acl, poweruser, {user, "bob", "example.org"}}.
|
||||
{acl, poweruser, {user, "jane", "example.org"}}.
|
||||
|
||||
{access, max_user_offline_messages, [ {5000, poweruser}, {2000, admin}, {100, all} ]}.
|
||||
|
||||
{modules,
|
||||
[
|
||||
...
|
||||
{mod_offline, [ {access_max_user_messages, max_user_offline_messages} ]},
|
||||
...
|
||||
]}.
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\makesubsection{modprivacy}{\modprivacy{}}
|
||||
\ind{modules!\modprivacy{}}\ind{Blocking Communication}\ind{Privacy Rules}\ind{protocols!RFC 3921: XMPP IM}
|
||||
|
@ -379,6 +379,9 @@
|
||||
%% Maximum number of simultaneous sessions allowed for a single user:
|
||||
{access, max_user_sessions, [{10, all}]}.
|
||||
|
||||
%% Maximum number of offline messages that users can have:
|
||||
{access, max_user_offline_messages, [{5000, admin}, {100, all}]},
|
||||
|
||||
%% This rule allows access only for local users:
|
||||
{access, local, [{allow, local}]}.
|
||||
|
||||
@ -481,7 +484,7 @@
|
||||
{access_admin, muc_admin}
|
||||
]},
|
||||
%%{mod_muc_log,[]},
|
||||
{mod_offline, []},
|
||||
{mod_offline, [{access_max_user_messages, max_user_offline_messages}]},
|
||||
{mod_privacy, []},
|
||||
{mod_private, []},
|
||||
%%{mod_proxy65,[]},
|
||||
|
@ -30,7 +30,7 @@
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/2,
|
||||
init/1,
|
||||
loop/1,
|
||||
stop/1,
|
||||
store_packet/3,
|
||||
resend_offline_messages/2,
|
||||
@ -58,6 +58,9 @@
|
||||
-define(DEFAULT_NS, ?NS_JABBER_CLIENT).
|
||||
-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
|
||||
|
||||
%% default value for the maximum number of user messages
|
||||
-define(MAX_USER_MESSAGES, infinity).
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
mnesia:create_table(offline_msg,
|
||||
@ -79,22 +82,18 @@ start(Host, Opts) ->
|
||||
?MODULE, webadmin_user, 50),
|
||||
ejabberd_hooks:add(webadmin_user_parse_query, HostB,
|
||||
?MODULE, webadmin_user_parse_query, 50),
|
||||
MaxOfflineMsgs = gen_mod:get_opt(user_max_messages, Opts, infinity),
|
||||
AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, max_user_offline_messages),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
spawn(?MODULE, init, [MaxOfflineMsgs])).
|
||||
spawn(?MODULE, loop, [AccessMaxOfflineMsgs])).
|
||||
|
||||
%% MaxOfflineMsgs is either infinity of integer > 0
|
||||
init(infinity) ->
|
||||
loop(infinity);
|
||||
init(MaxOfflineMsgs)
|
||||
when is_integer(MaxOfflineMsgs), MaxOfflineMsgs > 0 ->
|
||||
loop(MaxOfflineMsgs).
|
||||
|
||||
loop(MaxOfflineMsgs) ->
|
||||
loop(AccessMaxOfflineMsgs) ->
|
||||
receive
|
||||
#offline_msg{us=US} = Msg ->
|
||||
Msgs = receive_all(US, [Msg]),
|
||||
Len = length(Msgs),
|
||||
{User, Host} = US,
|
||||
MaxOfflineMsgs = get_max_user_messages(AccessMaxOfflineMsgs,
|
||||
User, Host),
|
||||
F = fun() ->
|
||||
%% Only count messages if needed:
|
||||
Count = if MaxOfflineMsgs =/= infinity ->
|
||||
@ -120,9 +119,18 @@ loop(MaxOfflineMsgs) ->
|
||||
end
|
||||
end,
|
||||
mnesia:transaction(F),
|
||||
loop(MaxOfflineMsgs);
|
||||
loop(AccessMaxOfflineMsgs);
|
||||
_ ->
|
||||
loop(MaxOfflineMsgs)
|
||||
loop(AccessMaxOfflineMsgs)
|
||||
end.
|
||||
|
||||
%% Function copied from ejabberd_sm.erl:
|
||||
get_max_user_messages(AccessRule, LUser, Host) ->
|
||||
case acl:match_rule(
|
||||
Host, AccessRule, jlib:make_jid(LUser, Host, "")) of
|
||||
Max when is_integer(Max) -> Max;
|
||||
infinity -> infinity;
|
||||
_ -> ?MAX_USER_MESSAGES
|
||||
end.
|
||||
|
||||
receive_all(US, Msgs) ->
|
||||
|
@ -32,7 +32,7 @@
|
||||
-export([count_offline_messages/2]).
|
||||
|
||||
-export([start/2,
|
||||
init/2,
|
||||
loop/2,
|
||||
stop/1,
|
||||
store_packet/3,
|
||||
pop_offline_messages/3,
|
||||
@ -57,6 +57,9 @@
|
||||
-define(DEFAULT_NS, ?NS_JABBER_CLIENT).
|
||||
-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
|
||||
|
||||
%% default value for the maximum number of user messages
|
||||
-define(MAX_USER_MESSAGES, infinity).
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:add(offline_message_hook, HostB,
|
||||
@ -73,22 +76,17 @@ start(Host, Opts) ->
|
||||
?MODULE, webadmin_user, 50),
|
||||
ejabberd_hooks:add(webadmin_user_parse_query, HostB,
|
||||
?MODULE, webadmin_user_parse_query, 50),
|
||||
MaxOfflineMsgs = gen_mod:get_opt(user_max_messages, Opts, infinity),
|
||||
AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, max_user_offline_messages),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
spawn(?MODULE, init, [Host, MaxOfflineMsgs])).
|
||||
spawn(?MODULE, loop, [Host, AccessMaxOfflineMsgs])).
|
||||
|
||||
%% MaxOfflineMsgs is either infinity of integer > 0
|
||||
init(Host, infinity) ->
|
||||
loop(Host, infinity);
|
||||
init(Host, MaxOfflineMsgs)
|
||||
when is_integer(MaxOfflineMsgs), MaxOfflineMsgs > 0 ->
|
||||
loop(Host, MaxOfflineMsgs).
|
||||
|
||||
loop(Host, MaxOfflineMsgs) ->
|
||||
loop(Host, AccessMaxOfflineMsgs) ->
|
||||
receive
|
||||
#offline_msg{user = User} = Msg ->
|
||||
Msgs = receive_all(User, [Msg]),
|
||||
Len = length(Msgs),
|
||||
MaxOfflineMsgs = get_max_user_messages(AccessMaxOfflineMsgs,
|
||||
User, Host),
|
||||
|
||||
%% Only count existing messages if needed:
|
||||
Count = if MaxOfflineMsgs =/= infinity ->
|
||||
@ -128,9 +126,18 @@ loop(Host, MaxOfflineMsgs) ->
|
||||
ok
|
||||
end
|
||||
end,
|
||||
loop(Host, MaxOfflineMsgs);
|
||||
loop(Host, AccessMaxOfflineMsgs);
|
||||
_ ->
|
||||
loop(Host, MaxOfflineMsgs)
|
||||
loop(Host, AccessMaxOfflineMsgs)
|
||||
end.
|
||||
|
||||
%% Function copied from ejabberd_sm.erl:
|
||||
get_max_user_messages(AccessRule, LUser, Host) ->
|
||||
case acl:match_rule(
|
||||
Host, AccessRule, jlib:make_jid(LUser, Host, "")) of
|
||||
Max when is_integer(Max) -> Max;
|
||||
infinity -> infinity;
|
||||
_ -> ?MAX_USER_MESSAGES
|
||||
end.
|
||||
|
||||
receive_all(Username, Msgs) ->
|
||||
|
Loading…
Reference in New Issue
Block a user