]> granicus.if.org Git - ejabberd/commitdiff
Add option to restrict max offline messages by Access and ACL (EJAB-951)
authorBadlop <badlop@process-one.net>
Mon, 15 Jun 2009 17:43:18 +0000 (17:43 +0000)
committerBadlop <badlop@process-one.net>
Mon, 15 Jun 2009 17:43:18 +0000 (17:43 +0000)
New option for mod_offline: access_max_user_messages.
The old option user_max_messages is no longer supported.

SVN Revision: 2162

doc/guide.html
doc/guide.tex
src/ejabberd.cfg.example
src/mod_offline.erl
src/mod_offline_odbc.erl

index 467a4dfe5e711106cf67ef9257df5a0482cce727..c8160e502a7c5e86089793649f96862d260e0749 100644 (file)
@@ -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&#XA0;<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>&#XA0;&#XA0;<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,
  [
   ...
index 1406b0523bfe1cd5352b27dd98ff383f6c46f64e..66747bbe5545c832571254ae95d2d351e225e107 100644 (file)
@@ -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}
index b0fcecadb0882b17aaaad168b8ec9ccf31839cd9..ebcd44ed063baa2b879d9f36888f6000801f1211 100644 (file)
 %% 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}]}.
 
                  {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,[]},
index e3898eb4fa4b5f5026c5f730095255699080cb75..c9fe276c13233c39ee450934b3d855b0e60e1eaf 100644 (file)
@@ -30,7 +30,7 @@
 -behaviour(gen_mod).
 
 -export([start/2,
-        init/1,
+        loop/1,
         stop/1,
         store_packet/3,
         resend_offline_messages/2,
@@ -52,6 +52,9 @@
 -define(PROCNAME, ejabberd_offline).
 -define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
 
+%% default value for the maximum number of user messages
+-define(MAX_USER_MESSAGES, infinity).
+
 start(Host, Opts) ->
     mnesia:create_table(offline_msg,
                        [{disc_only_copies, [node()]},
@@ -72,22 +75,18 @@ start(Host, Opts) ->
                       ?MODULE, webadmin_user, 50),
     ejabberd_hooks:add(webadmin_user_parse_query, Host,
                        ?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])).
-
-%% MaxOfflineMsgs is either infinity of integer > 0
-init(infinity) ->
-    loop(infinity);
-init(MaxOfflineMsgs) 
-  when is_integer(MaxOfflineMsgs), MaxOfflineMsgs > 0 ->
-    loop(MaxOfflineMsgs).
+            spawn(?MODULE, loop, [AccessMaxOfflineMsgs])).
 
-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 ->
@@ -113,9 +112,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) ->
index 3a61374dc1f75464abdbb3ebf1908e1cd61e8909..507da1f11f4e241bf83c45c735b811e77519fc40 100644 (file)
@@ -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,
@@ -51,6 +51,9 @@
 -define(PROCNAME, ejabberd_offline).
 -define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
 
+%% default value for the maximum number of user messages
+-define(MAX_USER_MESSAGES, infinity).
+
 start(Host, Opts) ->
     ejabberd_hooks:add(offline_message_hook, Host,
                       ?MODULE, store_packet, 50),
@@ -66,22 +69,17 @@ start(Host, Opts) ->
                       ?MODULE, webadmin_user, 50),
     ejabberd_hooks:add(webadmin_user_parse_query, Host,
                        ?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])).
-
-%% 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).
+            spawn(?MODULE, loop, [Host, AccessMaxOfflineMsgs])).
 
-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 ->
@@ -125,9 +123,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) ->