mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
319 lines
9.3 KiB
ReStructuredText
319 lines
9.3 KiB
ReStructuredText
Extending Modoboa
|
|
*****************
|
|
|
|
Introduction
|
|
============
|
|
|
|
Modoboa offers a plugin API to expand its capabilities. The current
|
|
implementation provides the following possibilities:
|
|
|
|
* Expand navigation by adding entry points to your plugin inside the GUI
|
|
* 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:
|
|
|
|
* Admin and user parameters
|
|
* Registered events
|
|
* Custom menu entries
|
|
|
|
The communication between both applications is provided by
|
|
events. Modoboa offers some kind of hooks to let plugin add custom
|
|
actions.
|
|
|
|
The following subsections describe plugin architecture and explain
|
|
how you can create your own plugin.
|
|
|
|
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.
|
|
|
|
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::
|
|
|
|
def init():
|
|
"""This function is called when Modoboa loads available and activated plugins.
|
|
|
|
Declare parameters and register events here.
|
|
"""
|
|
pass
|
|
|
|
def destroy():
|
|
"""This function is called when a plugin is disabled from the interface.
|
|
|
|
Unregister parameters and events here.
|
|
"""
|
|
pass
|
|
|
|
def infos():
|
|
"""This function is used to populate the plugins list
|
|
available in the administration panel.
|
|
|
|
It must return a dictionnary containing at least three
|
|
keys : "name", "version", "description"
|
|
"""
|
|
return {
|
|
"name" : "Example plugin",
|
|
"version" : "1.0",
|
|
"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
|
|
syncdb`` if your plugin provides custom tables.
|
|
|
|
Events
|
|
======
|
|
|
|
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.
|
|
|
|
Listening to a specific event is achieved as follow::
|
|
|
|
from modoboa.lib import events
|
|
|
|
events.register(event, callback)
|
|
|
|
``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):
|
|
pass
|
|
|
|
It is very generic, it allows events to provide arguments if needed.
|
|
|
|
You can also stop listening to an event like this::
|
|
|
|
events.unregister(event, callback)
|
|
|
|
The parameters are the same as those used with ``register``.
|
|
|
|
Read further to get a complete list and description of the 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.
|
|
|
|
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.
|
|
|
|
.. _usermenudisplay:
|
|
|
|
UserMenuDisplay
|
|
---------------
|
|
|
|
Raised when a user menu is about to be displayed. It provides a
|
|
``target`` argument that indicates which menu is being
|
|
displayed. Possible values are:
|
|
|
|
* ``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
|
|
dictionnaries (corresponding to menu entries). Each dictionnary must
|
|
contain at least the following keys::
|
|
|
|
{"name" : "a_name_without_spaces",
|
|
"label" : _("The menu label"),
|
|
"url" : reverse("your_view"), # can be set to ""
|
|
"img" : static_url("your_pic")} # can be set to ""
|
|
|
|
AdminMenuDisplay
|
|
----------------
|
|
|
|
Raised when an admin menu is about to be displayed. It provides a
|
|
``target`` argument that indicates which menu is being
|
|
displayed. Possible values are:
|
|
|
|
* ``admin_menu_box`` : corresponds to the menu bar available inside administration pages
|
|
* ``top_menu`` : corresponds to the *Admin* dropdown menu located inside the top blue bar
|
|
|
|
See :ref:`usermenudisplay` for a description of what callbacks that
|
|
listen to this event must return.
|
|
|
|
CreateDomain
|
|
------------
|
|
|
|
Raised when a new domain is created. The new domain object is
|
|
available inside the ``dom`` argument.
|
|
|
|
DeleteDomain
|
|
------------
|
|
|
|
Raised when an existing domain is about to be deleted. The domain
|
|
object is available inside the ``dom`` argument.
|
|
|
|
CreateMailbox
|
|
-------------
|
|
|
|
Raised when a new mailbox is created. The new mailbox object is
|
|
available inside the ``mbox`` argument.
|
|
|
|
DeleteMailbox
|
|
-------------
|
|
|
|
Raised when an existing mailbox is about to be deleted. The mailbox
|
|
object is available inside the ``mbox`` argument.
|
|
|
|
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.
|
|
|
|
.. _permsgettables:
|
|
|
|
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.
|
|
|
|
Callbacks that listen to this event must return a list of
|
|
dictionnaries (corresponding to tables). Each dictionnary must contain
|
|
at least the following elements::
|
|
|
|
{"id" : "table_id",
|
|
"title" : _("The title corresponding to this table"),
|
|
"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 ``content``, replace *MyPermClass* with the appropriate name.
|
|
|
|
.. _permsgetclass:
|
|
|
|
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.
|
|
|
|
Callbacks listening to this event must return the class object
|
|
corresponding to the given ``role`` argument.
|
|
|
|
ExtEnabled
|
|
----------
|
|
|
|
Raised just after an extension has been activated. The Extension
|
|
object is available inside the ``ext`` keyword argument.
|
|
|
|
ExtDisabled
|
|
-----------
|
|
|
|
Raised just after an extension has been disabled. The Extension
|
|
object is available inside the ``ext`` keyword argument.
|
|
|
|
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:
|
|
|
|
* ``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.
|
|
|
|
Callbacks listening to this event must return a list containing either
|
|
``True`` or ``False``. If at least one ``True`` is returned, the
|
|
*password change* will be cancelled (ie. changing the password for
|
|
this user is disabled).
|
|
|
|
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.
|
|
|
|
Playing with parameters
|
|
-----------------------
|
|
|
|
To declare a new administration parameter, use the following function::
|
|
|
|
from modoboa.lib import parameters
|
|
|
|
parameters.register_admin(name, **kwargs)
|
|
|
|
To declare a new user parameter, use the following function::
|
|
|
|
parameter.register_user(name, **kwargs)
|
|
|
|
Both functions accept extra arguments listed here:
|
|
|
|
* ``type`` : parameter's type, possible values are : ``int``, ``string``, ``list``, ``list_yesno``,
|
|
* ``deflt`` : default value,
|
|
* ``help`` : help text,
|
|
* ``values`` : list of possible values if ``type`` is ``list``.
|
|
|
|
To undeclare parameters (for example when a plugin is disabled is
|
|
disabled from the interface), use the following function::
|
|
|
|
parameters.unregister_app(appname)
|
|
|
|
``appname`` corresponds to your plugin's name, ie. the name of the
|
|
directory containing the source code.
|
|
|
|
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.
|
|
|
|
.. note::
|
|
See :ref:`permsgettables` and :ref:`permsgetclass` to learn how to
|
|
integrate your custom roles.
|
|
|
|
|