From 13919461e220ce4ab7b3935185d121c37c864d5e Mon Sep 17 00:00:00 2001 From: Serghei MIHAI Date: Tue, 9 Dec 2014 15:11:49 +0100 Subject: [PATCH] Multitenant package --- debian/authentic2-multitenant-ctl | 14 +++ debian/authentic2-multitenant.dirs | 5 + debian/authentic2-multitenant.docs | 3 + debian/authentic2-multitenant.init | 184 +++++++++++++++++++++++++++++++++ debian/authentic2-multitenant.install | 4 + debian/authentic2-multitenant.postinst | 46 +++++++++ debian/conf/nginx-example.conf | 4 +- debian/config.py | 41 ++++++++ debian/control | 18 ++++ debian/multitenant.py | 52 ++++++++++ debian/rules | 1 - 11 files changed, 369 insertions(+), 3 deletions(-) create mode 100644 debian/authentic2-multitenant-ctl create mode 100644 debian/authentic2-multitenant.dirs create mode 100644 debian/authentic2-multitenant.docs create mode 100644 debian/authentic2-multitenant.init create mode 100644 debian/authentic2-multitenant.install create mode 100644 debian/authentic2-multitenant.postinst create mode 100644 debian/config.py create mode 100644 debian/multitenant.py diff --git a/debian/authentic2-multitenant-ctl b/debian/authentic2-multitenant-ctl new file mode 100644 index 0000000..2434a47 --- /dev/null +++ b/debian/authentic2-multitenant-ctl @@ -0,0 +1,14 @@ +#!/bin/sh + +if [ "$(whoami)" != "authentic-multitenant" ]; then + if which sudo; then + if sudo -v -u authentic-multitenant; then + sudo -u authentic-multitenant authentic2-multitenant-ctl --config /usr/lib/authentic2-multitenant/multitenant.py "$@" + exit $? + fi + echo "You must run this script with authentic-multitenant user" + exit 1 + fi +fi + +/usr/lib/authentic2/manage.py "$@" diff --git a/debian/authentic2-multitenant.dirs b/debian/authentic2-multitenant.dirs new file mode 100644 index 0000000..bf059c0 --- /dev/null +++ b/debian/authentic2-multitenant.dirs @@ -0,0 +1,5 @@ +etc/authentic2-multitenant +usr/lib/authentic2-multitenant +var/lib/authentic2-multitenant/tenants +var/run/authentic2-multitenant +var/log/authentic2-multitenant diff --git a/debian/authentic2-multitenant.docs b/debian/authentic2-multitenant.docs new file mode 100644 index 0000000..232aa86 --- /dev/null +++ b/debian/authentic2-multitenant.docs @@ -0,0 +1,3 @@ +AUTHORS.txt +COPYING +README.rst diff --git a/debian/authentic2-multitenant.init b/debian/authentic2-multitenant.init new file mode 100644 index 0000000..6877e7c --- /dev/null +++ b/debian/authentic2-multitenant.init @@ -0,0 +1,184 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: authentic2-multitenant +# Required-Start: $network $local_fs +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Authentic2 is a versatile identity provider +# Description: Authentic2 is a versatile identity provider +### END INIT INFO + +# Author: Serghei MIHAI + +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC=authentic2 +NAME=authentic2-multitenant +DAEMON=/usr/bin/gunicorn +PID_DIR=/var/run/$NAME +CACHE_DIR=/var/cache/$NAME +LOG_DIR=/var/log/$NAME +PIDFILE=$PID_DIR/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME +BIND=unix:$RUN_DIR/$NAME.sock + +DJANGO_CONFIG_FILE='/usr/lib/${NAME}/multitenant.py' + +USER=authentic-multitenant +GROUP=authentic-multitenant + +# Exit if the package is not installed +[ -x $DAEMON ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +DAEMON_ARGS="--pid $PIDFILE \ +--user $USER --group $GROUP \ +--daemon \ +--access-logfile $LOG_DIR/gunicorn-access.log \ +--log-file $LOG_DIR/gunicorn-error.log \ +--bind=$BIND \ +--workers=10 \ +--worker-class=sync \ +--timeout=60 \ +authentic2.wsgi:application" + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# Create pid directory +if [ ! -d $PID_DIR ]; then + install -d -m 755 -o $USER -g $GROUP $PID_DIR +fi + +# Create cache directory +if [ ! -d $CACHE_DIR ]; then + install -d -m 755 -o $USER -g $GROUP $CACHE_DIR +fi + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --exec $DAEMON -- \ + $DAEMON_ARGS \ + || return 2 +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +do_migrate() { + log_action_msg "Applying new migrations .." + su $USER -p -c "/usr/bin/authentic2-multitenant-ctl sync_schemas --noinput" + su $USER -p -c "/usr/bin/authentic2-multitenant-ctl migrate_schemas --noinput" + log_action_msg ".. done" +} + +case "$1" in + start) + do_migrate + log_daemon_msg "Starting $DESC " "$NAME" + do_start + case "$?" in + 0|1) log_end_msg 0 ;; + 2) log_end_msg 1 ;; + esac + ;; + stop) + log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) log_end_msg 0 ;; + 2) log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + #reload|force-reload) + # + # If do_reload() is not implemented then leave this commented out + # and leave 'force-reload' as an alias for 'restart'. + # + #log_daemon_msg "Reloading $DESC" "$NAME" + #do_reload + #log_end_msg $? + #;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + do_migrate + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + diff --git a/debian/authentic2-multitenant.install b/debian/authentic2-multitenant.install new file mode 100644 index 0000000..5462ee3 --- /dev/null +++ b/debian/authentic2-multitenant.install @@ -0,0 +1,4 @@ +debian/conf/nginx-example.conf /etc/authentic2-multitenant +debian/authentic2-multitenant-ctl /usr/bin +debian/config.py /etc/authentic2-multitenant +debian/multitenant.py /usr/lib/authentic2-multitenant diff --git a/debian/authentic2-multitenant.postinst b/debian/authentic2-multitenant.postinst new file mode 100644 index 0000000..bf53e1e --- /dev/null +++ b/debian/authentic2-multitenant.postinst @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Postinst script for authentic2 +# + +set -e + +NAME=authentic2-multitenant +AUTHENTIC_USER=authentic-multitenant +AUTHENTIC_GROUP=authentic-multitenant +AUTHENTIC_HOME=/var/lib/$NAME + +# source debconf stuff +. /usr/share/debconf/confmodule + +case "$1" in + configure) + if ! getent group $AUTHENTIC_GROUP > /dev/null 2>&1; then + echo -n "Adding group $AUTHENTIC_GROUP.." >&2 + addgroup --quiet --system $AUTHENTIC_GROUP + echo "..done" >&2 + fi + if ! getent passwd $AUTHENTIC_USER > /dev/null 2>&1; then + echo -n "Adding user $AUTHENTIC_USER.." >&2 + adduser --quiet --system --gecos "Pootle daemon" \ + --ingroup $AUTHENTIC_GROUP \ + --no-create-home --home $AUTHENTIC_HOME \ + $AUTHENTIC_USER + echo "..done" >&2 + fi + + chown $AUTHENTIC_USER:$AUTHENTIC_GROUP $AUTHENTIC_HOME \ + $AUTHENTIC_HOME/tenants \ + /var/run/$NAME \ + /var/log/$NAME + + reconfigure|abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/debian/conf/nginx-example.conf b/debian/conf/nginx-example.conf index 606b616..0d9d3fc 100644 --- a/debian/conf/nginx-example.conf +++ b/debian/conf/nginx-example.conf @@ -14,7 +14,7 @@ server { } location / { - proxy_pass http://unix:/var/run/authentic2/authentic2.sock; + proxy_pass http://unix:/var/run/authentic2-multitenant/authentic2-multitenant.sock; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-SSL on; proxy_set_header X-Forwarded-Protocol ssl; @@ -34,7 +34,7 @@ server { } location / { - proxy_pass http://unix:/var/run/authentic2/authentic2.sock; + proxy_pass http://unix:/var/run/authentic2-multitenant/authentic2-multitenant.sock; proxy_set_header Host $http_host; } } diff --git a/debian/config.py b/debian/config.py new file mode 100644 index 0000000..5f1dab0 --- /dev/null +++ b/debian/config.py @@ -0,0 +1,41 @@ +# Here your custom configuration. +# Use it to declare new settings or overload existing ones + +# STATIC_ROOT='/var/lib/authentic2/static' + +# ALLOWED_HOSTS='*' + +# SAML_SIGNATURE_PUBLIC_KEY="" +# SAML_SIGNATURE_PRIVATE_KEY="" + +# USE_MEMCACHED=yes # required python-memcache memcached + +# IDP_SAML2='yes' +# IDP_OPENID='yes' # require package python-openid +# IDP_CAS='yes' +# AUTH_SAML2='yes' +# AUTH_OPENID='yes' # require package python-openid +# AUTH_SSL='yes' + +# Sentry / Raven configuration +# RAVEN_CONFIG_DSN='' # require package python-raven + +# Email configuration +# EMAIL_HOST = 'localhost' +# EMAIL_PORT = 25 +# EMAIL_SUBJECT_PREFIX='[Authentic2]' +# SERVER_EMAIL='admin+authentic2@entrouvert.com' + +# complete database config +# DATABASES = { +# 'default': { +# 'ENGINE': 'tenant_schemas.postgresql_backend', +# 'HOST': 'localhost', +# 'NAME': 'authentic', +# 'PASSWORD': 'secret', +# 'PORT': 5432 +# } +# } +# or each param separately +# DATABASES['default']['HOST'] = 'another host' +# DATABASES['default']['PASSWORD'] = 'another secret' diff --git a/debian/control b/debian/control index bc010bb..16e2861 100644 --- a/debian/control +++ b/debian/control @@ -43,3 +43,21 @@ Description: Versatile identity server Python module It has support for ID-FF and SAMLv2 thanks to Lasso, a free (GNU GPL) implementation of the Liberty Alliance specifications. +Package: authentic2-multitenant +Architecture: all +Pre-Depends: python-django (>= 1.5) +Depends: ${misc:Depends}, adduser, + python-authentic2 (= ${binary:Version}), python-psycopg2, + python-django-tenant-schemas, + python-entrouvert, + gunicorn, dbconfig-common, + debconf | debconf-2.0, ucf +Recommends: postgresql-client +Suggests: nginx +Description: Multitenant versatile identity server Python module + Authentic is a versatile identity provider aiming to address a broad + range of needs, from simple to complex setups; it has support for many + protocols and can bridge between them. + . + It has support for ID-FF and SAMLv2 thanks to Lasso, a free (GNU GPL) + implementation of the Liberty Alliance specifications. diff --git a/debian/multitenant.py b/debian/multitenant.py new file mode 100644 index 0000000..cdf8ff1 --- /dev/null +++ b/debian/multitenant.py @@ -0,0 +1,52 @@ +import os + +PROJECT_NAME = 'authentic2-multitenant' + +try: + import entrouvert +except ImportError: + raise ImproperlyConfigured('python-entrouvert MUST be installed for the multitenant mode to work') + +VAR_DIR = os.path.join('/var/lib/', PROJECT_NAME) +ETC_DIR = os.path.join('/etc', PROJECT_NAME) + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = False +TEMPLATE_DEBUG = False + +INSTALLED_APPS += ('entrouvert.djommon.multitenant', ) + +TENANT_MODEL = 'multitenant.Tenant' +TENANT_BASE = os.path.join(VAR_DIR, 'tenants') +TENANT_TEMPLATE_DIRS = (TENANT_BASE,) +TENANT_APPS = INSTALLED_APPS + +SHARED_APPS = ( + 'django.contrib.staticfiles', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', +) + +TEMPLATE_LOADERS = ('entrouvert.djommon.multitenant.template_loader.FilesystemLoader',) + TEMPLATE_LOADERS + +TEMPLATE_CONTEXT_PROCESSORS = ('django.core.context_processors.request',) + TEMPLATE_CONTEXT_PROCESSORS + +MIDDLEWARE_CLASSES = ( + 'entrouvert.djommon.multitenant.middleware.TenantMiddleware', + 'entrouvert.djommon.multitenant.middleware.JSONSettingsMiddleware', + 'entrouvert.djommon.multitenant.middleware.PythonSettingsMiddleware', +) + MIDDLEWARE_CLASSES + +DEFAULT_FILE_STORAGE = 'entrouvert.djommon.multitenant.storage.TenantFileSystemStorage' + +DATABASES = { + 'default': { + 'ENGINE': 'tenant_schemas.postgresql_backend', + 'NAME': PROJECT_NAME + } +} + +if os.path.exists(os.path.join(ETC_DIR, 'config.py')): + execfile(os.path.join(ETC_DIR, 'config.py')) diff --git a/debian/rules b/debian/rules index 0acf6e5..82d0577 100755 --- a/debian/rules +++ b/debian/rules @@ -10,4 +10,3 @@ override_dh_install: dh_install mv $(CURDIR)/debian/tmp/usr/bin/authentic2-ctl $(pythonauthentic2)/usr/lib/authentic2/manage.py install -m 755 -o root -g root debian/sql/syncdb.sh $(authentic2)/usr/share/dbconfig-common/scripts/authentic2/install/pgsql - -- 2.1.4