mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Documentation update.
This commit is contained in:
@@ -43,13 +43,19 @@ need to install a python database backend (like *MySQLdb*).
|
||||
|
||||
Initialize the database by running the following command::
|
||||
|
||||
$ python manage.py syncdb --migrate
|
||||
|
||||
It will let you create the default super administrator.
|
||||
$ python manage.py syncdb --migrate --noinput
|
||||
|
||||
Since version 0.8, Modoboa uses *south* to handle schema migrations,
|
||||
this is the reason why you must add the ``--migrate`` option.
|
||||
|
||||
At the end of this command, a default super administrator is
|
||||
available:
|
||||
|
||||
* Username: admin
|
||||
* Password: password
|
||||
|
||||
You may change its password the first time you log into Modoboa.
|
||||
|
||||
Finally, create the ``scripts`` directory::
|
||||
|
||||
$ mkdir scripts
|
||||
@@ -83,6 +89,12 @@ Throught the *Admin > Configuration* panel, you can customize the way
|
||||
Modoboa stores mailboxes on the filesystem. Here is the list of
|
||||
editable parameters with their default value::
|
||||
|
||||
The authentication type
|
||||
AUTHENTICATION_TYPE = Local
|
||||
|
||||
Does Modoboa need to handle the creation of directories on the file system?
|
||||
CREATE_DIRECTORIES = Yes
|
||||
|
||||
Where Modoboa stores mailboxes
|
||||
STORAGE_PATH = /var/vmail
|
||||
|
||||
@@ -97,12 +109,20 @@ editable parameters with their default value::
|
||||
potential sub-directory
|
||||
MAILDIR_ROOT = .maildir
|
||||
|
||||
Which encryption method is used to store passwords
|
||||
The encryption method used to store passwords
|
||||
PASSWORD_SCHEME = crypt
|
||||
|
||||
The number of displayed items per page for listing pages
|
||||
ITEMS_PER_PAGE = 30
|
||||
|
||||
Host configuration
|
||||
------------------
|
||||
|
||||
.. note::
|
||||
|
||||
You can skip this part in case you set the ``CREATE_DIRECTORIES``
|
||||
parameter to ``No``.
|
||||
|
||||
Before using Modoboa, you must create a group and a user that will be
|
||||
used to store emails on the host filesystem. There is only one
|
||||
group/user needed because we are in a virtual hosting configuration
|
||||
|
||||
+293
-80
@@ -11,12 +11,12 @@ implementation provides the following possibilities:
|
||||
* Access and modify administrative objects (domains, mailboxes, etc.)
|
||||
* Register callback actions for specific events
|
||||
|
||||
Plugins are nothing more than Django applications with an extra file
|
||||
called ``main.py``. This file contains a complete description of the
|
||||
plugin:
|
||||
Plugins are nothing more than Django applications using a specific
|
||||
structure. The ``__init__.py`` file contains a complete description of
|
||||
the plugin:
|
||||
|
||||
* Admin and user parameters
|
||||
* Registered events
|
||||
* Observed events
|
||||
* Custom menu entries
|
||||
|
||||
The communication between both applications is provided by
|
||||
@@ -32,15 +32,19 @@ Adding a custom plugin
|
||||
All Modoboa plugins must be located inside the ``extensions``
|
||||
directory. To create a new plugin, execute the following steps:
|
||||
|
||||
* Run ``python manage.py startapp`` to get some basefiles for your plugin,
|
||||
* Move the resulting directory inside the ``extensions`` one,
|
||||
* Create a file called ``main.py`` inside your plugin's directory.
|
||||
* Run ``python manage.py startapp`` to get some basefiles for your plugin
|
||||
* Move the resulting directory inside the ``extensions`` one
|
||||
|
||||
The last file you created (ie. ``main.py``) must follow a specific
|
||||
structure in order to be interpreted by Modoboa. The following
|
||||
functions are mandatory::
|
||||
The ``__init__.py`` file created inside your module's directory must
|
||||
follow a specific structure in order to be interpreted by Modoboa. The
|
||||
following functions are mandatory::
|
||||
|
||||
def init():
|
||||
"""This function is called when the extension is activated.
|
||||
"""
|
||||
pass
|
||||
|
||||
def load():
|
||||
"""This function is called when Modoboa loads available and activated plugins.
|
||||
|
||||
Declare parameters and register events here.
|
||||
@@ -67,20 +71,9 @@ functions are mandatory::
|
||||
"description" : "Example description"
|
||||
}
|
||||
|
||||
def urls(prefix):
|
||||
"""This function is used to update the global urls table.
|
||||
|
||||
It must return a sequence that corresponds to those used
|
||||
inside the main ``urls.py`` file. (ie. a classical
|
||||
Django construction)
|
||||
|
||||
:param prefix: the global url prefix (the part after the hostname)
|
||||
"""
|
||||
return (r'^%sexample/' % prefix, include('modoboa.extensions.example.urls'))
|
||||
|
||||
Once you have filled ``main.py``, simply add your plugin's name to the
|
||||
``INSTALLED_APPS`` variable located inside ``settings.py``. (use the
|
||||
same format as other plugins). Eventually, run ``python manage.py
|
||||
Once you have filled ``__init__.py``, simply add your plugin's name to
|
||||
the ``INSTALLED_APPS`` variable located inside ``settings.py``. (use
|
||||
the same format as other plugins). Eventually, run ``python manage.py
|
||||
syncdb`` if your plugin provides custom tables.
|
||||
|
||||
Events
|
||||
@@ -92,59 +85,77 @@ Playing with events
|
||||
Modoboa provides a simple API to interact with events. It understands
|
||||
two kinds of events:
|
||||
|
||||
* Those that return a value,
|
||||
* Those that return nothing.
|
||||
* Those that return a value
|
||||
* Those that return nothing
|
||||
|
||||
Listening to a specific event is achieved as follow::
|
||||
|
||||
from modoboa.lib import events
|
||||
from modoboa.lib import events
|
||||
|
||||
def callback(*args):
|
||||
pass
|
||||
|
||||
events.register('event', callback)
|
||||
|
||||
events.register(event, callback)
|
||||
You can also use the custom decorator ``events.observe``::
|
||||
|
||||
``event`` is the event's name you want to listen to, ``callback`` is
|
||||
the function that will be called when this event is raised. Its
|
||||
prototype must be as follow::
|
||||
|
||||
def callback(*args, **kwargs):
|
||||
@events.observe('event')
|
||||
def callback(*args):
|
||||
pass
|
||||
|
||||
It is very generic, it allows events to provide arguments if needed.
|
||||
``event`` is the event's name you want to listen to, ``callback`` is
|
||||
the function that will be called each time this event is raised. Each
|
||||
event impose to callbacks a specific prototype to respect. See below
|
||||
for a detailled list.
|
||||
|
||||
You can also stop listening to an event like this::
|
||||
To stop listening to as specific event, you must use the
|
||||
``unregister`` function::
|
||||
|
||||
events.unregister(event, callback)
|
||||
events.unregister('event', callback)
|
||||
|
||||
The parameters are the same as those used with ``register``.
|
||||
The parameters are the same than those used with ``register``.
|
||||
|
||||
Read further to get a complete list and description of the available events.
|
||||
Read further to get a complete list and description of all available events.
|
||||
|
||||
UserLogin
|
||||
---------
|
||||
|
||||
Raised when a user logs in. This event provides a ``request`` argument
|
||||
that corresponds to the ``Request`` object used inside the associated
|
||||
view function.
|
||||
Raised when a user logs in.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(request, username, password): pass
|
||||
|
||||
|
||||
UserLogout
|
||||
----------
|
||||
|
||||
Raised when a user logs out. This event provides a ``request`` argument
|
||||
that corresponds to the ``Request`` object used inside the associated
|
||||
view function.
|
||||
Raised when a user logs out.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(request): pass
|
||||
|
||||
|
||||
.. _usermenudisplay:
|
||||
|
||||
UserMenuDisplay
|
||||
---------------
|
||||
|
||||
Raised when a user menu is about to be displayed. It provides a
|
||||
``target`` argument that indicates which menu is being
|
||||
Raised when a user menu is about to be displayed.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(target, user): pass
|
||||
|
||||
The ``target`` argument indicates which menu is being
|
||||
displayed. Possible values are:
|
||||
|
||||
* ``uprefs_menu`` : corresponds to the menu bar available inside the *User preferences* page
|
||||
* ``uprefs_menu`` : corresponds to the menu bar available inside the
|
||||
*User preferences* page
|
||||
* ``top_menu`` : corresponds to the top blue bar
|
||||
|
||||
All callbacks that listen to this event must return a list of
|
||||
All the callbacks that listen to this event must return a list of
|
||||
dictionnaries (corresponding to menu entries). Each dictionnary must
|
||||
contain at least the following keys::
|
||||
|
||||
@@ -156,8 +167,13 @@ contain at least the following keys::
|
||||
AdminMenuDisplay
|
||||
----------------
|
||||
|
||||
Raised when an admin menu is about to be displayed. It provides a
|
||||
``target`` argument that indicates which menu is being
|
||||
Raised when an admin menu is about to be displayed.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(target, user): pass
|
||||
|
||||
The ``target`` argument indicates which menu is being
|
||||
displayed. Possible values are:
|
||||
|
||||
* ``admin_menu_box`` : corresponds to the menu bar available inside administration pages
|
||||
@@ -166,36 +182,187 @@ displayed. Possible values are:
|
||||
See :ref:`usermenudisplay` for a description of what callbacks that
|
||||
listen to this event must return.
|
||||
|
||||
AdminFooterDisplay
|
||||
------------------
|
||||
|
||||
Raised when the footer (ie. bottom of the page) of listing pages
|
||||
inside the ``admin`` application is displayed. Plugins can listen to
|
||||
this event when they want to add specific information into that place.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user, object_type): pass
|
||||
|
||||
* ``user`` is a ``User`` instance (the one that is displaying the page)
|
||||
* ``object_type`` is a string indicating which kind of object is
|
||||
displayed. Possible values are:
|
||||
|
||||
* ``domains``: a list of domains
|
||||
* ``domaliases``: a list of domain aliases
|
||||
* ``mailboxes``: a list of mailboxes
|
||||
* ``mbaliases``: a list of mailbox aliases
|
||||
|
||||
Registered callbacks must return a list of string objects.
|
||||
|
||||
CanCreateDomain
|
||||
---------------
|
||||
|
||||
Raised just before a user tries to access the ``newdomain`` function.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user): pass
|
||||
|
||||
* ``user`` is a ``User`` instance
|
||||
|
||||
Return ``True`` or ``False`` to indicate if this user can respectively
|
||||
create or not create a new ``Domain`` object.
|
||||
|
||||
CreateDomain
|
||||
------------
|
||||
|
||||
Raised when a new domain is created. The new domain object is
|
||||
available inside the ``dom`` argument.
|
||||
Raised when a new domain is created.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user, domain): pass
|
||||
|
||||
* ``user`` corresponds to the ``User`` object creating the domain (its owner)
|
||||
* ``domain`` is a ``Domain`` instance
|
||||
|
||||
DeleteDomain
|
||||
------------
|
||||
|
||||
Raised when an existing domain is about to be deleted. The domain
|
||||
object is available inside the ``dom`` argument.
|
||||
Raised when an existing domain is about to be deleted.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(domain): pass
|
||||
|
||||
* ``domain`` is a ``Domain`` instance
|
||||
|
||||
CanCreateDomainAlias
|
||||
--------------------
|
||||
|
||||
Raised just before a user tries to access the ``newdomalias`` function.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user): pass
|
||||
|
||||
* ``user`` is a ``User`` instance
|
||||
|
||||
Return ``True`` or ``False`` to indicate that the user can
|
||||
respectively create or not create a new domain alias.
|
||||
|
||||
DomainAliasCreated
|
||||
------------------
|
||||
|
||||
Raised when a new domain alias is created.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user, domain_alias): pass
|
||||
|
||||
* ``user`` is the new domain alias owner (``User`` instance)
|
||||
* ``domain_alias`` is the new domain alias (``DomainAlias`` instance)
|
||||
|
||||
DomainAliasDeleted
|
||||
------------------
|
||||
|
||||
Raised when an existing domain alias is about to be deleted.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(domain_alias): pass
|
||||
|
||||
* ``domain_alias`` is a ``DomainAlias`` instance
|
||||
|
||||
CanCreateMailbox
|
||||
----------------
|
||||
|
||||
Raised just before a user tries to access the ``newmailbox`` function.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user): pass
|
||||
|
||||
* ``user`` is a ``User`` instance
|
||||
|
||||
Return ``True`` or ``False`` to indicate that the user can
|
||||
respectively create or not create a new mailbox.
|
||||
|
||||
CreateMailbox
|
||||
-------------
|
||||
|
||||
Raised when a new mailbox is created. The new mailbox object is
|
||||
available inside the ``mbox`` argument.
|
||||
Raised when a new mailbox is created.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user, mailbox): pass
|
||||
|
||||
* ``user`` is the new mailbox's owner (``User`` instance)
|
||||
* ``mailbox`` is the new mailbox (``Mailbox`` instance)
|
||||
|
||||
DeleteMailbox
|
||||
-------------
|
||||
|
||||
Raised when an existing mailbox is about to be deleted. The mailbox
|
||||
object is available inside the ``mbox`` argument.
|
||||
Raised when an existing mailbox is about to be deleted.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(mailbox): pass
|
||||
|
||||
* ``mailbox`` is a ``Mailbox`` instance
|
||||
|
||||
ModifyMailbox
|
||||
-------------
|
||||
|
||||
Raised when an existing mailbox is modified. The old mailbox and the
|
||||
new mailbox objects are respectively available inside the ``oldmbox``
|
||||
and ``mbox`` arguments.
|
||||
Raised when an existing mailbox is modified.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(newmailbox, oldmailbox): pass
|
||||
|
||||
* ``newmailbox`` is a ``Mailbox`` instance containing the new values
|
||||
* ``oldmailbox`` is a ``Mailbox`` instance containing the old values
|
||||
|
||||
CanCreateMailboxAlias
|
||||
---------------------
|
||||
|
||||
Raised just before a user tries to access the ``newmbalias`` function.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user): pass
|
||||
|
||||
* ``user`` is a ``User`` instance
|
||||
|
||||
Return ``True`` or ``False`` to indicate that the user can
|
||||
respectively create or not create a new mailbox alias.
|
||||
|
||||
MailboxAliasCreated
|
||||
-------------------
|
||||
|
||||
Raised when a new mailbox alias is created.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user, mailbox_alias): pass
|
||||
|
||||
* ``user`` is the new domain alias owner (``User`` instance)
|
||||
* ``mailbox_alias`` is the new mailbox alias (``Alias`` instance)
|
||||
|
||||
MailboxAliasDeleted
|
||||
-------------------
|
||||
|
||||
Raised when an existing mailbox alias is about to be deleted.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(mailbox_alias): pass
|
||||
|
||||
* ``mailbox_alias`` is an ``Alias`` instance
|
||||
|
||||
.. _permsgettables:
|
||||
|
||||
@@ -203,8 +370,13 @@ PermsGetTables
|
||||
--------------
|
||||
|
||||
Raised when the different permission lists (one per role) are about to
|
||||
be displayed. The current *User* object is available inside the
|
||||
``user`` argument.
|
||||
be displayed.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(request): pass
|
||||
|
||||
* ``request`` is a ``Request`` instance
|
||||
|
||||
Callbacks that listen to this event must return a list of
|
||||
dictionnaries (corresponding to tables). Each dictionnary must contain
|
||||
@@ -215,8 +387,8 @@ at least the following elements::
|
||||
"rel" : "x y",
|
||||
"content" : MyPermClass().get(request)}
|
||||
|
||||
For ``rel``, replace x and y with the the *Add form* size (the
|
||||
one that appears when you click on the ``Add permission`` button.
|
||||
For ``rel``, replace x and y with the *Add form* size (the one that
|
||||
appears when you click on the ``Add permission`` button.
|
||||
|
||||
For ``content``, replace *MyPermClass* with the appropriate name.
|
||||
|
||||
@@ -227,40 +399,79 @@ PermsGetClass
|
||||
|
||||
Raised to retrieve the class (inheriting from ``Permissions``)
|
||||
implementing a specific role. This event is used to add or delete or
|
||||
new instance of this role. The role's name is available inside the
|
||||
``role`` argument.
|
||||
new instance of this role.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(role): pass
|
||||
|
||||
* ``role`` is a string indicating the role beeing added
|
||||
|
||||
Callbacks listening to this event must return the class object
|
||||
corresponding to the given ``role`` argument.
|
||||
|
||||
SuperAdminPromotion
|
||||
-------------------
|
||||
|
||||
Raised when an existing user becomes a super administrator. Each group
|
||||
that user belongs to is still available (inside the ``user.groups``
|
||||
queryset) at the time the event is raised.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user): pass
|
||||
|
||||
* ``user`` is a ``User`` instance
|
||||
|
||||
ExtEnabled
|
||||
----------
|
||||
|
||||
Raised just after an extension has been activated. The Extension
|
||||
object is available inside the ``ext`` keyword argument.
|
||||
Raised just after an extension has been activated.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(extension): pass
|
||||
|
||||
* ``extension`` is an ``Extension`` instance
|
||||
|
||||
ExtDisabled
|
||||
-----------
|
||||
|
||||
Raised just after an extension has been disabled. The Extension
|
||||
object is available inside the ``ext`` keyword argument.
|
||||
Raised just after an extension has been disabled.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(extension): pass
|
||||
|
||||
* ``extension`` is an ``Extension`` instance
|
||||
|
||||
GetAnnouncement
|
||||
---------------
|
||||
|
||||
Some places in the interface let plugins add their own announcement
|
||||
(ie. message). A keyword argument ``target`` is provided to registered
|
||||
callbacks and indicates the place where the announcement will appear:
|
||||
(ie. message).
|
||||
|
||||
* ``loginpage`` : corresponds to the login page
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(target): pass
|
||||
|
||||
* ``target`` is a string indicating the place where the announcement
|
||||
will appear:
|
||||
|
||||
* ``loginpage`` : corresponds to the login page
|
||||
|
||||
Callbacks listening to this event must return a list of string.
|
||||
|
||||
PasswordChange
|
||||
--------------
|
||||
|
||||
Raised just before a *password change* action. The associated ``User``
|
||||
object is provided inside the ``user`` keyword argument.
|
||||
Raised just before a *password change* action.
|
||||
|
||||
*Callback prototype*::
|
||||
|
||||
def callback(user): pass
|
||||
|
||||
* ``user`` is a ``User`` instance
|
||||
|
||||
Callbacks listening to this event must return a list containing either
|
||||
``True`` or ``False``. If at least one ``True`` is returned, the
|
||||
@@ -272,8 +483,10 @@ Parameters
|
||||
|
||||
A plugin can declare its own parameters. There are two levels available:
|
||||
|
||||
* 'Administration' parameters : used to configure the plugin, editable inside the *Admin > Settings > Parameters* page,
|
||||
* 'User' parameters : per-user parameters (or preferences), editable inside the *Options > Preferences* page.
|
||||
* 'Administration' parameters : used to configure the plugin, editable
|
||||
inside the *Admin > Settings > Parameters* page,
|
||||
* 'User' parameters : per-user parameters (or preferences), editable
|
||||
inside the *Options > Preferences* page.
|
||||
|
||||
Playing with parameters
|
||||
-----------------------
|
||||
@@ -308,8 +521,8 @@ Custom permission levels
|
||||
|
||||
Custom permissions roles can be added to Modoboa. If you to want to
|
||||
integrate the default permissions panel (*Admin > Permissions*), each
|
||||
role you add must inherit from the ``Permissions`` (file
|
||||
``admin/permissions.py``) class and implement all its methods.
|
||||
role you add must inherit from the ``Permissions`` class (see file
|
||||
``admin/permissions.py``) and implement all its methods.
|
||||
|
||||
.. note::
|
||||
See :ref:`permsgettables` and :ref:`permsgetclass` to learn how to
|
||||
|
||||
@@ -18,7 +18,6 @@ events = [
|
||||
"CanCreateDomain",
|
||||
"CreateDomain",
|
||||
"DeleteDomain",
|
||||
"DomainAssigned",
|
||||
|
||||
"CanCreateDomainAlias",
|
||||
"DomainAliasCreated",
|
||||
|
||||
Reference in New Issue
Block a user