django-ikari is an application for anchoring configurable urlconfs to user configurable subdomains or domains to use in software-as-a-service projects.
- Roadmap
- Installation
- Settings
- Models
- Permissions
- Middleware
- Views
- Caching
- Signals
- URLs
- Templates
- License
As of 0.0.7 django-ikari is able to drop in and serve homepages for your user assigned domains/subdomains.
However, there are some critical aspects missing:
- authenticate domain ownership, without which could lead to a denial of service by your other sass users. Ideally this would be either of: a. email verification sent to an address discovered via whois, or b. by prompting the user to modify/create a unique-hard-to-guess txt record on their dns server for the domain.
- claim form and view, presented on the DoesNotExist error template when a user is logged in, triggering the behaviour in #1 above.
Non critical, but perhaps nice to have would be :
- object level permissions: ensuring there is some consideration given towards django-guardian integration.
Finally some out of scope features that probably should be integrated at your projects level instead of here in the application:
- themes and assets per site, subclassing the
ikari.models.bases.BaseSite
and associating any functionality/relationship to assets should occur there. - metrics and dashboard display, you can collect metrics via the
ikari.signals.site_request
then display them on a user dashboard that you more than likely already have. - organisation and site membership: django-organisations is great for this.
pip install django-ikari
In order to use application, add ikari' to
INSTALLED_APPSin Django project
settings.py' file,
ikari.middleware.DomainsMiddleware' to
MIDDLEWARE_CLASSESafter
AuthenticationMiddleware', and configure application settings
described in the next section.
This needs to point at the domain of your main project, typically the place where you'd have forms that process payments, login users, process beta invites etc.
routes which define paths to views to allow users to manage their site(s)
routes that are anchored to the root of users sites. this urlconf will replace your ROOT_URLCONF setting when a requested hostname matches an active ( and published if the user is a site member) site.
- IKARI_URL_ERROR_DOESNTEXIST
- IKARI_URL_ERROR_PRIVATE
- IKARI_URL_ERROR_INACTIVE
- IKARI_URL_ERROR_UNKNOWN
Url to redirect visitors to when they land on a subdomain that isn't linked to a ikari site.
if user defines a valid whole word then it is joined to
this. Defaults to something like "."+IKARI_MASTER_DOMAIN
a python import path to your customised IkariSite model.
you can subclass the abstract ikari.models.bases.SiteBase
model as a good start.
a python import path to a verification backend that can be used to ensure the domain provided by the user satisfies your business logic.
Probably only relevant if you use the default provided ikari.models.default.Site
class.
Simply provides some role based permissions, although it is recommended that you
use django-guardian and implement some action based permissions.
Ikari ships with two default models, only one of which is required as defined
above in your settings as IKARI_SITE_MODEL
.
For the purpose of this section, "site urls" refers to the setting
attribute IKARI_SITE_URLCONF
.
You site model should at least have the following fields and methods:
-
is_public
, boolean. If True, then Anonymous users will be allowed to view the url routes in the "site urls". If False (default), DomainMiddleware will only allow the following instance of `auth.User':is_staff=True
or,is_superuser=True
, oruser in site.get_members()
-
is_active
, boolean. If False (default), DomainMiddleware will only allow anyauth.User.is_staff or auth.User.is_superuser
to access the "site urls"; if True, then site owners and other related users can also view the "site urls".
can_set_custom_domain' enables setting a domain which is not suffixed with the
IKARI_SUBDOMAIN_ROOT` value.can_set_public_status' does the same for
is_public' field.can_set_active_status' does the same for
is_active' field.
ikari.middleware.DomainsMiddleware' looks at
request.get_host()and, if it matches any
ikari.Site` model
instance:
- sets
request.ikari_site' to that instance (it can be later used by views and, with
request` context processor, in templates); - unless
request.ikari_site.is_public' is true, it immediately logs out (and redirects to reverse URL lookup of
settings.IKARI_URL_ERROR_PRIVATE) any
auth.User` that does not satisfy this sites get_moderators() method;
- if
IKARI_SITE_URLCONF' setting is set, sets
request.urlconf' to its value, allowing single project to display different URL hierarchies for main site and account sites; WARNING: setting `request.urlconf' doesn't fit well with reverse URL lookups (those will still be made against root urlconf), django-debug-toolbar, and probably other things as well. For maximum reliability, consider running two separate projects on single database: one for "main" site, other for account domains, or use single urlconf for both; - send signal
ikari.signals.site_request' and if any receiver returns an instance of
HttpResponse`, returns this response instead of actual page. This can be used for e.g. displaying error message and not allowing to log into expired accounts.
If current domain doesn't match any of existing ikari.Site
instances
and is not IKARI_MASTER_DOMAIN', middleware redirects user to
IKARI_MASTER_DOMAIN'.
ikari.views.DomainErrorView
: View used to render the templates for each of- IKARI_URL_ERROR_DOESNTEXIST
- IKARI_URL_ERROR_PRIVATE
- IKARI_URL_ERROR_INACTIVE
- IKARI_URL_ERROR_UNKNOWN
ikari.views.SiteHomeView
: Main view to render anikari.Site
ikari.views.SiteUpdateView
: Allows authorised users to update their site details.ikari.views.SiteCreateView
: Allows authorised users to create their site.
I susgest you install and use django-johnny-cache
with django-redis-cache
ikari.signals.site_request
: fired after default access rules satisfied but before delivery of site homepageikari.signals.site_created
: fired after a newikari.Site
is created.ikari.signals.site_updated
: fired after anikari.Site
is updated.ikari.signals.site_deleted
: fired after anikari.Site
is deleted.
Include this somewhere in your main site urlconf. example:
...
url(r'^sites/error/', include('ikari.urls.errors')),
...
Include this somewhere in your main site urlconf. example:
...
url(r'^users/sites/', include('ikari.urls.private')),
...
The default urlconf which provides the ikari.views.SiteHomeView
.
Ikari:
ikari/site-update.html
called byikari.views.SiteUpdateView
view. Receives two arguments:Site
-ikari.Site
instance, andform
-forms.IkariSiteForm
instance to display.
ikari/site-create.html
called byikari.views.SiteCreateView
view. Receives one argument,form
, holding an instance ofikari.forms.IkariSiteForm
.
This project is licensed on terms of GPL (GPL-LICENSE.txt) licenses.