hobo/hobo/multitenant
Frédéric Péters 20018fbac8 settings loaders: add all theme details in settings.THEME_INFO (#34025) 2019-06-16 20:22:56 +02:00
..
management multitenant: wrap schema creation in atomic() (#23119) 2019-03-18 15:01:11 +01:00
README multitenant: add support for haystack whoosh engine (#8744) 2015-10-23 09:27:26 +02:00
__init__.py multitenant: load multitenant thread classes early on (#32685) 2019-04-30 18:19:54 +02:00
apps.py multitenant: load multitenant thread classes early on (#32685) 2019-04-30 18:19:54 +02:00
cache.py Revert "multitenant: use settings object to create a cache key_prefix (#7635)" (#7659) 2015-07-23 18:57:32 +02:00
haystack.py haystack: don't declare a file storage for fake initial tenant (#20933) 2018-04-04 15:12:42 +02:00
log.py multitenant: include tenant domain in logging emails (#25715) 2018-08-29 09:48:26 +02:00
mellon.py general: update for python 3 (#22981) 2018-06-20 10:37:44 +02:00
middleware.py multitenant: always sort tenants (#25673) 2018-08-16 12:11:04 +02:00
models.py general: update for python 3 (#22981) 2018-06-20 10:37:44 +02:00
settings.py create a new UserSettingsHolder on each reload of tenant settings (#33563) 2019-06-04 16:41:54 +02:00
settings_loaders.py settings loaders: add all theme details in settings.THEME_INFO (#34025) 2019-06-16 20:22:56 +02:00
storage.py multitenant: inherit from TenantStorageMixin to avoid a warning (#18180) 2018-01-03 12:40:23 +01:00
template_loader.py multitenant: drop 1.8 compatibility from template loader (#33238) 2019-05-31 08:28:42 +02:00
threads.py multitenant: load multitenant thread classes early on (#32685) 2019-04-30 18:19:54 +02:00
utils.py fix filter bug in group provisioning (fixes #9811) 2016-01-29 16:03:37 +01:00
views.py multitenenant extension 2015-02-11 11:06:25 +01:00

README

Multitenant
-----------

An application for making a Django application multitenant for Entr'ouvert
customers.

Based on https://django-tenant-schemas.readthedocs.org/

It is developed, tested and supported on Django 1.7, but it should work with
Django 1.6 + south.


Install
-------

See also : https://django-tenant-schemas.readthedocs.org/

Set the tenant model:

    TENANT_MODEL = 'multitenant.Tenant'

Where are tenants:

    TENANT_BASE = '/var/lib/<project>/tenants'

Add the middlewares for multitenant, they must be first:

    MIDDLEWARE_CLASSES = (
        'hobo.multitenant.middleware.TenantMiddleware',
    ) + MIDDLEWARE_CLASSES
    TENANT_SETTINGS_LOADERS = (
        'hobo.multitenant.settings_loaders.TemplateVars',
        'hobo.multitenant.settings_loaders.SettingsJSON',
        # 'hobo.multitenant.settings_loaders.SettingsPy',
        # 'hobo.multitenant.settings_loaders.Authentic',
    )

    # use TemplateVars with :
    TEMPLATE_CONTEXT_PROCESSORS = (
        'django.core.context_processors.request',
        'hobo.context_processors.template_vars',
    ) + TEMPLATE_CONTEXT_PROCESSORS


Define the shared applications:

    SHARED_APPS = (
        'tenant_schemas',
        'hobo.multitenant',
        # those are needed for the public apps to work
        # add also any application needed by the public app
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    )

    TENANT_APPS = INSTALLED_APPS

    INSTALLED_APPS = ('hobo.multitenant',
        'tenant_schemas') + INSTALLED_APPS

    # or, with Django 1.6 or older:
    # INSTALLED_APPS += ('tenant_schemas', 'hobo.multitenant')

Use multitenant database engine:

    DATABASES = {
        'default': {
            'ENGINE': 'tenant_schemas.postgresql_backend',
            'NAME': '<db_name>',
        },
    }
    DATABASE_ROUTERS = (
        'tenant_schemas.routers.TenantSyncRouter',
    )

    # With Django 1.6 or older, use multitenant south adapter:
    # SOUTH_DATABASE_ADAPTERS = {'default': 'south.db.postgresql_psycopg2'}


To multitenant-ify your cache backend:

    CACHES = {
        'default': {
            'BACKEND': 'hobo.multitenant.cache.TenantCache',
            # add a real Django cache backend, with its parameters if needed
            'REAL_BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

Add the multitenant filesystem template loader and configure where the
multitenant templates are located:

    TEMPLATE_LOADERS = (
        'hobo.multitenant.template_loader.FilesystemLoader',
    ) + TEMPLATE_LOADERS
    TENANT_TEMPLATE_DIRS = (TENANT_BASE,)



If a tenant doesn't exist, the tenant middleware raise a 404 error. If you
prefer to redirect to a specific site, use:
    TENANT_NOT_FOUND_REDIRECT_URL = 'http://www.example.net/'


Usage
-----

Create a tenant:
   manage.py create_tenant www.example.net
Migration of all tenants:
   manage.py migrate_schemas
Add a super user to tenant:
   manage.py tenant_command createsuperuser --domain www.example.net

Tenants are created in TENANT_BASE directory, for example :
    /var/lib/project/tenants/www.example.net/
               templates/  <-- override project templates
               static/     <-- to be handled by HTTP server
               media/
Each tenant is a PostgreSQL schema, named www_example_net


Mellon Integration
------------------

Sites can be incorporated in a SAML circle-of-trust by mean of Mellon; there
is a custom django-mellon adapter that will look for the first active identity
provider in the hobo.json and use that for authentication.

MELLON_ADAPTER = ('hobo.multitenant.mellon.MellonAdapter',)

In the service login view, the code path to mellon can thus dynamically be
chosen, using " if any(mellon.utils.get_idps()) ".


Haystack Integration
--------------------

At the present time support for Haystack exists only for the Whoosh engine,
with a single ("default") connection.

The index will be located in $tenant_dir/whoosh_index.

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'hobo.multitenant.haystack.WhooshEngine',
    }
}