diff --git a/larpe/branches/idwsf/AUTHORS b/AUTHORS similarity index 100% rename from larpe/branches/idwsf/AUTHORS rename to AUTHORS diff --git a/larpe/branches/idwsf/COPYING b/COPYING similarity index 100% rename from larpe/branches/idwsf/COPYING rename to COPYING diff --git a/larpe/branches/idwsf/MANIFEST.in b/MANIFEST.in similarity index 100% rename from larpe/branches/idwsf/MANIFEST.in rename to MANIFEST.in diff --git a/larpe/tags/release-1.0/Makefile b/Makefile similarity index 100% rename from larpe/tags/release-1.0/Makefile rename to Makefile diff --git a/larpe/tags/release-1.0/NEWS b/NEWS similarity index 100% rename from larpe/tags/release-1.0/NEWS rename to NEWS diff --git a/larpe/tags/release-1.0/README b/README similarity index 100% rename from larpe/tags/release-1.0/README rename to README diff --git a/larpe/tags/release-1.0/TODO b/TODO similarity index 100% rename from larpe/tags/release-1.0/TODO rename to TODO diff --git a/larpe/tags/release-1.0/conf/apache2-vhost-larpe b/conf/apache2-vhost-larpe similarity index 100% rename from larpe/tags/release-1.0/conf/apache2-vhost-larpe rename to conf/apache2-vhost-larpe diff --git a/larpe/tags/release-1.0/conf/apache2-vhost-larpe-common b/conf/apache2-vhost-larpe-common similarity index 100% rename from larpe/tags/release-1.0/conf/apache2-vhost-larpe-common rename to conf/apache2-vhost-larpe-common diff --git a/larpe/tags/release-1.1.1/conf/filters/output_ciril_net_rh.py b/conf/filters/output_ciril_net_rh.py similarity index 100% rename from larpe/tags/release-1.1.1/conf/filters/output_ciril_net_rh.py rename to conf/filters/output_ciril_net_rh.py diff --git a/larpe/tags/release-1.1.1/conf/filters/output_replace_form.py b/conf/filters/output_replace_form.py similarity index 100% rename from larpe/tags/release-1.1.1/conf/filters/output_replace_form.py rename to conf/filters/output_replace_form.py diff --git a/larpe/tags/release-1.1.1/debian/changelog b/debian/changelog similarity index 100% rename from larpe/tags/release-1.1.1/debian/changelog rename to debian/changelog diff --git a/larpe/branches/idwsf/debian/compat b/debian/compat similarity index 100% rename from larpe/branches/idwsf/debian/compat rename to debian/compat diff --git a/larpe/branches/idwsf/debian/config b/debian/config similarity index 100% rename from larpe/branches/idwsf/debian/config rename to debian/config diff --git a/larpe/tags/release-1.1.1/debian/control b/debian/control similarity index 100% rename from larpe/tags/release-1.1.1/debian/control rename to debian/control diff --git a/larpe/branches/idwsf/debian/copyright b/debian/copyright similarity index 100% rename from larpe/branches/idwsf/debian/copyright rename to debian/copyright diff --git a/larpe/tags/release-1.0/debian/dirs b/debian/dirs similarity index 100% rename from larpe/tags/release-1.0/debian/dirs rename to debian/dirs diff --git a/larpe/tags/release-1.0/debian/docs b/debian/docs similarity index 100% rename from larpe/tags/release-1.0/debian/docs rename to debian/docs diff --git a/larpe/tags/release-1.0/debian/init b/debian/init similarity index 100% rename from larpe/tags/release-1.0/debian/init rename to debian/init diff --git a/larpe/branches/idwsf/larpe-reload-apache2-script b/debian/larpe-reload-apache2-script similarity index 100% rename from larpe/branches/idwsf/larpe-reload-apache2-script rename to debian/larpe-reload-apache2-script diff --git a/larpe/branches/idwsf/debian/postinst b/debian/postinst similarity index 100% rename from larpe/branches/idwsf/debian/postinst rename to debian/postinst diff --git a/larpe/branches/idwsf/debian/prerm b/debian/prerm similarity index 100% rename from larpe/branches/idwsf/debian/prerm rename to debian/prerm diff --git a/larpe/branches/idwsf/debian/pycompat b/debian/pycompat similarity index 100% rename from larpe/branches/idwsf/debian/pycompat rename to debian/pycompat diff --git a/larpe/tags/release-1.1.1/debian/rules b/debian/rules similarity index 100% rename from larpe/tags/release-1.1.1/debian/rules rename to debian/rules diff --git a/larpe/tags/release-1.0/doc/Makefile b/doc/Makefile similarity index 100% rename from larpe/tags/release-1.0/doc/Makefile rename to doc/Makefile diff --git a/larpe/branches/idwsf/doc/en/Makefile b/doc/en/Makefile similarity index 100% rename from larpe/branches/idwsf/doc/en/Makefile rename to doc/en/Makefile diff --git a/larpe/branches/idwsf/doc/en/custom.tex b/doc/en/custom.tex similarity index 100% rename from larpe/branches/idwsf/doc/en/custom.tex rename to doc/en/custom.tex diff --git a/larpe/branches/idwsf/doc/en/default.css b/doc/en/default.css similarity index 100% rename from larpe/branches/idwsf/doc/en/default.css rename to doc/en/default.css diff --git a/larpe/branches/idwsf/doc/en/fncychap.sty b/doc/en/fncychap.sty similarity index 100% rename from larpe/branches/idwsf/doc/en/fncychap.sty rename to doc/en/fncychap.sty diff --git a/larpe/branches/idwsf/doc/en/larpe-admin.rst b/doc/en/larpe-admin.rst similarity index 100% rename from larpe/branches/idwsf/doc/en/larpe-admin.rst rename to doc/en/larpe-admin.rst diff --git a/larpe/branches/idwsf/doc/scripts/removealpha.sh b/doc/scripts/removealpha.sh similarity index 100% rename from larpe/branches/idwsf/doc/scripts/removealpha.sh rename to doc/scripts/removealpha.sh diff --git a/larpe/branches/idwsf/doc/scripts/rst2latex.py b/doc/scripts/rst2latex.py similarity index 100% rename from larpe/branches/idwsf/doc/scripts/rst2latex.py rename to doc/scripts/rst2latex.py diff --git a/larpe/tags/release-1.0/exclude_from_dist b/exclude_from_dist similarity index 100% rename from larpe/tags/release-1.0/exclude_from_dist rename to exclude_from_dist diff --git a/larpe/tags/release-1.0/fedora/larpe-reload-apache2-script b/fedora/larpe-reload-apache2-script similarity index 100% rename from larpe/tags/release-1.0/fedora/larpe-reload-apache2-script rename to fedora/larpe-reload-apache2-script diff --git a/larpe/tags/release-1.0/fedora/larpe.init b/fedora/larpe.init similarity index 100% rename from larpe/tags/release-1.0/fedora/larpe.init rename to fedora/larpe.init diff --git a/larpe/tags/release-1.0/fedora/larpe.spec b/fedora/larpe.spec similarity index 100% rename from larpe/tags/release-1.0/fedora/larpe.spec rename to fedora/larpe.spec diff --git a/larpe/branches/idwsf/larpe-reload-apache2.c b/larpe-reload-apache2.c similarity index 100% rename from larpe/branches/idwsf/larpe-reload-apache2.c rename to larpe-reload-apache2.c diff --git a/larpe/tags/release-1.1.1/larpe/Defaults.py b/larpe/Defaults.py similarity index 100% rename from larpe/tags/release-1.1.1/larpe/Defaults.py rename to larpe/Defaults.py diff --git a/larpe/tags/release-1.1.1/larpe/__init__.py b/larpe/__init__.py similarity index 100% rename from larpe/tags/release-1.1.1/larpe/__init__.py rename to larpe/__init__.py diff --git a/larpe/tags/release-1.1.1/larpe/admin/__init__.py b/larpe/admin/__init__.py similarity index 100% rename from larpe/tags/release-1.1.1/larpe/admin/__init__.py rename to larpe/admin/__init__.py diff --git a/larpe/tags/release-1.1.1/larpe/admin/apache.py b/larpe/admin/apache.py similarity index 100% rename from larpe/tags/release-1.1.1/larpe/admin/apache.py rename to larpe/admin/apache.py diff --git a/larpe/tags/release-1.0/larpe/admin/fields_prefill.ptl b/larpe/admin/fields_prefill.ptl similarity index 100% rename from larpe/tags/release-1.0/larpe/admin/fields_prefill.ptl rename to larpe/admin/fields_prefill.ptl diff --git a/larpe/tags/release-1.0/larpe/admin/forms_prefill.ptl b/larpe/admin/forms_prefill.ptl similarity index 100% rename from larpe/tags/release-1.0/larpe/admin/forms_prefill.ptl rename to larpe/admin/forms_prefill.ptl diff --git a/larpe/tags/release-1.1.1/larpe/admin/hosts.ptl b/larpe/admin/hosts.ptl similarity index 100% rename from larpe/tags/release-1.1.1/larpe/admin/hosts.ptl rename to larpe/admin/hosts.ptl diff --git a/larpe/tags/release-1.0/larpe/admin/liberty_utils.py b/larpe/admin/liberty_utils.py similarity index 100% rename from larpe/tags/release-1.0/larpe/admin/liberty_utils.py rename to larpe/admin/liberty_utils.py diff --git a/larpe/tags/release-1.0/larpe/admin/root.ptl b/larpe/admin/root.ptl similarity index 100% rename from larpe/tags/release-1.0/larpe/admin/root.ptl rename to larpe/admin/root.ptl diff --git a/larpe/tags/release-1.0/larpe/admin/settings.ptl b/larpe/admin/settings.ptl similarity index 100% rename from larpe/tags/release-1.0/larpe/admin/settings.ptl rename to larpe/admin/settings.ptl diff --git a/larpe/tags/release-1.1.1/larpe/admin/users.ptl b/larpe/admin/users.ptl similarity index 100% rename from larpe/tags/release-1.1.1/larpe/admin/users.ptl rename to larpe/admin/users.ptl diff --git a/larpe/branches/idwsf/Makefile b/larpe/branches/idwsf/Makefile deleted file mode 100644 index 09bd32c..0000000 --- a/larpe/branches/idwsf/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -prefix = /usr -config_prefix = /var -config_dir = $(config_prefix)/lib/larpe - -INSTALL = /usr/bin/install -c -PYTHON = /usr/bin/python - -LARPE_USER = www-data -LARPE_GROUP = www-data -APACHE_INIT_SCRIPT = /etc/init.d/apache2 - -larpe-reload-apache2: larpe-reload-apache2.c - -install: larpe-reload-apache2 - rm -rf build - $(MAKE) -C po install - $(PYTHON) setup.py install --root "$(DESTDIR)/" --prefix "$(prefix)" - $(INSTALL) -d $(DESTDIR)$(prefix)/sbin/ - $(INSTALL) larpectl $(DESTDIR)$(prefix)/sbin/ - $(INSTALL) larpe-reload-apache2-script $(DESTDIR)$(prefix)/sbin/ - $(INSTALL) -m 4550 --group $(LARPE_GROUP) larpe-reload-apache2 $(DESTDIR)$(prefix)/sbin/ - $(INSTALL) -d $(DESTDIR)$(prefix)/share/larpe/ - $(INSTALL) -m 0644 apache2.conf $(DESTDIR)$(prefix)/share/larpe/ - chown -R $(LARPE_USER):$(LARPE_GROUP) /usr/share/larpe/ - - $(INSTALL) --owner=$(LARPE_USER) --group=$(LARPE_GROUP) -d $(DESTDIR)$(config_dir) - $(INSTALL) --owner=$(LARPE_USER) --group=$(LARPE_GROUP) -d $(DESTDIR)$(config_dir)/vhosts.d - $(INSTALL) --owner=$(LARPE_USER) --group=$(LARPE_GROUP) -d $(DESTDIR)$(config_dir)/vhost-locations.d - $(INSTALL) --owner=$(LARPE_USER) --group=$(LARPE_GROUP) -d $(DESTDIR)$(config_dir)/vhosts.d.disabled - $(INSTALL) --owner=$(LARPE_USER) --group=$(LARPE_GROUP) -d $(DESTDIR)$(config_dir)/vhost-locations.d.disabled - -uninstall: - $(MAKE) -C po uninstall - -rm -f $(DESTDIR)$(prefix)/sbin/larpe-reload-apache2 - -rm -f $(DESTDIR)$(prefix)/sbin/larpe-reload-apache2-script - -rm -f $(DESTDIR)$(prefix)/sbin/larpectl - -rm -rf $(DESTDIR)$(prefix)/share/larpe/ - @echo - @echo "Depending on your Python version, you will have to remove manually the files in /usr/lib/python(your_version)/site-packages/larpe/" - -clean: - $(MAKE) -C po clean - $(MAKE) -C doc clean - -$(PYTHON) setup.py clean - -rm larpe-reload-apache2 - diff --git a/larpe/branches/idwsf/NEWS b/larpe/branches/idwsf/NEWS deleted file mode 100644 index 2cd9e67..0000000 --- a/larpe/branches/idwsf/NEWS +++ /dev/null @@ -1,2 +0,0 @@ -NEWS -==== diff --git a/larpe/branches/idwsf/README b/larpe/branches/idwsf/README deleted file mode 100644 index 695f0f7..0000000 --- a/larpe/branches/idwsf/README +++ /dev/null @@ -1,33 +0,0 @@ -Larpe - Liberty Alliance Reverse Proxy -====================================== - -Description ------------ - -Larpe is a Liberty Alliance Reverse Proxy. It allow any service provider (that -is a website) to use Liberty Alliance features (Identity federation, Single -Sign On and Single Sign Logout) without changing the code of the service -provider itself. It uses the Lasso library which is certified by the Liberty -Alliance consortium. - - -Documentation -------------- - -* README, as you are doing; - -* doc/en/ for English documentation, published on the website as - http://larpe.labs.libre-entreprise.org/doc/en/larpe-admin.html - - -Copyright ---------- - -Larpe is copyrighted by Entr'ouvert and is licensed through the GNU General -Public Licence. Artwork and administrative design are from DotClear and -released under the GNU General Public License by Olivier Meunier and others. -Some artwork comes from GTK+ (LGPL). - -Read the COPYING file for the complete license text. Read the AUTHORS file for -additional credits. - diff --git a/larpe/branches/idwsf/TODO b/larpe/branches/idwsf/TODO deleted file mode 100644 index b2bd1ec..0000000 --- a/larpe/branches/idwsf/TODO +++ /dev/null @@ -1,94 +0,0 @@ -- Tests - - egroupware - - http://labs.libre-entreprise.org/ - - logs.entrouvert.org - -====== Roadmap de Larpe ====== - -===== 0.2 ===== - - * Vérifier la compatibilité avec egroupware - * Mettre le vhosts générés dans /var/lib/larpe/vhosts.d et mettre un include /var/lib/larpe/vhosts.d/* dans la conf générale - * Supprimer debconf - * Vérification des formulaires de configuration d'hôtes - * Tests de valeurs erronés diverses - * Erreur si on donne un label qui existe deja - * Ne plus inclure le binaire larpe-reload-apache2 dans les sources - * Corriger les avertissements debian - * Ne pas demander la clé publique de l'idp - * Compléter les traductions - * Ajouter la possibilité de changer la langue dans l'interface d'administration - * Mettre à jour la documentation - * Ajouter un chapitre sur les sites testés et leurs options de configuration particulières - * Traduire la documentation en français - -===== 0.3 ===== - - * Implémenter le SLO en SOAP - * Supprimer un /liberty/ des urls - * Voir comment activer le SSLProxyEngine quand on utilise un sous répertoire - * Faire un site web pour présenter Larpe - * Ajouter la possibilité d'envoyer les exceptions par courriel à l'administrateur - * Améliorer la journalisation des accès et des erreurs - -===== 1.0 ===== - - * Support de SAML 2.0 - * Implémenter l'accès à un site nécessitant une authentification préalable avant tout accès - * Choix de cette fonctionnalité par une option de configuration par site - * Lors de la création d'un site, choix d'un moteur de site connu (mediawiki, squirrelmail, ...) qui pré-remplirait un ensemble d'options nécessaire à ce moteur - * Documentation technique pour les développeurs ? - -===== Non classés ===== - - * Support des sites qui ont une authentification HTTP (à priori, nécessite de charger toute la configuration de larpe dans le filtre python d'apache) - * Création de nouveaux comptes pour les sites, avec des jetons (déjà implémenté en partie ; est-ce utile ?) - -Fait -==== - -- Serveur python principal - - Fonctionnalités liberty - - SSO (depuis le sp et depuis l'idp) - - Fédération - - SLO (depuis le sp et depuis l'idp) - - Défédération (depuis l'idp) en SOAP et redirect - - Support https - - Possibilité d'utiliser toutes les combinaisons de sous domaines et de sous répertoires - - RP par vhost (appli1.example.com, rp de appli1.interne) - - RP par repertoire (www.example.com/appli1, rp de appl1.interne) - - Récupère la configuration de l'IP des vhosts - -- Administration - - Authentification liberty sur l'admin - - Créer de nouveaux sites (+ modifier, supprimer) - - Écrire les vhosts correspondants - - Rechargement de la configuration d'apache - - Script + wrapper en C suid root - - Gestion d'utilisateurs pour administrer le RP (Authentification http) - - Gestion des traductions - -- Filtre Python branché en sortie sur Apache à la suite du filtre de réécriture html (proxy_html) - - Générique - - Personalisable par site pour une meilleure intégration dans les pages - -- Sites testés - - Dotclear - - Linuxfr - - listes.entrouvert.com - - https://listes.libre-entreprise.org/ - - all4dev.libre-entreprise.org - - www.libre-entreprise.org - - http://www.besancon.com/ - - quintine.entrouvert.org/egroupware/ - - squirrelmail - -- Documentation - -- Paquets Debian - - Debconf pour demander le nom de domaine et le courriel de l'admin, ainsi que le compte administrateur - -- Installation sur lupin - -- Batterie de tests de non-regression - diff --git a/larpe/branches/idwsf/apache2-vhost-larpe b/larpe/branches/idwsf/apache2-vhost-larpe deleted file mode 100644 index 869e306..0000000 --- a/larpe/branches/idwsf/apache2-vhost-larpe +++ /dev/null @@ -1,12 +0,0 @@ - - ServerName localhost - ServerAdmin root@localhost - - include /usr/share/larpe/apache2.conf - include /var/lib/larpe/vhost-locations.d - - CustomLog /var/log/apache2/larpe-access.log combined - ErrorLog /var/log/apache2/larpe-error.log - - -include /var/lib/larpe/vhosts.d diff --git a/larpe/branches/idwsf/apache2.conf b/larpe/branches/idwsf/apache2.conf deleted file mode 100644 index 80f01a0..0000000 --- a/larpe/branches/idwsf/apache2.conf +++ /dev/null @@ -1,31 +0,0 @@ -# Static files -DocumentRoot /usr/share/larpe/web/ - -# Python application -SCGIMount / 127.0.0.1:3007 - -# Don't change static files - - SCGIHandler off - - - SCGIHandler off - - - SCGIHandler off - - - - ProxyPass ! - SCGIHandler off - - - - ProxyPass ! - - -# No gzip compression -RequestHeader unset Accept-Encoding - -# HTML url rewriting module and customized Python module -SetOutputFilter OURFILTER diff --git a/larpe/branches/idwsf/debian/changelog b/larpe/branches/idwsf/debian/changelog deleted file mode 100644 index ec6c865..0000000 --- a/larpe/branches/idwsf/debian/changelog +++ /dev/null @@ -1,48 +0,0 @@ -larpe (0.2.1-1) unstable; urgency=low - - * New release - - -- Damien Laniel Wed, 20 Jun 2007 15:43:16 +0200 - -larpe (0.2.0-1) unstable; urgency=low - - * New release - - -- Damien Laniel Tue, 30 Jan 2007 18:07:04 +0100 - -larpe (0.1.1-2) unstable; urgency=low - - * Use python2.4 - - -- Damien Laniel Tue, 19 Dec 2006 17:21:05 +0100 - -larpe (0.1.1-1) unstable; urgency=low - - * New release - - -- Damien Laniel Thu, 5 Oct 2006 11:47:53 +0200 - -larpe (0.1.0-1) unstable; urgency=low - - * New release - - -- Damien Laniel Wed, 4 Oct 2006 10:19:26 +0200 - -larpe (0.0.4-1) unstable; urgency=low - - * New version, many improvements, more compatible sites, some bug fixes - - -- Damien Laniel Tue, 3 Oct 2006 20:44:06 +0200 - -larpe (0.0.3-1) unstable; urgency=low - - * New version, many improvements, more compatible sites, some bug fixes - - -- Damien Laniel Mon, 25 Sep 2006 11:11:36 +0200 - -larpe (0.0.2-1) unstable; urgency=low - - * Initial package. - - -- Damien Laniel Fri, 08 Sep 2006 16:00:00 +0200 - diff --git a/larpe/branches/idwsf/debian/control b/larpe/branches/idwsf/debian/control deleted file mode 100644 index 20f26b5..0000000 --- a/larpe/branches/idwsf/debian/control +++ /dev/null @@ -1,17 +0,0 @@ -Source: larpe -Section: web -Priority: optional -Maintainer: Damien Laniel -Build-Depends: debhelper (>= 5.0.37.2), python, python-central (>= 0.5), gettext -Standards-Version: 3.7.2.0 -XS-Python-Version: current - -Package: larpe -Architecture: any -XB-Python-Version: ${python:Versions} -Depends: ${python:Depends}, python-quixote | quixote (>= 2.0), python-lasso (>= 0.6.5), python-scgi, python-libxml2, apache2, libapache2-mod-scgi, libapache2-mod-python, libapache2-mod-proxy-html -Description: Liberty Alliance Reverse Proxy - Larpe allows any service provider (that is a website) to use Liberty Alliance - identity management and Single Sign On features without changing the code of - the service provider itself. - . diff --git a/larpe/branches/idwsf/debian/dirs b/larpe/branches/idwsf/debian/dirs deleted file mode 100644 index cc0f821..0000000 --- a/larpe/branches/idwsf/debian/dirs +++ /dev/null @@ -1,3 +0,0 @@ -etc/apache2/sites-available -usr/sbin -var/lib/larpe diff --git a/larpe/branches/idwsf/debian/docs b/larpe/branches/idwsf/debian/docs deleted file mode 100644 index e845566..0000000 --- a/larpe/branches/idwsf/debian/docs +++ /dev/null @@ -1 +0,0 @@ -README diff --git a/larpe/branches/idwsf/debian/init b/larpe/branches/idwsf/debian/init deleted file mode 100644 index 5177790..0000000 --- a/larpe/branches/idwsf/debian/init +++ /dev/null @@ -1,103 +0,0 @@ -#! /bin/sh -### BEGIN INIT INFO -# Provides: larpe -# Required-Start: $local_fs $network -# Required-Stop: $local_fs $network -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Start Larpe Liberty Alliance reverse proxy -# Description: Start Larpe Liberty Alliance reverse proxy -### END INIT INFO - -set -e - -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin -DESC="larpe" -NAME=larpe -DAEMON=/usr/sbin/larpectl -PIDFILE=/var/run/$NAME.pid -SCRIPTNAME=/etc/init.d/$NAME - -# Gracefully exit if the package has been removed. -test -x $DAEMON || exit 0 - -. /lib/lsb/init-functions - -# Read config file if it is present. -if [ -r /etc/default/$NAME ] -then - . /etc/default/$NAME -fi - -# -# Function that starts the daemon/service. -# -d_start() { - start-stop-daemon --start --quiet --pidfile $PIDFILE --oknodo \ - --chuid www-data:www-data --make-pidfile --background --exec $DAEMON -- start $OPTIONS -} - -# -# Function that stops the daemon/service. -# -d_stop() { - start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo - rm -f $PIDFILE -} - -# -# Function that sends a SIGHUP to the daemon/service. -# -d_reload() { - start-stop-daemon --stop --quiet --pidfile $PIDFILE \ - --make-pidfile --background --signal 1 -} - -case "$1" in - start) - log_begin_msg "Starting $DESC: $NAME" - d_start - log_end_msg $? - ;; - - stop) - log_begin_msg "Stopping $DESC: $NAME" - d_stop - log_end_msg $? - ;; - - #reload) - # - # If the daemon can reload its configuration without - # restarting (for example, when it is sent a SIGHUP), - # then implement that here. - # - # If the daemon responds to changes in its config file - # directly anyway, make this an "exit 0". - # - # echo -n "Reloading $DESC configuration..." - # d_reload - # echo "done." - #;; - - restart|force-reload) - # - # If the "reload" option is implemented, move the "force-reload" - # option to the "reload" entry above. If not, "force-reload" is - # just the same as "restart". - # - log_begin_msg "Restarting $DESC: $NAME" - d_stop - sleep 1 - d_start - log_end_msg $? - ;; - - *) - # echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 - echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 - exit 1 - ;; -esac - -exit 0 diff --git a/larpe/branches/idwsf/debian/rules b/larpe/branches/idwsf/debian/rules deleted file mode 100755 index 5b3c85f..0000000 --- a/larpe/branches/idwsf/debian/rules +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/make -f -# GNU copyright 1997 to 1999 by Joey Hess. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -PYTHON=/usr/bin/python2.4 - -ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) - CFLAGS += -g -endif -ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) - INSTALL_PROGRAM += -s -endif - -build: build-stamp - -build-stamp: - dh_testdir - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - - make clean - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - make install prefix=/usr DESTDIR=$(CURDIR)/debian/larpe/ - dh_install apache2-vhost-larpe etc/apache2/sites-available - find debian/larpe -name "*.pyc" -exec rm -f {} \; - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installdocs - dh_installinit - dh_installchangelogs -# dh_installdebconf - dh_link - dh_strip - dh_compress - dh_fixperms -X /var/lib/larpe -X /usr/sbin/larpe-reload-apache2 - dh_pycentral - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install diff --git a/larpe/branches/idwsf/debian/templates b/larpe/branches/idwsf/debian/templates deleted file mode 100644 index 9a6cc43..0000000 --- a/larpe/branches/idwsf/debian/templates +++ /dev/null @@ -1,37 +0,0 @@ -Template: larpe/hostname -Type: string -Default: localhost -Description: Hostname : - This is the name by which this reverse-proxy will be known on the network. - Your DNS server must have been configured accordingly. - -Template: larpe/enable_vhost -Type: boolean -Default: false -Description: Enable this vhost : - A new virtual host for Larpe will be created with the hostname you chose. It may break - your Apache2 configuration. - . - If you didn't tweak your Apache2 configuration a lot - and you don't have vital websites on the same server, you can safely say "yes" here - to enable it, and fix it later if needed. - . - If you prefer checking this vhost will fit well with your Apache2 configuration first, - and enable it by yourself later, say "no". - -Template: larpe/admin_username -Type: string -Default: admin -Description: Administrator login : - This is the login which will be used to connect to the administrator interface - -Template: larpe/admin_password -Type: password -Description: Administrator password : - This is the password which will be used to connect to the administrator interface - -Template: larpe/admin_email -Type: string -Default: root@localhost -Description: Administrator email address : - This is the email address to which problem reports will be sent diff --git a/larpe/branches/idwsf/doc/Makefile b/larpe/branches/idwsf/doc/Makefile deleted file mode 100644 index 4b3a5da..0000000 --- a/larpe/branches/idwsf/doc/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -all: - $(MAKE) -C en -# $(MAKE) -C fr - -clean: - $(MAKE) -C en clean -# $(MAKE) -C fr clean - -.PHONY: clean - diff --git a/larpe/branches/idwsf/larpe/Defaults.py b/larpe/branches/idwsf/larpe/Defaults.py deleted file mode 100644 index 0486a2c..0000000 --- a/larpe/branches/idwsf/larpe/Defaults.py +++ /dev/null @@ -1,4 +0,0 @@ -APP_DIR = "/var/lib/larpe" -DATA_DIR = "/usr/share/larpe" -ERROR_LOG = None #"/var/log/larpe.log" -WEB_ROOT = '/larpe' diff --git a/larpe/branches/idwsf/larpe/__init__.py b/larpe/branches/idwsf/larpe/__init__.py deleted file mode 100644 index e5babf0..0000000 --- a/larpe/branches/idwsf/larpe/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -import sys -import os -sys.path.insert(0, os.path.dirname(__file__)) - -import qommon - -try: - import lasso -except ImportError: - lasso = None - -if lasso and not hasattr(lasso, 'SAML2_SUPPORT'): - lasso.SAML2_SUPPORT = False - diff --git a/larpe/branches/idwsf/larpe/admin/__init__.py b/larpe/branches/idwsf/larpe/admin/__init__.py deleted file mode 100644 index 53f1b4b..0000000 --- a/larpe/branches/idwsf/larpe/admin/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from root import RootDirectory diff --git a/larpe/branches/idwsf/larpe/admin/apache.py b/larpe/branches/idwsf/larpe/admin/apache.py deleted file mode 100644 index 4bfb1c8..0000000 --- a/larpe/branches/idwsf/larpe/admin/apache.py +++ /dev/null @@ -1,299 +0,0 @@ -import os -import re -import urllib -import base64 - -from quixote import get_publisher, get_request - -from larpe.hosts import Host -from Defaults import APP_DIR - -def write_apache2_vhosts(): - hosts = Host.select(lambda x: x.name != 'larpe') - hosts.sort() - vhosts_dir = os.path.join(APP_DIR, 'vhosts.d') - vhost_locations_dir = os.path.join(APP_DIR, 'vhost-locations.d') - vhosts_dir_disabled = os.path.join(APP_DIR, 'vhosts.d.disabled') - vhost_locations_dir_disabled = os.path.join(APP_DIR, 'vhost-locations.d.disabled') - vhost_file_name = get_request().get_server().split(':')[0] - vhost_file = None - reversed_hostname = '' - other_locations_hosts = [] - vhost = None - - if get_publisher().cfg.get(str('allow_config_generation'), True): - vhost_file = open(os.path.join(vhosts_dir, vhost_file_name), 'w') - locations_file = open(os.path.join(vhost_locations_dir, vhost_file_name), 'w') - else: - vhost_file = open(os.path.join(vhosts_dir_disabled, vhost_file_name), 'w') - locations_file = open(os.path.join(vhost_locations_dir_disabled, vhost_file_name), 'w') - try: - main_vhost = open('/etc/apache2/sites-available/apache2-vhost-larpe', 'r') - file_content = main_vhost.read() - regexp = re.compile('') - vhost_ip = regexp.findall(file_content)[0] - except: - vhost_ip = '*' - - for host in hosts: - if host.orig_site is None: - # This site hasn't been fully configured - continue - if host.reversed_hostname != reversed_hostname and host.reversed_hostname != get_publisher().cfg['proxy_hostname']: - if vhost is not None: - vhost.close() - vhost = Vhost(host, vhost_ip) - vhost.write(vhost_file) - reversed_hostname = host.reversed_hostname - - if host.reversed_hostname == get_publisher().cfg['proxy_hostname']: - conf_file = locations_file - else: - conf_file = vhost_file - - Location(host).write(conf_file) - - if vhost_file is not None: - if vhost is not None: - vhost.close() - vhost_file.close() - if locations_file is not None: - locations_file.close() - - if get_publisher().cfg.get(str('allow_config_generation'), True): - os.system('/usr/sbin/larpe-reload-apache2') - - -class Vhost: - def __init__(self, host, main_ip_port): - self.host = host - self.main_ip_port = main_ip_port - self.conf_file = None - - def get_ip_port(self): - if self.host.scheme == 'https': - return self.main_ip_port.replace(':80', ':443') - else: - return self.main_ip_port.replace(':443', ':80') - ip_port = property(get_ip_port) - - def get_proxy_url(self): - if get_publisher().cfg.get('use_proxy', False) and self.host.use_proxy == True: - return 'http://%(proxy_ip)s:%(proxy_port)s' % get_publisher().cfg - return None - proxy_url = property(get_proxy_url) - - def get_proxy_auth(self): - if self.get_proxy_url() and get_publisher().cfg.get('proxy_user'): - credentials = base64.encodestring( - '%(proxy_user)s:%(proxy_password)s' % get_publisher().cfg)[:-1] - return '"Basic %s"' % credentials - return None - proxy_auth = property(get_proxy_auth) - - def get_cfg(self): - return { 'ip_port': self.ip_port, - 'reversed_hostname': self.host.reversed_hostname, - 'proxy_url': self.proxy_url, - 'proxy_auth': self.proxy_auth } - cfg = property(get_cfg) - - def write(self, conf_file): - self.conf_file = conf_file - conf_lines = [] - # Start Virtual Host - conf_lines.append('' % self.cfg) - # Server name and administrator - conf_lines.append('ServerName %(reversed_hostname)s' % self.cfg) - conf_lines.append('# ServerAdmin root@localhost\n') - # Include common vhost configuration - conf_lines.append('include /usr/share/larpe/apache2.conf\n') - # SSL - if self.host.scheme == 'https': - conf_lines.append('SSLEngine On\n') - if self.host.orig_site.startswith('https'): - conf_lines.append('SSLProxyEngine On\n') - # Remote proxy configuration - if self.proxy_url is not None: - conf_lines.append('ProxyRemote * %(proxy_url)s' % self.cfg) - if self.proxy_auth is not None: - conf_lines.append('RequestHeader set Proxy-Authorization %(proxy_auth)s\n' % self.cfg) - # Write it all - conf_file.write('\n\t'.join(conf_lines)) - - def close(self): - if self.conf_file: - self.conf_file.write('\n\n') - - -def apache_escape_chars(url): - special_characters = ('\\', '.', '?', '*', '+', '^', '$', '|', '(', ')', '[', ']') - for char in special_characters: - url = url.replace(char, '\%s' % char) - return url - -class Location: - def __init__(self, host): - self.host = host - - def get_reversed_directory(self): - if not self.host.reversed_directory: - return '%s/' % get_request().environ['SCRIPT_NAME'] - else: - return '%s/%s/' % (get_request().environ['SCRIPT_NAME'], self.host.reversed_directory) - reversed_directory = property(get_reversed_directory) - - def get_python_path(self): - if hasattr(self.host, 'apache_output_python_filters') and \ - hasattr(self.host, 'apache_python_paths') and self.host.apache_python_paths: - python_path = 'PythonPath "sys.path' - for path in self.host.apache_python_paths: - python_path += "+['%s']" % path - python_path += '"' - return python_path - else: - return None - python_path = property(get_python_path) - - def get_output_filters(self): - python_filters = '' - output_filters = [] - if hasattr(self.host, 'apache_output_python_filters'): - i = 0 - for filter_file in self.host.apache_output_python_filters: - filter_name = 'filter%d' % i - python_filters += 'PythonOutputFilter %s %s\n\t\t' % (filter_file, filter_name) - output_filters.append(filter_name) - i += 1 - if hasattr(self.host, 'apache_output_filters'): - for filter in self.host.apache_output_filters: - output_filters.append(filter) - if output_filters: - return python_filters + 'SetOutputFilter ' + ';'.join(output_filters) - else: - return None - output_filters = property(get_output_filters) - - def get_old_auth_url(self): - old_auth_url = None - if self.host.initiate_sso_url: - old_auth_url = self.host.initiate_sso_url - elif self.host.auth_url is not None: - if self.host.auth_url.startswith('http://'): - chars_to_skip = 5 - else: - chars_to_skip = 6 - regexp = re.compile(self.host.orig_site[chars_to_skip:]) - old_auth_url_short = regexp.sub('', self.host.auth_url[chars_to_skip:]) - if old_auth_url_short.startswith('/'): - old_auth_url = old_auth_url_short - else: - old_auth_url = '/' + old_auth_url_short - if old_auth_url: - old_auth_url = apache_escape_chars(old_auth_url) - return old_auth_url - old_auth_url = property(get_old_auth_url) - - def get_new_auth_url(self): - if not hasattr(self.host, 'base_url'): - return None - base_url_tokens = self.host.base_url.split('/') - base_url_tokens[-1] = 'login' - return '/'.join(base_url_tokens) - new_auth_url = property(get_new_auth_url) - - def get_old_logout_url(self): - old_logout_url = None - if self.host.logout_url is not None: - if self.host.logout_url.startswith('http://'): - chars_to_skip = 5 - else: - chars_to_skip = 6 - regexp = re.compile(self.host.orig_site[chars_to_skip:]) - old_logout_url_short = regexp.sub('', self.host.logout_url[chars_to_skip:]) - if old_logout_url_short.startswith('/'): - old_logout_url = old_logout_url_short - else: - old_logout_url = '/' + old_logout_url_short - old_logout_url = apache_escape_chars(old_logout_url) - return old_logout_url - old_logout_url = property(get_old_logout_url) - - def get_new_logout_url(self): - if not hasattr(self.host, 'base_url'): - return None - base_url_tokens = self.host.base_url.split('/') - base_url_tokens[-1] = 'logout' - return '/'.join(base_url_tokens) - new_logout_url = property(get_new_logout_url) - - def get_orig_site_url_and_dir(self): - # Split url - if self.host.orig_site.startswith('http://'): - orig_host, orig_query = urllib.splithost(self.host.orig_site[5:]) - else: - orig_host, orig_query = urllib.splithost(self.host.orig_site[6:]) - # Add a trailing slash if necessary - if self.host.orig_site.endswith('/'): - orig_url = self.host.orig_site - orig_dir = orig_query - else: - orig_url = self.host.orig_site + '/' - orig_dir = orig_query + '/' - return orig_url, orig_dir - - def get_orig_url(self): - orig_url, orig_dir = self.get_orig_site_url_and_dir() - return orig_url - orig_url = property(get_orig_url) - - def get_orig_dir(self): - orig_url, orig_dir = self.get_orig_site_url_and_dir() - return orig_dir - orig_dir = property(get_orig_dir) - - def get_cfg(self): - return { 'reversed_directory': self.reversed_directory, - 'old_auth_url': self.old_auth_url, - 'new_auth_url': self.new_auth_url, - 'old_logout_url': self.old_logout_url, - 'new_logout_url': self.new_logout_url, - 'orig_url': self.orig_url, - 'orig_dir': self.orig_dir } - cfg = property(get_cfg) - - def write(self, conf_file): - conf_lines = [] - # Start Location - conf_lines.append('\n\t' % self.cfg) - # No user restriction - conf_lines.append('Allow from all') - # Apache output filters - if self.python_path: - conf_lines.append(self.python_path) - if self.output_filters: - conf_lines.append(self.output_filters) - # Enable rewrite module - if self.old_auth_url is not None or self.old_logout_url is not None: - conf_lines.append('RewriteEngine On') - # Redirect old authentication url to the new one - if self.old_auth_url is not None and self.host.auth_form_places == 'form_once': - conf_lines.append( - 'RewriteRule %(old_auth_url)s %(new_auth_url)s [R]' % self.cfg) - # Redirect old logout url to the new one - if self.old_logout_url is not None: - conf_lines.append( - 'RewriteRule %(old_logout_url)s %(new_logout_url)s [R]' % self.cfg) - # Redirect the home page to the login page - if self.host.redirect_root_to_login is True: - conf_lines.append('RewriteRule /$ %(new_auth_url)s [R]' % self.cfg) - # Convert urls in http headers to/from the new domain - conf_lines.append('ProxyPass %(orig_url)s' % self.cfg) - conf_lines.append('ProxyPassReverse %(orig_url)s' % self.cfg) - # Convert urls in html pages to/from the new domain - conf_lines.append('ProxyHTMLURLMap %(orig_dir)s %(reversed_directory)s' % self.cfg) - conf_lines.append('ProxyHTMLURLMap %(orig_url)s %(reversed_directory)s' % self.cfg) - # Write it all and close the Location - conf_file.write('\n\t\t'.join(conf_lines)) - conf_file.write('\n\t\n') - diff --git a/larpe/branches/idwsf/larpe/admin/fields_prefill.ptl b/larpe/branches/idwsf/larpe/admin/fields_prefill.ptl deleted file mode 100644 index 9230551..0000000 --- a/larpe/branches/idwsf/larpe/admin/fields_prefill.ptl +++ /dev/null @@ -1,130 +0,0 @@ -from quixote import get_response, redirect -from quixote.directory import Directory - -from qommon.form import * - -from field_prefill import FieldPrefill -from menu import html_top, command_icon - -class FieldUI: - def __init__(self, field_prefill): - self.field_prefill = field_prefill - - def form_edit(self): - form = Form(enctype='multipart/form-data') - form.add(StringWidget, 'name', title = _('Field name'), required = True, - size = 50, value = self.field_prefill.name) - form.add(StringWidget, 'xpath', title = _('Xpath of the attribute'), required = True, - size = 50, value = self.field_prefill.xpath, hint=_('Example: /pp:PP/pp:InformalName')) - form.add(IntWidget, 'number', title = _('Number of the field in the data'), required = True, - size = 3, value = self.field_prefill.number, - hint=_('Change it if there are multiple fields corresponding to the same Xpath and you want to get another than the first one')) - form.add(CheckboxWidget, 'raw_xml', title=_('Get raw XML value'), - value = self.field_prefill.raw_xml) - form.add(StringWidget, 'regexp_match', title = _('Python regexp of a string to match'), - size = 50, value = self.field_prefill.regexp_match) - form.add(StringWidget, 'regexp_replacing', title = _('Python regexp of the replacing string'), - size = 50, value = self.field_prefill.regexp_replacing) - form.add(WidgetDict, 'select_options', title = _('Options mapping for a select field'), - value = self.field_prefill.select_options, add_element_label = _('Add item')) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_edit(self, form): - for f in ('name', 'xpath', 'number', 'raw_xml', 'regexp_match', 'regexp_replacing', 'select_options'): - widget = form.get_widget(f) - setattr(self.field_prefill, f, widget.parse()) - self.field_prefill.store() - -class FieldPage(Directory): - _q_exports = ['', 'delete'] - - def __init__(self, field_id): - self.field_prefill = FieldPrefill.get(field_id) - self.field_ui = FieldUI(self.field_prefill) - get_response().breadcrumb.append((field_id + '/', field_id)) - - def _q_index [html] (self): - form = self.field_ui.form_edit() - redo = False - - if form.get_widget('cancel').parse(): - return redirect('..') - - if form.get_widget('select_options') and form.get_widget('select_options').get_widget('add_element').parse(): - form.clear_errors() - redo = True - - if redo is False and form.is_submitted() and not form.has_errors(): - self.field_ui.submit_edit(form) - return redirect('..') - - get_response().breadcrumb.append( ('edit', _('Edit')) ) - html_top('edit', title = _('Edit')) - '

%s

' % _('Edit') - - form.render() - - def delete [html] (self): - form = Form(enctype='multipart/form-data') - form.widgets.append(HtmlWidget('

%s

' % _( - 'You are about to irrevocably delete this field.'))) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - if form.get_widget('cancel').parse(): - return redirect('..') - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append(('delete', _('Delete'))) - html_top('delete_form', title = _('Delete Field')) - '

%s : %s

' % (_('Delete Field'), self.field_prefill.id) - form.render() - else: - self.field_prefill.remove_self() - return redirect('..') - - -class FieldsDirectory(Directory): - _q_exports = ['', 'new'] - - def __init__(self, form_prefill): - get_response().breadcrumb.append(('fields/', _('Fields'))) - self.form_prefill = form_prefill - - def _q_lookup(self, component): - return FieldPage(component) - - def _q_index [html] (self): - html_top('fields', title = _('Fields')) - """""" % _('New Field') - - '
    ' - - for field_prefill in FieldPrefill.select(lambda x: x.form_id == self.form_prefill.id): - if not field_prefill.name: - continue - - # Split too long xpath - xpath = field_prefill.xpath - xpath_tokens = xpath.split(str('/')) - if len(xpath_tokens) > 3: - xpath = str('.../') + str('/').join(xpath_tokens[-3:]) - - '
  • ' - '%s' % field_prefill.name - '
    %s' % xpath - '

    ' - command_icon('%s/' % field_prefill.id, 'edit') - command_icon('%s/delete' % field_prefill.id, 'remove') - '

  • ' - '
' - - def new [html] (self): - get_response().breadcrumb.append(('new', _('New')) ) - field_prefill = FieldPrefill() - field_prefill.form_id = self.form_prefill.id - field_prefill.store() - return redirect('%s/' % field_prefill.id) - diff --git a/larpe/branches/idwsf/larpe/admin/forms_prefill.ptl b/larpe/branches/idwsf/larpe/admin/forms_prefill.ptl deleted file mode 100644 index 827a499..0000000 --- a/larpe/branches/idwsf/larpe/admin/forms_prefill.ptl +++ /dev/null @@ -1,127 +0,0 @@ -from quixote import get_response, redirect -from quixote.directory import Directory - -from qommon.form import * - -from form_prefill import FormPrefill -from fields_prefill import FieldsDirectory -from menu import html_top, command_icon - -class FormUI: - def __init__(self, form_prefill): - self.form_prefill = form_prefill - - def form_edit(self): - form = Form(enctype='multipart/form-data') - form.add(StringWidget, 'name', title = _('Form name'), required = True, - size = 50, value = self.form_prefill.name, hint=_('Only used for display')) - form.add(UrlWidget, 'url', title = _('Form address'), required = True, - size = 50, value = self.form_prefill.url) - form.add(StringWidget, 'profile', title = _('ID-WSF data profile'), required = True, - size = 50, value = self.form_prefill.profile, hint=_('Example: urn:liberty:id-sis-pp:2005-05')) - form.add(StringWidget, 'prefix', title = _('ID-WSF data XML prefix'), required = True, - size = 50, value = self.form_prefill.prefix, hint=_('Example: pp')) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_edit(self, form): - for f in ('name', 'url', 'profile', 'prefix'): - widget = form.get_widget(f) - setattr(self.form_prefill, f, widget.parse()) - self.form_prefill.store() - -class FormPage(Directory): - _q_exports = ['', 'edit', 'delete'] - - def __init__(self, form_id): - self.form_prefill = FormPrefill.get(form_id) - self.form_ui = FormUI(self.form_prefill) - get_response().breadcrumb.append((form_id + '/', form_id)) - - def _q_index [html] (self): - html_top('forms_prefill', title = 'Form prefilling') - - '

%s

' % _('Form prefilling configuration') - '
' - '
%s
%s
' % ( - _('Edit'), _('Configure this form')) - '
%s
%s
' % ( - _('Fields'), _('Configure the fields of this form')) - '
' - - def _q_lookup(self, component): - if component == 'fields': - return FieldsDirectory(self.form_prefill) - - def edit [html] (self): - form = self.form_ui.form_edit() - if form.get_widget('cancel').parse(): - return redirect('.') - - if form.is_submitted() and not form.has_errors(): - self.form_ui.submit_edit(form) - return redirect('.') - - get_response().breadcrumb.append( ('edit', _('Edit')) ) - html_top('edit', title = _('Edit')) - '

%s

' % _('Edit') - - form.render() - - def delete [html] (self): - form = Form(enctype='multipart/form-data') - form.widgets.append(HtmlWidget('

%s

' % _( - 'You are about to irrevocably delete this form.'))) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - if form.get_widget('cancel').parse(): - return redirect('..') - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append(('delete', _('Delete'))) - html_top('delete_form', title = _('Delete Form')) - '

%s : %s

' % (_('Delete Form'), self.form_prefill.id) - form.render() - else: - self.form_prefill.remove_self() - return redirect('..') - - -class FormsDirectory(Directory): - _q_exports = ['', 'new'] - - def __init__(self, host): - get_response().breadcrumb.append(('forms_prefill/', _('Forms'))) - self.host = host - - def _q_lookup(self, component): - return FormPage(component) - - def _q_index [html] (self): - html_top('forms', title = _('Forms')) - """""" % _('New Form') - - '
    ' - - for form_prefill in FormPrefill.select(lambda x: x.host_id == self.host.id): - if not form_prefill.name: - continue - '
  • ' - '%s' % form_prefill.name - url = form_prefill.url - '
    %s' % (url, url) - '

    ' - command_icon('%s/' % form_prefill.id, 'edit') - command_icon('%s/delete' % form_prefill.id, 'remove') - '

  • ' - '
' - - def new [html] (self): - get_response().breadcrumb.append(('new', _('New')) ) - form_prefill = FormPrefill() - form_prefill.host_id = self.host.id - form_prefill.store() - return redirect('%s/edit' % form_prefill.id) - diff --git a/larpe/branches/idwsf/larpe/admin/hosts.ptl b/larpe/branches/idwsf/larpe/admin/hosts.ptl deleted file mode 100644 index 2ff4aa3..0000000 --- a/larpe/branches/idwsf/larpe/admin/hosts.ptl +++ /dev/null @@ -1,1839 +0,0 @@ -import os -import urllib -import urlparse - -from quixote import redirect, get_request, get_response, get_publisher -from quixote.directory import Directory - -import lasso - -from larpe.qommon import get_cfg -from larpe.qommon.form import * -from larpe.qommon.misc import http_get_page, get_abs_path - -import site_authentication -from larpe import errors -from larpe import misc -from larpe.hosts import Host -from larpe.admin.liberty_utils import * -#from larpe.filter import filter_misc -from larpe.admin.apache import write_apache2_vhosts -from larpe.admin.forms_prefill import FormsDirectory - -from menu import * - -def check_basic_configuration(form): - get_publisher().reload_cfg() - # Check reversed_hostname and reversed_directory - reversed_hostname = form.get_widget('reversed_hostname').parse() - reversed_directory = form.get_widget('reversed_directory').parse() - if reversed_hostname == get_publisher().cfg['proxy_hostname'] and not reversed_directory: - form.set_error('reversed_hostname', - _('You must either choose a different hostname from Larpe or specify a reversed directory')) - -def check_minimal_configuration(form): - # Check auth_url and auth_form_page_url - auth_url = form.get_widget('auth_url').parse() - auth_form_page_url = form.get_widget('auth_form_page_url').parse() - if auth_url and auth_form_page_url: - form.set_error('auth_form_page_url', - _('"Authentication page" and "Authentication form page" are incompatible. Only fill one of them.')) - -def convert_label_to_name(label): - '''Build host name from host label''' - name = label.lower() - invalid_characters = [' ', "'"] - for char in invalid_characters: - name = name.replace(char, '_') - return name - -class DictWidget(Widget): - def render_content [html] (self): - self.render_br = False - if self.value['enabled'] is True: - htmltag('input', xml_end=True, type='checkbox', name=self.name + '_enabled', checked='checked') - else: - htmltag('input', xml_end=True, type='checkbox', name=self.name + '_enabled') - ' ' + self.name + '  ' - htmltag('input', xml_end=True, type='text', name=self.name, value=self.value['value'], size='35', **self.attrs) - - def _parse(self, request): - enabled = request.form.get(self.name + '_enabled') - value = request.form.get(self.name) - self.value = { 'enabled': enabled, 'value': value } - - -class ConfigurationAssistant(Directory): - _q_exports = ['start', 'check_new_address', 'modify_site_address_and_name', 'authentication_and_logout_adresses', - 'check_auto_detected_configuration', 'credentials', 'check_authentication', 'send_authentication_request', - 'see_authentication_response', 'see_response_html_page', 'authentication_success_criteria', - 'modify_authentication_request', 'auth_request_post_parameters', 'auth_request_http_headers', - 'sso_init_link', 'metadatas', 'check_full_configuration', 'advanced_options'] - - def __init__(self, host): - self.host = host - - def start [html] (self): - # Check the global domain name has been previously set - get_publisher().reload_cfg() - if not get_cfg('domain_names') or not get_cfg('domain_names')[0]: - html_top('preamble', title=_('Need domain name configuration')) - return htmltext(_('Before configuring hosts, you must setup a global domain name in %(settings)s menu.') % { 'settings': _('Settings') }) - - form = self.form_start() - - if form.get_widget('cancel').parse(): - return redirect('../..') - - connection_failure = None - if form.is_submitted() and not form.has_errors(): - try: - self.submit_start_form(form) - except Exception, e: - connection_failure = e - else: - return redirect('check_new_address') - - html_top('step1', title=_('Step 1 - Basic configuration')) - '

%s

' % _('Step 1 - Basic configuration') - - if connection_failure: - '
%s
' % connection_failure - - form.render() - - def form_start(self): - form = Form(enctype='multipart/form-data') - form.add(UrlWidget, 'orig_site', title = _('Original site root address'), required = True, - size = 50, value = self.host.orig_site, - hint = _('If your site address is http://test.org/index.php, put http://test.org/ here')) - get_publisher().reload_cfg() - if get_cfg('use_proxy'): - form.add(CheckboxWidget, 'use_proxy', title = _('Use a proxy'), - hint = _("Uncheck it if Larpe doesn't need to use the proxy to connect to this site"), - value = self.host.use_proxy) - else: - form.add(HtmlWidget, htmltext('

%s

' % \ - _('If Larpe needs to use a proxy to connect to this site, you must first configure it in global proxy parameters.'))) - form.add_submit('cancel', _('Cancel')) - form.add_submit('submit', _('Next')) - return form - - def submit_start_form(self, form): - fields = ['orig_site'] - if get_cfg('use_proxy'): - fields += ['use_proxy'] - for f in fields: - setattr(self.host, f, form.get_widget(f).parse()) - - # If no proxy is setup yet, set use_proxy to False for new hosts in case a proxy is later configured - if not get_cfg('use_proxy'): - self.host.use_proxy = False - - # Remove what is after the last '/' - #self.host.orig_site = '/'.join(self.host.orig_site.split('/')[:-1]) - - html_page = self.get_data_after_redirects(self.host.orig_site) - - if not self.host.label: - # Look for html title in original site index page - regexp = re.compile("""(.*?)""", re.DOTALL | re.IGNORECASE) - title = regexp.findall(html_page) - if title: - self.host.label = title[0] - else: - self.host.label = 'Untitled' - # If another site already uses this site title, add trailings "_" until we find an available name - existing_label = True - while existing_label is True: - for any_host in Host.select(): - if any_host.id != self.host.id and self.host.label == any_host.label: - self.host.label += '_' - break - else: - existing_label = False - - # Fill host.name attribute - self.host.name = convert_label_to_name(self.host.label) - - if not self.host.scheme: - # Get tokens from orig site url - orig_scheme, rest = urllib.splittype(self.host.orig_site) - orig_host, rest = urllib.splithost(rest) - - get_publisher().reload_cfg() - # Set url scheme (HTTP or HTTPS) - # TODO: Handle the option "Both" - if get_cfg('sites_url_scheme'): - self.host.scheme = get_cfg('sites_url_scheme') - else: - self.host.scheme = orig_scheme - - if not self.host.reversed_hostname: - # Build a new domain name - short_name = orig_host.split('.')[0] - if short_name == 'www': - short_name = orig_host.split('.')[1] - self.host.reversed_hostname = '%s.%s' % (short_name, get_cfg('domain_names')[0]) - # If another site already uses this domain name, add some trailing "_" until we find an available name - existing_domain = True - while existing_domain is True: - for any_host in Host.select(): - if any_host.id != self.host.id and self.host.reversed_hostname == any_host.reversed_hostname: - self.host.reversed_hostname += '-' - break - else: - existing_domain = False - self.host.reversed_directory = None - - if not self.host.new_url: - # New url for this host - self.host.new_url = '%s://%s%s/' % (self.host.scheme, self.host.reversed_hostname, get_request().environ['SCRIPT_NAME']) - # FIXME: Check if the new domain name already exists - - # New url for this host - # self.host.new_url = '%s://%s%s/' % (self.host.scheme, self.host.reversed_hostname, get_request().environ['SCRIPT_NAME']) - # if self.host.reversed_directory is not None: - # self.host.new_url += '%s/' % self.host.reversed_directory - - self.host.store() - write_apache2_vhosts() - - # XXX: Should use the FancyURLopener class instead when it supports proxies - def get_data_after_redirects(self, start_url): - if not start_url: - return '' - status = 302 - location = None - while status // 100 == 3: - if location is None: - url = start_url - elif location.startswith('http'): - # Location is an absolute path - url = location - else: - # Location is a relative path - url = urlparse.urljoin(start_url, location) - response, status, data, auth_headers = http_get_page(url, use_proxy=self.host.use_proxy) - location = response.getheader('Location', None) - return data - - def create_dirs(self): - # Hack : sites must use the configuration which is stored in main Larpe directory, - # but they need to have a directory named with their hostname, which will contain the - # main domain name for Larpe so they know where is the main configuration - hostname_dir = get_abs_path(os.path.join('..', self.host.reversed_hostname)) - if not os.path.exists(hostname_dir): - os.mkdir(hostname_dir) - # Load the configuration from the main directory - get_publisher().reload_cfg() - # Write it in the site directory - get_publisher().write_cfg(hostname_dir) - - # Storage directories - if not self.host.reversed_directory: - reversed_dir = 'default' - else: - reversed_dir = self.host.reversed_directory - self.host.site_dir = \ - os.path.join(get_publisher().app_dir, 'sp', self.host.reversed_hostname, reversed_dir) - user_dir = os.path.join(self.host.site_dir, 'users') - token_dir = os.path.join(self.host.site_dir, 'tokens') - filter_dir = os.path.join(self.host.site_dir, 'filters') - for dir in (self.host.site_dir, user_dir, token_dir, filter_dir): - if not os.path.isdir(dir): - os.makedirs(dir) - - def generate_ssl_keys(self): - # Generate SSL keys - private_key_path = os.path.join(self.host.site_dir, 'private_key.pem') - public_key_path = os.path.join(self.host.site_dir, 'public_key.pem') - if not os.path.isfile(private_key_path) or not os.path.isfile(public_key_path): - set_provider_keys(private_key_path, public_key_path) - self.host.private_key = private_key_path - self.host.public_key = public_key_path - - def generate_metadatas(self): - metadata_cfg = {} - - # Organization name - self.host.organization_name = self.host.label - metadata_cfg['organization_name'] = self.host.organization_name - - # Base URL - base_url = '%s://%s%s/liberty/%s/liberty' % (self.host.scheme, - self.host.reversed_hostname, - get_request().environ['SCRIPT_NAME'], - self.host.name) - metadata_cfg['base_url'] = base_url - self.host.base_url = base_url - - if lasso.SAML2_SUPPORT: - saml2_base_url = '%s://%s%s/liberty/%s/saml' % (self.host.scheme, - self.host.reversed_hostname, - get_request().environ['SCRIPT_NAME'], - self.host.name) - metadata_cfg['saml2_base_url'] = saml2_base_url - self.host.saml2_base_url = saml2_base_url - - # Provider Id - provider_id = '%s/metadata' % base_url - metadata_cfg['provider_id'] = provider_id - self.host.provider_id = provider_id - - if lasso.SAML2_SUPPORT: - saml2_provider_id = '%s/metadata' % saml2_base_url - metadata_cfg['saml2_provider_id'] = saml2_provider_id - self.host.saml2_provider_id = saml2_provider_id - - # Read public key - public_key = '' - if self.host.public_key is not None and os.path.exists(self.host.public_key): - metadata_cfg['signing_public_key'] = open(self.host.public_key).read() - - # Write metadatas - metadata_path = os.path.join(self.host.site_dir, 'metadata.xml') - open(metadata_path, 'w').write(get_metadata(metadata_cfg)) - self.host.metadata = metadata_path - - if lasso.SAML2_SUPPORT: - saml2_metadata_path = os.path.join(self.host.site_dir, 'saml2_metadata.xml') - open(saml2_metadata_path, 'w').write(get_saml2_metadata(metadata_cfg)) - self.host.saml2_metadata = saml2_metadata_path - - def check_new_address [html] (self): - form = Form(enctype='multipart/form-data') - form.add_submit('cancel', _('Previous')) - form.add_submit('submit', _('Next')) - - if form.get_widget('cancel').parse(): - return redirect('start') - - if form.is_submitted(): - self.create_dirs() - if self.host.private_key is None: - self.generate_ssl_keys() - self.generate_metadatas() - self.host.store() - return redirect('authentication_and_logout_adresses') - - html_top('step2', title=_('Step 2 - Check the new site address works')) - '

%s

' % _('Step 2 - Check the new site address works') - - htmltext(_('''\ -

Before opening the following link, ensure you have configured your DNS for this address. If you don't -have a DNS server and you just want to test Larpe, add this domain name in the file "/etc/hosts".

-

Then you can open this link in a new window or tab and see if your site is displayed. If it's ok, -you can click the "%(next)s" button. Otherwise, click the "%(previous)s" button and check your settings.

-''') % {'next': _('Next'), 'previous': _('Previous')}) - '

' - htmltext(_('The new address of this site is ')) - '%s
' % (self.host.new_url, self.host.new_url) - htmltext(_('The name of this site is "%s".') % self.host.label) - '

' - htmltext(_('You can also modify the address or the name of this site')) - '

' - - form.render() - - def modify_site_address_and_name [html] (self): - form = self.form_modify_site_address_and_name() - - if form.get_widget('cancel').parse(): - return redirect('check_new_address') - - if form.is_submitted() and not form.has_errors(): - label = form.get_widget('label').parse() - name = convert_label_to_name(label) - for any_host in Host.select(): - if any_host.id != self.host.id and name == any_host.name: - form.set_error('label', _('An host with the same name already exists')) - break - - if form.is_submitted() and not form.has_errors(): - self.submit_modify_site_address_and_name_form(form) - return redirect('check_new_address') - - html_top('modify_site_address_and_name', title=_('Modify site address and name')) - '

%s

' % _('Modify site address and name') - form.render() - - def form_modify_site_address_and_name(self): - form = Form(enctype='multipart/form-data') - form.add(UrlWidget, 'new_url', title = _('Address'), required = True, - size = 50, value = self.host.new_url) - form.add(StringWidget, 'label', title = _('Name'), required = True, - size = 50, value = self.host.label) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_modify_site_address_and_name_form(self, form): - fields = ['new_url', 'label'] - for f in fields: - setattr(self.host, f, form.get_widget(f).parse()) - - # Split url to retrieve components - tokens = urlparse.urlparse(self.host.new_url) - self.host.scheme = tokens[0] - self.host.reversed_hostname = tokens[1] - self.host.reversed_directory = tokens[2] - if self.host.reversed_directory.startswith('/'): - self.host.reversed_directory = self.host.reversed_directory[1:] - - # Fill host.name attribute - self.host.name = convert_label_to_name(self.host.label) - - self.host.store() - write_apache2_vhosts() - - def authentication_and_logout_adresses [html] (self): - form = self.form_authentication_and_logout_adresses() - - if form.get_widget('cancel').parse(): - return redirect('check_new_address') - - if form.is_submitted() and not form.has_errors(): - self.submit_authentication_and_logout_adresses_form(form) - return redirect('check_auto_detected_configuration') - - html_top('step3', title=_('Step 3 - Configure authentication and logout pages')) - '

%s

' % _('Step 3 - Configure authentication and logout pages') - form.render() - - def form_authentication_and_logout_adresses(self): - form = Form(enctype='multipart/form-data') - form.add(ValidUrlWidget, 'auth_url', title = _('Authentication form page address'), - hint = _('Address of a page on the site which contains the authentication form'), - required = True, size = 50, value = self.host.auth_url) - form.add(ValidUrlWidget, 'logout_url', title = _('Logout address'), required = False, - hint = _('Address of the logout link on the site'), - size = 50, value = self.host.logout_url) - form.add_submit('cancel', _('Previous')) - form.add_submit('submit', _('Next')) - return form - - def submit_authentication_and_logout_adresses_form(self, form): - fields = ['auth_url', 'logout_url'] - for f in fields: - setattr(self.host, f, form.get_widget(f).parse()) - self.host.auth_form_url = self.host.auth_url - - if not self.host.http_headers: - self.host.http_headers = { - 'Content-Type': { 'enabled': True, 'value': 'application/x-www-form-urlencoded', 'immutable': False }, - 'X-Forwarded-For': { 'enabled': True, 'value': _('(computed automatically)'), 'immutable': True }, - 'X-Forwarded-Host': { 'enabled': True, 'value': self.host.reversed_hostname, 'immutable': False }, - } - - self.auto_detect_configuration() - self.host.store() - write_apache2_vhosts() - - def check_auto_detected_configuration [html] (self): - form = Form(enctype='multipart/form-data') - form.add_submit('cancel', _('Previous')) - form.add_submit('submit', _('Next')) - - if form.get_widget('cancel').parse(): - return redirect('authentication_and_logout_adresses') - - if form.is_submitted(): - return redirect('credentials') - - html_top('step4', title=_('Step 4 - Check automatically detected configuration for the authentication form')) - '

%s

' % _('Step 4 - Check automatically detected configuration for the authentication form') - - host_attrs = ( - ('auth_check_url', _('Address where the authentication form must be sent')), - ('login_field_name', _('Name of the login field')), - ('password_field_name', _('Name of the password field')), - ) - - html_fields = '' - success = True - for attr, name in host_attrs: - color = 'black' - if attr in ('auth_check_url', 'login_field_name', 'password_field_name') and \ - not getattr(self.host, str(attr)): - color = 'red' - success = False - html_fields += '
%s
' % (color, name) - html_fields += '
%s
' % \ - (color, getattr(self.host, str(attr))) - if getattr(self.host, str(attr)) == '': - html_fields += '
' - - '

' - if success: - htmltext(_('''\ -The following authentication form parameters have been detected. If they look right, you can go to the next step. -If you think they are wrong, go back and check your settings then try again. -''')) - else: - htmltext(_('''\ -The following authentication form parameters in red haven't been correctly detected. Go back and check -your settings then try again. -''')) - '

' - - html_fields - form.render() - - def credentials [html] (self): - form = self.form_credentials() - - if form.get_widget('cancel').parse(): - return redirect('check_auto_detected_configuration') - - if form.is_submitted() and not form.has_errors(): - self.submit_credentials_form(form) - return redirect('send_authentication_request') - - html_top('step5', title=_('Step 5 - Fill in a valid username/password for this site')) - '

%s

' % _('Step 5 - Fill in a valid username/password for this site') - form.render() - - def form_credentials(self): - form = Form(enctype='multipart/form-data') - form.add(StringWidget, 'username', title = _('Username'), required = True, - size = 30, value = self.host.valid_username) - form.add(PasswordWidget, 'password', title = _('Password'), required = True, - size = 30, value = self.host.valid_password) - for name, values in self.host.select_fields.iteritems(): - options = [] - if values: - for value in values: - options.append(value) - form.add(SingleSelectWidget, name, title = name.capitalize(), - value = values[0], options = options) - form.add_submit('cancel', _('Previous')) - form.add_submit('submit', _('Next')) - return form - - def submit_credentials_form(self, form): - self.host.valid_username = form.get_widget('username').parse() - self.host.valid_password = form.get_widget('password').parse() - self.host.valid_select = {} - for name, values in self.host.select_fields.iteritems(): - if form.get_widget(name): - self.host.valid_select[name] = form.get_widget(name).parse() - - self.host.store() - - def send_authentication_request(self): - site_auth = site_authentication.get_site_authentication(self.host) - self.host.auth_request_status, self.host.auth_request_data = site_auth.local_auth_check_dispatch( - self.host.valid_username, self.host.valid_password, self.host.valid_select) - self.host.auth_request_success, self.host.auth_request_return_content = \ - site_auth.check_auth(self.host.auth_request_status, self.host.auth_request_data) - - self.host.store() - - return redirect('check_authentication') - - def check_authentication [html] (self): - form = Form(enctype='multipart/form-data') - form.add_submit('cancel', _('Previous')) - form.add_submit('submit', _('Next')) - - if form.get_widget('cancel').parse(): - return redirect('credentials') - - if form.is_submitted(): - return redirect('sso_init_link') - - html_top('step6', title=_('Step 6 - Check the authentication process')) - '

%s

' % _('Step 6 - Check the authentication process') - - if self.host.auth_request_success: - htmltext(_('''

Authentication succeeded ! You can go to the next step.

''')) - else: - htmltext(_('''\ -

Authentication has failed. To resolve this problem, you can :

- -''')) - - form.render() - - def see_authentication_response [html] (self): - html_top('see_authentication_response', title=_('Authentication response')) - '

%s

' % _('Authentication response') - - color = str('black') - name = str(_('HTTP status code')) - '
%s
' % (color, name) - '
%s (%s)
' % \ - (color, self.host.auth_request_status, status_reasons[self.host.auth_request_status]) - - '
' - '
%s
' % _('See HTML page') - '
' - '

' % _('Back') - - def see_response_html_page (self): - return self.host.auth_request_data - - def authentication_success_criteria [html] (self): - form = self.form_authentication_success_criteria() - - if form.get_widget('cancel').parse(): - return redirect('check_authentication') - - if form.is_submitted() and not form.has_errors(): - self.submit_authentication_success_criteria_form(form) - return redirect('check_authentication') - - html_top('authentication_success_criteria', title=_('Criteria of authentication success')) - '

%s

' % _('Criteria of authentication success') - form.render() - - def form_authentication_success_criteria(self): - form = Form(enctype='multipart/form-data') - form.add(RadiobuttonsWidget, 'auth_system', title = _('Authentication system of the original site'), - options=[ - ('password', _('Check the existence of a password field'), 'password'), - ('match_text', _('Match some text to detect an authentication failure'), 'match_text'), - ], - sort=False, - delim=htmltext('
'), - value = self.host.auth_system) - form.add(RegexStringWidget, 'auth_match_text', title = _('Text to match in case of authentication failure'), - required = False, size = 50, value = self.host.auth_match_text) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_authentication_success_criteria_form(self, form): - for f in ('auth_system', 'auth_match_text'): - value = form.get_widget(f).parse() - setattr(self.host, f, value) - - self.host.store() - - def modify_authentication_request [html] (self): - html_top('modify_authentication_request', title=_('Modify the parameters of the authentication request')) - '

%s

' % _('Modify the parameters of the authentication request') - - '
' - '
%s
%s
' % ( - _('Modify POST parameters'), _('Configure the form attributes that will be sent within the authentication POST requests')) - '
%s
%s
' % ( - _('Modify HTTP headers'), _('Configure the HTTP headers of the authentication requests made by Larpe')) - '
' - '

' % _('Back') - - def auth_request_post_parameters [html] (self): - form = self.form_auth_request_post_parameters() - - if form.get_widget('cancel').parse(): - return redirect('modify_authentication_request') - - if form.is_submitted() and not form.has_errors(): - self.submit_auth_request_post_parameters_form(form) - return redirect('modify_authentication_request') - - html_top('auth_request_post_parameters', title=_('Configure POST parameters')) - '

%s

' % _('Configure POST parameters') - - '

' - htmltext(_('''Here are the detected form fields that will be sent as parameters of the authentication POST - request. You can desactivate some or all of them, or change their value.''')) - '

' - - form.render() - - def form_auth_request_post_parameters(self): - form = Form(enctype='multipart/form-data') - for name, value in self.host.post_parameters.iteritems(): - if value['immutable']: - form.add(DictWidget, name, value, disabled = 'disabled') - else: - form.add(DictWidget, name, value) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_auth_request_post_parameters_form(self, form): - for name, old_value in self.host.post_parameters.iteritems(): - value = form.get_widget(name).parse() - if value['enabled'] == 'on': - old_value['enabled'] = True - else: - old_value['enabled'] = False - if old_value['immutable'] is False: - old_value['value'] = value['value'] - self.host.post_parameters[name] = old_value - self.host.store() - - def auth_request_http_headers [html] (self): - form = self.form_auth_request_http_headers() - - if form.get_widget('cancel').parse(): - return redirect('modify_authentication_request') - - if form.is_submitted() and not form.has_errors(): - self.submit_auth_request_http_headers_form(form) - return redirect('modify_authentication_request') - - html_top('auth_request_http_headers', title=_('Configure HTTP headers')) - '

%s

' % _('Configure HTTP headers') - - '

' - htmltext(_('''Here are the HTTP headers that will be sent within the authentication POST - request. You can desactivate some or all of them, or change their value.''')) - '

' - - form.render() - - def form_auth_request_http_headers(self): - form = Form(enctype='multipart/form-data') - for name, value in self.host.http_headers.iteritems(): - if value['immutable']: - form.add(DictWidget, name, value, disabled = 'disabled') - else: - form.add(DictWidget, name, value) - form.add(HtmlWidget, htmltext('

%s

' % \ - _('The headers "Host", "Accept-Encoding" and "Content-Length" will also automatically be sent.'))) - if get_cfg('use_proxy') and self.host.use_proxy: - form.add(HtmlWidget, htmltext('

%s

' % \ - _('As Larpe uses a proxy for this site, the headers "Proxy-Authorization", "Proxy-Connection" and "Keep-Alive" will be sent as well.'))) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_auth_request_http_headers_form(self, form): - for name, old_value in self.host.http_headers.iteritems(): - value = form.get_widget(name).parse() - if value['enabled'] == 'on': - old_value['enabled'] = True - else: - old_value['enabled'] = False - if old_value['immutable'] is False: - old_value['value'] = value['value'] - self.host.http_headers[name] = old_value - self.host.store() - - def generate_apache_filter (self): - # Set Python filter path for Apache configuration - if not hasattr(self.host, 'apache_python_paths'): - self.host.apache_python_paths = [] - python_path = os.path.join(self.host.site_dir, 'filters') - if python_path not in self.host.apache_python_paths: - self.host.apache_python_paths.append(python_path) - - # Write Python filter - python_file = open(os.path.join(self.host.site_dir, 'filters', 'output_replace_form.py'), 'w') - python_file.write(open(os.path.join(get_publisher().data_dir, 'output_filter_base.py'), 'r').read()) - python_file.write('''\ -def filter_page(filter, page): - current_form = re.compile('
.*?
', re.DOTALL) - return current_form.sub('
', page) -''' % { 'auth_form_action': self.host.auth_form_action, 'name': self.host.name }) - python_file.close() - - # Set Python filter for Apache configuration - if not hasattr(self.host, 'apache_output_python_filters'): - self.host.apache_output_python_filters = [] - if not 'output_replace_form' in self.host.apache_output_python_filters: - self.host.apache_output_python_filters.append('output_replace_form') - - def sso_init_link [html] (self): - form = self.form_sso_init_link() - - if form.get_widget('cancel').parse(): - return redirect('check_authentication') - - if form.is_submitted() and not form.has_errors(): - self.submit_sso_init_link_form(form) - return redirect('metadatas') - - html_top('step7', title=_('Step 7 - Configure how a Single Sign On can be initiated')) - '

%s

' % _('Step 7 - Configure how a Single Sign On can be initiated') - - '

' - htmltext(_('''\ -Most sites use one of the following 2 ways to allow users to initialise an authentication : -

    -
  1. The site has a single authentication page. It redirects users to this page when they click a "Login" button or try to access a page which require users to be authenticated.
  2. -
  3. The site includes an authentication form in most or all of his pages. Users can authenticate on any of these pages, and don't need to be redirected to a separate authentication page.
  4. -
''')) - '

' - - '

' - htmltext(_('''\ -Larpe needs to change this part of the site in a different way depending on the usual way the site works. It can either : -

    -
  1. Redirect the user to the Single Sign On url instead of the previous authentication page.
  2. -
  3. Replace the form included in pages with a simple button. When users press this button, they will be redirected to the Single Sign On url.
  4. -
''')) - '

' - - form.render() - - def form_sso_init_link(self): - form = Form(enctype='multipart/form-data') - form.add(RadiobuttonsWidget, 'auth_form_places', title = _('Authentication page or form'), - options=[ - ('form_once', _('The site has a single authentication page'), 'form_once'), - ('form_everywhere', _('The site includes an authentication form in most or all pages'), 'form_everywhere'), - ], - sort=False, required = True, delim=htmltext('
'), value = self.host.auth_form_places) - form.add_submit('cancel', _('Previous')) - form.add_submit('submit', _('Next')) - return form - - def submit_sso_init_link_form(self, form): - fields = [ 'auth_form_places', ] - for f in fields: - setattr(self.host, f, form.get_widget(f).parse()) - self.host.auth_form_url = self.host.auth_url - - if self.host.auth_form_places == 'form_everywhere' and self.host.auth_form_action: - self.generate_apache_filter() - else: - if hasattr(self.host, 'apache_output_python_filters'): - del self.host.apache_output_python_filters - - # Add mod proxy html - # TODO: add an option somewhere to disable it - if not hasattr(self.host, 'apache_output_filters'): - self.host.apache_output_filters = [] - if 'proxy-html' not in self.host.apache_output_filters: - self.host.apache_output_filters.append('proxy-html') - - self.host.store() - write_apache2_vhosts() - - def metadatas [html] (self): - form = Form(enctype='multipart/form-data') - form.add_submit('cancel', _('Previous')) - form.add_submit('submit', _('Next')) - - if form.get_widget('cancel').parse(): - return redirect('sso_init_link') - - if form.is_submitted(): - return redirect('check_full_configuration') - - html_top('step8', title=_('Step 8 - Configure the site metadatas on your identity provider')) - '

%s

' % _('Step 8 - Configure the site metadatas on your identity provider') - - '

' - htmltext(_('''Download the metadatas and the public key for this site and -upload them on your identity provider in order to use Liberty Alliance features''')) - '

' - - '
' - if hasattr(self.host, str('base_url')): - if lasso.SAML2_SUPPORT: - saml2_metadata_url = '%s/metadata.xml' % self.host.saml2_base_url - '
%s
%s
' % ( - saml2_metadata_url, - _('Service Provider SAML 2.0 Metadata'), - _('Download Service Provider SAML 2.0 Metadata file')) - metadata_url = '%s/metadata.xml' % self.host.base_url - '
%s
%s
' % ( - metadata_url, - _('Service Provider Metadata'), - _('Download Service Provider ID-FF 1.2 Metadata file')) - else: - '

%s

' % _('No metadata has been generated for this host.') - - if hasattr(self.host, str('base_url')) and self.host.public_key and os.path.exists(self.host.public_key): - public_key_url = '%s/public_key' % self.host.base_url - '
%s
%s
' % ( - public_key_url, - _('Public key'), - _('Download Service Provider SSL Public Key file')) - else: - '

%s

' % _('No public key has been generated for this host.') - '
' - - form.render() - - def check_full_configuration [html] (self): - form = Form(enctype='multipart/form-data') - form.add_submit('cancel', _('Previous')) - form.add_submit('submit', _('Finish')) - - if form.get_widget('cancel').parse(): - return redirect('metadatas') - - if form.is_submitted(): - return redirect('../..') - - html_top('step9', title=_('Step 9 - Check everything works')) - '

%s

' % _('Step 9 - Check everything works') - - '

' - htmltext(_('''Now you can fully test your site, start from the home page, initiate a Single Sign On, -federate your identities and do a Single Logout.''')) - '

' - - '

' - htmltext(_('The address of your site is : ')) - '%s' % (self.host.new_url, self.host.new_url) - '

' - - '

' - htmltext(_('''If everything works, click the "%(finish)s" button, otherwise you can go back and -check your settings or configure some advanced options.''')) % { 'finish': _('Finish') } - '

' - - form.render() - - def advanced_options [html] (self): - form = self.form_advanced_options() - - if form.get_widget('cancel').parse(): - return redirect('check_full_configuration') - - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append( ('advanced_options', _('Advanced options')) ) - html_top('hosts', title = _('Advanced options')) - '

%s

' % _('Advanced options') - form.render() - else: - self.submit_advanced_options_form(form) - return redirect('check_full_configuration') - - def form_advanced_options(self): - form = Form(enctype='multipart/form-data') - form.add(UrlOrAbsPathWidget, 'initiate_sso_url', title = _('URL which must initiate the SSO'), - hint = _('''Address which must initiate the SSO. If empty, defaults to the previously -specified "%s"''') % _('Authentication form page address'), - required = False, size = 50, value = self.host.initiate_sso_url) - form.add(CheckboxWidget, 'redirect_root_to_login', - title=_('Redirect the root URL of the site to the login page.'), - value = self.host.redirect_root_to_login) - form.add(UrlOrAbsPathWidget, 'return_url', title = _('Return address'), - hint = _('Where the user will be redirected after a successful authentication'), - required = False, size = 50, value = self.host.return_url) - form.add(UrlOrAbsPathWidget, 'root_url', title = _('Error address'), - hint = _('Where the user will be redirected after a disconnection or an error'), - required = False, size = 50, value = self.host.root_url) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_advanced_options_form(self, form): - old_redirect_root_to_login = self.host.redirect_root_to_login - - for f in ('initiate_sso_url', 'redirect_root_to_login', 'return_url', 'root_url'): - value = form.get_widget(f).parse() - setattr(self.host, f, value) - - self.host.store() - - if self.host.initiate_sso_url or self.host.redirect_root_to_login is not old_redirect_root_to_login: - write_apache2_vhosts() - - def auto_detect_configuration(self): -# """Guess other SP parameters""" -# if self.host.auth_url is not None: -# # Separate auth page -# self.host.auth_form_url = self.host.auth_url -# else: -# if self.host.auth_form_page_url is not None: -# # Auth form is not on index page -# self.host.auth_form_url = self.host.auth_form_page_url -# else: -# # Auth form is on index page -# self.host.auth_form_url = self.host.orig_site - - # Reset previous detected values - self.host.auth_form = None - self.host.auth_check_url = None - self.host.login_field_name = None - self.host.password_field_name = None - if not self.host.post_parameters: - self.host.post_parameters = {} - - self.parse_page(self.host.auth_form_url) - - def parse_page(self, page_url): - # Get the authentication page - try: - response, status, page, auth_header = http_get_page(page_url, use_proxy=self.host.use_proxy) - except Exception, msg: - print msg - return - - # Check if this site uses HTTP authentication -# if status == 401: -# if auth_header.startswith('Basic'): -# self.host.auth_mode = 'http_basic' -# else: -# self.host.auth_mode = 'unsupported' -# self.host.store() -# return - - if page is None: - return - #raise FormError, ('auth_check_url', '%s : %s' % (_('Failed to get page'), self.host.auth_form_url)) - - # Default authentication mode - self.host.auth_mode = 'form' - - self.host.site_authentication_plugin = site_authentication.guess_site_authentication_class(page) - self.parse_frames(page) - self.parse_forms(page) - if self.host.auth_form is not None: - self.parse_form_action() - input_fields = self.parse_input_fields() - self.parse_login_field(input_fields) - self.parse_password_field(input_fields) - self.parse_select_fields(input_fields) - self.parse_other_fields(input_fields) - - def parse_frames(self, page): - '''If there are frames, parse them recursively''' - regexp = re.compile("""]*?>""", re.DOTALL | re.IGNORECASE) - found_frames = regexp.findall(page) - if found_frames: - for frame_url in found_frames: - if frame_url.startswith('http'): - frame_full_url = frame_url - else: - page_url_tokens = page_url.split('/') - page_url_tokens[-1] = frame_url - frame_full_url = '/'.join(page_url_tokens) - self.parse_page(frame_full_url) - - def parse_forms(self, page): - '''Search for an authentication form''' - # Get all forms - regexp = re.compile("""""", re.DOTALL | re.IGNORECASE) - found_forms = regexp.findall(page) - if not found_forms: - return - #raise FormError, ('auth_check_url', '%s : %s' % (_('Failed to find any form'), self.host.auth_form_url)) - - # Get the first form with a password field - for found_form in found_forms: - regexp = re.compile("""]*?type=["']?password["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - if regexp.search(found_form) is not None: - self.host.auth_form = found_form - break - - def parse_form_action(self): - '''Get the action url of the form''' - regexp = re.compile("""].*?>""", re.DOTALL | re.IGNORECASE) - self.host.auth_form_action = regexp.findall(self.host.auth_form)[0] - # FIXME: Find a Python module which unescapes html entities - self.host.auth_check_url = self.host.auth_form_action.replace('&', '&') - if not self.host.auth_check_url.startswith('http'): - if self.host.auth_check_url.startswith('/'): - if self.host.orig_site.startswith('https'): - orig_site_root = 'https://%s' % urllib.splithost(self.host.orig_site[6:])[0] - else: - orig_site_root = 'http://%s' % urllib.splithost(self.host.orig_site[5:])[0] - self.host.auth_check_url = orig_site_root + self.host.auth_check_url - else: - auth_form_url_tokens = self.host.auth_form_url.split('/') - auth_form_url_tokens[-1] = self.host.auth_check_url - self.host.auth_check_url = '/'.join(auth_form_url_tokens) - - def parse_input_fields(self): - '''Get all input fields''' - regexp = re.compile("""]*?>""", re.DOTALL | re.IGNORECASE) - return regexp.findall(self.host.auth_form) - - def parse_login_field(self, input_fields): - '''Get login field name''' - try: - regexp = re.compile("""]*?type=["']?text["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - text_fields = regexp.findall(self.host.auth_form) - login_field = '' - if text_fields: - login_field = text_fields[0] - else: - for field in input_fields: - if re.search("""type=["']?""", field, re.DOTALL | re.IGNORECASE) is None: - login_field = field - break - regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - self.host.login_field_name = regexp.findall(login_field)[0] - if not self.host.post_parameters.has_key(self.host.login_field_name): - self.host.post_parameters[self.host.login_field_name] = \ - { 'enabled': True, 'value': _('(filled by users)'), 'immutable': True } - self.host.store() - except IndexError, e: - self.host.login_field_name = None - print 'Error handling login field : %s' % e - - def parse_password_field(self, input_fields): - '''Get password field name''' - try: - regexp = re.compile("""]*?type=["']?password["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - password_field = regexp.findall(self.host.auth_form)[0] - regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - self.host.password_field_name = regexp.findall(password_field)[0] - if not self.host.post_parameters.has_key(self.host.password_field_name): - self.host.post_parameters[self.host.password_field_name] = \ - { 'enabled': True, 'value': _('(filled by users)'), 'immutable': True } - except IndexError, e: - self.host.password_field_name = None - print 'Error handling password field : %s' % e - - def parse_select_fields(self, input_fields): - '''Add select fields to host attributes''' - # First added for Imuse (Rennes) - regexp = re.compile("""""", re.DOTALL | re.IGNORECASE) - self.host.select_fields = {} - for field in regexp.findall(self.host.auth_form): - try: - regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - name = regexp.findall(field)[0] - regexp = re.compile("""]*?>.*?""", re.DOTALL | re.IGNORECASE) - options = regexp.findall(field) - values = [] - for option in options: - regexp = re.compile("""]*?>(.*?)""", re.DOTALL | re.IGNORECASE) - option_label = regexp.findall(option) - regexp = re.compile("""value=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - option_value = regexp.findall(option) - if option_label: - if not option_value: - option_value = option_label - values.append((option_value[0], option_label[0])) - else: - print >> sys.stderr, 'W: Could not parse select options' - self.host.select_fields[name] = values - if not self.host.post_parameters.has_key(name): - self.host.post_parameters[name] = \ - { 'enabled': True, 'value': _('(filled by users)'), 'immutable': True } - except IndexError, e: - continue - - def parse_other_fields(self, input_fields): - '''Get the default value of all other fields''' - self.host.other_fields = {} - - # Get hidden fields - regexp = re.compile("""]*?type=["']?hidden["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - other_fields = regexp.findall(self.host.auth_form) - - # Only get first submit field - regexp = re.compile("""]*?type=["']?submit["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - found = regexp.findall(self.host.auth_form) - if found: - if other_fields: - other_fields.append(found[0]) - else: - other_fields = found[0] - - for field in other_fields: - try: - regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - name = regexp.findall(field)[0] - regexp = re.compile("""value=["'](.*?)["'][\s/>]""", re.DOTALL | re.IGNORECASE) - value = regexp.findall(field)[0] - self.host.other_fields[name] = value - if not self.host.post_parameters.has_key(name): - self.host.post_parameters[name] = { 'enabled': True, 'value': value, 'immutable': False } - except IndexError, e: - continue - - -class HostUI: - def __init__(self, host): - self.host = host - - def form_edit(self): - # FIXME : homogeneise the size of the fields - form = Form(enctype='multipart/form-data') - form.add(StringWidget, 'label', title = _('Site name'), required = True, - size = 30, value = self.host.label) - form.add(UrlWidget, 'orig_site', title = _('Original site root address'), required = True, - size = 50, value = self.host.orig_site) - form.add(ValidUrlWidget, 'auth_url', title = _('Authentication page'), - hint = _('If there is a separate authentication page'), - required = False, size = 70, value = self.host.auth_url) - form.add(ValidUrlWidget, 'auth_form_page_url', - title = _('Authentication form page'), - hint = _('If the authentication form is not in a separate page and not in the index page either'), - required = False, size = 70, value = self.host.auth_form_page_url) - form.add(ValidUrlWidget, 'logout_url', title = _('Logout address'), required = False, - size = 70, value = self.host.logout_url) - form.add(StringWidget, 'reversed_hostname', title = _('Reversed host name'), - size = 30, required = True, value = self.host.reversed_hostname) - form.add(StringWidget, 'reversed_directory', title = _('Reversed directory'), - size = 30, required = False, value = self.host.reversed_directory) - form.add(CheckboxWidget, 'use_ssl', title = _('Use SSL'), - hint = _('This only affects the connection between the browser and Larpe'), - value = self.host.use_ssl) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_edit_form(self, form): - metadata_cfg = {} - for f in ('label', 'orig_site', 'auth_url', 'auth_form_page_url', 'logout_url', 'reversed_hostname', - 'reversed_directory', 'use_ssl'): - widget = form.get_widget(f) - setattr(self.host, f, widget.parse()) - # Get the special use_proxy attribute if it exists - if hasattr(widget, 'use_proxy'): - self.host.use_proxy = widget.use_proxy - - self.host.organization_name = self.host.label - metadata_cfg['organization_name'] = self.host.organization_name - - # Build host name from host label - self.host.name = self.host.label.lower() - invalid_characters = [' ', "'"] - for char in invalid_characters: - self.host.name = self.host.name.replace(char, '_') - - # Set url scheme (ie protocol) according to SSL usage - if self.host.use_ssl: - self.host.scheme = 'https' - else: - self.host.scheme = 'http' - - # Liberty Alliance / SAML parameters - base_url = '%s://%s%s/liberty/%s/liberty' % (self.host.scheme, - self.host.reversed_hostname, - get_request().environ['SCRIPT_NAME'], - self.host.name) - metadata_cfg['base_url'] = base_url - self.host.base_url = base_url - - if lasso.SAML2_SUPPORT: - saml2_base_url = '%s://%s%s/liberty/%s/saml' % (self.host.scheme, - self.host.reversed_hostname, - get_request().environ['SCRIPT_NAME'], - self.host.name) - metadata_cfg['saml2_base_url'] = saml2_base_url - self.host.saml2_base_url = saml2_base_url - - provider_id = '%s/metadata' % base_url - metadata_cfg['provider_id'] = provider_id - self.host.provider_id = provider_id - - if lasso.SAML2_SUPPORT: - saml2_provider_id = '%s/metadata' % saml2_base_url - metadata_cfg['saml2_provider_id'] = saml2_provider_id - self.host.saml2_provider_id = saml2_provider_id - - # Storage directories - if self.host.reversed_directory is None: - reversed_dir = 'default' - else: - reversed_dir = self.host.reversed_directory - site_dir = os.path.join(get_publisher().app_dir, 'sp', - self.host.reversed_hostname, reversed_dir) - user_dir = os.path.join(site_dir, 'users') - token_dir = os.path.join(site_dir, 'tokens') - for dir in (site_dir, user_dir, token_dir): - if not os.path.isdir(dir): - os.makedirs(dir) - metadata_cfg['site_dir'] = site_dir - self.host.site_dir = site_dir - - # Tweaking for larpe vhosts - hostname_dir = get_abs_path(os.path.join('..', self.host.reversed_hostname)) - if not os.path.exists(hostname_dir): - os.mkdir(hostname_dir) - # Load the configuration from the main directory - get_publisher().reload_cfg() - get_publisher().write_cfg(hostname_dir) - - # Generate SSL keys - private_key_path = os.path.join(site_dir, 'private_key.pem') - public_key_path = os.path.join(site_dir, 'public_key.pem') - if not os.path.isfile(private_key_path) or not os.path.isfile(public_key_path): - set_provider_keys(private_key_path, public_key_path) - self.host.private_key = private_key_path - self.host.public_key = public_key_path - - # Read public key - public_key = '' - if self.host.public_key is not None and os.path.exists(self.host.public_key): - metadata_cfg['signing_public_key'] = open(self.host.public_key).read() - - # Write metadatas - metadata_path = os.path.join(site_dir, 'metadata.xml') - open(metadata_path, 'w').write(get_metadata(metadata_cfg)) - self.host.metadata = metadata_path - - if lasso.SAML2_SUPPORT: - saml2_metadata_path = os.path.join(site_dir, 'saml2_metadata.xml') - open(saml2_metadata_path, 'w').write(get_saml2_metadata(metadata_cfg)) - self.host.saml2_metadata = saml2_metadata_path - - # Use default idps -# idp_dir = os.path.join(get_publisher().app_dir, 'idp') -# self.host.idps = os.listdir(idp_dir) - - self.host.store() - - for attr in ('auth_check_url', 'login_field_name', 'password_field_name'): - if not hasattr(self.host, attr) or not getattr(self.host, attr): - self.auto_detect_configuration() - break - - write_apache2_vhosts() - - def auto_detect_configuration(self): - """Guess other SP parameters""" - if self.host.auth_url is not None: - # Separate auth page - self.host.auth_form_url = self.host.auth_url - else: - if self.host.auth_form_page_url is not None: - # Auth form is not on index page - self.host.auth_form_url = self.host.auth_form_page_url - else: - # Auth form is on index page - self.host.auth_form_url = self.host.orig_site - - # Reset previous detected values - self.host.auth_form = None - self.host.auth_check_url = None - self.host.login_field_name = None - self.host.password_field_name = None - self.host.store() - - self.parse_page(self.host.auth_form_url) - - def parse_page(self, page_url): - # Get the authentication page - try: - response, status, page, auth_header = http_get_page(page_url, use_proxy=self.host.use_proxy) - except Exception, msg: - print msg - return - - # Check if this site uses HTTP authentication - if status == 401: - if auth_header.startswith('Basic'): - self.host.auth_mode = 'http_basic' - else: - self.host.auth_mode = 'unsupported' - self.host.store() - return - - if page is None: - return - #raise FormError, ('auth_check_url', '%s : %s' % (_('Failed to get page'), self.host.auth_form_url)) - - self.host.site_authentication_plugin = site_authentication.guess_site_authentication_class(page) - - # If there are frames, parse them recursively - regexp = re.compile("""]*?>""", re.DOTALL | re.IGNORECASE) - found_frames = regexp.findall(page) - if found_frames: - for frame_url in found_frames: - if frame_url.startswith('http'): - frame_full_url = frame_url - else: - page_url_tokens = page_url.split('/') - page_url_tokens[-1] = frame_url - frame_full_url = '/'.join(page_url_tokens) - self.parse_page(frame_full_url) - - # Default authentication mode - self.host.auth_mode = 'form' - - # Get all forms - regexp = re.compile("""""", re.DOTALL | re.IGNORECASE) - found_forms = regexp.findall(page) - if not found_forms: - return - #raise FormError, ('auth_check_url', '%s : %s' % (_('Failed to find any form'), self.host.auth_form_url)) - - # Get the first form with a password field - found = False - for found_form in found_forms: - regexp = re.compile("""]*?type=["']?password["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - if regexp.search(found_form) is not None: - self.host.auth_form = found_form - found = True - break - - if not found: - return - #raise FormError, ('auth_check_url', _('Failed to find the authentication form')) - - # If we found a form, search for all needed information - - # Get the action url of the form - regexp = re.compile("""].*?>""", re.DOTALL | re.IGNORECASE) - self.host.auth_check_url = regexp.findall(self.host.auth_form)[0] - # FIXME : Find a module which unescapes html entities - self.host.auth_check_url = self.host.auth_check_url.replace('&', '&') - if not self.host.auth_check_url.startswith('http'): - if self.host.auth_check_url.startswith('/'): - if self.host.orig_site.startswith('https'): - orig_site_root = 'https://%s' % urllib.splithost(self.host.orig_site[6:])[0] - else: - orig_site_root = 'http://%s' % urllib.splithost(self.host.orig_site[5:])[0] - self.host.auth_check_url = orig_site_root + self.host.auth_check_url - else: - auth_form_url_tokens = self.host.auth_form_url.split('/') - auth_form_url_tokens[-1] = self.host.auth_check_url - self.host.auth_check_url = '/'.join(auth_form_url_tokens) - - # Get all inputs - regexp = re.compile("""]*?>""", re.DOTALL | re.IGNORECASE) - inputs = regexp.findall(self.host.auth_form) - - # Get login field name - try: - regexp = re.compile("""]*?type=["']?text["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - text_fields = regexp.findall(self.host.auth_form) - login_field = '' - if text_fields: - login_field = text_fields[0] - else: - for field in inputs: - if re.search("""type=["']?""", field, re.DOTALL | re.IGNORECASE) is None: - login_field = field - break - regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - self.host.login_field_name = regexp.findall(login_field)[0] - except IndexError, e: - self.host.login_field_name = None - print 'Error handling login field : %s' % e - - # Get password field name - try: - regexp = re.compile("""]*?type=["']?password["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - password_field = regexp.findall(self.host.auth_form)[0] - regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - self.host.password_field_name = regexp.findall(password_field)[0] - except IndexError, e: - self.host.password_field_name = None - print 'Error handling password field : %s' % e - - # Get the default value of all other fields - self.host.other_fields = {} - - # Get hidden and submit fields - regexp = re.compile("""]*?type=["']?(?:hidden|submit)["']?[^>]*?>""", re.DOTALL | re.IGNORECASE) - other_fields = regexp.findall(self.host.auth_form) - for field in other_fields: - try: - regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - name = regexp.findall(field)[0] - regexp = re.compile("""value=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - value = regexp.findall(field)[0] - self.host.other_fields[name] = value - except IndexError, e: - continue - - # Add select fields to host attributes - # First added for Imuse (Rennes) - regexp = re.compile("""""", re.DOTALL | re.IGNORECASE) - self.host.select_fields = {} - for field in regexp.findall(page): - try: - regexp = re.compile("""name=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - name = regexp.findall(field)[0] - regexp = re.compile("""]*?>.*?""", re.DOTALL | re.IGNORECASE) - options = regexp.findall(field) - values = [] - for option in options: - regexp = re.compile("""value=["']?(.*?)["']?[\s/>]""", re.DOTALL | re.IGNORECASE) - option_value = regexp.findall(option) - regexp = re.compile("""]*?>(.*?)""", re.DOTALL | re.IGNORECASE) - option_label = regexp.findall(option) - if option_value and option_label: - values.append((option_value[0], option_label[0])) - self.host.select_fields[name] = values - except IndexError, e: - continue - -# print 'action : %s' % self.host.auth_check_url -# print 'login field : %s' % self.host.login_field_name -# print 'password field : %s' % self.host.password_field_name -# print 'other fields : %s' % self.host.other_fields - - self.host.store() - - def form_auto_detected_configuration(self): - form = Form(enctype='multipart/form-data') - form.add(RadiobuttonsWidget, 'auth_mode', title = _('Authentication mode'), - options=[ - ('form', _('Form'), 'form'), - ('http_basic', _('HTTP Basic'), 'http_basic'), - ], - sort=False, - required = True, - value = self.host.auth_mode) - form.add(ValidUrlWidget, 'auth_check_url', title = _('Address where the authentication form must be sent'), - required = False, size = 70, value = self.host.auth_check_url) - form.add(StringWidget, 'login_field_name', title = _('Name of the login field'), - required = False, size = 30, value = self.host.login_field_name) - form.add(StringWidget, 'password_field_name', title = _('Name of the password field'), - required = False, size = 30, value = self.host.password_field_name) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_auto_detected_configuration_form(self, form): - for f in ('auth_mode', 'auth_check_url', 'login_field_name', 'password_field_name'): - value = form.get_widget(f).parse() - setattr(self.host, f, value) - - # Ensure auth_check_url is a full url - if 'auth_mode' == 'form': - if not self.host.auth_check_url.startswith('http'): - if self.host.auth_check_url.startswith('/'): - if self.host.orig_site.endswith('/'): - self.host.auth_check_url = self.host.orig_site + self.host.auth_check_url[1:] - else: - self.host.auth_check_url = self.host.orig_site + self.host.auth_check_url - else: - auth_form_url_tokens = self.host.auth_form_url.split('/') - auth_form_url_tokens[-1] = self.host.auth_check_url - self.host.auth_check_url = '/'.join(auth_form_url_tokens) - - self.host.store() - - def form_advanced_configuration(self): - form = Form(enctype='multipart/form-data') - form.add(UrlOrAbsPathWidget, 'return_url', title = _('Return address'), - hint = _('Where the user will be redirected after a successful authentication'), - required = False, size = 50, value = self.host.return_url) - form.add(UrlOrAbsPathWidget, 'root_url', title = _('Error address'), - hint = _('Where the user will be redirected after a disconnection or an error'), - required = False, size = 50, value = self.host.root_url) - form.add(CheckboxWidget, 'redirect_root_to_login', - title=_('Redirect the root url of the site to the login page.'), - value = self.host.redirect_root_to_login) - form.add(CheckboxWidget, 'send_hidden_fields', title=_('Send authentication form hidden fields'), - value = self.host.send_hidden_fields) - form.add(RadiobuttonsWidget, 'auth_system', title = _('Authentication system of the original site'), - options=[ - ('password', _('Check the existence of a password field'), 'password'), - ('match_text', _('Match some text to detect an authentication failure'), 'match_text'), - ], - sort=False, - delim=htmltext('
'), - value = self.host.auth_system) - form.add(RegexStringWidget, 'auth_match_text', title = _('Text to match in case of authentication failure'), - required = False, size = 50, value = self.host.auth_match_text) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_advanced_configuration_form(self, form): - old_redirect_root_to_login = self.host.redirect_root_to_login - - for f in ('return_url', 'root_url', 'redirect_root_to_login', 'send_hidden_fields', 'auth_system', 'auth_match_text'): - value = form.get_widget(f).parse() - setattr(self.host, f, value) - - self.host.store() - - if self.host.redirect_root_to_login is not old_redirect_root_to_login: - write_apache2_vhosts() - - def form_apache_filters(self): - form = Form(enctype='multipart/form-data') - if not hasattr(self.host, 'apache_output_filters'): - self.host.apache_output_filters = [ 'proxy-html' ] - self.host.store() - form.add(CheckboxWidget, 'proxy-html', title = _('HTML proxy'), - hint = _('Converts urls in the html pages according to the host new domain name'), - value = 'proxy-html' in self.host.apache_output_filters) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_apache_filters_form(self, form): - f = 'proxy-html' - value = form.get_widget(f).parse() - if value is True and f not in self.host.apache_output_filters: - self.host.apache_output_filters.append(f) - if value is False and f in self.host.apache_output_filters: - self.host.apache_output_filters.remove(f) - self.host.store() - write_apache2_vhosts() - -class HostPage(Directory): - _q_exports = ['', 'minimal_configuration', 'auto_detect_configuration', 'auto_detected_configuration', 'advanced_configuration', 'apache_filters', 'see_current_configuration', 'delete'] - - def __init__(self, host_id): - self.host = Host.get(host_id) - self.host_ui = HostUI(self.host) - get_response().breadcrumb.append((host_id + '/', self.host.label)) - - def _q_lookup(self, component): - if component == 'configuration_assistant': - return ConfigurationAssistant(self.host) - elif component == 'forms_prefill': - return FormsDirectory(self.host) - - def _q_index [html] (self): - get_publisher().reload_cfg() - html_top('hosts', title = self.host.label) - - '

%s

' % _('Reverse Proxy') - - '
' - '
%s
%s
' % ( - _('Minimal Configuration'), _('Configure the minimum parameters to set up a reverse proxy for this site')) - '
%s
%s
' % ( - _('Auto Detected Configuration'), _('Check the auto detected parameters and change them if necessary')) - '
%s
%s
' % ( - _('Advanced Configuration'), _("Configure advanced parameters if it doesn't work with minimal configuration")) - '
%s
%s
' % ( - _('Apache filters'), _('Select what apache filters to use')) - '
%s
%s
' % ( - _('See Current Configuration'), _('See the current configuration of this host')) - '
' - - if lasso.SAML2_SUPPORT: - '

Liberty Alliance & SAML 2.0

' - else: - '

Liberty Alliance

' - - '
' - if hasattr(self.host, str('base_url')): - if lasso.SAML2_SUPPORT: - saml2_metadata_url = '%s/metadata.xml' % self.host.saml2_base_url - '
%s
%s
' % ( - saml2_metadata_url, - _('Service Provider SAML 2.0 Metadata'), - _('Download Service Provider SAML 2.0 Metadata file')) - metadata_url = '%s/metadata.xml' % self.host.base_url - '
%s
%s
' % ( - metadata_url, - _('Service Provider ID-FF 1.2 Metadata'), - _('Download Service Provider ID-FF 1.2 Metadata file')) - else: - '

%s

' % _('No metadata has been generated for this host.') - - if hasattr(self.host, str('base_url')) and self.host.public_key and os.path.exists(self.host.public_key): - public_key_url = '%s/public_key' % self.host.base_url - '
%s
%s
' % ( - public_key_url, - _('Public key'), - _('Download Service Provider SSL Public Key file')) - else: - '

%s

' % _('No public key has been generated for this host.') - '
' - - '

%s

' % _('Form prefilling with ID-WSF') - - '
' - '
%s
%s
' % ( - _('Forms'), _('Configure the forms to prefill')) - '
' - - def minimal_configuration [html] (self): - form = self.host_ui.form_edit() - if form.get_widget('cancel').parse(): - return redirect('.') - - if form.is_submitted() and not form.has_errors(): - check_minimal_configuration(form) - - if form.is_submitted() and not form.has_errors(): - self.host_ui.submit_edit_form(form) - return redirect('see_current_configuration') - - get_response().breadcrumb.append( ('minimal_configuration', _('Edit')) ) - html_top('hosts', title = _('Edit Host')) - '

%s

' % _('Edit Host') - - form.render() - - def auto_detect_configuration (self): - self.host_ui.auto_detect_configuration() - return redirect('auto_detected_configuration') - - def auto_detected_configuration [html] (self, detect=False): - form = self.host_ui.form_auto_detected_configuration() - if form.get_widget('cancel').parse(): - return redirect('.') - - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append( ('auto_detected_configuration', _('Auto Detected Configuration')) ) - html_top('hosts', title = _('Auto Detected Configuration')) - '

%s

' % _('Auto Detected Configuration') - '
%s

' \ - % (_('Auto detect'), _('Warning, this will erase your custom modifications !')) - form.render() - else: - self.host_ui.submit_auto_detected_configuration_form(form) - return redirect('see_current_configuration') - - def advanced_configuration [html] (self): - form = self.host_ui.form_advanced_configuration() - if form.get_widget('cancel').parse(): - return redirect('.') - - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append( ('advanced_configuration', _('Advanced Configuration')) ) - html_top('hosts', title = _('Advanced Configuration')) - '

%s

' % _('Advanced Configuration') - form.render() - else: - self.host_ui.submit_advanced_configuration_form(form) - return redirect('see_current_configuration') - - def apache_filters [html] (self): - form = self.host_ui.form_apache_filters() - if form.get_widget('cancel').parse(): - return redirect('.') - - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append( ('apache_filters', _('Apache filters')) ) - html_top('hosts', title = _('Apache filters')) - '

%s

' % _('Apache filters') - form.render() - else: - self.host_ui.submit_apache_filters_form(form) - return redirect('see_current_configuration') - - def see_current_configuration [html] (self): - get_response().breadcrumb.append( ('see_current_configuration', _('See Current Configuration')) ) - html_top('hosts', title = _('Current Host Configuration')) - '

%s

' % _('Current Host Configuration') - - for attr in ('auth_check_url', 'login_field_name', 'password_field_name'): - if not getattr(self.host, str(attr)): - '
%s
' % _("This site is not fully configured yet. \ -The following red fields don't have a correct value.") - break - - # New url for this host - url = '%s://%s%s/' % (self.host.scheme, self.host.reversed_hostname, get_request().environ['SCRIPT_NAME']) - if self.host.reversed_directory is not None: - url += '%s/' % self.host.reversed_directory - '
%s
' % _('New url for this host') - '' % (url, url) - - get_publisher().reload_cfg() - if get_cfg('use_proxy'): - '
%s
' % _('Use proxy') - '
%s
' % self.host.use_proxy - - host_attrs_minimal = ( - ('label', _('Site name')), - ('orig_site', _('Original site root address')), - ('auth_url', _('Authentication page')), - ('auth_form_page_url', _('Authentication form page')), - ('logout_url', _('Logout address')), - ('reversed_hostname', _('Reversed host name')), - ('reversed_directory', _('Reversed directory')), - ('use_ssl', _('Use SSL')) - ) - host_attrs_auto = ( - ('auth_mode', _('Authentication mode')), - ('auth_check_url', _('Address where the authentication form must be sent')), - ('login_field_name', _('Name of the login field')), - ('password_field_name', _('Name of the password field')), - ('site_authentication_plugin', _('Plugin used for site specific authentication behaviour')) - ) - host_attrs_advanced = ( - ('return_url', _('Return address')), - ('root_url', _('Root address')), - ('redirect_root_to_login', _('Redirect the root url of the site to the login page.')), - ('auth_system', _('Authentication system of the original site')), - ('auth_match_text', _('Text to match in case of authentication failure')), - ('send_hidden_fields', _('Send authentication form hidden fields')) - ) - host_menus = ( - (host_attrs_minimal, '%s' % _('Minimal Configuration')), - (host_attrs_auto, '%s' % _('Auto Detected Configuration')), - (host_attrs_advanced, '%s' % _('Advanced Configuration')), - ) - for host_attrs, category in host_menus: - '

%s

' % category - for attr, name in host_attrs: - color = 'black' - if attr in ('auth_check_url', 'login_field_name', 'password_field_name') and \ - not getattr(self.host, str(attr)): - color = 'red' - '
%s
' % (color, name) - '
%s
' % \ - (color, getattr(self.host, str(attr))) - if getattr(self.host, str(attr)) == '': - '
' - '

' % _('Back') - - def delete [html] (self): - form = Form(enctype='multipart/form-data') - form.widgets.append(HtmlWidget('

%s

' % _( - 'You are about to irrevocably delete this host.'))) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - if form.get_widget('cancel').parse(): - return redirect('..') - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append(('delete', _('Delete'))) - html_top('hosts', title = _('Delete Host')) - '

%s : %s

' % (_('Delete Host'), self.host.label) - form.render() - else: - self.host.remove_self() - write_apache2_vhosts() - return redirect('..') - - -class HostsDirectory(Directory): - _q_exports = ['', 'new'] - - def _q_index [html] (self): - get_response().breadcrumb.append(('hosts/', _('Hosts'))) - html_top('hosts', title = _('Hosts')) - """""" % _('New Host') - - '
    ' - - for host in Host.select(lambda x: x.name != 'larpe', order_by = 'label'): - if not host.name: - continue - if not hasattr(host, str('scheme')): - host.scheme = str('http') - '
  • ' - '%s' % host.label - if hasattr(host, str('new_url')) and host.new_url: - url = host.new_url - else: - # Compat with older Larpe versions - url = '%s://%s%s/' % (host.scheme, host.reversed_hostname, get_request().environ['SCRIPT_NAME']) - if host.reversed_directory is not None: - url += '%s/' % host.reversed_directory - '
    %s' % (url, url) - '

    ' - command_icon('%s/' % host.id, 'edit') - command_icon('%s/delete' % host.id, 'remove') - '

  • ' - '
' - - def new [html] (self): - if not os.path.isdir(os.path.join(get_publisher().app_dir, str('idp'))): - html_top('hosts', title = _('New Host')) - html = '

%s

' % _('New Host') - html += 'You must ' % misc.get_root_url() - html += 'configure an Identity Provider first

' - html += '' % _('Back') - return html - - get_response().breadcrumb.append(('hosts/', _('Hosts'))) - get_response().breadcrumb.append(('new', _('New')) ) - host = Host() - host.store() -# configuration_assistant = ConfigurationAssistant(host) - return redirect('%s/configuration_assistant/start' % host.id) - - def _q_lookup(self, component): - get_response().breadcrumb.append(('hosts/', _('Hosts'))) - return HostPage(component) - diff --git a/larpe/branches/idwsf/larpe/admin/liberty_utils.py b/larpe/branches/idwsf/larpe/admin/liberty_utils.py deleted file mode 100644 index 758dc0c..0000000 --- a/larpe/branches/idwsf/larpe/admin/liberty_utils.py +++ /dev/null @@ -1,129 +0,0 @@ -import os - -def set_provider_keys(private_key_path, public_key_path): - # use system calls for openssl since PyOpenSSL doesn't expose the - # necessary functions. - if os.system('openssl version > /dev/null 2>&1') == 0: - os.system('openssl genrsa -out %s 2048' % private_key_path) - os.system('openssl rsa -in %s -pubout -out %s' % (private_key_path, public_key_path)) - - -def get_metadata(cfg): - prologue = """\ - -""" % cfg - - sp_head = """ - """ - - signing_public_key = '' - if cfg.has_key('signing_public_key') and cfg['signing_public_key']: - if 'CERTIF' in cfg['signing_public_key']: - signing_public_key = """ - - - %s - - """ % cfg['signing_public_key'] - elif 'KEY' in cfg['signing_public_key']: - signing_public_key = """ - - - %s - - """ % cfg['signing_public_key'] - - sp_body = """ - %(base_url)s/assertionConsumer - - %(base_url)s/soapEndpoint - - %(base_url)s/singleLogout - %(base_url)s/singleLogoutReturn - http://projectliberty.org/profiles/slo-idp-http - http://projectliberty.org/profiles/slo-sp-soap - http://projectliberty.org/profiles/slo-sp-http - - %(base_url)s/federationTermination - %(base_url)s/federationTerminationReturn - http://projectliberty.org/profiles/fedterm-idp-soap - http://projectliberty.org/profiles/fedterm-idp-http - http://projectliberty.org/profiles/fedterm-sp-soap - http://projectliberty.org/profiles/fedterm-sp-http - - true - - """ % cfg - - orga = '' - if cfg.get('organization_name'): - orga = """ - - %s - """ % unicode(cfg['organization_name'], 'iso-8859-1').encode('utf-8') - - epilogue = """ -""" - - return '\n'.join([prologue, sp_head, signing_public_key, sp_body, orga, epilogue]) - - - -def get_saml2_metadata(cfg): - prologue = """\ - -""" % cfg - - sp_head = """ - """ - - signing_public_key = '' - if cfg.has_key('signing_public_key') and cfg['signing_public_key']: - if 'CERTIF' in cfg['signing_public_key']: - signing_public_key = """ - - - %s - - """ % cfg['signing_public_key'] - elif 'KEY' in cfg['signing_public_key']: - signing_public_key = """ - - - %s - - """ % cfg['signing_public_key'] - - sp_body = """ - - - - - """ % cfg - - orga = '' - if cfg.get('organization_name'): - orga = """ - - %s - """ % unicode(cfg['organization_name'], 'iso-8859-1').encode('utf-8') - - epilogue = """ -""" - - return '\n'.join([prologue, sp_head, signing_public_key, sp_body, orga, epilogue]) - diff --git a/larpe/branches/idwsf/larpe/admin/logger.ptl b/larpe/branches/idwsf/larpe/admin/logger.ptl deleted file mode 100644 index ae784df..0000000 --- a/larpe/branches/idwsf/larpe/admin/logger.ptl +++ /dev/null @@ -1,161 +0,0 @@ -import random - -from quixote import get_publisher, get_request, get_response, redirect -from quixote.directory import Directory - -from larpe.qommon.form import * -from larpe.qommon import template - -from qommon import logger -from larpe import misc -from larpe.users import User - -from menu import * - -class ByUserDirectory(Directory): - def _q_lookup(self, component): - return ByUserPages(component) - - -class LoggerDirectory(Directory): - _q_exports = ['', 'download', 'by_user'] - - by_user = ByUserDirectory() - - def _q_index [html] (self): - get_response().breadcrumb.append( ('logger/', _('Logs')) ) - html_top('logger', title = _('Logs')) - request = get_request() - logfile = request.get_field('logfile', 'larpe.log') - if not logfile.startswith(str('larpe.log')) or str('/') in str(logfile): - return template.error_page(_('Bad log file: %s') % logfile) - logfilename = str(os.path.join(get_publisher().app_dir, logfile)) - - if not os.path.exists(logfilename): - _('Nothing to show') - else: - if logfile: - '%s' % (logfile, _('Download Raw Log File')) - else: - '%s' % _('Download Raw Log File') - - user_color_keys = {} - last_date = None - '\n' - '' - ' ' % _('Time') - ' ' % _('User') - ' ' % _('Message') - '\n' - '\n' - for line in open(logfilename): - d = logger.readline(line) - user_color_key = d['user_id'] - if user_color_key == 'anonymous': - user_color_key += d['ip'] - if not user_color_keys.has_key(user_color_key): - user_color_keys[user_color_key] = ''.join( - ['%x' % random.randint(0xc, 0xf) for x in range(3)]) - '' % ( - d['level'].lower(), user_color_keys[user_color_key]) - if (last_date != d['date']): - ' ' % (d['date'], d['hour'][:-4]) - last_date = d['date'] - else: - ' ' % (d['hour'][:-4]) - if d['user_id'] == 'anonymous': - userlabel = _('Anonymous') - ip = d['ip'] - ' ' % (ip, userlabel) - else: - try: - user = User.get(d['user_id']) - except KeyError: - userlabel = _('Unknown') - else: - if user.name is not None: - userlabel = htmltext(user.name.replace(str(' '), str(' '))) - else: - userlabel = _('Unknown') - ' ' % userlabel - ' ' % d['message'] - '\n' - '\n' - '
%s%s%s
%s %s%s%s%s%s
\n' - - logfiles = [x for x in os.listdir(get_publisher().app_dir) if x.startswith(str('larpe.log'))] - if len(logfiles) > 1: - options = [] - for lfile in logfiles: - firstline = open(os.path.join(get_publisher().app_dir, lfile)).readline() - d = logger.readline(firstline) - if not d: - continue - if logfile == lfile: - selected = 'selected="selected" ' - else: - selected = '' - options.append({'selected': selected, 'lfile': lfile, - 'date': '%s %s' % (d['date'], d['hour'])}) - - '
' - _('Select another logfile:') - '' - '' % _('Submit') - - - def download(self): - request = get_request() - logfile = request.get_field('logfile', 'larpe.log') - if not logfile.startswith(str('larpe.log')) or str('/') in logfile: - return template.error_page(_('Bad log file: %s') % logfile) - logfilename = os.path.join(get_publisher().app_dir, logfile) - response = get_response() - response.set_content_type('text/x-log', 'iso-8859-1') - response.set_header('content-disposition', 'attachment; filename=%s' % logfile) - return open(logfilename).read() - - -class ByUserPages(Directory): - _q_exports = [''] - - def __init__(self, component): - try: - self.user = User.get(component) - except KeyError: - raise TraversalError() - - def _q_index [html] (self): - html_top('logger', title = _('Logs')) - '

%s - %s

' % (_('User'), self.user.name) - - last_date = None - '' - '' - ' ' % _('Time') - ' ' % _('Message') - '' - '' - logfile = get_publisher().get_app_logger_filename() - if os.path.exists(logfile): - for line in open(logfile): - d = logger.readline(line) - if d['user_id'] != str(self.user.id): - continue - '' - if (last_date != d['date']): - ' ' % (d['date'], d['hour'][:-4]) - last_date = d['date'] - else: - ' ' % (d['hour'][:-4]) - ' ' % (d['url'], d['message']) - '' - '' - '
%s%s
%s %s%s%s
' - diff --git a/larpe/branches/idwsf/larpe/admin/menu.ptl b/larpe/branches/idwsf/larpe/admin/menu.ptl deleted file mode 100644 index c88a408..0000000 --- a/larpe/branches/idwsf/larpe/admin/menu.ptl +++ /dev/null @@ -1,107 +0,0 @@ -from quixote import get_request, get_response, get_session, get_publisher - -from larpe import storage -from larpe import misc -from larpe.users import User -from larpe.hosts import Host - -items = [ - ('hosts', N_('Hosts')), - ('users', N_('Users')), - ('settings', N_('Settings')), - ('logger', N_('Logs')), - # FIXME : use get_request().environ['SCRIPT_NAME']) ? - ('/', N_('Liberty Alliance Reverse Proxy'))] - -def generate_header_menu [html] (selected = None): - s = ["""\n') - return ''.join(s) - -def generate_user_info [html] (): - hosts = Host.select(lambda x: x.name == 'larpe') - if not hosts: - return - host = hosts[0] - user = get_session().get_user(host.provider_id) - if user and user.name: - logout_url = '%s/liberty/%s/logout' % (get_request().environ['SCRIPT_NAME'], host.name) - """""" % (user.name, logout_url, _('logout')) - - -def html_top [html] (section, title = None, scripts = None): - header_menu = generate_header_menu(section) - user_info = generate_user_info() - subtitle = '' - for s in items: - if s[0] == section: - subtitle = _(s[1]) - if not title: - title = '' - else: - title = ' - ' + title - if not scripts: - scripts = '' - else: - scripts = '\n'.join(['' % x for x in scripts]) - - sitetitle = _('Larpe Administration') -# if title: -# sitetitle += ' - ' - - admin_ezt = True - get_response().filter.update(locals()) - -def error_page [html] (section, error): - html_top(section, title = _('Error')) - '
' - '

%s

' % _('Error') - '

%s

' % error - '
' - -def command_icon [html] (url, type, label = None, icon = None): - script_name = get_request().environ['SCRIPT_NAME'] - icons = { - 'edit': 'stock_edit_16.png', - 'add': 'stock_add_16.png', - 'remove': 'stock_remove_16.png', - 'duplicate': 'stock_copy_16.png', - 'view': 'view_16.png', - } - labels = { - 'add': N_('Add'), - 'edit': N_('Edit'), - 'remove': N_('Remove'), - 'duplicate': N_('Duplicate'), - 'view': N_('View'), - } - if not label: - label = _(labels[str(type)]) - if not icon: - icon = icons[str(type)] - if url: - ''' - %(label)s -''' % locals() - else: - # no url -> image button - ''' - -''' % locals() - diff --git a/larpe/branches/idwsf/larpe/admin/root.ptl b/larpe/branches/idwsf/larpe/admin/root.ptl deleted file mode 100644 index 65ae2df..0000000 --- a/larpe/branches/idwsf/larpe/admin/root.ptl +++ /dev/null @@ -1,76 +0,0 @@ -import os - -from quixote import get_session, get_session_manager, get_publisher, get_request, get_response -from quixote.directory import Directory, AccessControlled - -import hosts -import users -import settings -import logger -from larpe.admin.menu import html_top - -from larpe import errors -from larpe import misc - -def gpl [html] (): - """

This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version.

- -

This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details.

- -

You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 Temple - Place - Suite 330, Boston, MA 02111-1307, USA.

- """ - - -class RootDirectory(AccessControlled, Directory): - _q_exports = ['', 'hosts', 'users', 'settings', 'logger'] - - hosts = hosts.HostsDirectory() - users = users.UsersDirectory() - settings = settings.SettingsDirectory() - logger = logger.LoggerDirectory() - - def _q_access(self): - # FIXME : this block should be moved somewhere else - get_publisher().reload_cfg() - if not get_publisher().cfg.has_key('proxy_hostname'): - get_publisher().cfg['proxy_hostname'] = get_request().get_server().split(':')[0] - get_publisher().write_cfg() - - response = get_response() - if not hasattr(response, 'breadcrumb'): - response.breadcrumb = [ ('../admin/', _('Administration')) ] - - # Cheater - if os.path.exists(os.path.join(get_publisher().app_dir, 'ADMIN_FOR_ALL')): - return - - # No admin user created yet, free access - user_list = users.User.select(lambda x: x.is_admin) - if not user_list: - return - - host_list = hosts.Host.select(lambda x: x.name == 'larpe') - if host_list: - host = host_list[0] - else: - raise errors.AccessForbiddenError() - user = get_session().get_user(host.provider_id) - if user: - if not user.name or not user.is_admin: - raise errors.AccessForbiddenError() - else: - raise errors.AccessUnauthorizedError() - - - def _q_index [html] (self): - html_top('/') - gpl() - diff --git a/larpe/branches/idwsf/larpe/admin/settings.ptl b/larpe/branches/idwsf/larpe/admin/settings.ptl deleted file mode 100644 index 18ba481..0000000 --- a/larpe/branches/idwsf/larpe/admin/settings.ptl +++ /dev/null @@ -1,566 +0,0 @@ -import cStringIO -import cPickle -import re -import os -import lasso -import glob -import zipfile - -from quixote import get_publisher, get_request, get_response, redirect -from quixote.directory import Directory, AccessControlled - -from menu import * - -from larpe.qommon.form import * -from larpe.qommon.misc import get_abs_path -from larpe.qommon.admin.emails import EmailsDirectory - -from larpe import misc -from larpe.hosts import Host -from larpe.admin.liberty_utils import * - -class LibertyIDPDir(Directory): - _q_exports = ['', ('metadata.xml', 'metadata')] - - def _q_index [html] (self): - form = Form(enctype="multipart/form-data") - form.add(FileWidget, "metadata", title = _("Metadata"), required=True) - form.add(FileWidget, "publickey", title = _("Public Key"), required=False) - form.add(FileWidget, "cacertchain", title = _("CA Certificate Chain"), required=False) - form.add_submit("submit", _("Submit")) - - if not form.is_submitted() or form.has_errors(): - html_top('settings', title = _('New Identity Provider')) - "

%s

" % _('New Identity Provider') - form.render() - else: - self.submit_new(form) - - def submit_new(self, form, key_provider_id = None): - metadata, publickey, cacertchain = None, None, None - if form.get_widget('metadata').parse(): - metadata = form.get_widget('metadata').parse().fp.read() - if form.get_widget('publickey').parse(): - publickey = form.get_widget('publickey').parse().fp.read() - if form.get_widget('cacertchain').parse(): - cacertchain = form.get_widget('cacertchain').parse().fp.read() - - if not key_provider_id: - try: - provider_id = re.findall(r'(provider|entity)ID="(.*?)"', metadata)[0][1] - except IndexError: - return error_page(_('Bad metadata')) - key_provider_id = provider_id.replace(str('://'), str('-')).replace(str('/'), str('-')) - - dir = get_abs_path(os.path.join('idp', key_provider_id)) - if not os.path.isdir(dir): - os.makedirs(dir) - - if metadata: - metadata_fn = os.path.join(dir, 'metadata.xml') - open(metadata_fn, 'w').write(metadata) - if publickey: - publickey_fn = os.path.join(dir, 'public_key') - open(publickey_fn, 'w').write(publickey) - else: - publickey_fn = None - if cacertchain: - cacertchain_fn = os.path.join(dir, 'ca_cert_chain.pem') - open(cacertchain_fn, 'w').write(cacertchain) - else: - cacertchain_fn = None - - p = lasso.Provider(lasso.PROVIDER_ROLE_IDP, metadata_fn, publickey_fn, None) - - try: - misc.get_provider_label(p) - get_publisher().cfg['idp'] = key_provider_id - get_publisher().write_cfg() - except TypeError: - if metadata: - os.unlink(metadata_fn) - if publickey: - os.unlink(publickey_fn) - if cacertchain: - os.unlink(cacertchain_fn) - return error_page(_('Bad metadata')) - - redirect('..') - - def metadata(self): - response = get_response() - response.set_content_type('text/xml', 'utf-8') - get_publisher().reload_cfg() - if get_publisher().cfg['idp']: - idp_metadata = os.path.join(get_abs_path('idp'), get_publisher().cfg['idp'], 'metadata.xml') - return unicode(open(idp_metadata).read(), 'utf-8') - return 'No IDP is configured' - - -class EmailsDirectory(Directory): - emails = [] - - def __init__(self): - self._q_exports = ['', 'options'] + [x[0] for x in self.emails] - - def options [html] (self): - form = Form(enctype="multipart/form-data") - emails = get_publisher().cfg.get('emails', {}) - form.add(StringWidget, 'smtp_server', title = _('SMTP Server'), - required = False, value = emails.get('smtp_server', '')) - form.add(StringWidget, 'from', title = _('Email Sender'), - required = True, value = emails.get('from', 'larpe@localhost')) - form.add(StringWidget, 'reply_to', title = _('Reply-To Address'), - required = False, value = emails.get('reply_to')) - - form.add_submit("submit", _("Submit")) - form.add_submit("cancel", _("Cancel")) - if form.get_widget('cancel').parse(): - return redirect('.') - - if not form.is_submitted() or form.has_errors(): - html_top('settings', title = _('Emails')) - "

%s

" % _('General Options') - form.render() - else: - self.options_submit(form) - redirect('.') - - def options_submit(self, form): - get_publisher().reload_cfg() - if not get_publisher().cfg.has_key('emails'): - get_publisher().cfg['emails'] = {} - for k in ('smtp_server', 'from', 'reply_to'): - get_publisher().cfg['emails'][k] = form.get_widget(k).parse() - get_publisher().write_cfg() - - def _q_index [html] (self): - html_top('settings', title = _('Emails')) - '

%s

' % _('Emails') - - '
    ' - '
  • %s
  • ' % _('General Options') - for email_key, email_label in self.emails: - '
  • %s %s
  • ' % (email_key, - _('Custom Email:'), _(email_label)) - '
' - - '

' - '%s' % _('Back') - '

' - - - def email [html] (self, email_key, email_label, hint = None, check_template = None, - enabled = True): - emails_cfg = get_publisher().cfg.get('emails', {}) - cfg_key = 'email-%s' % email_key - - form = Form(enctype='multipart/form-data') - form.add(CheckboxWidget, cfg_key + '_enabled', title = _('Enabled Email'), - value = emails_cfg.get(cfg_key + '_enabled', True), default = enabled) - form.add(StringWidget, cfg_key + '_subject', title = _('Subject'), - value = emails_cfg.get(cfg_key + '_subject', '')) - form.add(TextWidget, cfg_key, title = email_label, value = emails_cfg.get(cfg_key), - cols = 80, rows = 10, hint = hint) - form.add_submit('submit', _('Submit')) - form.add_submit('restore-default', _('Restore default email')) - form.add_submit('cancel', _('Cancel')) - - if form.get_submit() == 'cancel': - return redirect('.') - - if form.get_submit() == 'restore-default': - self.email_submit(None, cfg_key) - return redirect('.') - - if form.is_submitted() and not form.has_errors(): - if self.email_submit(form, cfg_key, check_template): - return redirect('.') - form.set_error(cfg_key, _('Invalid template')) - - html_top('settings', title = _('Emails')) - '

%s - %s

' % (_('Email'), email_label) - form.render() - - def email_submit(self, form, cfg_key, check_template = None): - get_publisher().reload_cfg() - if not get_publisher().cfg.has_key('emails'): - get_publisher().cfg['emails'] = {} - if form: - template = form.get_widget(cfg_key).parse() - if check_template and not check_template(template): - return False - get_publisher().cfg['emails'][str(cfg_key)] = template - get_publisher().cfg['emails'][str(cfg_key + '_enabled')] = form.get_widget( - cfg_key + '_enabled').parse() - get_publisher().cfg['emails'][str(cfg_key + '_subject')] = form.get_widget( - cfg_key + '_subject').parse() - else: - get_publisher().cfg['emails'][str(cfg_key)] = None - get_publisher().write_cfg() - return True - - -class SettingsDirectory(AccessControlled, Directory): - _q_exports = ['', 'liberty_sp', 'liberty_idp', 'domain_names', 'apache2_configuration_generation', - 'language', 'emails', 'proxy' ] - - liberty_idp = LibertyIDPDir() - emails = EmailsDirectory() - - def _q_access(self): - get_response().breadcrumb.append( ('settings/', _('Settings')) ) - - def _q_index [html] (self): - get_publisher().reload_cfg() - html_top('settings', title = _('Settings')) - - if lasso.SAML2_SUPPORT: - '

%s

' % _('Liberty Alliance & SAML 2.0 Service Provider') - else: - '

%s

' % _('Liberty Alliance Service Provider') - '
%s
%s
' % ( - _('Service Provider'), _('Configure Larpe as a Service Provider')) - - hosts = Host.select(lambda x: x.name == 'larpe') - if hosts: - self.host = hosts[0] - - if lasso.SAML2_SUPPORT and self.host.saml2_metadata is not None: - metadata_url = '%s/metadata.xml' % self.host.saml2_base_url - '
%s
%s
' % ( - metadata_url, - _('Service Provider Metadata'), - _('Download Service Provider SAML 2.0 Metadata file')) - - if self.host.metadata is not None: - metadata_url = '%s/metadata.xml' % self.host.base_url - '
%s
%s
' % ( - metadata_url, - _('Service Provider Metadata'), - _('Download Service Provider ID-FF 1.2 Metadata file')) - - if self.host.public_key is not None: - public_key_url = '%s/public_key' % self.host.base_url - '
%s
%s
' % ( - public_key_url, - _('Public key'), - _('Download Service Provider SSL Public Key file')) - - if lasso.SAML2_SUPPORT: - '

%s

' % _('Liberty Alliance & SAML 2.0 Identity Provider') - else: - '

%s

' % _('Liberty Alliance Identity Provider') - - '
' - - '
%s
%s
' % ( - _('Identity Provider'), _('Configure an identity provider')) - - if get_publisher().cfg.has_key('idp'): - '
%s
%s
' % ( - _('Identity Provider metadatas'), _('See current identity provider metadatas')) - - '
' - - '

%s

' % _('Global parameters for the sites') - - '
' - '
%s
%s
' % ( - _('Domain name'), _('Configure the base domain name for the sites')) - '
%s
%s
' % ( - _('Apache 2 configuration generation'), _('Customise Apache 2 configuration generation')) - '
%s
%s
' % ( - _('Proxy'), _('Connect to the sites through a web proxy')) - '
' - - '

%s

' % _('Customisation') - - '
' - '
%s
%s
' % ( - _('Language'), _('Configure site language')) - '
%s
%s
' % ( - _('Emails'), _('Configure email settings')) - '
' -# '

%s

' % _('Misc') -# '
' -# '
%s
%s
' % ( -# _('Misc'), _('Configure misc options')) -# '
%s
%s
' % ( -# _('Debug Options'), _('Configure options useful for debugging')) -# '
' - - - def liberty_sp [html] (self): - get_publisher().reload_cfg() - - # Get the host object for the reverse proxy - hosts = Host.select(lambda x: x.name == 'larpe') - if hosts: - self.host = hosts[0] - else: - self.host = Host() - self.host.reversed_hostname = get_publisher().cfg[str('proxy_hostname')] - - form = Form(enctype='multipart/form-data') - form.add(StringWidget, 'organization_name', title=_('Organisation Name'), size=50, - required = True, value = self.host.organization_name) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - if form.get_widget('cancel').parse(): - return redirect('.') - if not form.is_submitted() or form.has_errors(): - html_top('settings', title = _('Service Provider Configuration')) - '

%s

' % _('Service Provider Configuration') - form.render() - else: - self.liberty_sp_submit(form) - redirect('.') - - def liberty_sp_submit(self, form): - get_publisher().reload_cfg() - metadata_cfg = {} - - f = 'organization_name' - if form.get_widget(f): - setattr(self.host, f, form.get_widget(f).parse()) - - metadata_cfg['organization_name'] = self.host.organization_name - - self.host.name = 'larpe' - - # Liberty Alliance / SAML parameters - base_url = '%s/liberty/%s/liberty' % (misc.get_root_url(), self.host.name) - metadata_cfg['base_url'] = base_url - self.host.base_url = base_url - - if lasso.SAML2_SUPPORT: - saml2_base_url = '%s/liberty/%s/saml' % (misc.get_root_url(), self.host.name) - metadata_cfg['saml2_base_url'] = saml2_base_url - self.host.saml2_base_url = saml2_base_url - - provider_id = '%s/metadata' % base_url - metadata_cfg['provider_id'] = provider_id - self.host.provider_id = provider_id - - if lasso.SAML2_SUPPORT: - saml2_provider_id = '%s/metadata' % saml2_base_url - metadata_cfg['saml2_provider_id'] = saml2_provider_id - self.host.saml2_provider_id = saml2_provider_id - - # Storage directories - site_dir = os.path.join(get_publisher().app_dir, 'sp', - self.host.reversed_hostname, self.host.name) - user_dir = os.path.join(site_dir, 'users') - token_dir = os.path.join(site_dir, 'tokens') - for dir in (site_dir, user_dir, token_dir): - if not os.path.isdir(dir): - os.makedirs(dir) - metadata_cfg['site_dir'] = site_dir - self.host.site_dir = site_dir - - # Generate SSL keys - private_key_path = os.path.join(site_dir, 'private_key.pem') - public_key_path = os.path.join(site_dir, 'public_key') - if not os.path.isfile(private_key_path) or not os.path.isfile(public_key_path): - set_provider_keys(private_key_path, public_key_path) - self.host.private_key = private_key_path - metadata_cfg['signing_public_key'] = open(public_key_path).read() - self.host.public_key = public_key_path - - # Write metadatas - metadata_path = os.path.join(site_dir, 'metadata.xml') - open(metadata_path, 'w').write(get_metadata(metadata_cfg)) - self.host.metadata = metadata_path - - if hasattr(self.host, 'saml2_provider_id'): - saml2_metadata_path = os.path.join(site_dir, 'saml2_metadata.xml') - open(saml2_metadata_path, 'w').write(get_saml2_metadata(metadata_cfg)) - self.host.saml2_metadata = saml2_metadata_path - - self.host.root_url = '%s/' % misc.get_root_url() - self.host.return_url = '%s/admin/' % misc.get_root_url() - - self.host.store() - - def domain_names [html] (self): - form = self.form_domain_name() - - if form.get_widget('cancel').parse(): - return redirect('.') - - if not form.is_submitted() or form.has_errors(): - html_top('settings', title = _('Domain name')) - '

%s

' % _('Domain name') - form.render() - else: - self.submit_domain_name(form) - redirect('.') - - def form_domain_name(self): - get_publisher().reload_cfg() - if get_cfg('domain_names'): - domain_name = get_cfg('domain_names')[0] - else: - domain_name = None - - form = Form(enctype='multipart/form-data') - form.add(StringWidget, 'domain_name', - title=_('Domain name for the sites'), - value = domain_name) - # TODO: Add the option "Both" and handle it in hosts configuration - form.add(SingleSelectWidget, 'sites_url_scheme', title = _('Use HTTP or HTTPS'), - value = get_cfg('sites_url_scheme'), - options = [ (None, _('Same as the site')), - ('http', 'HTTP'), - ('https', 'HTTPS') ] ) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - return form - - def submit_domain_name(self, form): - get_publisher().reload_cfg() - get_publisher().cfg['domain_names'] = [ form.get_widget('domain_name').parse() ] - get_publisher().cfg['sites_url_scheme'] = form.get_widget('sites_url_scheme').parse() - get_publisher().write_cfg() - - def apache2_configuration_generation [html] (self): - get_publisher().reload_cfg() - - form = Form(enctype='multipart/form-data') - form.add(CheckboxWidget, 'allow_config_generation', - title=_('Automatically generate Apache 2 configuration for new hosts and reload Apache 2 after changes'), - value = get_publisher().cfg.get(str('allow_config_generation'), True)) - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - if form.get_widget('cancel').parse(): - return redirect('.') - if not form.is_submitted() or form.has_errors(): - html_top('settings', title = _('Apache 2 configuration generation')) - '

%s

' % _('Apache 2 configuration generation') - form.render() - else: - self.apache2_configuration_generation_submit(form) - redirect('.') - - def apache2_configuration_generation_submit(self, form): - get_publisher().reload_cfg() - - f = 'allow_config_generation' - get_publisher().cfg[f] = form.get_widget(f).parse() - - get_publisher().write_cfg() - - def language [html] (self): - form = Form(enctype='multipart/form-data') - language_cfg = get_publisher().cfg.get('language', {}) - form.add(SingleSelectWidget, 'language', title = _('Language'), - value = language_cfg.get('language'), - options = [ (None, _('System Default')), - (str('en'), _('English')), - (str('fr'), _('French')) ] ) - - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - if form.get_widget('cancel').parse(): - return redirect('.') - - if not form.is_submitted() or form.has_errors(): - html_top('settings', title = _('Language')) - '

%s

' % _('Language') - form.render() - else: - self.language_submit(form) - redirect('.') - - def language_submit(self, form): - get_publisher().reload_cfg() - if not get_publisher().cfg.has_key('language'): - get_publisher().cfg['language'] = {} - for k in ('language', ): - get_publisher().cfg['language'][k] = form.get_widget(k).parse() - get_publisher().write_cfg() - - def proxy [html] (self): - get_publisher().reload_cfg() - form = Form(enctype='multipart/form-data') - - form.add(CheckboxWidget, 'use_proxy', - title=_('Use a web proxy'), - value = get_publisher().cfg.get(str('use_proxy'), False)) - form.add(StringWidget, 'proxy_ip', - title=_('Proxy IP address or domain name'), - value = get_publisher().cfg.get(str('proxy_ip'))) - form.add(StringWidget, 'proxy_port', - title=_('Proxy port'), - value = get_publisher().cfg.get(str('proxy_port'))) - form.add(StringWidget, 'proxy_user', - title=_('User name'), - value = get_publisher().cfg.get(str('proxy_user'))) - form.add(PasswordWidget, 'proxy_password', - title=_('User password'), - value = get_publisher().cfg.get(str('proxy_password'))) - - form.add_submit('submit', _('Submit')) - form.add_submit('cancel', _('Cancel')) - if form.get_widget('cancel').parse(): - return redirect('.') - - if not form.is_submitted() or form.has_errors(): - html_top('settings', title = _('Proxy')) - '

%s

' % _('Proxy') - form.render() - else: - self.proxy_submit(form) - redirect('.') - - def proxy_submit(self, form): - get_publisher().reload_cfg() - for f in ('use_proxy', 'proxy_ip', 'proxy_port', 'proxy_user', 'proxy_password'): - get_publisher().cfg[f] = form.get_widget(f).parse() - get_publisher().write_cfg() - -# def debug_options [html] (self): -# form = Form(enctype="multipart/form-data") -# debug_cfg = get_publisher().cfg.get('debug', {}) -# form.add(StringWidget, 'error_email', title = _('Email for Tracebacks'), -# value = debug_cfg.get('error_email', '')) -# form.add(SingleSelectWidget, 'display_exceptions', title = _('Display Exceptions'), -# value = debug_cfg.get('display_exceptions', ''), -# options = [ (str(''), _('No display')), -# (str('text'), _('Display as Text')), -# (str('text-in-html'), _('Display as Text in HTML an error page')), -# (str('html'), _('Display as HTML')) ]) -# form.add(CheckboxWidget, 'logger', title = _('Logger'), -# value = debug_cfg.get('logger', False)) -# form.add_submit("submit", _("Submit")) -# form.add_submit("cancel", _("Cancel")) - -# if form.get_widget('cancel').parse(): -# return redirect('.') - -# if not form.is_submitted() or form.has_errors(): -# html_top('settings', title = _('Debug Options')) -# '

%s

' % _('Debug Options') -# form.render() -# else: -# self.debug_options_submit(form) -# redirect('.') - -# def debug_options_submit(self, form): -# get_publisher().reload_cfg() -# if not get_publisher().cfg.has_key('debug'): -# get_publisher().cfg['debug'] = {} -# for k in ('error_email', 'display_exceptions', 'logger'): -# get_publisher().cfg['debug'][k] = form.get_widget(k).parse() -# get_publisher().write_cfg() -# get_publisher().set_config() - - -def error_page [html] (error_message): - html_top(_('Error')) - '

%s

' % _('Error') - '
' - '

%s

' % error_message - '
' - diff --git a/larpe/branches/idwsf/larpe/admin/users.ptl b/larpe/branches/idwsf/larpe/admin/users.ptl deleted file mode 100644 index 1af2132..0000000 --- a/larpe/branches/idwsf/larpe/admin/users.ptl +++ /dev/null @@ -1,276 +0,0 @@ -import random -import lasso - -from quixote import get_request, get_session, redirect, get_publisher -from quixote.directory import Directory - -from larpe.qommon.form import * -from larpe.qommon import emails - -from larpe import errors -from larpe import misc -from larpe import storage -from larpe.users import User -from larpe.hosts import Host - -from menu import * - -class UserUI: - def __init__(self, user): - self.user = user - - def form_new(self): - form = Form(enctype="multipart/form-data") - form.add(StringWidget, "name", title = _('User Name'), required = True, size=30) - form.add(StringWidget, "email", title = _('Email'), required = False, size=30) - form.add_submit("submit", _("Submit")) - form.add_submit("cancel", _("Cancel")) - return form - - def form_edit(self): - form = Form(enctype="multipart/form-data") - form.add(StringWidget, "id", title = _('User Id'), required = False, size=30, - value = self.user.id, readonly = 'readonly') - form.add(StringWidget, "name", title = _('User Name'), required = True, size=30, - value = self.user.name) - form.add(StringWidget, "email", title = _('Email'), required = False, size=30, - value = self.user.email) - form.add_submit("submit", _("Submit")) - form.add_submit("cancel", _("Cancel")) - return form - - def submit_form(self, form): - if not self.user: - self.user = User() - for f in ('name', 'email'): - widget = form.get_widget(f) - if widget: - setattr(self.user, f, widget.parse()) - self.user.is_admin = True - self.user.store() - - -class UserPage(Directory): - _q_exports = ['', 'edit', 'delete', 'token'] - - def __init__(self, component): - self.user = User.get(component) - self.user_ui = UserUI(self.user) - get_response().breadcrumb.append((component + '/', self.user.name)) - - def _q_index [html] (self): - html_top('users', '%s - %s' % (_('User'), self.user.name)) - '

%s - %s

' % (_('User'), self.user.name) - '
' - '
%s
' % _('Name') - '
%s
' % self.user.name - if self.user.email: - '
%s
' % _('Email') - '
%s
' % self.user.email -# if self.user.lasso_dump: -# identity = lasso.Identity.newFromDump(self.user.lasso_dump) -# server = misc.get_lasso_server() -# if len(identity.providerIds) and server: -# '

%s

' % _('Liberty Alliance Details') -# '
    ' -# for pid in identity.providerIds: -# provider = server.getProvider(pid) -# label = misc.get_provider_label(provider) -# if label: -# label = '%s (%s)' % (label, pid) -# else: -# label = pid -# federation = identity.getFederation(pid) -# '
  • ' -# _('Account federated with %s') % label -# '
    ' -# if federation.localNameIdentifier: -# _("local: ") + federation.localNameIdentifier.content -# if federation.remoteNameIdentifier: -# _("remote: ") + federation.remoteNameIdentifier.content -# '
  • ' -# '
' - -# # XXX: only display this in debug mode: -# '

%s

' % _('Lasso Identity Dump') -# '
%s
' % self.user.lasso_dump - '
' - - def debug [html] (self): - get_response().breadcrumb.append( ('debug', _('Debug')) ) - html_top('users', 'Debug') - "

Debug - %s

" % self.user.name - "
"
-        self.user.lasso_dump
-        "
" - - def edit [html] (self): - form = self.user_ui.form_edit() - if form.get_widget('cancel').parse(): - return redirect('..') - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append( ('edit', _('Edit')) ) - html_top('users', title = _('Edit User')) - '

%s

' % _('Edit User') - form.render() - else: - self.user_ui.submit_form(form) - return redirect('..') - - def delete [html] (self): - form = Form(enctype="multipart/form-data") - form.widgets.append(HtmlWidget('

%s

' % _( - "You are about to irrevocably delete this user."))) - form.add_submit("submit", _("Submit")) - form.add_submit("cancel", _("Cancel")) - if form.get_widget('cancel').parse(): - return redirect('..') - if not form.is_submitted() or form.has_errors(): - get_response().breadcrumb.append(('delete', _('Delete'))) - html_top('users', title = _('Delete User')) - '

%s %s

' % (_('Deleting User :'), self.user.name) - form.render() - else: - self.user.remove_self() - return redirect('..') - - def token [html] (self): - form = Form(enctype="multipart/form-data", use_tokens = False) - form.add_submit("submit", _("Generate")) - form.add_submit("cancel", _("Cancel")) - request = get_request() - if request.form.has_key('cancel') or request.form.has_key('done'): - return redirect('..') - - get_response().breadcrumb.append(('token', _('Identification Token'))) - - if not form.is_submitted() or form.has_errors(): - html_top('users', title = _('Identification Token')) - '

%s

' % _('Identification Token') - '

%s

' % _('You are about to generate a token than can be used to federate the account.') - '

%s

' % _('After that, you will have the choice to send it to the user by email so that he can federate his accounts.') - if self.user.identification_token: - '

%s

' % _('Note that user has already been issued an identification token : %s') % self.user.identification_token - form.render() - else: - if request.form.has_key('submit'): - html_top('users', title = _('Identification Token')) - token = '-'.join(['%04d' % random.randint(1, 9999) for x in range(4)]) - self.user.identification_token = str(token) - self.user.store() - - '

' - _('Identification Token for %s') % self.user.name - ' : %s

' % self.user.identification_token - - form = Form(enctype="multipart/form-data", use_tokens = False) - form.add_submit('done', _('Done')) - if self.user.email: - form.add_submit("submit-email", _("Send by email")) - form.render() - else: - site_url = '%s://%s%s/token?token=%s' \ - % (request.get_scheme(), request.get_server(), - get_request().environ['SCRIPT_NAME'], self.user.identification_token) - body = _("""You have been given an identification token. - -Your token is %(token)s - -Click on %(url)s to use it. -""") % {'token': self.user.identification_token, 'url': site_url} - try: - emails.email(_('Identification Token'), body, self.user.email) - except errors.EmailError, e: - html_top('users', title = _('Identification Token')) - _('Failed sending email. Check your email configuration.') - '

' % _('Back') - else: - return redirect('..') - -class UsersDirectory(Directory): - - _q_exports = ['', 'new'] - - def _q_index [html] (self): - get_publisher().reload_cfg() - get_response().breadcrumb.append( ('users/', _('Users')) ) - html_top('users', title = _('Users')) - - - if not list(Host.select(lambda x: x.name == 'larpe')): - '

%s

' % _('Liberty support must be setup before creating users.') - else: - """""" % _('New User') - - debug_cfg = get_publisher().cfg.get('debug', {}) - - users = User.select(lambda x: x.name is not None, order_by = 'name') - - '
    ' - for user in users: - '
  • ' - '%s' % user.name - if user.email: - '

    ' - user.email - '

    ' - - '

    ' - command_icon('%s/' % user.id, 'view') - if not user.name_identifiers: - if not user.identification_token: - command_icon('%s/token' % user.id, 'token', - label = _('Identification Token'), icon = 'stock_exec_16.png') - else: - command_icon('%s/token' % user.id, 'token', - label = _('Identification Token (current: %s)') % \ - user.identification_token, - icon = 'stock_exec_16.png') - command_icon('%s/edit' % user.id, 'edit') - command_icon('%s/delete' % user.id, 'remove') - if debug_cfg.get('logger', False): - command_icon('../logger/by_user/%s/' % user.id, 'logs', - label = _('Logs'), icon = 'stock_harddisk_16.png') - '

  • ' - '
' - - def new [html] (self): - get_response().breadcrumb.append( ('users/', _('Users')) ) - get_response().breadcrumb.append( ('new', _('New')) ) - hosts = list(Host.select(lambda x: x.name == 'larpe')) - if not hosts: - return error_page('users', _('Liberty support must be setup before creating users.')) - host = hosts[0] - # XXX: user must be logged in to get here - user_ui = UserUI(None) - # FIXME : should be able to use User.count(). Track fake user creations. - users = User.select(lambda x: x.name is not None) - first_user = (len(users) == 0) - form = user_ui.form_new() - if form.get_widget('cancel').parse(): - return redirect('.') - - if not form.is_submitted() or form.has_errors(): - html_top('users', title = _('New User')) - '

%s

' % _('New User') - form.render() - else: - user_ui.submit_form(form) - if first_user: - req = get_request() - if hasattr(req, str('user')) and req.user: - user_ui.user.name_identifiers = req.user.name_identifiers - user_ui.user.lasso_dump = req.user.lasso_dump - user_ui.user.store() - # TODO : SAML 2.0 - get_session().set_user(user_ui.user.id, host.provider_id) - return redirect('.') - - def _q_lookup(self, component): - get_response().breadcrumb.append( ('users/', _('Users')) ) - try: - return UserPage(component) - except KeyError: - raise errors.TraversalError() diff --git a/larpe/branches/idwsf/larpe/ctl/start.py b/larpe/branches/idwsf/larpe/ctl/start.py deleted file mode 100644 index 0f6335f..0000000 --- a/larpe/branches/idwsf/larpe/ctl/start.py +++ /dev/null @@ -1,34 +0,0 @@ -import socket -import sys - -from qommon.scgi_server import run - -import publisher - -def start(args): - port = 3007 - script_name = '' - - i = 0 - while i < len(args): - if args[i] == '--port': - port = int(args[i+1]) - i += 1 - elif args[i] == '--silent': - sys.stdout = open('/dev/null', 'w') - sys.stderr = open('/dev/null', 'w') - elif args[i] == '--script-name': - script_name = args[i+1] - i += 1 - i += 1 - - try: - run(publisher.LarpePublisher.create_publisher, port=port, script_name=script_name) - except socket.error, e: - if e[0] == 98: - print >> sys.stderr, 'address already in use' - sys.exit(1) - raise - except KeyboardInterrupt: - sys.exit(1) - diff --git a/larpe/branches/idwsf/larpe/errors.ptl b/larpe/branches/idwsf/larpe/errors.ptl deleted file mode 100644 index ad41aef..0000000 --- a/larpe/branches/idwsf/larpe/errors.ptl +++ /dev/null @@ -1,12 +0,0 @@ -from quixote import get_session, get_request, redirect - -from qommon.errors import * - -class AccessUnauthorizedError(AccessError): - def render [html] (self): - session = get_session() - request = get_request() - session.after_url = str('%s?%s' % (request.get_url(), request.get_query())) - # TODO : SAML2 - login_url = '%s/liberty/larpe/login' % request.environ['SCRIPT_NAME'] - redirect(login_url) diff --git a/larpe/branches/idwsf/larpe/federations.py b/larpe/branches/idwsf/larpe/federations.py deleted file mode 100644 index 39af4b8..0000000 --- a/larpe/branches/idwsf/larpe/federations.py +++ /dev/null @@ -1,35 +0,0 @@ -from storage import StorableObject - -class Federation(StorableObject): - _names = 'federations' - - username = None - password = None - host_id = None - name_identifiers = None - cookies = None - select_fields = {} - - def __init__(self, username, password, host_id, name_identifier, cookies=None, select={}): - StorableObject.__init__(self) - self.username = username - self.password = password - self.host_id = host_id - self.name_identifiers = [ name_identifier ] - self.cookies = cookies - self.select_fields = select - -# def add_name_identifier(self, name_identifier): -# self.name_identifiers.append(name_identifier) - - def remove_name_identifier(self, name_identifier): - self.name_identifiers.remove(name_identifier) - if not self.name_identifiers: - self.remove_self() - - def set_cookies(self, cookies): - self.cookies = cookies - - def __str__(self): - return 'Federation username : %s, name identifiers : %s, cookies : %s' \ - % (self.username, self.name_identifiers, self.cookies) diff --git a/larpe/branches/idwsf/larpe/field_prefill.py b/larpe/branches/idwsf/larpe/field_prefill.py deleted file mode 100644 index aed6fda..0000000 --- a/larpe/branches/idwsf/larpe/field_prefill.py +++ /dev/null @@ -1,13 +0,0 @@ -from storage import StorableObject - -class FieldPrefill(StorableObject): - _names = 'field_prefill' - - form_id = 0 - name = None - xpath = None - number = 1 - raw_xml = False - regexp_match = None - regexp_replacing = None - select_options = {} diff --git a/larpe/branches/idwsf/larpe/filter/larpe-filter.py b/larpe/branches/idwsf/larpe/filter/larpe-filter.py deleted file mode 100755 index e309b28..0000000 --- a/larpe/branches/idwsf/larpe/filter/larpe-filter.py +++ /dev/null @@ -1,164 +0,0 @@ -import os -import re - -from mod_python import apache - -#import larpe.hosts - -app_dir = '/var/lib/larpe' - -def outputfilter(filter): - # Only filter html code - if filter.req.content_type is not None: - is_html = re.search('text/html', filter.req.content_type) - if filter.req.content_type is not None and not is_html: - filter.pass_on() - else: - if not hasattr(filter.req, 'temp_doc'): # the start - filter.req.temp_doc = [] # create new attribute to hold document - # If content-length ended up wrong, Gecko browsers truncated data, so - if 'Content-Length' in filter.req.headers_out: - del filter.req.headers_out['Content-Length'] - -# filter.write(filter.req.headers_in['Cookie']) -# delete_cookies(filter) - #filter.req.headers_out['Set-Cookie'] = 'dc_admin="deleted"; max-age=0; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=/' - - temp_doc = filter.req.temp_doc - s = filter.read() - while s: # could get '' at any point, but only get None at end - temp_doc.append(s) - s = filter.read() - - if s is None: # the end - page = ''.join(temp_doc) - - page = filter_dispatch(filter, page) - - filter.write(page) - filter.close() - -def filter_dispatch(filter, page): -# host = get_host_from_url(filter) -# if host is None: -# apache.log_error('Host not found') -# return page - try: -# function_name = 'filter_' + host.label.lowercase() - host_name = filter.req.hostname.split('.')[-3] - function_name = 'filter_' + host_name - return eval(function_name + '(filter, page)') - except: - return page -# return filter_default(filter, page) - - -def filter_default(filter, page): -# host = get_host_from_url(filter) -# if host is None: -# apache.log_error('Host not found') -# return page -# if host.auth_url is not None or host.auth_form is None: -# return page - form = find_auth_form(page) - if form is not None: - try: - host_name = filter.req.hostname.split('.')[-3] - return page.replace(form, """ - - - """ % host_name) - except: - pass - return page - -def find_auth_form(page): - regexp = re.compile("""""", re.DOTALL | re.IGNORECASE) - found_forms = regexp.findall(page) - - for found_form in found_forms: - regexp = re.compile("""]*?type="password"[^>]*?>""", re.DOTALL | re.IGNORECASE) - if regexp.search(found_form) is not None: - return found_form - return None - -#def get_host_from_url(filter): -# try: -# return list(Host.select(lambda x: x.reversed_hostname == filter.req.hostname \ -# and x.reversed_directory == get_proxied_site_name(filter)))[0] -# except: -# return None - - -def filter_linuxfr(filter, page): - str_to_replace = re.compile(str('
.*?
'), re.DOTALL) - return str_to_replace.sub(str(r"""
- -
""" - ), page) - -def filter_dotclear(filter, page): - if filter.req.uri == '/dot/ecrire/redac_list.php': - str_to_replace = re.compile(str('(\[[^\?]+\?id=)([^"]+)(">[^\]]*)\]'), re.DOTALL) - return str_to_replace.sub(str(r'\1\2\3 - token ]'), page) - if filter.req.uri == '/dot/ecrire/redacteur.php': - str_to_replace = re.compile(str('(