This package provides multi-tenant support for Kiwi TCMS and is a wrapper around django-tenants. You can use it to host different organizations on the same application server or host multiple product instances used by different teams. Each tenant is able to see only the information created by themselves.
IMPORTANT: multi-tenancy is backed by PostgreSQL schemas! It will not work with a different database backend.
WARNING: current tenant is decided based on the FQDN by which you are accessing Kiwi TCMS!
The following changes need to be introduced into a downstream Docker image or your Python virtualenv where the main Kiwi TCMS instance is hosted:
pip install kiwitcms-tenants
then make sure KIWI_TENANTS_DOMAIN
ENV variable is specified !!!
The rest of the settings are installed into tcms_settings_dir/multi_tenant.py
and Kiwi TCMS will pick them up automatically!
When starting your multi-tenant Kiwi TCMS instance for the first time you also need to create information about the so called public tenant. That is the default tenant on which your application runs:
./manage.py initial_setup
Your tenant will be available at https://$KIWI_TENANTS_DOMAIN!
Other tenants can be created via the web interface and will be available
under team-01.$KIWI_TENANTS_DOMAIN, product-02.$KIWI_TENANTS_DOMAIN, etc
depnding on the actual schema name
you give them.
You need wildcard DNS resolution to be configured for *.tenants.example.org
!
If using AWS Route 53 create an A record with Name==*.tenants
for the
example.org
domain and point it to the IP address of your Kiwi TCMS instance.
Once DNS has been configured you should be able to query for various domains with
tools like dig
and nslookup
:
$ dig public.tenant.kiwitcms.org ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-12.P2.el7 <<>> public.tenant.kiwitcms.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58543 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;public.tenant.kiwitcms.org. IN A ;; ANSWER SECTION: public.tenant.kiwitcms.org. 36 IN A 100.24.231.234 ;; Query time: 35 msec ;; SERVER: 10.38.5.26#53(10.38.5.26) ;; WHEN: Tue Nov 19 14:04:09 EET 2019 ;; MSG SIZE rcvd: 71 $ nslookup linux.tenant.kiwitcms.org Server: 10.38.5.26 Address: 10.38.5.26#53 Non-authoritative answer: Name: linux.tenant.kiwitcms.org Address: 100.24.231.234
All sub-domains should resolve to the same IP address!
See Migrating Single-Tenant to Multi-Tenant section in the official django-tenants documentation! It has been contributed by the Kiwi TCMS team and that was the procedure we've used to migrate the previous demo website (ST) to its new MT version!
Starting with Kiwi TCMS v13.1 session and CSRF cookies are configured only on HTTPS connections which will prevent browsers from sending cookies over a plain text HTTP connection. This will result in not being able to login if you are using a local development server. To workaround this issue, first generate an SSL certificate:
/usr/bin/sscg -v -f --country BG --locality Sofia --organization "Kiwi TCMS" --organizational-unit "QA" --ca-file ssl/ca.crt --cert-file ssl/host.crt --cert-key-file ssl/host.key
Then use the runerver_plus
command to start Kiwi TCMS development server with HTTPS:
PYTHONPATH=../Kiwi/ KIWI_TENANTS_DOMAIN=tenant.example.bg ./manage.py runserver_plus --cert-file ssl/host.crt --key-file ssl/host.key
Then point your browser to https://tenant.example.bg:8000/. The SSL warning from the browser is expected!
You can use your OS hosts file to configure DNS resolution during development:
127.0.0.1 localhost tenant.example.bg empty.tenant.example.bg
- Update email template for invited users
- Update django-tenants from 3.6.1 to 3.7.0
- Add context processor for the
TENANT_SCHEMA_NAME
template variable - Update test suite for changes related to Django 5
- Relicense this package under GNU Affero General Public License v3 or later
- Prior versions are still licensed under GNU General Public License v3
- Make sure to populate the
extra_emails
field when cloning a tenant
- Allow downstream installations to override Edit tenant page template
- Bug-fix: display empty string instead of
None
on Invite users page - Add test for utils function with an email which won't validate according to
settings.EMAIL_VALIDATORS
- Refactor HTML template for Invite Users page to display form field errors
- When inviting users validate addresses taking into account the value of
settings.EMAIL_VALIDATORS
- Updated documentation
- Adjust tests for newer version of django-grappelli
- Add the
Tenant.extra_emails
field for storing information like technical email, billing email, etc. To be used by add-on tools - Add the
initialize_tenants
management command - Update local development instructions
- Enable code formatting with
black
- Start testing using upstream Postgres container
- Execute CodeQL on pull request and branches
- Adjust tests for Django 5.0
- Remove use of
non-existing.png
file in tenant name area to avoid 404 responses which trigger rate limiting
- Update django-tenants from 3.5.0 to 3.6.1
- Update pylint-django from 2.5.3 to 2.5.5
- Start building and testing with Python 3.11
- Start testing with psycopg3
- Add
trackers_integration
intotenant_groups.models.Group.relevant_apps
to allow per-tenant assignment for permissions around personal API tokens, see kiwitcms/trackers-integration#44
- Update to django-tenants==3.5.0
- Replace
form_errors_to_list()
which was removed in Kiwi TCMS v12.2
- Update to django-tenants==3.4.8
- Bug fix on Create Tenant page for Kiwi TCMS v11.7 or later
- Allow customization of tenant logo in navigation (Ivajlo Karabojkov)
- Add CodeQL workflow for GitHub code scanning
- Fix make messages command
- Update django-tenants from 3.4.5 to 3.4.7
- Don't add users to TenantGroup on
empty
tenant - Adjust redirects from Tenant admin page to avoid confusion
- Update docs for initial configuration
- Add more assertions into test
- Don't access
request.tenant
if such attribute does not exist. Fixes KIWI-TCMS-K2
- Don't grant
auth.view_
permissions even on publicly readable tenants - Honor
settings.DEFAULT_GROUPS
instead of hard-coding. Invited users and users authorized via the Admin panel will be added to tenant groups which matchsettings.DEFAULT_GROUPS
("Tester" by default) if such tenant groups exist. If the setting is an empty list or there are no tenant groups matching the specific names configured then authorized users will be left without group associations. It will be up to a Kiwi TCMS administrator to manually assign permissions and tenant groups for each user.
- Fix a bug in the
create_oss_tenant()
helper function
- Update django-tenants from 3.4.2 to 3.4.4
- Show tenant information in navigation (Ivajlo Karabojkov)
- Allow editing Tenant.name to make it easier for admins to customize the text shown in navigation!
- Internal updates around testing and CI
- Don't crash if user can't change tenant groups. Fixes KIWI-TCMS-J8
- Add
refresh_tenant_permissions
command which will be executed automatically byrefresh_permissions
- Fix URL is help message
- Define per-tenant
Group
model and add an authentication backend which will consume permissions from tenant-groups. Closes #104 Issue #104 - Add pre-commit CI config & apply automatic fixes
- Add System check for
KIWI_TENANTS_DOMAIN
environment variable. Closes Issue #140
- Update django-tenants from 3.4.1 to 3.4.2, will help with migration to Django 4
- Update django-tenants from 3.3.4 to 3.4.1
- Update expected error message for tests
- Fix code coverage uploads
- Update django-tenants from 3.3.2 to 3.3.4. Fixes a bug for cloning tenants when DB username contains a dash
- Use f-strings b/c pylint really loves them
- Faster tenant creation with
clone_tenant
. Fixes Issue #127 Requires a schema with nameempty
to be present! - Fix pylint warnings
- Migrate from Travis CI to GitHub Actions
- Update django-tenants from 3.3.1 to 3.3.2
- More robust tenant domain detection to avoid bugs in the case where public tenant's domain doesn't use a prefix (e.g. matches KIWI_TENANT_DOMAIN)
- Database: Rename
Tenant.on_trial
->Tenant.publicly_readable
- Allow unauthorized users to access publicly readable tenants
- Update django-tenants from 3.3.0 to 3.3.1
- Update translation strings
- Tested with Kiwi TCMS v10.1
- Convert
NewTenantForm
to inherit fromModelForm
- Update django-tenants from 3.2.1 to 3.3.0
- Tested with Kiwi TCMS v10.0
- Tested with Python 3.8
- Add missing csrf_token in NewTenantForm
- Fix a bug with how we override captcha field in user registration form
- Fix invitation email subject
- Tested with Kiwi TCMS v8.9
- Add warning for
owner_id
in README - Replace ModelChoiceField with UserField. Fixes Issue #114
- Support user invitions for tenant. Fixes Issue #116
- Replace deprecated import to silence warnings with Django 3.1
- Tested with Kiwi TCMS v8.6
- Update django-tenants from 3.1.0 to 3.2.1
- Don't pin dependencies in devel.txt
- Filter out AuthorizedUsersChangeForm even on errors
- Tested with Kiwi TCMS v8.5
- Update django-tenants from 3.0.3 to 3.1.0
- Improvements in tests and minor updates to make linters happy
- Tested with Kiwi TCMS v8.4
- Do not ship
TENANT_APPS
b/c it is distributed with Kiwi TCMS v8.3
- Bring back an improved HTML placeholder for schema_name
- Properly validate input values for schema/domain names
- Always lower case schema_name to make sure it can actually be used as a valid hostname
- Update django-tenants from 3.0.1 to 3.0.3
- Show valid schema_name pattern as help text in UI
- Remove schema_name placeholder text because it was misleading
- Slightly adjust default values for settings
TENANT_APPS
andMULTITENANT_RELATIVE_MEDIA_ROOT
to match Kiwi TCMS and installations prior to turning this package into a plugin. This will avoid dusrupting existing deployments!
- Turn into proper Kiwi TCMS plugin and install settings overrides under
tcms_settings_dir/
(compatible with Kiwi TCMS v8.2 or later)- does not need
MENU_ITEMS
andROOT_URLCONF
override anymore - does not need to load
tcms_tenants
inINSTALLED_APPS
manually - only need to specify
KIWI_TENANTS_DOMAIN
env variable!
- does not need
- Require
tcms_tenants.add_tenant
permission forNewTenantView
- Reimplement
NewTenantView
asFormView
- Refactor
redirect_to()
to class based view - Add tests for admin.py. Closes #5 Issue #5
- Replace
datetime.now
withtimezone.now
for better support of installations with enabled timezone config - Enable pylint. Closes Issue #17
- Enable flake8
- Update django-tenants from 3.0.0 to 3.0.1. Fixes Issue #60
- Bump django-tenants from 2.2.3 to 3.0.0
- Tested successfully against Kiwi TCMS v7.3 with Django 3.0
- Set
tcms_tenants.tests.LoggedInTestCase.tenant.owner.password
to "password" so it can be reused by downstream tests
- New translations for Slovenian
- Replace ugettext_lazy with gettext_lazy for Django 3.0
- Start shipping
tcms_tenants.tests
to be used by other multi-tenant add-on packages - Confirmed working against Kiwi TCMS v7.2
- Document how to configure multi-tenancy
- Document ST to MT migration
- Add helper method
create_oss_tenant()
- Internal updates to
TENANT_APPS
while testing
- New translations for Russian
- Add
Tenant.organization
field - When creating tenant set site.name to tenant.domain.domain
- Allow overriding create tenant form URL via additional
context variable named
form_action_url
- Send email when a new tenant is created
- Add middleware which can be used to block unpaid tenants
- Rewrite middleware without deprecated
MiddlewareMixin
, Refers to Issue #17 - Add more tests
- Remove
django.contrib.contenttypes
fromTENANT_APPS
- Make it easier to override
NewTenantView
- Use
DateTimeField
instead ofDateField
- Show first primary domain in Admin
- Massive speed up tests
- Pylint fixes
- Bring back
tenant_url
template tag with optionalschema_name
parameter
- Fix failing tests
- Fix packaging for missing migrations directory
- Add view which facilitates GitHub login & redirects.
Callers are supposed to perform OAuth login via public tenant and then
redirect to this view which will send the browser to the actual tenant!
This will resolve problems with
redirect_uri
mismatch that we're seeing from GitHub b/c you can only specify one redirect uri - pylint fixes
- Remove unused
templatetags/
directory
- Tenant object now has an owner
- Update django-tenants to 2.2.3
- New translations for Slovenian
- Don't ship
test_project/
files in wheel package
- Update to django-tenants 2.2.0 for Django 2.2 support
- Rename setting
TCMS_TENANTS_DOMAIN
toKIWI_TENANTS_DOMAIN
- Support creating of tenants via web interface
- Support for deleting tenants only by super-user
- Support for authorizing other users to access the current tenant
- Middleware which returns 403 Forbidden when non-authorized user tries to access a tenant
- Support for overriding the
tcms_tenants/new.html
template to provide SLA, terms and conditions, etc.