django-xmpp-account
django-xmpp-account copied to clipboard
Django application for Jabber account registration
django-xmpp-account
django-xmpp-account is a stand-alone Django application that manages registrations to your
Jabber/XMPP server. It was written for account.jabber.at but can be
used for any Jabber/XMPP server. Users can also use the site to reset their password or their email
address or delete their account.
Features
- Users can use the site to register an account, reset their password or email address or delete their account.
- Supports Python 2.7+ and Python 3.4+.
- Fully localized, translation is available in German.
- As standard Django application, it runs on any WSGI capable webserver and supports e.g. MySQL, PostgreSQL.
- Currently works only with ejabberd (via
mod_xmlrpcorejabberd_xmlrpc), but could easily extended to work with other servers. - Robust anti-SPAM features including CAPTCHA support, email confirmations and configurable rate-limiting.
- Manages accounts on multiple XMPP servers, page will adapt to the URL used (e.g. see how the default XMPP domain changes on account.jabber.at and account.xmpp.zone).
- Users can give a GPG key (either via fingerprint or direct upload) so the site can use GPG to sign and encrypt any confirmation emails it sends.
- Support for Celery to send emails asynchronously for fast page response times.
- Facebook and Twitter integration via "Share" and "Tweet" buttons. Buttons use Shariff to protect users privacy.
- Fabric file for fast and automated deployment of updates.
This project currently only interacts with ejabberd servers (either via the
ejabberdctl command line tool or via the ejabberd_xmlrpc plugin), because
this is what we run. But it is written in a way that you
just have to implement a certain subclass to make it communicate with other
servers. Please feel free to contribute additional backends to this project via
a merge request!
Documentation
Preface: This documentation assumes you are already running your own Jabber/XMPP server. It
also assumes system administration knowledge. django-xmpp-account is a
Django project which typically runs inside a virtualenv. This means
that all references to any python invocation assume that you have it activated (see Basic
installation) or all dependencies manually installed.
Requirements
- Currently only ejabberd via
mod_xmlrpcorejabberd_xmlrpcis supported. If you want to use a different server, please consider contributing your own backend. - Python 2.7 or Python 3.4
- We strongly recommend you run the project inside a
virtualenv and install all Python
library requirements inside. If you don't want to use virtualenv, all used libraries are listed
in
requirements.txt, older versions are not tested but are probably fine for most libraries. - Any database that Django supports, for example MySQL or PostgreSQL.
- GnuPG to sign and encrypt confirmation mails.
If you use Debian/Ubuntu, you can copy & paste this command:
apt-get install gcc python-virtualenv gnupg libxml2-dev libxslt1-dev python-dev \
libfreetype6-dev gettext libjpeg-dev zlib1g-dev
Basic installation
Simply clone the project, setup a virtualenv and install the requirements:
git clone https://github.com/mathiasertl/django-xmpp-account.git
cd django-xmpp-account
virtualenv .
source bin/activate
pip install -r requirements.txt
Depending on the database backend you want to use, you probably need to install additional packages. For MySQL, this would be:
apt-get install libmysqlclient-dev mysql-common
pip install MySQL-python
Configuration
The project is configured via the file xmppaccount/localsettings.py. There is an example config
file in xmppaccount/localsettings.py.example, simply copy it and fill in the details for your
preferred setup. The file is imported by a standard Django settings file, so you can use any of the
official settings, even if they are not
documented in the examples file.
Database setup
The database the project uses is configured by the DATABASES setting in
xmppaccount/localsettings.py. Also see the official
documentation for possible options.
Make sure the database exists and the configured user has sufficient permissions, and simply
execute:
python manage.py migrate
... to create all the databases tables.
Webserver setup
There are many ways to run a standard WSGI application like this one. The WSGI file is located in
xmppaccount/wsgi.py. For example, you might want to use
mod_wsgi or uWSGI and
nginx. uWSGI can also
be used with Apache.
NOTE: Unless you deactivate GPG support, we highly recommend you enable threading support.
A Django project does not serve static files (like JavaScript or CSS files) by itself, this should
be done by the webserver. Configure your webserver to serve the directory configured with the
STATIC_ROOT setting under the location configured with the STATIC_URL setting. Then collect all
static files there with:
python manage.py collectstatic
You can optimize page load speed by using browser caching. See Google's PageSpeed Insights for more information. Here is what we use using mod_expires:
ExpiresActive on
ExpiresDefault "access plus 1 month"
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
<Location /captcha>
ExpiresByType image/png "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
</Location>
Generate translations
django-xmpp-account is a fully internationalized project, currently a German translation is
available. The project has per-app translations, so to generate the translations manually, you must
execute manage.py inside the app directories (core, register, reset and delete):
cd core
python ../manage.py compilemessages
Note that all translations are automatically compiled with manage.py update.
Schedule cron-jobs
The manage.py cleanup command removes users from the database if users were removed from the XMPP
server. It also removes users from the database if they registered but never clicked the
confirmation link sent to them via email.
HOME=/usr/local/home/xmpp-account
PATH=/usr/local/home/xmpp-account/bin
# m h dom mon dow user command
22 * * * * xmpp-account python django-xmpp-account/manage.py cleanup
If your server allows In-Band Registration (IBR), you can also add the manage.py ejabberd_registrations command. It is an XMPP bot that parses messages that ejabberd sends to
contacts named in its registration_watchers setting. Note that it uses additional settings,
please see your localsettings.py.
GPG setup
django-xmpp-account sends out confirmation emails on any action. Emails can be encrypted if users
upload their public key, but for emails to also be signed, you must generate a private key. You
can simply do this with:
python manage.py genkey <hostname>
Where <hostname> is any of the hosts you configured in the XMPP_HOSTS settings. You must then
manually add the key to the respective XMPP_HOSTS setting. The key is also saved to the static/
directory, so you must update your staticfiles with python manage.py collectstatic.
WARNING: GPG is very strict about permissions to its configuration directory. Make sure the
directory is owned and read/writeable only by the system user the webserver runs as. The genkey
command must also be executed as that same user, which will also create the GPG config directory if
it doesn't exist.
Celery setup
Celery is a distributed task queue. django-xmpp-account can use celery to send emails asynchronously. This is especially recommended if you enable GPG, since GPG operations can be quite slow and doing all GPG operations inside the WSGI process will result in long page load times. The downside is that if some GPG operations fail, no error message can be displayed anymore and the user will receive an unencrypted email instead.
To enable Celery, just edit the relevant sections in your localsettings.py file. We strongly
recommend using redis as a broker, on Debian/Ubuntu a simple apt-get install redis-server
should suffice.
Celery obviously runs as a daemon, so it needs to be started. Example files for systemd are
included in files/systemd. They assume that celery runs as user xmpp-account with the home
directory /usr/local/home/xmpp-account, a virtualenv and the source code in that directory. If
this doesn't suit your needs, you need to modify the files accordingly. After that, three simple
symlinks should enable the service:
ln -s /usr/local/home/xmpp-account/django-xmpp-account/files/systemd/celery-xmpp-account.tmpfiles \
/etc/tmpfiles.d/celery-xmpp-account.conf
ln -s /usr/local/home/xmpp-account/django-xmpp-account/files/systemd/celery-xmpp-account.conf \
/etc/conf.d/
ln -s /usr/local/home/xmpp-account/django-xmpp-account/files/systemd/celery-xmpp-account.service \
/etc/systemd/system/
Then just start the celery daemon with:
service celery-xmpp-account start
If you're not using systemd, the official documentation has a few more examples for other init systems.
Update
When want to update the project, simply do (don't forget to activate the virtualenv!):
source bin/activate
git fetch
git pull origin master
pip install -r requirements.txt
python manage.py update
Don't forget to restart your webserver afterwards.
Deployment
We use a fabric script for easy, fast and reproduceable deployment. If you have local modifications
to this software, you might want to use the script instead. It's somewhat customizable via the
file fab.conf, see the example file in the repositories root directory.
The deployment script pushes a local repository (where you'd write and test your changes) to a remote, then updates the repository on the deployed host from that. It will also do all other update-related tasks for you.
If the fab-file suits your needs (if not: do a merge request!), you should be able to update a deployment simply by doing:
fab deploy
Custom backends
Currently only ejabberd via mod_xmlrpc or ejabberd_xmlrpc is
supported. But django-xmpp-account was written with additional backends in
mind, so you can easily add support for any custom XMPP server, if you know a
little Python. If you do, please consider doing a pull request for your backend.
To implement support for your own server, simply create a python class that subclasses
backends.base.XmppBackendBase. Raise backends.base.UserExists if the user already exists and
backends.base.UserNotFound if the user is not found. The docstrings document precisely what
Exceptions are expected. Make sure that your backend implements all methods defined by the base
class and the methods use the same argument names (backend functions are always called with
keyword arguments).
Regenerate JavaScript/CSS
The site uses minified JavaScript and CSS for faster pageloads. If you change a JS/CSS file, you must regenerate the minifed files:
sudo apt-get install nodejs npm
# Ubunut installs node as nodejs, but we need "node"
sudo ln -s /usr/bin/nodejs /usr/local/bin/node
npm install clean-css uglify-js
