From 291c5679505e0f06b99ec9496c4fcde009dcdac3 Mon Sep 17 00:00:00 2001 From: Xavier Guimard Date: Mon, 15 Oct 2007 05:29:29 +0000 Subject: [PATCH] LEMONLDAP::NG : * Liberty alliance module from FederID project * Debian integration in progress --- build/lemonldap-ng/changelog | 6 + build/lemonldap-ng/debian/changelog | 5 + build/lemonldap-ng/debian/control | 3 +- build/lemonldap-ng/debian/copyright | 13 +- build/lemonldap-ng/debian/rules | 2 +- modules/lemonldap-ng-portal/MANIFEST | 63 + .../example/AuthLA/idps.xml | 15 + .../example/AuthLA/index.pl | 70 + .../lemonldap-ng-portal/example/AuthLA/la.log | 1 + .../AuthLA/liberty/assertionConsumer.pl | 1 + .../AuthLA/liberty/federationTermination.pl | 1 + .../liberty/federationTerminationReturn.pl | 1 + .../example/AuthLA/liberty/singleLogout.pl | 1 + .../AuthLA/liberty/singleLogoutReturn.pl | 1 + .../example/AuthLA/liberty/soapCall.pl | 1 + .../example/AuthLA/liberty/soapEndpoint.pl | 1 + .../example/AuthLA/liberty/tpl | 1 + .../AuthLA/ressources/db/liberty_tables.sql | 37 + .../AuthLA/ressources/db/taccounts.sql | 11 + .../example/AuthLA/ressources/db/tnameid.sql | 12 + .../AuthLA/ressources/db/tsessions.sql | 14 + .../AuthLA/ressources/lemonsp-metadata.xml | 51 + .../example/AuthLA/tpl/auth.tpl | 54 + .../example/AuthLA/tpl/themes/CHANGELOG | 11 + .../example/AuthLA/tpl/themes/README | 13 + .../AuthLA/tpl/themes/bouton_authentic.png | Bin 0 -> 871 bytes .../AuthLA/tpl/themes/bouton_federid.png | Bin 0 -> 774 bytes .../AuthLA/tpl/themes/bouton_interldap.png | Bin 0 -> 895 bytes .../tpl/themes/bouton_lemonldap::ng.png | Bin 0 -> 1143 bytes .../AuthLA/tpl/themes/dc2/button-hover.png | Bin 0 -> 226 bytes .../AuthLA/tpl/themes/dc2/button-normal.png | Bin 0 -> 228 bytes .../example/AuthLA/tpl/themes/dc2/default.css | 731 ++++++++ .../AuthLA/tpl/themes/dc2/dotclear-logo.png | Bin 0 -> 2371 bytes .../example/AuthLA/tpl/themes/dc2/drag.png | Bin 0 -> 415 bytes .../example/AuthLA/tpl/themes/dc2/head-bg.png | Bin 0 -> 357 bytes .../AuthLA/tpl/themes/dc2/head-logo.png | Bin 0 -> 4397 bytes .../AuthLA/tpl/themes/dc2/magnifier.png | Bin 0 -> 499 bytes .../AuthLA/tpl/themes/dc2/msg-error.png | Bin 0 -> 667 bytes .../example/AuthLA/tpl/themes/dc2/msg-std.png | Bin 0 -> 647 bytes .../example/AuthLA/tpl/themes/dc2/page-bg.png | Bin 0 -> 225 bytes .../example/AuthLA/tpl/themes/dc2/tab-bg.png | Bin 0 -> 199 bytes .../example/AuthLA/tpl/themes/dc2/tab-c-l.png | Bin 0 -> 281 bytes .../example/AuthLA/tpl/themes/dc2/tab-c-r.png | Bin 0 -> 442 bytes .../example/AuthLA/tpl/themes/dc2/tab-l-l.png | Bin 0 -> 466 bytes .../example/AuthLA/tpl/themes/dc2/tab-l-r.png | Bin 0 -> 598 bytes .../example/AuthLA/tpl/themes/dc2/tab-n-l.png | Bin 0 -> 462 bytes .../example/AuthLA/tpl/themes/dc2/tab-n-r.png | Bin 0 -> 586 bytes .../tpl/themes/federid-dc2/button-hover.png | Bin 0 -> 226 bytes .../tpl/themes/federid-dc2/button-normal.png | Bin 0 -> 228 bytes .../AuthLA/tpl/themes/federid-dc2/default.css | 252 +++ .../AuthLA/tpl/themes/federid-dc2/head-bg.png | Bin 0 -> 357 bytes .../tpl/themes/federid-dc2/head-logo.png | Bin 0 -> 5852 bytes .../tpl/themes/federid-dc2/msg-error.png | Bin 0 -> 667 bytes .../AuthLA/tpl/themes/federid-dc2/msg-std.png | Bin 0 -> 647 bytes .../AuthLA/tpl/themes/federid-dc2/page-bg.png | Bin 0 -> 225 bytes .../tpl/themes/federid/button-hover.png | Bin 0 -> 226 bytes .../tpl/themes/federid/button-normal.png | Bin 0 -> 228 bytes .../AuthLA/tpl/themes/federid/default.css | 265 +++ .../AuthLA/tpl/themes/federid/fond.jpg | Bin 0 -> 3034 bytes .../AuthLA/tpl/themes/federid/head-bg.png | Bin 0 -> 886 bytes .../AuthLA/tpl/themes/federid/head-logo.png | Bin 0 -> 12452 bytes .../example/AuthLA/tpl/themes/federid/idp.css | 15 + .../AuthLA/tpl/themes/federid/laap.css | 15 + .../AuthLA/tpl/themes/federid/msg-error.png | Bin 0 -> 667 bytes .../AuthLA/tpl/themes/federid/msg-std.png | Bin 0 -> 647 bytes .../AuthLA/tpl/themes/federid/page-bg.png | Bin 0 -> 10400 bytes .../example/AuthLA/tpl/themes/federid/sso.css | 15 + .../example/AuthLA/tpl/themes/federid/wui.css | 15 + .../AuthLA/tpl/themes/styleswitcher.js | 1 + .../example/AuthLA/tpl/themes/template.html | 92 + .../lib/Lemonldap/NG/Portal.pm | 2 +- .../lib/Lemonldap/NG/Portal/AuthLA.pm | 1505 +++++++++++++++-- 72 files changed, 3164 insertions(+), 133 deletions(-) create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/idps.xml create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/index.pl create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/la.log create mode 120000 modules/lemonldap-ng-portal/example/AuthLA/liberty/assertionConsumer.pl create mode 120000 modules/lemonldap-ng-portal/example/AuthLA/liberty/federationTermination.pl create mode 120000 modules/lemonldap-ng-portal/example/AuthLA/liberty/federationTerminationReturn.pl create mode 120000 modules/lemonldap-ng-portal/example/AuthLA/liberty/singleLogout.pl create mode 120000 modules/lemonldap-ng-portal/example/AuthLA/liberty/singleLogoutReturn.pl create mode 120000 modules/lemonldap-ng-portal/example/AuthLA/liberty/soapCall.pl create mode 120000 modules/lemonldap-ng-portal/example/AuthLA/liberty/soapEndpoint.pl create mode 120000 modules/lemonldap-ng-portal/example/AuthLA/liberty/tpl create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/ressources/db/liberty_tables.sql create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/ressources/db/taccounts.sql create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/ressources/db/tnameid.sql create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/ressources/db/tsessions.sql create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/ressources/lemonsp-metadata.xml create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/auth.tpl create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/CHANGELOG create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/README create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_authentic.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_federid.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_interldap.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_lemonldap::ng.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/button-hover.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/button-normal.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/default.css create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/dotclear-logo.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/drag.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/head-bg.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/head-logo.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/magnifier.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/msg-error.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/msg-std.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/page-bg.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-bg.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-c-l.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-c-r.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-l-l.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-l-r.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-n-l.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-n-r.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/button-hover.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/button-normal.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/default.css create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/head-bg.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/head-logo.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/msg-error.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/msg-std.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/page-bg.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/button-hover.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/button-normal.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/default.css create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/fond.jpg create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/head-bg.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/head-logo.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/idp.css create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/laap.css create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/msg-error.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/msg-std.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/page-bg.png create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/sso.css create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/wui.css create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/styleswitcher.js create mode 100644 modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/template.html diff --git a/build/lemonldap-ng/changelog b/build/lemonldap-ng/changelog index af2d49e88..3d60d8c2c 100644 --- a/build/lemonldap-ng/changelog +++ b/build/lemonldap-ng/changelog @@ -1,3 +1,9 @@ +lemonldap-ng (0.9) unstable; urgency=low + + * Liberty Alliance module issued of the FederID project is now included. + + -- Xavier Guimard Sun, 14 Oct 2007 12:02:33 +0200 + lemonldap-ng (0.8.3) unstable; urgency=high * Syntax errors in configuration are now displayed diff --git a/build/lemonldap-ng/debian/changelog b/build/lemonldap-ng/debian/changelog index e69de29bb..706b2d846 100644 --- a/build/lemonldap-ng/debian/changelog +++ b/build/lemonldap-ng/debian/changelog @@ -0,0 +1,5 @@ +lemonldap-ng (0.8.3-0) unstable; urgency=low + + * Local build + + -- Xavier Guimard Sun, 14 Oct 2007 09:11:36 +0200 diff --git a/build/lemonldap-ng/debian/control b/build/lemonldap-ng/debian/control index cbe38bfbf..918747625 100644 --- a/build/lemonldap-ng/debian/control +++ b/build/lemonldap-ng/debian/control @@ -55,8 +55,7 @@ Description: Lemonldap::NG apache manager part Package: liblemonldap-ng-portal-perl Architecture: all -Depends: libapache-session-perl, libnet-ldap-perl, liblemonldap-ng-conf-perl (>=0.8.2.3) -Recommends: liblasso-perl +Depends: libapache-session-perl, libnet-ldap-perl, liblemonldap-ng-conf-perl (>=0.8.2.3), liblasso-perl Description: Lemonldap::NG apache authentication portal part Lemonldap::NG is a complete Web-SSO system that can run with reverse-proxies or directly on application apache servers. diff --git a/build/lemonldap-ng/debian/copyright b/build/lemonldap-ng/debian/copyright index 16f03523a..e354baabf 100644 --- a/build/lemonldap-ng/debian/copyright +++ b/build/lemonldap-ng/debian/copyright @@ -6,13 +6,12 @@ Copyright: Copyright 2004, 2005, 2006 by Xavier Guimard Licence: - -Lemonldap::NG is distributed under your choice of the GNU General Public -License or the Artistic License. On Debian GNU/Linux systems, the copyright -terms for Perl itself are located in `/usr/share/doc/perl/copyright'. On Debian -GNU/Linux systems, the complete text of the GNU General Public License version -2 can be found in `/usr/share/common-licenses/GPL' and the Artistic Licence in -`/usr/share/common-licenses/Artistic'. +Lemonldap::NG is distributed under your choice under the GNU General Public +License or the Artistic License. +On Debian GNU/Linux systems, the complete text of the GNU General Public +License version 2 can be found in `/usr/share/common-licenses/GPL' and the +Artistic Licence in `/usr/share/common-licenses/Artistic'. File lemonldap-ng-manager/example/lemonldap-ng-manager.js is distributed under GNU General Public License version 2. + diff --git a/build/lemonldap-ng/debian/rules b/build/lemonldap-ng/debian/rules index 4b4d2d6bd..ae8b9fafa 100755 --- a/build/lemonldap-ng/debian/rules +++ b/build/lemonldap-ng/debian/rules @@ -67,7 +67,7 @@ binary-indep: build install binary-arch: build install dh_testdir dh_testroot - dh_installchangelogs changelogs + dh_installchangelogs changelog dh_installdocs mkdir debian/tmp/var/lib/lemonldap-ng/protected cp _example/index.pl debian/tmp/var/lib/lemonldap-ng/protected diff --git a/modules/lemonldap-ng-portal/MANIFEST b/modules/lemonldap-ng-portal/MANIFEST index ea302c7af..cd4dcb8a4 100644 --- a/modules/lemonldap-ng-portal/MANIFEST +++ b/modules/lemonldap-ng-portal/MANIFEST @@ -1,4 +1,67 @@ Changes +example/AuthLA/idps.xml +example/AuthLA/index.pl +example/AuthLA/la.log +example/AuthLA/liberty/assertionConsumer.pl +example/AuthLA/liberty/federationTermination.pl +example/AuthLA/liberty/federationTerminationReturn.pl +example/AuthLA/liberty/singleLogout.pl +example/AuthLA/liberty/singleLogoutReturn.pl +example/AuthLA/liberty/soapCall.pl +example/AuthLA/liberty/soapEndpoint.pl +example/AuthLA/ressources/db/liberty_tables.sql +example/AuthLA/ressources/db/taccounts.sql +example/AuthLA/ressources/db/tnameid.sql +example/AuthLA/ressources/db/tsessions.sql +example/AuthLA/ressources/lemonsp-metadata.xml +example/AuthLA/tpl/auth.tpl +example/AuthLA/tpl/themes/bouton_authentic.png +example/AuthLA/tpl/themes/bouton_federid.png +example/AuthLA/tpl/themes/bouton_interldap.png +example/AuthLA/tpl/themes/bouton_lemonldap::ng.png +example/AuthLA/tpl/themes/CHANGELOG +example/AuthLA/tpl/themes/dc2/button-hover.png +example/AuthLA/tpl/themes/dc2/button-normal.png +example/AuthLA/tpl/themes/dc2/default.css +example/AuthLA/tpl/themes/dc2/dotclear-logo.png +example/AuthLA/tpl/themes/dc2/drag.png +example/AuthLA/tpl/themes/dc2/head-bg.png +example/AuthLA/tpl/themes/dc2/head-logo.png +example/AuthLA/tpl/themes/dc2/magnifier.png +example/AuthLA/tpl/themes/dc2/msg-error.png +example/AuthLA/tpl/themes/dc2/msg-std.png +example/AuthLA/tpl/themes/dc2/page-bg.png +example/AuthLA/tpl/themes/dc2/tab-bg.png +example/AuthLA/tpl/themes/dc2/tab-c-l.png +example/AuthLA/tpl/themes/dc2/tab-c-r.png +example/AuthLA/tpl/themes/dc2/tab-l-l.png +example/AuthLA/tpl/themes/dc2/tab-l-r.png +example/AuthLA/tpl/themes/dc2/tab-n-l.png +example/AuthLA/tpl/themes/dc2/tab-n-r.png +example/AuthLA/tpl/themes/federid-dc2/button-hover.png +example/AuthLA/tpl/themes/federid-dc2/button-normal.png +example/AuthLA/tpl/themes/federid-dc2/default.css +example/AuthLA/tpl/themes/federid-dc2/head-bg.png +example/AuthLA/tpl/themes/federid-dc2/head-logo.png +example/AuthLA/tpl/themes/federid-dc2/msg-error.png +example/AuthLA/tpl/themes/federid-dc2/msg-std.png +example/AuthLA/tpl/themes/federid-dc2/page-bg.png +example/AuthLA/tpl/themes/federid/button-hover.png +example/AuthLA/tpl/themes/federid/button-normal.png +example/AuthLA/tpl/themes/federid/default.css +example/AuthLA/tpl/themes/federid/fond.jpg +example/AuthLA/tpl/themes/federid/head-bg.png +example/AuthLA/tpl/themes/federid/head-logo.png +example/AuthLA/tpl/themes/federid/idp.css +example/AuthLA/tpl/themes/federid/laap.css +example/AuthLA/tpl/themes/federid/msg-error.png +example/AuthLA/tpl/themes/federid/msg-std.png +example/AuthLA/tpl/themes/federid/page-bg.png +example/AuthLA/tpl/themes/federid/sso.css +example/AuthLA/tpl/themes/federid/wui.css +example/AuthLA/tpl/themes/README +example/AuthLA/tpl/themes/styleswitcher.js +example/AuthLA/tpl/themes/template.html example/index.pl example/scripts/purgeCentralCache example/scripts/purgeCentralCache.cron.d diff --git a/modules/lemonldap-ng-portal/example/AuthLA/idps.xml b/modules/lemonldap-ng-portal/example/AuthLA/idps.xml new file mode 100644 index 000000000..efebb3912 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/idps.xml @@ -0,0 +1,15 @@ + + + http://idp1/liberty/metadata + /path/to/idp1-metadata.xml + /path/to/idp1-key-public.pem + /path/to/idp1-key-public.pem + + + http://idp2/liberty/metadata + /path/to/idp2-metadata.xml + /path/to/idp2-key-public.pem + /path/to/idp2-key-public.pem + + + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/index.pl b/modules/lemonldap-ng-portal/example/AuthLA/index.pl new file mode 100644 index 000000000..3e796ad48 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/index.pl @@ -0,0 +1,70 @@ +#!/usr/bin/perl + +use strict ; +use warnings ; + +use HTML::Template ; +use Lemonldap::NG::Portal::AuthLA; + + + +my $portal = Lemonldap::NG::Portal::AuthLA->new({ + configStorage => { + type => 'File' , + dirName => '/var/lib/lemonldap-ng/config' , + } , + + # Liberty Parameters + laSp => { + certificate => '/var/lib/lemonldap-ng/web/portal/ressources/lemonsp-key-public.pem' , + metadata => '/var/lib/lemonldap-ng/web/portal/ressources/lemonsp-metadata.xml' , + privkey => '/var/lib/lemonldap-ng/web/portal/ressources/lemonsp-key-private.pem' , + secretkey => '/var/lib/lemonldap-ng/web/portal/ressources/lemonsp-key-private.pem' , + } , + laIdpsFile => '/var/lib/lemonldap-ng/web/portal/idps.xml' , + laStorage => 'Apache::Session::File', + laStorageOptions => { + Directory => '/var/lib/lemonldap-ng/var/assertion' , + LockDirectory => '/var/lib/lemonldap-ng/var/lock' , + } , + laDebug => 1 , + laLdapLoginAttribute => 'uid' , + + # Parameters that permit to access lemonldap::NG::Handler local cache + localStorage => 'Cache::FileCache' , + localStorageOptions => {} , +}); + + + +if( $portal->process() ) { + + # Print protected URLs + + print $portal->header ; + print " $_
" + foreach ($portal->getProtectedURLs) ; + +} else { + + # Retrieve IDP list. + + my @idps = () ; + foreach ($portal->getIdpIDs) { + my %row_data ; + $row_data{IDPNAME} = $_ ; + push (@idps, \%row_data) ; + } + @idps = sort {$a cmp $b} @idps ; + + # Print template + + print $portal->header ; + my $template = HTML::Template->new( filename => '/var/lib/lemonldap-ng/web/portal/tpl/auth.tpl' ) ; + $template->param( AUTH_ERROR => $portal->error ) ; + $template->param( AUTH_URL => $portal->param('url') ) ; + $template->param( AUTH_IDPS => \@idps ) ; + print $template->output ; + +} + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/la.log b/modules/lemonldap-ng-portal/example/AuthLA/la.log new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/la.log @@ -0,0 +1 @@ + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/liberty/assertionConsumer.pl b/modules/lemonldap-ng-portal/example/AuthLA/liberty/assertionConsumer.pl new file mode 120000 index 000000000..aaea3e99b --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/liberty/assertionConsumer.pl @@ -0,0 +1 @@ +../index.pl \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/liberty/federationTermination.pl b/modules/lemonldap-ng-portal/example/AuthLA/liberty/federationTermination.pl new file mode 120000 index 000000000..aaea3e99b --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/liberty/federationTermination.pl @@ -0,0 +1 @@ +../index.pl \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/liberty/federationTerminationReturn.pl b/modules/lemonldap-ng-portal/example/AuthLA/liberty/federationTerminationReturn.pl new file mode 120000 index 000000000..aaea3e99b --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/liberty/federationTerminationReturn.pl @@ -0,0 +1 @@ +../index.pl \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/liberty/singleLogout.pl b/modules/lemonldap-ng-portal/example/AuthLA/liberty/singleLogout.pl new file mode 120000 index 000000000..aaea3e99b --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/liberty/singleLogout.pl @@ -0,0 +1 @@ +../index.pl \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/liberty/singleLogoutReturn.pl b/modules/lemonldap-ng-portal/example/AuthLA/liberty/singleLogoutReturn.pl new file mode 120000 index 000000000..aaea3e99b --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/liberty/singleLogoutReturn.pl @@ -0,0 +1 @@ +../index.pl \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/liberty/soapCall.pl b/modules/lemonldap-ng-portal/example/AuthLA/liberty/soapCall.pl new file mode 120000 index 000000000..aaea3e99b --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/liberty/soapCall.pl @@ -0,0 +1 @@ +../index.pl \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/liberty/soapEndpoint.pl b/modules/lemonldap-ng-portal/example/AuthLA/liberty/soapEndpoint.pl new file mode 120000 index 000000000..aaea3e99b --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/liberty/soapEndpoint.pl @@ -0,0 +1 @@ +../index.pl \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/liberty/tpl b/modules/lemonldap-ng-portal/example/AuthLA/liberty/tpl new file mode 120000 index 000000000..b3a91eee2 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/liberty/tpl @@ -0,0 +1 @@ +../tpl \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/liberty_tables.sql b/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/liberty_tables.sql new file mode 100644 index 000000000..d531fa9b8 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/liberty_tables.sql @@ -0,0 +1,37 @@ +create table taccounts +( + id_account int NOT NULL AUTO_INCREMENT, + uid blob NOT NULL, + identity_dump blob NOT NULL, + timestamp TIMESTAMP, + divers blob NULL, + unique index (id_account), + primary key (id_account) +); + +create table tnameid +( + id_nameid int NOT NULL AUTO_INCREMENT, + nameid varchar(100) NOT NULL, + id_account int NOT NULL, + timestamp TIMESTAMP, + divers blob NULL, + unique index (id_nameid), + primary key (id_nameid) +); + +create table tsessions +( + id_session int NOT NULL AUTO_INCREMENT, + session_nb blob NOT NULL, + id_account int NOT NULL, + id_nameid int NOT NULL, + session_dump blob NULL, + timestamp TIMESTAMP, + divers blob NULL, + unique index (id_session), + primary key (id_session) +); + + + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/taccounts.sql b/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/taccounts.sql new file mode 100644 index 000000000..0faea2a5a --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/taccounts.sql @@ -0,0 +1,11 @@ +create table taccounts +( + id_account int NOT NULL AUTO_INCREMENT, + uid blob NOT NULL, + identity_dump blob NULL, + timestamp TIMESTAMP, + divers blob NULL, + unique index (id_account), + primary key (id_account) +); + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/tnameid.sql b/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/tnameid.sql new file mode 100644 index 000000000..0d63a7aa5 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/tnameid.sql @@ -0,0 +1,12 @@ +create table tnameid +( + id_nameid int NOT NULL AUTO_INCREMENT, + nameid varchar(100) NOT NULL, + id_account int NOT NULL, + timestamp TIMESTAMP, + divers blob NULL, + unique index (id_nameid), + primary key (id_nameid) +); + + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/tsessions.sql b/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/tsessions.sql new file mode 100644 index 000000000..b0d0aa5bc --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/ressources/db/tsessions.sql @@ -0,0 +1,14 @@ +create table tsessions +( + id_session int NOT NULL AUTO_INCREMENT, + session_nb blob NOT NULL, + id_account int NOT NULL, + id_nameid int NOT NULL, + session_dump blob NULL, + timestamp TIMESTAMP, + divers blob NULL, + unique index (id_session), + primary key (id_session) +); + + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/ressources/lemonsp-metadata.xml b/modules/lemonldap-ng-portal/example/AuthLA/ressources/lemonsp-metadata.xml new file mode 100644 index 000000000..5f0fd27cf --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/ressources/lemonsp-metadata.xml @@ -0,0 +1,51 @@ + + + + + + + http://auth.example.com/liberty/assertionConsumer.pl + + http://auth.example.com/liberty/singleLogout.pl + http://auth.example.com/liberty/singleLogoutReturn.pl + + http://projectliberty.org/profiles/slo-idp-soap + http://projectliberty.org/profiles/slo-idp-http + http://projectliberty.org/profiles/slo-sp-soap + http://projectliberty.org/profiles/slo-sp-http + + http://auth.example.com/liberty/federationTermination.pl + http://auth.example.com/liberty/federationTerminationReturn.pl + 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 + + + + http://auth.example.com/liberty/soapEndpoint.pl + + + + true + + + + + + Lemonldap-NG Service Provider + Lemonldap-NG Service Provider + http://auth.example.com/ + + + + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/auth.tpl b/modules/lemonldap-ng-portal/example/AuthLA/tpl/auth.tpl new file mode 100644 index 000000000..f42a31b7d --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/auth.tpl @@ -0,0 +1,54 @@ + + + + + LemonLDAP::NG Portal - Authentication + + + + + + +
+

 

+

FederID WebSSO

LemonLDAP::NG Portal - Authentication

+
+ +
+ +

+ + " /> + +
Authentication on this service (no Identity federation) + + + " /> +
+ +
+
+ + + +
+ +
Liberty Alliance authentication + +
+ +
Submit your choice + + +
+
+ + + + + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/CHANGELOG b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/CHANGELOG new file mode 100644 index 000000000..dbc8e0db9 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/CHANGELOG @@ -0,0 +1,11 @@ +- 22/O7/2007 - Clement OUDOT : + * Remove old skins + * Create alternatives for all FederID components, based on specifc colors +- 20/07/2007 - Clement OUDOT: + * Modifiy layout -> template.html + * Import DotClear 2 admin theme + * Build a first FederID theme based upon DC2 admin + * Build a real FederID theme +- 08/07/2007 - Clement OUDOT : + * Import default theme from Authentic project, based on DotClear 2 theme + * Create sample test page diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/README b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/README new file mode 100644 index 000000000..4d8ea8c1d --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/README @@ -0,0 +1,13 @@ +================================================================================ + README +================================================================================ + +These are the themes for FederID project. The goal is to provide to all FederID +components the same Look 'n Feel. + +Each theme has its own directory (eg. default/) and can have alternatives. + +A sample page test (template.html) must be modified to allow switching between +the themes that are created. + +You can use this page locally to test your theme. diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_authentic.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_authentic.png new file mode 100644 index 0000000000000000000000000000000000000000..eb62ae21ff1e4e5c562436c1adc5558e1dfc6894 GIT binary patch literal 871 zcmV-t1DO1YP)e zSad^gZEa<4bO0!0DIh~^>1}0hbRbVvL{C%=f}+y^00PfRL_t(o!|j+~OWR-+#(!;E zLsbmw{F_jW5Hll{lB-TA>Q=>)1 zYU?h>Tx$~-ont~hSIK+wq@{>Dg{9JrGKcRD73Y;y;#0y7qGRp zmFekeIyyQYg)>bPRaHF$YHx3UcA@CNWKu zmX?-(D`0UO2G5;b52f9a2%%wH#9WF+1VM1M1pucezzWr#TXkK!*yMn znwq#jO(=>&I-T~!`tjY*_*g8)`1m-NmzTJ%izG?a8C!WX;5l~2Z9lEQ4qMhbQmGUT4GrkJ?kiv@6bhWx#bObF zQmItcpF~kak|Y#G0q_jc4;$1(QKV2P`1&KyRl1>22vt>CT3P}ipU;y{rwNC{l*?rR z1VKO$1VmA+=_OAIFqg|ANz&a2C5mETY*4;~g98$Y1ncYTKYLz9JkKhiEX(Bcc{VpU ztNLL)9%p-d8-Uf-RVF7VIXyk);^LwTzq7N$=;$bhVK6s07l_kw9J;%^nV6UWpj<8o z#s=lv+uK8yWu~U4xW2w7lgVJ)_V2`*ot?e?brSJ2zY_lV_6qe zSad^gZEa<4bO0!0DIh~^>1}0hbRbVvL{C%=f}+y^00M4FL_t(o!|j;QOCn(y$3M;p z3Q=KhZQwu$8xX;(wg+Q|u8Xkej{AqS=U~}Cpj+U*!`?b1cu_ANM1l;aKqYA2P$P^n zoINbH$&A0(FzkDLpYJ@+cfRw^`@YZX(KOB0G>s38k4z?mSJN~O4h{e~JZicUliz;3 zj(_>I4?wkArBA40Qr30 zA?!86;V^+f0K+g4LO9}*BoU29v27cV$1`yrMN#N>yKHQ1P_0%mO>->$k|d$)I)6i`)l_ze86{cwWj^k^Y6B*DTAjxVgFMiK(heCX)f6 zUau1lhbb0|J)EtrEsl?mUrcbrD0u+N)PG`(Mq+$H$5D40?W4EG;d)tmkjG1`dJ{g7fopn$5rGPM^=`;8>Q$ z^71nG_xFTCAy;!o$ulh^Ng^JPb9s3=KL(ziouTVGvMl5EdMOr*TwGlAaI)DfsZ@$~ zyG^IlnK;j+NF)-(VliY{#xM-m4P<5p4m(sg8VycPP6l%7^*ZTvdg?rbwDgPRa=DQk zgLiR|o@eyTz@YlWmGt%V@V@Z5wOO=Y*z<84Gu>^>AJZ5dUmYL>>;M1&07*qoM6N<$ Ef>pC(B>(^b literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_interldap.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_interldap.png new file mode 100644 index 0000000000000000000000000000000000000000..623c149b105e414e81219cdff017326677b6d031 GIT binary patch literal 895 zcmV-_1AzRAP)e zSad^gZEa<4bO0!0DIh~^>1}0hbRbVvL{C%=f}+y^00QSpL_t(o!|j;8OB-<*$3NyG z7mYMQkc5~;xtt*og$SAv? zPwzed43y93DHIAXioDLwP5_*L3qOB5c@TkxLV>llwHHNTJRS$Y@mh$FgYzkZPEJlT zGc$9mT`U$u(==37eUg0fcpOQR&~+U_5ZK$>Bb`oPvl|;5!|8M~KR@5l-!KeJ(`0dR z5yLQ^p1`Zq0#prjh)~1-z`a{Qn5;>zyFWZ z>FFt@QprYOC=}x0;DBniO0ifZ5{cMiRjXB2S63f&kmu*;xLhuqtf!}km6a80wHm|2 z!)$MF+w_BjgY@h=0RZADSUaN7K?a19;+vcqWE8O zIUEiK1_sFGa+XYzByzbNhlhs%WV2ahS-#fip8XcSEB5#I85tQN5{WQ3H)jpye!rjb z@o}qnUFvRv*Xw0sV!}F<+1XiJ2}Yw)1VKPmRoev;4u@G@UPjY20FI81NG6l_BCu(C zdb)nOiQI&nO8Co%KcD$a9Hf_)mR<+xXBnj5_TRo2UamGTZWm6aQV$ODbN=;j%x~5@ VEX=n-B)b3r002ovPDHLkV1g>6mSF$@ literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_lemonldap::ng.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/bouton_lemonldap::ng.png new file mode 100644 index 0000000000000000000000000000000000000000..b50979c7d51f576523339ef8007a37fae3fdce2f GIT binary patch literal 1143 zcmV--1c>{IP)F#aKr!r02y>e zSad^gZEa<4bO0!0DIh~^>1}0hbRbVvL{C%=f}+y^00ZAiL_t(o!|j;MN-J9shQB0@ z9gRjq2#OaJb3=o1;2nZQoTvdEIMgTbC3HWB6JH<`k%JRKB;W-!h<95}3r5hS;{{FZ zpy@NR*}=rUw`Y4M`cJy)s%(9$AP54cs!Jsmvef0%I)o~?q6M9&C$_OL5}tHbtFl`Xf!e~FhE;d z8;6I7R8>`x%jFP75mi;WzrQCO4kHKx6B83}1O!l3m6nzk_V)GwC@n3eqoafQ`FYam zGysi_jd^Q6Erok}dT=-#B$G)72M4iQtpoxAYHMqGe0*edbQGV@M=F(KWMqW?{(h>f ztGT(kAruN>u~>BfOeVwd@bJ5Qxm=EojSbvxH_gq>#9}ed&dzYTTt!c_+wIn`0NdN! z`2Bti1_J=i&CMJiAM4@)oS&Z;Phq>ea1r@Pb#}YmEH5tuaCv!&)9FN2RXxSJySrIk zT_u~%;`90NdcDlf&Z21=R;v}4%a!Nf(b4hCpglf5Vm6!cdc8y<5nf(i7#tjAZ*LE) z)ynwzIHD*LjYiqu-$&ClVzC&SreU|+QB{@m^K(2N4*+FlWjs7Q0N`*q=!Q( z92{_WcL#tditqZ1qDWL+xLen%7i3GAN69@#}mvlB&8u-ok@ijrsB+S;PMy`6MA&C1FOp-@N{`SkQO&(|iqLu_&VBrxmozN)%X~GeEGjI{{rG002ov JPDHLkV1jJ@0D=Gj literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/button-hover.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/button-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..43d298b9511cb803b9bcc5b67e450caccdd9a525 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!VDw>m!3)iQq09po*^6@9Je3(KLBz?1AIbU z|F0AMe?y zW>IQ+eo=O@f^Wp`iCQWk(>z@qLn`JZ7bG+|GPbcOm@ph-U}IxYj$k^t#^7NlPz8gh LtDnm{r-UW|a~49A literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/button-normal.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/button-normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b9d4de86308f93debda2179766c97617f3a6eb GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!VDw>m!3)iQq09po*^6@9Je3(KLBz?1AIbU zx1YUs>ej>kmu_Er@ND<_8)xr6K6d^7e=fI|Kn0uy9+AZi4BSE>%y{W;-5;Q!Scz*y ziE~kEVo7FxogTe~DWM4f7-mPn literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/default.css b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/default.css new file mode 100644 index 000000000..8c9025b03 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/default.css @@ -0,0 +1,731 @@ +body { + font: 62.5%/1.5em "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif; + color : #000; + background : #fff url(page-bg.png) repeat-y top left; + margin : 0; + padding : 0; +} +body.auth { + background-image: none; +} +body.install #content { + margin-top: 1em; + font-size: 1.1em; +} + +a img,:link img,:visited img { border:none } + +a, a:link, a:visited { + color : #06c; + text-decoration : none; + border-bottom : 1px dotted #f90; +} +a:hover, a:active, a:focus { + +} + +h1, h2, h3, h4, h5, h6, p { + margin-top : 0; + margin-bottom: 0.6em; +} + +h2 { + font-family : Arial,Helvetica,sans-serif; + color : #069; + font-size : 1.4em; +} + +h3 { + color : #333; + font-size : 1.2em; +} + +p, div.p { + margin : 0 0 1em 0; +} + +hr { + height : 1px; + border-width : 1px 0 0 0; + border-color : #999; + border-style : solid; +} + +pre, code { + font: 100% "Andale Mono","Courier New",monospace; +} + +/* LAYOUT +-------------------------------------------------------- */ +/* General font-size */ +#top, #info-box, #main, #main-menu, #footer { + font-size: 1.1em; +} + +#top { + margin : 0; + padding : 0; + background : transparent url(head-bg.png) repeat-x; +} +#top h1 { + padding : 0; + margin : 0; + height : 58px; + text-indent : -1000px; + background : transparent url(head-logo.png) no-repeat 0 0; +} +#top h1 a { + position: absolute; + top: 3px; + left: 0; + width: 170px; + height: 35px; + border: none; +} + +#info-box { + position : absolute; + right : 20px; + top : 6px; + margin : 0; + padding : 3px 3px 4px 15px; +} +#info-box div { + margin: 0; padding: 0; +} +#info-box div div { + display: inline; +} +#info-box select { + width : 160px; +} +#info-box a { + font-weight : bold; +} + +#main { + width : 100%; + float : right; + margin-left : -155px; + margin-top : 0; +} + +#content { + margin-left : 155px; + margin-bottom : 10px; + padding-top : 1px; + margin-right : 15px; +} + +#main-menu { + width : 135px; + float : left; + margin-top : 0; + margin-bottom : 10px; +} +#main-menu h3 { + margin : 0; + padding : 0 0 0 5px; +} +#main-menu ul { + margin : 0 0 1em 0; + padding : 0; + list-style : none; +} +#main-menu li { + display : block; + margin : 0.5em 0 0 5px; + padding : 2px 0 1px 20px; + background-repeat: no-repeat; + background-position: 0 0; +} +#main-menu a { + font-weight : bold; +} +#main-menu .active a { + border-bottom-style: solid; +} + +#default-blog { + position: absolute; + top: 58px; + right: 30px; + height: 1.5em; + font-size : 140%; + font-weight: bold; +} + +#footer { + clear : both; + padding : 3px 5px 0 25px; +} +#footer a { + border: none; +} + +#debug { + position: absolute; + top: 0; + width: 100%; + height: 4px; + background: #d99; +} +#debug div { + display: none; + padding: 3px 0.5em 2px; +} +#debug p { + margin : 0.5em 0; +} +#debug:hover { + height: auto; +} +#debug:hover div { + display: block; +} + +/* DASHBOARD */ +#dashboard { + font-size: 120%; + padding-top: 2em; + clear: left; +} +#dashboard p img { + vertical-align: middle; +} +#dashboard ul { + display: block; + margin: 0; + padding-left: 1.5em; + list-style: square; +} +#dashboard li { + margin: 0.25em 0 0 0; + color: #666; +} + +#dashboard-icons p { + float: left; + width: 32%; + text-align: center; + margin: 2em 0 0 0; +} +#dashboard-icons span { + display: block; +} +#dashboard-icons a { + border-bottom-width: 0; +} +#dashboard-icons span a { + border-bottom-width: 1px; +} + +/* POST */ +#entry-sidebar { + width : 200px; + float : right; +} +#entry-content { + margin-right : 220px; +} +#comments { + clear : both; +} + +/* MEDIA */ +#media-icon { + float: left; +} +#media-details { + margin-left: 70px; +} +#media-details ul { + display: block; + margin-left: 0; + padding: 0; +} +#media-details li { + list-style: square inside; + margin: 0; + padding: 0; +} +#media-original-image { + overflow: auto; +} +#media-original-image.overheight { + height: 500px; +} + +#add-file-f { + position: relative; +} +#add-file-f .more-file { + position:absolute; + right: 0.5em; + background: #999; + color: #fff; + border: none; +} + +/* POPUP */ +body.popup { + background-position : -120px 0; +} +body.popup #top h1 { + background-position : -120px 0; +} +body.popup #main { + margin-left : -35px; +} +body.popup #content { + margin-left : 35px; +} +body.popup #footer { + clear : both; + padding-top : 20px; + padding-left : 35px; +} + +/* CLASSES +-------------------------------------------------------- */ +a.help-link { + border: none; +} + +.help-content dt { + font-weight: bold; + color: #666; + margin: 0; +} +.help-content dd { + margin: 0.3em 0 1.5em 0; +} + +.clear { + clear : both; +} +.lclear { + clear : left; +} +div.clearer { + height : 1px; + font-size : 1px; +} + +.hide { + display : none; +} + +.right { + text-align : right; +} + +.frame-shrink { + border: 1px solid #666; + padding: 0.5em; + margin-bottom: 1em; + height: 120px; + overflow: auto; +} + +div.error { + border : 2px solid #c00; + padding : 0.5em 0.5em 0.5em 40px; + margin-bottom : 1em; + background : transparent url(msg-error.png) no-repeat 5px 50%; +} + + +.line p { + margin : 0; +} + +.message, .static-msg { + font-weight : bold; + color : #f60; + padding : 0.5em 0.5em 0.5em 40px; + border : 1px solid #ccc; + background : transparent url(msg-std.png) no-repeat 5px 50%; +} + +.offline { + color : #666; +} + +ul.nice { + margin: 1em 0; + padding: 0 0 0 2em; + list-style: square; +} +ul.nice li { + margin:0; + padding: 0; +} + +.three-cols { +} +.three-cols .col { + width : 32.3%; + float : left; + margin-left : 1%; +} +.three-cols .col:first-child { + width : 33.3%; + margin-left : 0; +} + +.two-cols { + position : static; +} +.two-cols .col { + width : 49%; + margin-left : 1%; + float : left; +} +.two-cols .col:first-child { + width : 50%; + margin-left : 0; +} + +.comment { + border-top : 2px solid #ccc; + margin-bottom : 1em; + padding : 2em 0 1em 0; + position : relative; +} +.comment form p { + margin : 0; + position : absolute; + top : 2px; + right : 0; +} + + +.part-tabs { + float: left; + width: 100%; + background: transparent url(tab-bg.png) repeat-x bottom; + margin-bottom: 2em; +} +.part-tabs ul { + margin: 0; + padding: 10px 10px 0; + list-style: none; +} +.part-tabs li { + float: left; + background: transparent url(tab-n-l.png) no-repeat top left; + margin: 0 3px 0 0; + padding: 0 0 0 5px; +} +.part-tabs a { + display: block; + background: transparent url(tab-n-r.png) no-repeat top right; + padding: 1px 10px 1px 5px; + border: none; +} +.part-tabs li.part-tabs-active { + background-image: url(tab-c-l.png); +} +.part-tabs li.part-tabs-active a { + background-image: url(tab-c-r.png); + padding-bottom: 2px; + font-weight : bold; +} +.part-tabs li.part-tabs-link { + background-image: url(tab-l-l.png); +} +.part-tabs li.part-tabs-link a { + background-image: url(tab-l-r.png); +} + + +.screenshot { + width: 250px; + float: left; + margin-left: 10px; +} +.screenshot img { + border : 1px solid #333; +} +.screenshot p { + font-size: 0.9em; +} + +.media-list { + position : static; +} +.media-col-0 { + clear: left; +} +.media-item { + position: relative; + border-top: 1px solid #ccc; + margin-bottom: 1em; + padding: 5px 0; +} +div.media-list .media-item { + width: 49%; + float: left; + margin-right: 1%; +} +a.media-icon { + display: block; + border-bottom: none; + float: left; +} +.media-icon img { + display: block; +} +.media-item ul { + display: block; + list-style: none; + margin: 0 0 0 60px; + padding: 0; +} +li.media-action { + display: block; + position: absolute; + top: 5px; + right: 5px; + height: 16px; +} +li.media-action a { + border: none; +} +li.media-action form { + display: inline; +} +li.media-action input { + border: none; +} + +select.l10n option { + padding-left: 16px; +} +option.avail10n { + background: transparent url(../images/check-on.png) no-repeat 0 50%; +} + +/* TABLES +-------------------------------------------------------- */ +table { + font-size : 1em; + border-collapse : collapse; + margin : 0 0 1em 0; +} +tr.line:hover { + background : #ddd; +} +th, td { + border-width : 0 0 1px 0; + border-style : solid; + border-color : #ccc; + padding : 2px 5px; + vertical-align : top; +} +th { + text-align : left; + border-bottom-color : #666; +} + +.noborder td, td.noborder, .noborder th, th.noborder { + border-width : 0; +} + +table .maximal, table.maximal { + width : 100%; +} +table .minimal { + width : 1px; +} + +table .nowrap { + white-space : nowrap; +} + +td.status { + vertical-align: middle; +} +td.status img { + margin-bottom: -2px; +} +td.status a { + border: none; +} + +tr.line img.expand { + margin-right: 10px; + margin-bottom: -2px; +} +tr.expand td { + border-bottom: none; +} +td.expand { + padding: 1em; +} + +.dragable { + border-collapse: separate; +} +.dragable tbody td { + +} +.handle { + padding : 0; +} +.handler { + cursor : move; + background : transparent url(drag.png) no-repeat 0 50%; + padding-left : 15px; +} + +/* FORMS +-------------------------------------------------------- */ +form { + display : block; + margin : 0; + padding : 0; +} + +fieldset { + display : block; + margin : 0 0 1em 0; + padding : 1em 0.5em; + border-width : 1px 0; + border-style: solid; + border-color: #ccc; + background: #fbfbfb; +} +legend { + font-weight : bold; + padding: 0.2em 0.6em; + border-width: 1px; + border-style: solid; + border-color: #ccc; + background: #fbfbfb; +} +optgroup { + font-weight : bold; + font-style : normal; +} +option { + font-weight : normal; +} + +input, textarea, select { + background : #f9f9f9; + border-width : 1px; + border-style : solid; + border-color : #000 #ccc #ccc #000; +} +input, textarea, select, option { + font: 1em "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif; +} +input[type=text], input[type=password], textarea { + padding : 2px 0; +} +input[type=checkbox], input[type=radio] { + border: none; +} +textarea { + padding : 2px 0; +} +/*input[type=text]:focus, input[type=password]:focus, textarea:focus, option { + background : #dfdcc7; +} can't select text with opera */ +input[type=submit], input[type=reset], input[type=button] { + padding : 1px 2px; + background : #d2e0e6 url(button-normal.png) repeat-x bottom left; + border-width : 1px; + border-style : outset; + border-color : #ccc; + +} +input[type=submit]:hover, input[type=reset]:hover, input[type=button]:hover { + background-color : #fc3; + background-image : url(button-hover.png); +} + +input[type=submit] { + font-weight : bold; +} + +input[type=checkbox], input[type=radio] { + margin : 0; + padding : 0; + background : transparent; +} + +label { + display : block; +} +label input, label select, label span { + display : block; +} +p.form-note { + margin-top : -1em; + color : #f60; +} + +label.classic { + display : inline; +} +label.classic input, label span input, label.classic select, label span select { + display : inline; +} + +label.area, p.area { + width: inherit !important; + margin-right : 6px !important; +} +.area textarea { + display : block; + width : 100%; +} + +label.required { + font-weight : bold; +} +label.required:before { + content : '* '; + color : #c00; +} + +label .maximal, textarea.maximal, input.maximal { + width : 100%; +} + +a.form-control { + display : none; + font-weight: bold; + background: url(magnifier.png) no-repeat 0 0; + color: green; + padding-left: 20px; +} + +fieldset.constrained { + margin: 0; + padding: 0; + border: none; + background: transparent; +} + +#login-screen { + display: block; + width : 180px; + margin : 30px auto 0; + font-size: 1.1em; +} +#login-screen h1 { + text-indent: -2000px; + background: transparent url(dotclear-logo.png) no-repeat top left; + height: 25px; +} +#login-screen fieldset { + border: 1px solid #999; + padding: 1em 10px; +} +#login-screen input[type=text], #login-screen input[type=password] { + width: 100%; +} \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/dotclear-logo.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/dotclear-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f373df1952d146cf791f3b878ffe5f41f24b9f78 GIT binary patch literal 2371 zcmV-J3B2}+P)gxaOpXur8=;-L@=jZ0;=H=z( z;^N}r;o;!m;NRch-rnBb-QC>W+}qpR+S=OL+1c3G*w@$B*4Eb5 z)z#G0)YH?`($doZ)-ci0(a_M)&(F`!&d$ut%>U02%gf8k%F4;f$^Xm%$jHdY$H&IT z#>K_O#KgqI!^6VD!ok78zrVk}zP`P^y}Z1rlzK)rKO~#q@$ywqN1Xq zp`oClpr4JRnwgoIn3$NCmzS27mX(#2l$4Z{larE?l97>-kB^Uzj*g9u zjf{+pii(PfiHV4ah=zuSg@uKLgoJ~GgMxyBfq{X5fPjC0e|~;`eSLj=e0+O*dwP0$ zd3kwwczAbrcXoDmb#--gbaZobb8>QWadB~QaBy#LZ*FdGY;0_6Yinw1YH4X{XlQ6> zXJ=++W@Tk%WMpJxV`E}sVqsxnU|?WhUteBcUR_;XTwGjRTU%OMT3K0HSXfwBS65b6 zR#jD1R8&+`Q&Un>Qc+P+P*6}$Pft!xPEAcsOiWBmOG`>hN=ZpcNJvOWM@L3RMny$M zL_|bGLqkGBLP0@6KtMo0KR-S`K0Q4>JUl!*J3Bf$IypHxI5;>rH#asmHZ?UhG&D3b zGcz(WGA}PLEiEl9EG!}-A|W9m93O9<00009a7bBm000XT000XT0n*)m`~Uy|7IZ~e zbVG7wVRUJ4ZXi@?ZDjy3IWI9dFEBL&`&VNC001C#MObuGZ)S9NVRB^vO<`klZ*65{ zX<;BnX>w(EZ*psMAWc}ikt!qr00t9DL_t(|oYj~6SJP$~$J0i7BeYO#L2g=#TqH27 zcxurBt8g{}FS9`o)v6N-8nGMb;uP(eQ;Sp4Fc4!E5o(b#!D6vTMes6o4xDa((ULT` z;t{5t9k=ff&^+&(H=jIt@_nBG!2eUALJ`eKE|>B_nG&L;072%rGFp&K^6^l4DYS;% zJX$%%M2#YhEsN1-n#|@rL%a$ERl23Qxw-jahjuRwdW|&AsSP&)!!F-6jE1Vy5!oUYhwXDAX)$bv{&o^}Mp5JYU)vDyu zrYnI!e@~BpsrSNk9TnF^`EcD2EAcuC+TD;U>9k98ycONY1BnHcxZOWL6BzQ zqysDg!l*1kb6lSrbocV2(ie-OL$ zc&KTWhO!ZvuCyf-I$j(Hf@#}sPT$;?CZ|o>NkWlSvqKx{EF=*h(jom862K&Q%>%()|}=72^C>W_{t zqX=jtiL<{7#Lxv)z$b?G0f1c$ZI6To;?|uU8|!Mn_q@xNL>~i+jNP|hc#tFz6hre@ zdk3@|XT_K?6m|~W%|eIG!;F$HuB3}1LzGwA`@6 z_wssm@_eAJr1+oU(=Psu`9W*TPK}LqTnIiVtCAT!MdqG?=cFz1{h%Yu!xg53!ZykK zG|JoN{K`X?w262e__4Wv(z`oTNiP?(qABqB{QCIFn#PIufHrc8Cum0()ig?STlt5+ zh#M2-QmHx*?R(mLppFu%HnUDZ zOGiKD*`Nu&3f%ZRpn(JdI)Mq;1ZW#GcgE&I?}$_Vjg?kwW$me<2`{!9ww)avIaga| zHdpMw6dG;sfe%!=&bpXEaR9>iVXp9*s~6jdUN`m=Ud5 zxEgKqj|>eA3=exx+VeG1N=aKfLLFPe?oAh}n{K6zl-WWICyubPiVqN2C%yyv21L-r zOcVO&lBaEGzH+0x+vDlFaICI01CmPRx|P*P*#gI=xRa;wtnwf}*yLqQ-Y plgU6@LQF<|gDb@WAY%BV>TiiG0(gK9d{_Vg002ovPDHLkV1maqs6_w( literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/drag.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/drag.png new file mode 100644 index 0000000000000000000000000000000000000000..3e3a78dcdd68b08c586458793842f306d195f8ee GIT binary patch literal 415 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZVhIpAgqe zx1V3Q`rzP&$4AcJKXBsewiEX@9=*GI|ILLvF3s9}e&(hNlh>S^wB~HXqT@~T4^_@O zT04DjVgKID{=LynoBeCIhE{Iytk~>cvEDsrscG~iNZp zC;$Kd--3&`8)&0aNswPKkc%HM@Lo7v2vp5k;1O92^v)U(W_-_f%pEAGP~sX<5}cn_ zQl40p%HW%rT$G=inv$8Q;FejGTAp8&U98|6v3sJH3Q%pCr;B4q#hlQycg30=91pbHp0UHx3vIVCg!091&(r~m)} literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/head-bg.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/head-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..1622ef8bfaec23b3c2919e21602b82ff55fa2b43 GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^Ahs0;GmzXj%|Z!CF&8^|hH!9j+JTy{5w1us6qjx zA~-*-q&%@GmBBYLxhOw3H6=4q!7Z~WwLHHlyI8?DV)sNX6`PZ!6KiaB?W?G$Zd zU|>BM8omdKI;Vst01ua>5dZ)H literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/head-logo.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/head-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0981e096a6f8ee465211ee6b9662a84a190e4113 GIT binary patch literal 4397 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 literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/magnifier.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/magnifier.png new file mode 100644 index 0000000000000000000000000000000000000000..4e959630ae6c6acfe421e24b97b4b3e4cf8526f9 GIT binary patch literal 499 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZWLeJ|V8t z<0ZCU`O>oN($wh-H=KHLbb89&tz9Q>f4ung`|kFD89VMDz5Dg^tA{lUE-WoHJh!Cm z?yH|4U)+0fdiA=KFLs@OarVL21Gm0hUDq~o#fe>0Qm#G!e*ewSnG4rHIXHKHwZq=) zpEsR*H)r?#Gc(hUF0X(5?$_LOrO)r4?Y;Wp(471mum0S6{iki!^>feuuRs4`PjBd{ zCDs4`|L1+-o(puIVM&l*Fpx_UV342XrwG){S>O>_%)r3)0fZTy)|kuy3M!PiMwA5S zrDR4=P`5bA7uMFzF6>0N~79_ zwL@@fP{vlyf{n){Ce2|Ncra(N`OmG)nw~OI_nk~N9(+Asb@M>Vo)}RfhUbUVa(8)e zN>N^>6t|`Q?4sO~|8{eG^N!EgdzyGxJN$3gTe~DWM4f DM&t_s literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/msg-error.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/msg-error.png new file mode 100644 index 0000000000000000000000000000000000000000..db6f2b5bcf51d4df227c39f1f9e94b3eaa11a8fa GIT binary patch literal 667 zcmeAS@N?(olHy`uVBq!ia0vp^5M1+QhdU$v^IXN9Xc<{`bGe?geg)sjA{`UR* zcc5M%Hp7<{C~Rl|D&z{@2>iPd&&Rnv;SY6{{K?{ z{|jCJ&$awNUGx7~!T%%K{|}}9-=FY*Z`A+YA^*3!|KIHRf4#;3wTAy!Y5iZO@PD!7 z{{=$-=W_p_$>968hZE=^^O7LHUBukPQ!nV z+W$&b{}qe>OO*T$%p;BCJBtKG*t6TNo`xZY3D`Ne%qLVZJg zQUYU{b;E+(3X8PxBTC*6+MT}qYpGCESZ3(?y7mUQNa^ackLU8SM`TH;@0;Rv(m%Ph zQ)!;}i5D$XCk5Txu<=^xjB{x{@_`ND)&wyes(AMvi^QWSR~vwAj8Y z*o#%${KvN#hWSwn-`vV$!;|yxzF2$ULW)q2Vbts09IUGiq9bq5-luuj;MdizSR+I#Ez{D<@3e`Y;lAQQDLi$xe1o(!I@elF{r5}E+K C^fN91 literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/page-bg.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/page-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..729154ede43a2dd45319f4a53536d0e79f8c9fb0 GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^JwVLG!VDy*u&+J=q?n7HJVQ7*IBq}me*okP1^9%x zzIk=;-kpmV&K=peXVbDJb0$yf@|?F^6DZ4B;1OBOz`!j8!i<;h*8Kqrij}xVlsFfq zCYEI8=P86_=B6?jSn3;E=o^?a{|-+Es!#x_2+mI{DNig)W$;Z*F3QhMP037DaLX)8 zEzd8?E>`f3*ga881*lfS)5S5QVoq|x0vQ9X-9ZPZ1SY%nDqfdhP#0j4zM*>QDo_oB Mr>mdKI;Vst01JdiCjbBd literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-bg.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..875d66168636ce0a3795c8c5d51c5f181771132a GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^Aa(#FGmw;eS(Xo^n2Vh}LpV4%Za?&Y0OYa-_=LFr z|NlQNEv@fe&H|taXMsm#F#`j)5C}6~x?A@LC@5Cq8d2h0l$uzQnV+W+l9`*zU}T_g zV5VSNR>BeIx*fm;ZK886+f`vVjdD{+k|aV|PZ0fq0fj+{*0C3=5P^QkdRxZ3n7m@O1Ta JS?83{1OPT)X%_$h literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-c-r.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-c-r.png new file mode 100644 index 0000000000000000000000000000000000000000..c34402c60fee9a4fffbd06d3ededb7ae49c34119 GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0y~yV3Yu|9XXhRr0p_qQy|4$?Bp53!NGC+q5lIQ*DSy% z#P$FG|9}7f{r&s**RNkce*F0E-Mg1BUp{;G?7)Eo`}gnPvuDqa9XqB>nbOkI($LUQ zUtgb*k&&LB?w6#u4QPT;NswPK(1id08Neiz_!NA{5-7`A;1OBOz`!j8!i<;h*8Kqr zij}xVlsFfqCYEI8=P86_=B6?j8R#3B=^L0o|E`q;R3QUW5uBe^Ql40p%HWuipOmWL zmRXcqo?nz*tl%7MJmZ=h$Wxm=T^vIy=DfY&&DRvbaKK^FqyL)s{%?B68GAVC8H?|7 z`RvDr=RY60_2*B|Y{O{1_lakgeg3|${E*|`WA|9uOJl$3S*)0BcyLC7kAa$ma1ZA( hmgFXyayR^8d>t;fdrJALI-v6zJYD@<);T3K0RXybxdH$H literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-l-l.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-l-l.png new file mode 100644 index 0000000000000000000000000000000000000000..3ef3c827edfd8892ca3a678b1d30baf1a14b4e8c GIT binary patch literal 466 zcmeAS@N?(olHy`uVBq!ia0vp^tU&C@!3-qzD(0;PQq09po*^6@9Je3(KLB#;0(?ST z|NndU|KI!n|6c$9fA|0Yd;kC6|NsBN|NjsF|9kZR-{b%Pp8Ws!^#8wS|NlMz|L?{B ze=q<4d-ea{oB#jb{{MgN|Nra%|KIrk|K|VyxBmaX{r~@+|NpOk`TX?D=O^#py?gfT z*{PHJk00B6;J}{!`}fS4F}bCsvAMaisj0rUwmJg@(%&21nGSS`R!NXw@PB-O0a;SX zWpX)C7iWP-WHAE+w-5+3Ub5;9gLfGI}&dEXWQ#u+q}+k=5F)3KeyIidv^EloHyS*G$W%W=LtY4TuT7KdAe?Rz$`i0~dG9LxM2vjvx$XhkrDb+RHbAB&y-)Z^<=_CF>{xXU_ Wkhs42;$vH&wG5uFelF{r5}E*i1OU+h literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-l-r.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-l-r.png new file mode 100644 index 0000000000000000000000000000000000000000..7daecc100d7d76bf82fbcf9571448fe15213d9f2 GIT binary patch literal 598 zcmeAS@N?(olHy`uVBq!ia0y~yV3Yu|9XXhRr0p_qQy|4$?Bp53!NGC+q5lIQw>Q8i z#P$EbcmMx=`2X+y|9@})|G)YF|E>T3Z~y;)=l}n^|Nr0n|Ns8~{}2BEfB663qyPUN z|Nr;o|G%gI|2_Nv@A?0KFaG~~`TyUm|Nmb9|M%wq|7-vMU;qFA#{d6U|NeRR``4?l zU!HyZ@c11NynXQU#jR)0o*g)_XaD{^d-iPEv19#|Dg7-ijSUTT^>sBF85!y6=|JL3 z@Y*>*hv}CD`33(c02ol^v%lDV0BYqd@Q5sCVBi)4Va7{$>;3=*#Y$WwN}P*Q6H7Al z^Atidb5j|N4D=1m^bO3Pf7eO^s*nMx2+mI{DNig)WpGT%PfAsA%PdMQ&o9a@R&WkB zo^j0$6p*()T^vIy=DfXdJdh=jfjRKu-tPeibm|@~{&V>8K96*ZFWn1Pf9*~E{My7f z>fofKx1ay9$rRmhQ+KAPQ*K{e%ahuFubb*$WoGamv`ywZCgL3KArZ_ItCZ+-a7NM# zCeGxpg~cj8nr-JM7%WThF)Zn7F+6&KQwXT=xW}0pJ%+8NEiFKz14J~m7_ugFWy^B{ z34RbE4kV6=T;l^Ozh(v^#DGMP<{Dq1iEDU4L@AJv2#(kev^2sTL|g|F2Fo_Q16uci Z|I4heGczAd%mI3n!PC{xWt~$(69C6oJh%V= literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-n-l.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-n-l.png new file mode 100644 index 0000000000000000000000000000000000000000..a3fb8b95cab90fd41188f2400c5ec6d3f6493d7e GIT binary patch literal 462 zcmeAS@N?(olHy`uVBq!ia0vp^tU&C@!3-qzD(0;PQq09po*^6@9Je3(KLB#81AIbU z-@SYH>iL6L&+or_@$l8NJFlMKd-V*6?!J0@`_cQCucdtLVcVqYNoqKj~ z+qHAY&K+AOPV8@JsBfsRtE;Q6s;bP$NY6-5|HA!z8_*e=B|(0{4F8D)PRGx!0BYha z@Q5sCVBi)4Va7{$>;3=*#Y$WwN}P*Q6H7Al^Atidb5j|N4D=1m^bO3Pf7eO^s*nMx z2+mI{DNig)WpGT%PfAsA%PdMQ&o9a@R&WkBo^j0$6kyq&E{-7*Q*)2F^D!BUxEwT7 zdp_qgPsO`>C%JC@i$Ys9Ja=8cw4us=$*;~GTa|bJwB^zzlj`ygzIRy4y`OzQ zuPO79+8@e4f`17ANIqh`BJ#le!|{*qXCKi%B7G$KhxL)_6_y9=57|FtzIIijfBV5p RPl47lc)I$ztaD0e0sz6b_ay)T literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-n-r.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/dc2/tab-n-r.png new file mode 100644 index 0000000000000000000000000000000000000000..1d1cbc2cc3fe432349ae6bf51310609578ac1de5 GIT binary patch literal 586 zcmeAS@N?(olHy`uVBq!ia0y~yV3Yu|9XXhRr0p_qQy|4$?Bp53!NGC+q5lIQw=2LW z#P!{~cdwp5c=h7ZtLOJ$y?FTQ`Mp=q?!J0<=hd@&ub$p{_4L-$r%zuzd+_S%?N?83 zJb!Zc)svgAo?L(R`0A_2*Iqro{_4?{SC1~gdUWa4Lm;~F>fyy#56-=MaN*U1^RFJ9 zeR%)oy*t-#-@J1D%DLUUckbG?bL09oYuBvk>+No6sIRT5uCA`iNC$z8jP%*<(`Nx) zrB@Q<7tHXV6c9B11JJ(=oCO|{#S9GGLLkg|>2BR0prBZZYeb22QEFmIW`3SRNM>#- zgOP#0ftkL6`Sb5uNkA1cAQi#+X(i=}MX3yqDfvmM3T~N2spa`a*~JRZ!NxPLxq$-l zvZsqE}CVy!iQh?u-oEOzwlX71XShmr2}mbn9DQwi62v#BvQKAZ# zOX7OX#c9}D+6z>&3us5;T}8!Z3d=U+0o6wEd#rJX7-S1p{F<|~p7B^ob^Q~+pWHz2 OF?hQAxvXm!3)iQq09po*^6@9Je3(KLBz?1AIbU z|F0AMe?y zW>IQ+eo=O@f^Wp`iCQWk(>z@qLn`JZ7bG+|GPbcOm@ph-U}IxYj$k^t#^7NlPz8gh LtDnm{r-UW|a~49A literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/button-normal.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/button-normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b9d4de86308f93debda2179766c97617f3a6eb GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!VDw>m!3)iQq09po*^6@9Je3(KLBz?1AIbU zx1YUs>ej>kmu_Er@ND<_8)xr6K6d^7e=fI|Kn0uy9+AZi4BSE>%y{W;-5;Q!Scz*y ziE~kEVo7FxogTe~DWM4f7-mPn literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/default.css b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/default.css new file mode 100644 index 000000000..1d598eb6e --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/default.css @@ -0,0 +1,252 @@ +body { + font: 62.5%/1.5em "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif; + color : #000; + background : #fff url(page-bg.png) repeat-y top left; + margin : 0; + padding : 0; +} + +a img,:link img,:visited img { border:none } + +a, a:link, a:visited { + color : #06c; + text-decoration : none; + border-bottom : 1px dotted #f90; +} +a:hover, a:active, a:focus { + +} + +h1, h2, h3, h4, h5, h6, p { + margin-top : 0; + margin-bottom: 0.6em; +} + +h2 { + font-family : Arial,Helvetica,sans-serif; + color : #069; + font-size : 1.4em; +} + +h3 { + color : #333; + font-size : 1.2em; +} + +p, div.p { + margin : 0 0 1em 0; +} + +hr { + height : 1px; + border-width : 1px 0 0 0; + border-color : #999; + border-style : solid; +} + +pre, code { + font: 100% "Andale Mono","Courier New",monospace; +} + +/* LAYOUT +-------------------------------------------------------- */ +/* General font-size */ +#top, #info-box, #content, #main-menu, #footer { + font-size: 1.1em; +} + +#top { + margin : 0; + padding : 0; + background : transparent url(head-bg.png) repeat-x; +} + +#top h1 { + padding : 0; + margin : 0; + height : 58px; + text-indent : -1000px; + background : transparent url(head-logo.png) no-repeat 0 0; +} + +#info-box { + position : absolute; + right : 20px; + top : 6px; + margin : 0; + padding : 3px 3px 4px 15px; +} + +#main-menu { + width : 135px; + float : left; + margin-top : 0; + margin-bottom : 10px; +} +#main-menu h3 { + margin : 0; + padding : 0 0 0 5px; +} +#main-menu ul { + margin : 0 0 1em 0; + padding : 0; + list-style : none; +} +#main-menu li { + display : block; + margin : 0.5em 0 0 5px; + padding : 2px 0 1px 20px; + background-repeat: no-repeat; + background-position: 0 0; +} +#main-menu a { + font-weight : bold; +} +#main-menu .active a { + border-bottom-style: solid; +} + +#content { + margin-left : 155px; + margin-bottom : 10px; + padding-top : 1px; + margin-right : 15px; +} + +#footer { + clear : both; + padding : 3px 5px 0 25px; +} +#footer a { + border: none; +} + +/* CLASSES +-------------------------------------------------------- */ +.error { + border : 2px solid #c00; + padding : 0.5em 0.5em 0.5em 40px; + margin-bottom : 1em; + background : transparent url(msg-error.png) no-repeat 5px 50%; +} + + +.message { + font-weight : bold; + color : #f60; + padding : 0.5em 0.5em 0.5em 40px; + border : 1px solid #ccc; + background : transparent url(msg-std.png) no-repeat 5px 50%; +} + +/* TABLES +-------------------------------------------------------- */ +table { + font-size : 1em; + border-collapse : collapse; + margin : 0 0 1em 0; +} +tr.line:hover { + background : #ddd; +} +th, td { + border-width : 0 0 1px 0; + border-style : solid; + border-color : #ccc; + padding : 2px 5px; + vertical-align : top; +} +th { + text-align : left; + border-bottom-color : #666; +} + +/* FORMS +-------------------------------------------------------- */ +form { + display : block; + margin : 0; + padding : 0; +} + +fieldset { + display : block; + margin : 0 0 1em 0; + padding : 1em 0.5em; + border-width : 1px 0; + border-style: solid; + border-color: #ccc; + background: #fbfbfb; +} +legend { + font-weight : bold; + padding: 0.2em 0.6em; + border-width: 1px; + border-style: solid; + border-color: #ccc; + background: #fbfbfb; +} +optgroup { + font-weight : bold; + font-style : normal; +} +option { + font-weight : normal; +} + +input, textarea, select { + background : #f9f9f9; + border-width : 1px; + border-style : solid; + border-color : #000 #ccc #ccc #000; +} +input, textarea, select, option { + font: 1em "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif; +} +input[type=text], input[type=password], textarea { + padding : 2px 0; +} +input[type=checkbox], input[type=radio] { + border: none; +} +textarea { + padding : 2px 0; +} +input[type=submit], input[type=reset], input[type=button] { + padding : 1px 2px; + background : #d2e0e6 url(button-normal.png) repeat-x bottom left; + border-width : 1px; + border-style : outset; + border-color : #ccc; + +} +input[type=submit]:hover, input[type=reset]:hover, input[type=button]:hover { + background-color : #fc3; + background-image : url(button-hover.png); +} + +input[type=submit] { + font-weight : bold; +} + +input[type=checkbox], input[type=radio] { + margin : 0; + padding : 0; + background : transparent; +} + +label { + display : block; +} +label input, label select, label span { + display : block; +} + +label.required { + font-weight : bold; +} +label.required:before { + content : '* '; + color : #c00; +} + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/head-bg.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/head-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..1622ef8bfaec23b3c2919e21602b82ff55fa2b43 GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^Ahs0;GmzXj%|Z!CF&8^|hH!9j+JTy{5w1us6qjx zA~-*-q&%@GmBBYLxhOw3H6=4q!7Z~WwLHHlyI8?DV)sNX6`PZ!6KiaB?W?G$Zd zU|>BM8omdKI;Vst01ua>5dZ)H literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/head-logo.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/head-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e4e6a8b383bf3ca95adee0d20b0c3ff402a2025c GIT binary patch literal 5852 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 C^fN91 literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/page-bg.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid-dc2/page-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..729154ede43a2dd45319f4a53536d0e79f8c9fb0 GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^JwVLG!VDy*u&+J=q?n7HJVQ7*IBq}me*okP1^9%x zzIk=;-kpmV&K=peXVbDJb0$yf@|?F^6DZ4B;1OBOz`!j8!i<;h*8Kqrij}xVlsFfq zCYEI8=P86_=B6?jSn3;E=o^?a{|-+Es!#x_2+mI{DNig)W$;Z*F3QhMP037DaLX)8 zEzd8?E>`f3*ga881*lfS)5S5QVoq|x0vQ9X-9ZPZ1SY%nDqfdhP#0j4zM*>QDo_oB Mr>mdKI;Vst01JdiCjbBd literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/button-hover.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/button-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..43d298b9511cb803b9bcc5b67e450caccdd9a525 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!VDw>m!3)iQq09po*^6@9Je3(KLBz?1AIbU z|F0AMe?y zW>IQ+eo=O@f^Wp`iCQWk(>z@qLn`JZ7bG+|GPbcOm@ph-U}IxYj$k^t#^7NlPz8gh LtDnm{r-UW|a~49A literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/button-normal.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/button-normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b9d4de86308f93debda2179766c97617f3a6eb GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!VDw>m!3)iQq09po*^6@9Je3(KLBz?1AIbU zx1YUs>ej>kmu_Er@ND<_8)xr6K6d^7e=fI|Kn0uy9+AZi4BSE>%y{W;-5;Q!Scz*y ziE~kEVo7FxogTe~DWM4f7-mPn literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/default.css b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/default.css new file mode 100644 index 000000000..97aa55278 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/default.css @@ -0,0 +1,265 @@ +/* Default CSS */ +/* Main color : gray */ +/* Link color : cyan and red underlined*/ + +body { + font: 62.5%/1.5em sans-serif; + color : #000; + background : #fff url(page-bg.png) repeat top left; + margin : 0; + padding : 0; +} + +a img,:link img,:visited img { border:none } + +a, a:link, a:visited { + color : navy; + text-decoration : none; + border-bottom : 1px dotted red; +} +a:hover, a:active, a:focus { + +} + +h1, h2, h3, h4, h5, h6 { + margin-top : 0.5em; + margin-bottom : 0.5em; + color : gray ; +} + +h1 {font-size : 2em;} + +h2 {font-size : 1.8em;} + +h3 {font-size : 1.6em;} + +hr { + border-width : 3px 0 0 0; + border-color : gray; + border-style : dotted; +} + +pre, code { + font: 1.5em monospace; + border-left : 5px gray solid; + padding: 0 0 0 10px; + background: #eeeee6; +} + +/* LAYOUT +-------------------------------------------------------- */ +/* General font-size */ +#top, #info-box, #content, #main-menu, #footer { + font-size: 1.3em; +} + +#page { + margin : 0 100px 0 100px; + padding : 10px; + background : white; + border-width : 0 3px 0 3px; + border-color : gray; + border-style : dotted; +} + +#top { + margin : 0 0 50px 0; + padding : 0; + background : transparent url(head-bg.png) repeat-y top right; +} + +#top h1 { + padding : 0; + margin : 0; + height : 100px; + text-indent : -1000px; + background : transparent url(head-logo.png) no-repeat 0 0; +} +#info-box { + position : absolute; + right : 120px; + top : 30px; + margin : 0; + padding : 0; + letter-spacing : 0.2em ; + text-align : right; +} + +#main-menu { + width : 170px; + float : left; + margin : 0; + padding : 0 10px 10px 10px ; + background : transparent url(head-bg.png) repeat-y top right; +} +#main-menu h3 { + text-align: center; +} +#main-menu ul { + margin : 0 0 1em 0; + padding : 0; + list-style : none; +} +#main-menu li { + display : block; + margin : 0.5em 0 0 5px; + padding : 2px 0 1px 20px; + background-repeat: no-repeat; + background-position: 0 0; +} +#main-menu a { + font-weight : bold; +} +#main-menu .active a { + border-bottom-style: solid; +} + +#content { + margin-left : 200px; + margin-right : 10px; + margin-bottom : 10px; + padding-top : 0; +} + +#footer { + clear : both; + margin-left : 200px; + padding : 10px 0 10px 0 ; + border-top : 3px gray dotted; + text-align : center; +} +#footer a { + border: none; +} + +/* CLASSES +-------------------------------------------------------- */ +.error { + border : 2px solid red; + padding : 0.5em 0.5em 0.5em 40px; + margin-bottom : 1em; + background : transparent url(msg-error.png) no-repeat 5px 50%; +} + + +.message { + font-weight : bold; + padding : 0.5em 0.5em 0.5em 40px; + border : 2px solid gray; + background : transparent url(msg-std.png) no-repeat 5px 50%; +} + +/* TABLES +-------------------------------------------------------- */ +table { + font-size : 1em; + border-collapse : collapse; + margin : 0.5em; +} +tr.line:hover { + background : #ddd; +} +th, td { + border-style : dotted; + border-color : gray; + vertical-align : middle; + padding : 0.5em; +} +td { + border-width : 2px; +} +th { + text-align : center; + border-bottom-color : #666; + border-width : 0 0 2px 0; +} + +/* FORMS +-------------------------------------------------------- */ +form { + display : block; + margin : 0; + padding : 0; +} + +fieldset { + display : block; + margin : 0 0 1em 0; + padding : 1em 0.5em; + border-width : 1px 0; + border-style : solid; + border-color : gray; + background : #fbfbfb; +} +legend { + font-weight : bold; + padding : 0.2em 0.6em; + border-width : 1px; + border-style : solid; + border-color : gray; + background : #fbfbfb; +} +optgroup { + font-weight : bold; + font-style : normal; +} +option { + font-weight : normal; +} + +input, textarea, select { + background : #f9f9f9; + border-width : 1px; + border-style : solid; + border-color : gray; +} +input, textarea, select, option { + font : 1em sans-serif; +} +input[type=text], input[type=password], textarea { + padding : 2px 0; +} + +textarea { + padding : 2px 0; +} + +input[type=submit], input[type=reset], input[type=button] { + padding : 1px 2px; + background : #d2e0e6 url(button-normal.png) repeat-x bottom left; + border-width : 1px; + border-style : outset; + border-color : #ccc; + +} +input[type=submit]:hover, input[type=reset]:hover, input[type=button]:hover { + background-color : #fc3; + background-image : url(button-hover.png); +} + +input[type=submit] { + font-weight : bold; +} + +input[type=checkbox], input[type=radio] { + margin : 0.2em; + padding : 0; + background : transparent; + border : 1px solid gray; +} + +label { + display : block; + margin-top: 0.5em; + margin-bottom: 0.5em; +} + +label.required { + font-weight : bold; +} + +label.required:before { + content : '* '; + color : red; +} + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/fond.jpg b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/fond.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bfd94dcfdb171c6f4332235ab44f29bdbdff179e GIT binary patch literal 3034 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 C^fN91 literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/page-bg.png b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/page-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..581ed9d5f65f7a09eeb9b877532a683d1b9c78ea GIT binary patch literal 10400 zcmV;RC|}o!P)2#I`i|fp@tufGPlNwnnze2OoLV>gi^)!2(by-2L>^Pt6s03-QDM#q4^)5qj}4qi=_R`9MJb!vJWmF@=4iU3GLV60#@VW$B!ladHgOA-mu6d z^Stu*Qvo1IdAfF1Thslly=`WCCId)(_XJvyEg9b?vUw3TN+vq!xd5JcC1gex1q-> z-)nc?)Nk+a@B3z~pufHTeqri*LVPeTSQ(Ho1YliO`Mn#F@3Eo(@d({{-zyET3=Oz( z3XbgExwRj5->=L> zIR6$F+nXH_-(C+|f}cKpa+f$VdC6xgO`hCElqs~+)z_7LaC|)*z$lcv^nvFv#N z{ylL8?M66UvM@W*e|~s)kTWx!qUYyl7y7FOBg0fAe(%QV-OrJ!9nU%$-9hJB72Vlm zk1xydkXb?gUSu#zXeSjWlTmF2i7ecgp&14HNH)Ow39gmyCr9_IqO&2K;8_$EX1ZRl zfBp4WDI|n~kNtb){PfRzHuX4!U4;X~^Q-k>L6_a>EcADA$g6VotM5_uc`bnctB5zN zAb9oqPjwY0z7%mSs`H<8Ig$Vu9b*lag6tM*tMTT|n`AJi6j>SnMbJ4so5H5b3%3y2 zeYGt5L}og?wq#aBL37tHm7o0Z!w=krP=95KUJ~f{ZFtPd^?LpI@niqQ1^3cJ=IGzL z6a2lXE}(^ zZ=l*R&ROTv$fMoE2)kCa%C@N5y(&8+w8JW^GqUvRw;>VNttC5tzf~8)UH@{!P11gj zvtTY6?(z}nxoXQ?66#wBG4qt0lH=}1uPt=2>myTsBnRT+bC}_J2L{mc7=);E({CZSwRMrN_Z$ahJ)+Mlvni0X0 z<-BUkk(q(gTcf@)Q|_EuJe%;d#~#)?Atr?ME(@x7k+$@wp)#tVOpn z7?oPCBK%kg8*=e2$BE3FJd$(Vt9I`o`=APq#`Rmf?aE7pC~H;u?7`P9{CQPq$szo# zO3+kCJ~1)3G*?|`5>hXZUWYDO`0~3B<@lLm!WXZG0RC5PHyq@qr^UuUw%7MXE^kji$BF`%$p17NQ|%;Jvv zSLK!{%Pd_2%k|HXD)i4pqgDN$^{<*BGO7Ejma(2)^H~ke$bD8mAeB`{Ug+2ptAwRh zS=`sd^@j>SRZdt{-1E5CQiA5wQ(W5nC&aU+m4Z+rHHlHec_Yuua>4VEOFl<=&XTf0 z!*!w)T5RqgD${Ah*h!aZm~s?bS_LcJ402LVhkQP+UwJ-*OWHmc#CUvs>_4a%R&HtI zfMK$U!##Q*q;D?N>@ZrM;H+quC4>kxWFIcey!u>0}ujD+eg2G7I$*wmP z^|yJCc0lB`ia#^=n;}^ZR^n@+PPzISmA6*= z10W?tWy)>T)*{PLzrS>y2cJvzd70RiQT_@v6tMw~mzsU=GYNjA+9rO+ys z(H9OZxLB&a_#qNn+G5dIr5Luy9_K;xBkMNFfi6Ket~>5V_tnnQWdLl^e>t3 zrHHJhj%Hz0p41Xlan9U45D)Et$fOFbmUOONSTj+DdZ-J=*-__%E`$=zv{ZEjRgq5c zAlSHdGx^1*vM6p{0YZ>R=Bi3OtBzhiO9(tRi{(a!P}!F2l35D=*ddS$N3t~TVM-ap zZ8w&8(d}=QKKHaMrHE28O60D$Y1jINvDbEK_BayK%17nHkOA3GEtdvCZM**}VutOb zBKd($wEVLmAxVHCVRE@|x-yq2N{zmY^s8~_yhBX;y^oKN7WI<*4T)9BmYqC%O#CP$ zNu)lPS(gSB^JKl5%DPO4V*md8?^fvpWiu6S9h-$2W)gInXOR|`Q^sf44- zf?Xd#)-Ys*KHZ)GnJCn_27adqI-`e6?10OmL>G+alb02`W!9l^>RbrmW!~#O_L#6g z%U2yI4oRP%hu$qoLxrL&bp)l6-8f~nd#=iY+HVhw4>_ts^QJ;_<12^^gOZFJ#0=X! zr{Qe;swk?Ow~-{_5ZNt{4iU55GGxt(C1T}ApJ%%@WE7}E->(6BMJJfK+uxk)b^Lf# zonqJROXN`!2or}?}2yb``JrZx7`6CEHmiabM@rKYD%$q*Il zYD{dk#Sa;dd#PKqeb(Wgu5|ZZU@B)xW_#qkRkQlCu}l)jlH%ax_qsbEf9_|$zo=Hk zA^cRM4hOmZ(+VaQ7+X2sQ0w@9l)aC;fVYp>$VCF^j) zC9|zAWfa6J-nbVw2tR6vbJwkkyJT=}&+6DM2O)b-9Lle46!ovF7UV@X-7>Od_5huK zgZ@2U=Lm^#2lp2QP1Jj24ZA{DBns~0c%|qypuZ}s9kvCXKPiZA&EN#5T*)wy>#^R2 z>bqj?Rk;81%T}VOVQVlBNmZwI_r69*k?_GRN*P()u(=zLkrBnD()}Xky(ADF$J_UD zE*iD41tcO}>ls+Z=}(GR-h7}IfYmN{FA$X>H3|0VN+O56HbnRtWiH9Cx9UByP`Ek| z3Tv)vB);moNS%8Zs-kizbpgZ0Qgv*y%*bU85qB%&`dV=}H<4-$@o|L>9tBb7N9$85 zb&Sd31hza>>eqRk_H%Yi!9BjsQHA*23gztv56>lAjkcVCp6W8|k_M9%x3&+LJ=m3B zLqr<8*>O9J%5!CCrWO08pvP)!53K&rT*%Bi7@6KIsKuLdW8AZ$^51Ic`R&`cVcE31 zua(4GGqn)BW#`$%a$7TlT>)c;@J{w3gz=cN=GUoV67y|5;UN5OrU?u>1KrQ zDe8Nmy7{8>WJKJOTQxVe$#~xM>t8kHyPv=wXM~m%_6bH`!t_;O6 zm4oopgz`@^^njqhtW~qVgpE?8{WLFdj2wpkUnv(6rsx|c{K)K z48aTp*-@D_$`TN-qx8Pmd7G=mC4{bwzGwLDRhQ;q%U!nD|MuH&r6p3mrBwusYV@}X zwQt3tyjApwKSyhuB&XlL+pg&k?>f`3psG@bjt{p$0?KWF1G!=J&8E5z`F>{OO!-mbQ-r6qIyrQlpYQ)_rQA-o~ruq7t=)cFe;1cA|$=_%T*ZT1`3tIA}!!Ep;PANn_ z0d?j=6Bw3n{Sl7J;Hyl|r@B5TTEx2di{|-O<+f+P z@5f>1WnqQ*sYrJfv|2UAXCsDHTz15PLoUJl_wU^epeHWF0-(_AMP=4Vbd|q~`7XkQ zAmn~;@3x4d!YblIqVkAq9=d9%mSAE*x(V5&7+l7bXWA+w@w-9bNxo372w;npH^_QW zkflmY+GCH`Fp!-It6H1aip!Eq-E12n6LV;YlvN1fL?K$+Mcy7}yW55#jN{w7x`k2e zjb9zL}iU8Co$^20hW;*+s73fB$_Z0j)$o^YhQQ z@IgZl$>>S$<~ZAMnYbuhetn{HG~`_uTNfa&LtM+ z_bE;*Z@52eQv6Z1i%LTOX8IBwoYn8X`!2t6qe*Bc`tI(Y84OcZp2>HI<)cb;;R`if zZ{xpc|3!GFiqmcd{SUfEE1~}?LQeJkb4&U4k5$)+yk0b)w*1sykBiGQZJTBJj$6Y} zBK)|JeU+$Ip9hOg-P#qhwN#`2Zi}>u+87%xb4_+WtAOT{Gw9s&6NR6AjY`txtCo+W zr2OUu?eQAM1cy6$yizMx23!(B)iEKgci%fASjpAaISta)*Uu=89^ZN0NW`a4pGe0s z`-hfLK=Q%Hi!`Rv?5777n&#a(XCQs`#gKVgFaRdUjAT}f|_W(lpocsAj&`@<)2}H zc-M1xzspp_uI1dj>VivL&?BK4yGqa7e{Y2w=lT()p#PW7#a~sn``TQBRoNKCQASH- zB*+v1Qcx+=Y5+xa+^q$PmS)P5GSS&gD--$WN|de9GPt|DJCs1ILPkl*$ieIf;_mJ@hI&oQ(!$y$ZX=R4BB$Cp0l#DDYqxOLHyJ>&op=|!S0u+?BTQV7jt zHJ89d)W?7*!pQ?rR$OJ{Gu^e8tSi-BxYdR5`P?p1JX8Lp+}+UrTg}G5HrzO^02V|4 z*XAvKYY>0c{ERZAq)UMG{=-%;1ZWb78AkniRK{*RNr>;>m#S?bk~O2mZKONU7K`Q| z4cP~vrQ0K@a%A#f)n{YL>!1{n+(nM&+4lY5&k=n!x)EgJ?Ur29Dc@s{S2d=gOj3^= zHJL%igb;M|A!KgOdGc{}|pkhtfq#Edx9I}V+1UIX9~9$t^D!*O94?B{*a755C+iCdI>_xT{Zb(I)~Vtz7lpV^|^&q)qf z^+0H|324_HCH&(J{rC71N2Wy)YImjV7)sujLKR65#D0-7jFRw!`WQ%M&+x*My6gy} zqjK2C$43|3BmI8V7sb{95SNDB?6jz5vYT6#P*kna%7hM&h>#wHbIZp;U4JqzRZ&hE zr7P)@TlnQ!=m=YyAt5>30U%7hB85aUUSoF#% zsETfXoLtsU$b%7q3PEQSE*e|Ka7En752GV0iWY9<>iF>ka)H9mZtCFfVxhg?2K-bM zztn}Nne@mWd)#(ZvzH;34SyRdw~*FLq-US{t4<(6-JQaDKsL(tUSu6w*T0whMIW}d zjqAh{=xO_EU9VRu7a{HQ$B!RNo1p7p^z4Lf;Uc@jD=Ru$YpFRTuGbPAQsw%i$wzw} zy6m$DbqGJxB25ZRoDEg0OR74R)8d9pyvBTd@oZ?4e2x|*krqxz zuK)P@Y@iFQd;YMj6Xj&NuC_(q1FBY;PVTxLB>_tBIlr#@^&=&X&}5@t#o;} zsP&J!e*3Vt9{(O+;&{pK@_7tuk5sicL}|?;V-$SJM?Kw6y&PI8us*UGZW@F`NjDAR z;v##G(k{vG3PrRvfHV74KN2Yg$rfN4qGpDdbDRl z|0H5wKA#7-76K(-2J|3-Wb`^!A!f1$V;I@@@87#qfm(`;=nGF=y7w!i9mtm$t=W=Y zHb=AxW$^iOeSUtHEYW-EzZnHp=x-R*-%k%`?_>=b!Da$i7Vpzam69MPKic!&|?K9pP8 zH=^Iq%Nvr)b+>9+TdLUz_rW}6z~b1;Dx%J+EfbwTRO&bwMW}XnTbM9fuCj9E_%MrN z$#&Kr5rR#1tg6IE>j#zjhS#HPy^8Cf>=H75{?C8@u6jjLOR0>0nG8a_ zef!ph{wN})T3_YMqtyxBa^dUssTjoBn=X$oT&NXVxtX2;LA>8+88A-ZoQvKv0D02x+sm#1CxiTD8s*r#a^eUGqyq|0DZI#^nnY^D_P2-1)yu zl-(rRz-n3VTn9PbtD)0L3fIt7t-zs6%vyA-0JCMvOOF6 z@A3Lwg(Q&%ajC=FIai0?zH}%{JnWSM>k~D5F7#Kr{^|g0pKXOwlKXBUm+}gfeOBz6 zj%V_K6;Ye=klIyPQq{oLrCF5)t#-RdoOnc(y_L9UwPhGuSJRkC{)wvP7{5YX{020(5f8PSLQAE!-)l8GQ20=3 zX`gDZHk9Av>l^4bY?MZiq}Hc#jM@q%6J05lN&BYoYyU5?d)9!c^T=-xLz8(GZ1;Ex z#ki!h>q3nGN{H#YQpr9iRh)yaAGH8OS(Jm>fXw`(>`J}^44I#5h_i}kR^em^Y5eP7 z|8fr{uiTPbUFA(CqrB5z;3}_?D80De3(rCzQNsLHS%Ae0=ZOh$BfiyE6sw}ALwr;H z;SjI1(liLOqHlLup4IF8^y!oPE!LFq^H;MR4-XG6^dHwls>kGi$@+2Y#%w*==yvJ4 z9C;JDmSDEW9^WSV=g<=oimEjRiZV7H!u^MGrRa>$NKYQ#E z?)#x#ogmgKBgP3lmawi03_|EXAfQWF3R|Ha!Gfq(xMAfwbOET0xEl4Z;ugfk=X*Wj z?kDZAa_ur5C;1f~g#NcuVw@vFf9AyAs;q659zS_Sm&jC|-78L2=ufM>qo_beq2&nl z?@?i-DRv$dD_u{I79gzywTD@YiRviY=LJ%#RZ9N>MJZ5_Mn&HDLbX9`$(83xI(E`hM<+g$@rem>|yh3kYomoWM{;S!(mKA!aX1trK$5!xK>3fGwVJdmA7JxFG=)L=W(O{U4f_JC^f&HahR&v z7+vOi;E4;DCDk^uXOBHr z*iRcfN8LtIa76Z6D%oxKPyYVzFEYmh&y>}&I)<8sHB zI7&V^MaZ0v{iFFr5WgRv&jwU4Nr_O0BDQvuvSrh+IqtJ6gzD_GfBf->dnhXNT~#KV zd__aAE>w&ma*9W;zq(37j#?fvHcV2_FBe-L)TqEbn*Ra0h=x7C^0m*!D*TMDgc<1X zni3lYx3TBxsC-C*=xmuwji$h_X>?SMx{e)$~tXWdpJWcGp^luE%*o z6$tg-xxN9K|B+=2b}8_QdQkeyHE%4TZNU6Si6m%D1Os)^%0_V{w4zm?fVfuzu- zcY8%uaX%@+w0OXU{$U8lwd8qm&nnj+5qnTJfCutqcLJ+(Z=v3C=$~0voYUX1n0>2r z{oU>a8GCLOhwLW4XE`2a000OxNklL!n=y=T!j=$ z;e>Sd=G^*ZSHk>5C9S+|%-c=ix)RQr=xN53Bz5;uzjtLC>^!6El+afGfJDBkSqRh$ zN(tkj^^X$G%Jp*Z7nOIT<>B%^(XtsX2ik|oD$PXSt=_YAO>J9%ygs+wT&)!f#qwU* zwb#cJlcWJmBsx$#ouPrO@`YD$9`+4^6rRHlC=6TL)bNl=Jy4 zI5^QjyJTXjCael2&yEhNL`ew!t6ToG`c=koxI`3}r?K4cOon$>DKHR@J7fg4rBV_u^bx^PNPqk287bowW1U)?A<>d-nNZtkK%r(X~v z{LGaH<)>zq_qos-W|nve{i}%{)S@E1&ZMhAx-+`vuw;vB#V&f)=jfWe@4oxa{X;@9 zBOOxg=hg0vnZDWNMUY)2$r<>%n#&9Qzpwwfsa1U>-1r~A$7Hk;L2$*j&9vS_jfYE7 zqN+(vQ+_`XbB%H%o;2~kHPr|o=lI9je%<)Y-iPns5A z7T&6>M7t`wUoF>L#i>Hj96|p%!jcvDJZ}1Vj}J?<;87FA;ht`h#>;)iX-CxIVE7g# zaFvdJ-Zjl2P8Gyb2|hO%Zvy}*V8drXnqYZ%>N$>Y?@AiBd|7on9`_|(h|Iiw{P@u& zL>)=Us_7+t7((uH_`N%dzsJjrGlE<;q>TuW$PTYkW|QxcwZrxg-@kuPLKXH@Asz_D zB`s*qKao6DBN=tJ+YOJ2xNT>SC>$b)KNrGq_rVY+xS&gEYNKxPtKOzny8Fq;J^p)8 zB$q+|RmMe?IZk(LTlIPMdwGi}YY1HbRhHW(p#y??)AO(H)N-s{*pxI?DreUYmvNH< zT>h9yf-h4oifpS&k`R+b!YYI`KmKYYc8RE*Dywys?~^;hcw|USR*JG&hmdrcQK#Zr z9rsmgw5UKEEL=WLY8&$1I#(%{?7jheyoP}Sz#-Om0Yo0)=07I}aCGOjQ4iE&tSZ(l z+lMQ0A+-mu{NROs)*jLb%_J|r?Q3iR{+v0AH8 z6{)Z86r{!5+`c0x+?8E9o$zzE7xe;O9Vzo|piFb_Rmqe~P7r=v)1w-Ok6-0q=?q&m zKMyF2G7`S(SHyHSugsSh72JJ3T0&8W1d~X#hOZwo!&P4^Bdz1Q7R{7^yTmZ$LL}c) z>%gG-L0bsl67ph&$yFWdTPHu?{Rj5QEYwxyiPqodfyUA5NLj71{*!1jgi6Wn1BnYG zg`BX3pSpe|3xUp0_Jz>BnFu|oYzCP6rq6>b@E-<5KiDhw`2%% z)%%;rtI0aIg9K444*S11WmQ=%D#x7g4woFi&{eR}SrojSsGvtDuex3?amB6moGZ_* zatD)9a}>iKKS-iTn@T|Qc$H?ul;@_6pJ1;derMCab$JBdwhHh z$=UL%Y}B9AqftL1WZp-O6N+7;3nTl2b>}QuAZ(eM)W7FSN~DcIav+F*kb~Z$+DN`I z)O@y=Z4tW=e_EI9pwg(S$sDWN&d*A5PdC6>75`dQ7Q9x}i9|OKin5`oPxxxt7s-ut z4{=gudQ|h2()=H346d>bHp-sVgRe#l(65w2LKq$C5Rh=R)b%57D|+szwxlYinQTt! zt~ZJMRaDHLZO(?ugu8ofD0*i#zm=$NhN^ppkn?$=hdsXfVWDTWwj^VXt!T0fK|;3l zk@~>#zF);4wjE_zkws0~LyIrfU86oH8C(={s0c*@)jWh^qsp%GGTGzy3b_QyJ`$lr zf(S5HZe&iWuNw7VMFdi{jxOFfBJP=I4c-0n%P%KIGG1nDTm}8B=g)K(Zs!z?bDj0% z4fb4T4?m1BkELAadtSI+#CbpmZH-S)Pvee;1$laU8X|g%yK;Yj-;aNKdg^Y;V2`*e zKnUosQf}#6odmc<$7UL2NPOQv8Q&|vS}9BP`ROwmc6UB$$i#7@B0qDl`G)3ue9MD~ zb(RoGl}nvDkMtJaym_Nc+4z<0lOPEXw#CQu^Yi6$d47IY4Eq-d4NT0B+@m|V?ANcH zsL+n7d7HaVVxLRU-@2MdT-@{KAJr;w7L3a&7?ZDd`6c)>Ps9FdiKi2-wI-JGmpd+( zOJB_o4-fbE_bR!O=O!Y3ciXz+WqK;#|9A8Y=s%FJ9&o=qLMkDCljoxLt#%+?OQ5qV zZ0PG@I7p*sq_x_8dcU9!*?a7<$HD#1ML83FIVS9(3;jnoU$>F4A}CHMrQC3yGvSGG zQ#}MG`}>C9I}E$rXx1wEe7Wm988{13jcU?oYwP9YlV^9{{Qn=E!dP=61@M0W0000< KMNUMnLSTXtOzp1# literal 0 HcmV?d00001 diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/sso.css b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/sso.css new file mode 100644 index 000000000..c5f126914 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/sso.css @@ -0,0 +1,15 @@ +/* CSS for SSO */ +/* Main color : orange #d9b500 */ + +@import url(default.css); + +h1, h2, h3, h4, h5, h6 { color : #d9b500; } + +#page { border-color : #d9b500; } + +#footer { border-top : #d9b500; } + +.message { border-color : #d9b500; } + +hr, pre, code, th, td, fieldset, legend { border-color : #d9b500; } + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/wui.css b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/wui.css new file mode 100644 index 000000000..3e7a94dd2 --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/federid/wui.css @@ -0,0 +1,15 @@ +/* CSS for LDAP Content Management (WUI) */ +/* Main color : blue #1335e2 */ + +@import url(default.css); + +h1, h2, h3, h4, h5, h6 { color : #1335e2; } + +#page { border-color : #1335e2; } + +#footer { border-top : #1335e2; } + +.message { border-color : #1335e2; } + +hr, pre, code, th, td, fieldset, legend { border-color : #1335e2; } + diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/styleswitcher.js b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/styleswitcher.js new file mode 100644 index 000000000..3a7d9f7ee --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/styleswitcher.js @@ -0,0 +1 @@ +function setActiveStyleSheet(title) { var i, a, main; for(i=0; (a = document.getElementsByTagName("link")[i]); i++) { if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) { a.disabled = true; if(a.getAttribute("title") == title) a.disabled = false; } } } function getActiveStyleSheet() { var i, a; for(i=0; (a = document.getElementsByTagName("link")[i]); i++) { if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title"); } return null; } function getPreferredStyleSheet() { var i, a; for(i=0; (a = document.getElementsByTagName("link")[i]); i++) { if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("rel").indexOf("alt") == -1 && a.getAttribute("title") ) return a.getAttribute("title"); } return null; } function createCookie(name,value,days) { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = "; expires="+date.toGMTString(); } else expires = ""; document.cookie = name+"="+value+expires+"; path=/"; } function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } window.onload = function(e) { var cookie = readCookie("style"); var title = cookie ? cookie : getPreferredStyleSheet(); setActiveStyleSheet(title); } window.onunload = function(e) { var title = getActiveStyleSheet(); createCookie("style", title, 365); } var cookie = readCookie("style"); var title = cookie ? cookie : getPreferredStyleSheet(); setActiveStyleSheet(title); \ No newline at end of file diff --git a/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/template.html b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/template.html new file mode 100644 index 000000000..cf02826ab --- /dev/null +++ b/modules/lemonldap-ng-portal/example/AuthLA/tpl/themes/template.html @@ -0,0 +1,92 @@ + + + + + Themes for FederID Project + + + + + + + + + + + + + + + +
+

 

+

Title

Other text

+ +
+

H2 Title in content div

+
+

Some text in content div

+

FederID special themes

+

Change style to FederID Test

+

Change style to FederID Test Authentic

+

Change style to FederID Test WUI

+

Change style to FederID Test LAAP

+

Change style to FederID Test SSO

+

Old themes

+

Change style to DC2

+

Change style to FederID DC2

+

Div and messages

+

Error

+

Info

+

A table

+ + + + +
Title 1Title 2
Content 1Content 2
Content 3Content 4
+

A form

+
+
Identification + + +
+ +
Informations + + + + Yes + No + + 1 + 2 + + +
+ +
Submit + + +
+
+ +

Texts

+
Text in "pre"
+ Text in "code" +
+ +
+ + diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal.pm index cf2ff37df..3fba4c059 100644 --- a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal.pm +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal.pm @@ -2,7 +2,7 @@ package Lemonldap::NG::Portal; print STDERR "See Lemonldap::NG::Portal(3) to know which Lemonldap::NG::Portal::* module to use."; -our $VERSION = "0.77"; +our $VERSION = "0.8"; 1; diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthLA.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthLA.pm index 4a867f412..d0b4c542f 100644 --- a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthLA.pm +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthLA.pm @@ -1,8 +1,9 @@ -#============================================================================== + +#=============================================================================== # Liberty Alliance Authentication for LemonLDAP. # # This file is part of the LemonLDAP project and released under GPL. -#============================================================================== +#=============================================================================== package Lemonldap::NG::Portal::AuthLA; @@ -11,166 +12,1423 @@ use warnings; use Lemonldap::NG::Portal::SharedConf qw(:all); use lasso; +use CGI qw/:standard/; +use CGI::Cookie; +use DBI; +use HTTP::Request; +use HTTP::Response; +use LWP::UserAgent; +use MIME::Base64; +use XML::Simple; +use XML::Parser; +use XML::XPath; +use UNIVERSAL qw( isa can VERSION ); *EXPORT_OK = *Lemonldap::NG::Portal::SharedConf::EXPORT_OK; *EXPORT_TAGS = *Lemonldap::NG::Portal::SharedConf::EXPORT_TAGS; *EXPORT = *Lemonldap::NG::Portal::SharedConf::EXPORT; -our $VERSION = '0.1'; +our $VERSION = '0.2'; +our @ISA = qw(Lemonldap::NG::Portal::SharedConf); -our @ISA = qw(Lemonldap::NG::Portal::SharedConf); +#=============================================================================== +# Global Constants +#=============================================================================== -#============================================================================== -# Overloaded methods -#============================================================================== +sub PE_LA_FAILED { 500 } +sub PE_LA_ARTFAILED { 501 } +sub PE_LA_DEFEDFAILED { 502 } +sub PE_LA_QUERYEMPTY { 503 } +sub PE_LA_SOAPFAILED { 504 } +sub PE_LA_SLOFAILED { 505 } +sub PE_LA_SSOFAILED { 506 } +sub PE_LA_SSOINITFAILED { 507 } +sub PE_LA_SESSIONERROR { 508 } +sub PE_LA_SEPFAILED { 509 } -# Main process as described in Portal::Simple module +sub PC_LA_URLAC { '/liberty/assertionConsumer.pl' } +sub PC_LA_URLFT { '/liberty/federationTermination.pl' } +sub PC_LA_URLFTR { '/liberty/federationTerminationReturn.pl' } +sub PC_LA_URLSL { '/liberty/singleLogout.pl' } +sub PC_LA_URLSLR { '/liberty/singleLogoutReturn.pl' } +sub PC_LA_URLSC { '/liberty/soapCall.pl' } +sub PC_LA_URLSE { '/liberty/soapEndpoint.pl' } -# 1. Retrieve source URL -# Not overloaded +#=============================================================================== +#=============================================================================== +# +# TODO +# ------------------------------------------------------------------------------ +# - category / function : comments +# ------------------------------------------------------------------------------ +# - association / store : Replace files by hastable or DBI implementation +# - optimization / libertySignOn : Catching error when retrieving $providerID +# - optimization / _getAttributeValuesOfSamlAssertion : Checking errors +# - security / process : Check if URL figures in locationRules +# - security / libertyFederationTermination : Implementation +# - security / libertySoapEndpoint : Does Lemonldap::NG do defederation ? +# - wsf / setSessionInfo : Code for getting informations via wsf protocol +# +#=============================================================================== +#=============================================================================== -# 2. Control existing sessions -# Not overloaded +################################################################################ +################################################################################ +## ## +## Lemonldap::NG::Portal functions ## +## ## +################################################################################ +################################################################################ -# 3. Retrieve user credentials -# Test here if the user was authenticated by IdP -sub extractFormInfo { - my $self = shift; - &_lasso_init(); - my $libertyFilesDir = $self->{libertyFilesDir} ; - my $server = &_lasso_create_server($libertyFilesDir); - my $login = &_lasso_create_authnrequest($server); +#=============================================================================== +# new +#=============================================================================== +# +# Instanciate this class. This constructor takes special parameters with +# classical Lemonldap::NG::SharedConf parameters. +# +#=============================================================================== - print STDERR $server->dump(); - print STDERR $login->dump(); +sub new { + my $class = shift; + my $this = $class->SUPER::new(@_); - return PE_OK; + $this->{isLibertyProcess} = 1; + $this->{laDebug} = 0 unless ( $this->{laDebug} ); + + die('No Liberty Alliance Service Provider data defined') + unless ( $this->{laSp} ); + die('No Liberty Alliance Identity Provider file defined') + unless ( $this->{laIdpsFile} ); + die('No laStorage configuration defined') + unless ( $this->{laStorage} ); + die('No laLdapLoginAttribute configuration defined') + unless ( $this->{laLdapLoginAttribute} ); + die('No localStorage configuration defined') + unless ( $this->{localStorage} and $this->{localStorageOptions} ); + + bless( $this, $class ); + + # Create LassoServer + + $this->{laServer} = lasso::Server->new( + $this->{laSp}->{metadata}, + $this->{laSp}->{privkey}, + undef, #$this->{laSp}->{secretkey} , + undef, #$this->{laSp}->{certificate} , + ); + + $this->_loadXmlIdpFile(); + return $this; } -# 4. LDAP format filter for attributes reading -# We must retrive user DN in SAML response -# Or use WSF to retrieve attributes -sub formateFilter { - my $self = shift; +#=============================================================================== +# authenticate +#=============================================================================== +# +# User is authenticated automatically, no ldap authentication. +# +#=============================================================================== - # Get DN in SAML response (TODO) - my $dn = "uid=clement,ou=personnes,dc=linagora,dc=com"; - - # Explode DN to build RDN - my @rdn = split /,/ , $dn; - - $self->{filter}="(".shift(@rdn).")"; - - return PE_OK; -} - -# 5. LDAP connection -# Overload only if WSF is used to retrieve attributes -#sub connectLDAP { -# return PE_OK; -#} - -# 6. LDAP bind (with Directory Manager or anonymous) -# Overload only if WSF is used to retrieve attributes -#sub bind { -# return PE_OK; -#} - - -# 7. Search the DN -# Overload only if WSF is used to retrieve attributes -#sub search { -# return PE_OK; -#} - -# 8. Load parameters -# Overload only if WSF is used to retrieve attributes -#sub setSessionInfo { -# # Use WSF to get "exprotedVars" -# return PE_OK; -#} - -# 9. Set macros -# Not overloaded - -# 10. Set groups -# Not overloaded - -# 11. LDAP unbind -# Overload only if WSF is used to retrieve attributes -#sub unbind { -# return PE_OK; -#} - -# 12. Authentication -# Authentication is done by IdP, so we disable this step sub authenticate { - return PE_OK; + my $this = shift; + return $this->SUPER::authenticate() + unless ( $this->{isLibertyProcess} ); + return PE_BADCREDENTIALS + unless ( defined $this->{user} ); + return PE_OK; } -# 13. Store parameters in session -# Not overloaded +#=============================================================================== +# extractFormInfo +#=============================================================================== +# +# This function is just override to do nothing. +# $this->{user} is already fixed in libertySetSessionInfo function. +# +#=============================================================================== -# 14. Build cookie -# Not overloaded - -# 15. Log -# Not overloaded - -# 16. Redirection -# Not overloaded - -#============================================================================== -# Liberty Alliance methods -#============================================================================== -# Lasso intialisation -sub _lasso_init { - lasso::init; +sub extractFormInfo { + my $this = shift; + return $this->SUPER::extractFormInfo() + unless ( $this->{isLibertyProcess} ); + return PE_OK; } -# Create server object -sub _lasso_create_server { +#=============================================================================== +# formateFilter +#=============================================================================== +# +# By default, the user is searched in the LDAP server with its UID. Here, +# $this->{user} contains nameIdentifier of the user, which is already stored +# in LDAP directory. +# +#=============================================================================== - # TODO: file names in global configuration - - my $libertyFilesDir = shift; - - my $server = lasso::Server->new( - "$libertyFilesDir/lemonldapng-metadata.xml", - "private-key.pem", - undef, undef); - - $server->addProvider( - $lasso::PROVIDER_ROLE_IDP, - "$libertyFilesDir/idp-http-authentic.demo.interldap.org-liberty-metadata-metadata.xml", - "$libertyFilesDir/idp-http-authentic.demo.interldap.org-liberty-metadata-publickey.pem", - undef); - - return $server; +sub formateFilter { + my $this = shift; + return $this->SUPER::formateFilter() + unless ( $this->{isLibertyProcess} ); + $this->{filter} = + "(&(uid=" . $this->{user} . ")(objectClass=inetOrgPerson))"; + return PE_OK; } -# Create AuthnRequest -sub _lasso_create_authnrequest { +#=============================================================================== +# process +#=============================================================================== +# +# Do portal Lemonldap::NG processing. Actions based on Lemonldap::NG structure +# and philosophy. +# +#=============================================================================== - my $server = shift; +sub process { + my $this = shift; + $this->{error} = PE_OK; - my $login = lasso::Login->new($server); + # Trace param() + # my @params = $this->param() ; + # foreach( @params ) { + # $this->_debug("parameter : $_ = " . $this->param($_)) ; + # } + # while(my($k,$v) = each(%ENV)) { + # $this->_debug("env : $k = $v") ; + # } - return $login; + #-------- + # Nothing to do if user access to portal directly. We have to verify if + # user was redirected from a protected host. + #-------- + + my $url = $this->url(); + my $urlr = $url . substr( $ENV{'SCRIPT_NAME'}, 1 ); + + if ( not $this->param('url') + and ( $url eq $this->{portal} or $urlr eq $this->{portal} ) ) + { + + # TODO Security tricks : + # - Check if URL figures in locationRules + $this->{error} = PE_DONE; + return $this->{error}; + } + + #-------- + # Authentication process + #-------- + + my $urldir = $this->url( -absolute => 1 ); + + # assertionCustomer + if ( $urldir eq $this->PC_LA_URLAC ) { + + $this->{error} = $this->_subProcess( + qw( libertyAssertionConsumer libertySetSessionInfo )); + + $this->_debug( "Login user = '" . $this->{user} . "'" ); + + # federationTermination + } + elsif ( $urldir eq $this->PC_LA_URLFT ) { + + $this->{error} = $this->_subProcess( + qw( libertyFederationTermination log autoRedirect )); + + # federationTerminationReturn + } + elsif ( $urldir eq $this->PC_LA_URLFTR ) { + + $this->{error} = $this->_subProcess( + qw( libertyFederationTerminationReturn log + autoRedirect ) + ); + + # singleLogout : called when IDP request Logout. + } + elsif ( $urldir eq $this->PC_LA_URLSL ) { + + $this->{error} = $this->_subProcess( + qw( libertyRetrieveExistingSession libertySingleLogout + libertyDeletingExistingSession ) + ); + + $this->_debug( "Logout user = '" . $this->{'dn'} . "'" ); + + # OK : $this->{urldc} is fixed at the end of this process. + + # singleLogoutReturn + } + elsif ( $urldir eq $this->PC_LA_URLSLR ) { + + $this->{error} = + $this->_subProcess(qw( libertySingleLogoutReturn log autoRedirect )); + + # soapCall + } + elsif ( $urldir eq $this->PC_LA_URLSC ) { + + $this->{error} = $this->_subProcess(qw( libertySoapCall log )); + + # soapEndpoint + } + elsif ( $urldir eq $this->PC_LA_URLSE ) { + + $this->{error} = + $this->_subProcess(qw( libertySoapEndpoint log autoRedirect )); + + # Direct access or simple access -> main + # WARNING : we permit authentication on service. + } + elsif ( not $this->param('user') and not $this->param('password') ) { + + $this->{error} = $this->_subProcess( + qw( libertyRetrieveExistingSession + libertyExtractFormInfo libertySignOn log + autoRedirect ) + ); + + # Not in liberty authentication process. + } + else { + $this->{isLibertyProcess} = 0; + } + + # $this->_debug("ERROR = " . $this->{error} . "\n") ; + + return 0 + if ( $this->{error} ); + + # Liberty Process OK -> do Lemonldap::NG process. + my $err = $this->SUPER::process(@_); + $this->_subProcess(qw( log autoRedirect )) + if ( $this->{urldc} ); + return $err; } +#=============================================================================== +# setSessionInfo +#=============================================================================== +# +# Après une consommation d'assertion d'auth valide cette fonction est appelée +# pour initialiser les infos de session dans le cas où c'est le wsf qui est +# choisi pour récup les infos du user (sera par défaut en ldap). +# +# TODO : +# * Faire de cette fonction un override de setSessionInfo avec par défaut +# le comportement de l'ancienne version et si dans la conf recup +# attribut par wsf... recup en wsf2.0. +# +#=============================================================================== + +sub setSessionInfo { + my $this = shift; + + # Si configuration fixée à WSF + # Alors + # Traitement de récupération des informations par WSF + # Sinon + # Traitement de récupération des informations en appelant la fonction + # SUPER::setSessionInfo. + + # $this->{sessionInfo}->{dn} = "cn=tutu,ou=people,dc=example,dc=com" ; + # $this->{sessionInfo}->{cn} = "tutu" ; + # $this->{sessionInfo}->{mail} = "tutu@example;com" ; + # $this->{sessionInfo}->{uid} = "ttutu" ; + + return $this->SUPER::setSessionInfo; +} + +#=============================================================================== +# store +#=============================================================================== +# +# This function store existing association between userNameIdentifier from IDP +# and Apache session ID of Lemonldap::NG. +# +#=============================================================================== + +sub store { + my $this = shift; + + my $err = $this->SUPER::store(); + return $err if ( $err or not $this->{isLibertyProcess} ); + + return PE_APACHESESSIONERROR + unless ( defined $this->{laStorageOptions}->{Directory} + and defined $this->{id} ); + + my $dir = $this->{laStorageOptions}->{Directory}; + $dir =~ s/(.*)\/?$/$1/; + + # We have to store association. + # Create a file named by userNameIdentifier from IDP, single, which + # contains session ID from Apache. + + if ( defined $this->{userNameIdentifier} ) { + + #my %h; + #eval { + # tie %h, $this->{laStorage}, + # substr($this->{userNameIdentifier},1), + # $this->{laStorageOptions}; + #}; + #if ( $@ ) { + # $this->_debug("$@\n"); + # return PE_APACHESESSIONERROR; + #} + #$h{id} = $this->{id} ; + #$h{_utime} = time(); + #untie %h; + + my $file = $dir . '/' . $this->{userNameIdentifier}; + $this->_debug("$file already exists : override association") + if ( -e $file ); + open( MYFILE, '> ' . $file ); + print MYFILE $this->{id}; + close MYFILE; + + # In other case, we considere that store action failed. + # So, we have to delete Apache session file. + + } + else { + my $file = $dir . '/' . $this->{id}; + unlink $file; + return PE_APACHESESSIONERROR; + } + + return PE_OK; +} + +#=============================================================================== +#=============================================================================== + +################################################################################ +################################################################################ +## ## +## Some Data Access functions ## +## ## +################################################################################ +################################################################################ + +#=============================================================================== +# getIdpURLs +#=============================================================================== +# +# Returns all IDP URLs +# +#=============================================================================== + +sub getIdpIDs { + my $this = shift; + my @tab = (); + + if ( $this->{laIdps} ) { + push @tab, $_ foreach ( keys %{ $this->{laIdps} } ); + } + + return @tab; +} + +#=============================================================================== +# getProtectedURLs +#=============================================================================== +# +# Returns all protected URLs +# +#=============================================================================== + +sub getProtectedURLs { + my $this = shift; + my @tab = (); + + if ( $this->{locationRules} ) { + push @tab, $_ foreach ( keys %{ $this->{locationRules} } ); + } + + return @tab; +} + +#=============================================================================== +#=============================================================================== + +################################################################################ +################################################################################ +## ## +## Liberty Alliance functions ## +## ## +################################################################################ +################################################################################ + +#=============================================================================== +# libertyArtefactResolution +#=============================================================================== +# +# This function do Liberty artefact resolution. Verification is already made +# if this function is called, normaly it is authorized. +# +#=============================================================================== + +sub libertyArtefactResolution { + my $this = shift; + + my $lassoLogin = undef; + my $lassoHttpMethod = + ( defined( $ENV{'REQUEST_METHOD'} ) and $ENV{'REQUEST_METHOD'} eq 'GET' ) + ? $lasso::HTTP_METHOD_REDIRECT + : $lasso::HTTP_METHOD_POST; + + # Retrieve or create lassoLogin. + + if ( $this->{laLogin} and defined( $this->{laLogin} ) ) { + $lassoLogin = $this->{laLogin}; + } + else { + $lassoLogin = lasso::Login->new( $this->{laServer} ); + } + + # POST + + if ( $lassoHttpMethod == $lasso::HTTP_METHOD_POST + and $this->param('LARES') ) + { + + my $formLares = $this->param('LARES'); + + if ( my $error = $lassoLogin->processAuthnResponseMsg($formLares) ) { + $this->_debug("lassoLogin->initRequest(...) : error = $error"); + return PE_LA_ARTFAILED; + } + + if ( my $error = $lassoLogin->acceptSso() ) { + $this->_debug("lassoLogin->acceptSso(...) : error = $error"); + return PE_LA_SSOFAILED; + } + + # GET : artefact is in QUERY_STRING param + + } + elsif ( $lassoHttpMethod == $lasso::HTTP_METHOD_REDIRECT + and defined $ENV{'QUERY_STRING'} ) + { + + # NOTES : + # Documentation indicates that $formLareq is QUERY_STRING HTTP + # header. We should have + # $formLareq = $this->param('QUERY_STRING'). + # But initRequest method on lassoLogin returns -502 error code + # (LASSO_PARAM_ERROR_INVALID_VALUE) when QUERY_STRING is like + # 'SAMLart=...&RelayState=...'. So, $formLareq is rebuild so + # that it only contains 'SAMLart=...'. + + my $formLareq = $ENV{'QUERY_STRING'}; + if ( $this->param('SAMLart') ) { + $formLareq = 'SAMLart=' . $this->param('SAMLart'); + } + + if ( my $error = + $lassoLogin->initRequest( $formLareq, $lassoHttpMethod ) ) + { + $this->_debug( +"libertyArtefactResolution : lassoLogin->initRequest(...) : error = $error" + ); + return PE_LA_ARTFAILED; + } + + if ( my $error = $lassoLogin->buildRequestMsg() ) { + $this->_debug( +"libertyArtefactResolution : lassoLogin->buildRequestMsg(...) : error = $error" + ); + return PE_LA_ARTFAILED; + } + + # Check if SSO is OK + # Successed = $soapResponseMsg contains code 200. + + my $soapResponseMsg = + $this->_soapRequest( $lassoLogin->{msgUrl}, $lassoLogin->{msgBody} ); + + if ( my $error = $lassoLogin->processResponseMsg($soapResponseMsg) ) { + $this->_debug( +"libertyArtefactResolution : lassoLogin->processResponseMsg(...) : error = $error" + ); + return PE_LA_SOAPFAILED; + } + + if ( my $error = $lassoLogin->acceptSso() ) { + $this->_debug( +"libertyArtefactResolution : lassoLogin->acceptSso(...) : error = $error" + ); + return PE_LA_SSOFAILED; + } + + } + else { + return PE_LA_SSOFAILED; + } + + # Backup $lassoLogin object + $this->{laLogin} = $lassoLogin; + + # Save RelayState. + + if ( $this->param('RelayState') ) { + $this->{urldc} = $this->param('RelayState'); + } + + return PE_OK; +} + +#=============================================================================== +# libertyAssertionConsumption +#=============================================================================== +# +# Realize assertion. +# +#=============================================================================== + +sub libertyAssertionConsumer { + my $this = shift; + + $this->{laLogin} = lasso::Login->new( $this->{laServer} ); + + return PE_LA_SSOFAILED + unless ( $this->{laLogin} + and defined( $this->{laLogin} ) + and defined( $this->param('SAMLart') ) ); + + return $this->libertyArtefactResolution(@_); +} + +#=============================================================================== +# libertyDeletingExistingSession +#=============================================================================== +# +# Delete existing Apache session file and Apache session ID <-> nameIdentifier +# association file. +# +#=============================================================================== + +sub libertyDeletingExistingSession { + my $this = shift; + + # Deleting local cache session shared by all Lemonldap::NG::Handler. + + if ( $this->{datas} ) { + my $refLocalStorage = undef; + my $localStorage = $this->{localStorage}; + my $localStorageOptions = {}; + $localStorageOptions->{namespace} ||= "lemonldap"; + $localStorageOptions->{default_expires_in} ||= 600; + + eval "use $localStorage;"; + die("Unable to load $localStorage: $@") if ($@); + + eval '$refLocalStorage = new ' + . $localStorage + . '($localStorageOptions);'; + if ( defined $refLocalStorage ) { + $refLocalStorage->remove( ${ $this->{datas} }{_session_id} ); + + #$refLocalStorage->remove(substr($this->{userNameIdentifier},1)) ; + $refLocalStorage->purge(); + $this->_debug("Deleting apache session succeed"); + } + else { + $this->_debug("Deleting apache session failed"); + } + } + + # Deleting association file, which is created when asserting consumer, + # in store function. + + if ( $this->{sessionInfo}->{'laNameIdentifier'} + and $this->{globalStorageOptions}->{Directory} ) + { + my $dir = $this->{globalStorageOptions}->{Directory}; + $dir =~ s/(.*)\/?$/$1/; + my $file = $dir . '/' . $this->{sessionInfo}->{'laNameIdentifier'}; + + if ( not unlink $file ) { + $this->_debug("Deleting liberty-apache association file failed"); + } + else { + $this->_debug("Deleting liberty-apache association file succeed"); + } + } + + return PE_OK; +} + +#=============================================================================== +# libertyExtractFormInfo +#=============================================================================== +# +# Verify that user has choose a IDP for authentication. +# +#=============================================================================== + +sub libertyExtractFormInfo { + my $this = shift; + + # If only one IDP -> redirect automatically on this IDP + my $idp; + my @idps = keys %{ $this->{laIdps} }; + if ( $#idps >= 0 && $this->param('idpChoice') ) { + $idp = $this->param('idpChoice'); + } + return PE_FIRSTACCESS + unless $idp; + $this->{idp}->{id} = $idp; + return PE_OK; +} + +#=============================================================================== +# libertyFederationTermination +#=============================================================================== +# +# Terminate federation. +# +# TO BE DONE. +# +#=============================================================================== + +sub libertyFederationTermination { + my $this = shift; + + $this->_debug("Processing federation termination..."); + + my $query = $ENV{'QUERY_STRING'}; + return PE_LA_QUERYEMPTY + unless $query; + + if ( lasso::isLibertyQuery($query) ) { + $this->{lassoDefederation} = + lasso::Defederation->new( $this->{laServer} ); + + return PE_LA_DEFEDFAILED + unless ( $this->{lassoDefederation} + and defined( $this->{lassoDefederation} ) + and $this->{lassoDefederation}->processNotificationMsg($query) ); + + $this->_debug("lassoDefederation->processNotificationMsg... OK"); + + # TODO : + # $this->fedTerm(); + + return PE_OK; + } + return PE_DONE; +} + +#=============================================================================== +# libertyFederationTerminationReturn +#=============================================================================== +# +# Quand cet appel ce produit t'il? +# +# TO BE DONE. +# +#=============================================================================== + +sub libertyFederationTerminationReturn { + my $this = @_; + + $this->_debug("The Return of the federation termination..."); + $this->{urldc} = $this->{portal}; + return PE_OK; +} + +#=============================================================================== +# libertyRetrieveExistingSession +#=============================================================================== +# +# Try to restore session whithin userNameIdentifier. +# +#=============================================================================== + +sub libertyRetrieveExistingSession { + my $this = shift; + + # To retrieve current Liberty session, there are two ways : + # - 1/ We have Lemonldap::NG cookie. Then we have lassoLoginDump ; + # - 2/ We have a query string that contains the userNameIdentifier. + # Then, we could retrieve apache session from cache files. + + return PE_LA_SESSIONERROR + unless ( defined $this->{laStorageOptions}->{Directory} ); + + # TODO : + # Retrieve NameIdentifier by catching and parsing $ENV{'QUERY_STRING'} + + # 2/ + + if ( $this->param('NameIdentifier') ) { + + # Retrieve apache session id from userNameIdentifier. + # $id contains apache session id. + + my $dir = $this->{laStorageOptions}->{Directory}; + $dir =~ s/(.*)\/?$/$1/; + my $file = $dir . '/' . $this->param('NameIdentifier'); + + return PE_LA_SESSIONERROR + unless ( open( MYFILE, $file ) ); + + my $id = readline(*MYFILE); + chomp($id); + close(MYFILE); + + # We can not rebuild factice cookie for Lemonldap::NG retrieving + # itself the session. So, we retrieve here directly the session. + # Lemonldap::NG::Simple code of controlExistingSession function. + + # Trying to recover session from global session storage + my %h; + eval { + tie %h, $this->{globalStorage}, $id, $this->{globalStorageOptions}; + }; + if ( $@ or not tied(%h) ) { + + # Session not available (expired ?) + print STDERR + "Session $id isn't yet available ($ENV{REMOTE_ADDR})\n"; + return PE_OK; + } + $this->{id} = $id; + + # A session has been find => calling &existingSession + my $r; + %{ $this->{datas} } = %h; + untie(%h); + if ( $this->{existingSession} ) { + $r = &{ $this->{existingSession} }( $this, $id, $this->{datas} ); + } + else { + $r = $this->existingSession( $id, $this->{datas} ); + } + + # Save datas in sessionInfo. + while ( my ( $k, $v ) = each( %{ $this->{datas} } ) ) { + $this->{sessionInfo}->{$k} = $v; + } + + $this->_debug("No existing liberty session found") + unless ( $r == PE_OK ); + } + + return PE_OK; +} + +#=============================================================================== +# libertySetSessionInfo +#=============================================================================== +# +# This function store in session cache information retrieve from IDP. If +# ID-WSF option is specified, it also store ID-WSF-attributes. +# In all cases, it fixes username of user who is authenticated on IDP. +# +#=============================================================================== + +sub libertySetSessionInfo { + my $this = shift; + + return PE_LA_FAILED + unless ( defined $this->{laLogin} ); + + my $lassoLogin = $this->{laLogin}; + + # Store identity in LDAP Directory, if identity not exists. Good + # opportunity to ask user some more informations. + + return PE_LA_FAILED + unless ( + defined $lassoLogin->{session} + + # and defined $lassoLogin->{identity} + and $lassoLogin->{nameIdentifier}->{content} + ); + + # Here, we store liberty identity and session in Apache session. + # We just store informations in cache, then those are saved by + # store function. Saved nameIdentifier too. + + # $this->{sessionInfo}->{laIdentityDump} = $lassoLogin->{identity}->dump() ; + $this->{sessionInfo}->{laSessionDump} = $lassoLogin->{session}->dump(); + $this->{sessionInfo}->{laNameIdentifier} = + $lassoLogin->{nameIdentifier}->{content}; + + # Get username from assertion and restore it in param('user'). Be + # carefull, IDP does not return username but an id for user assertion. + # The Lemonldap::NG search consists to perform a search with a filter + # using nameIdentifier, instead of username. + + $this->{userNameIdentifier} = $lassoLogin->{nameIdentifier}->{content}; + $this->{user} = $this->{userNameIdentifier}; + $this->{password} = 'none'; + + # Try to retrieve uid in SAML response form assertion statement. + # For the moment, uid have to be unique in LDAP directory. + my @uidValues = + $this->_getAttributeValuesOfSamlAssertion( $lassoLogin->{response}, + $this->{laLdapLoginAttribute} ); + $this->{user} = $uidValues[0] + if (@uidValues); + + return PE_OK; +} + +#=============================================================================== +# libertySignOn +#=============================================================================== +# +# Init SSO request. If successfull, $this->{urldc} contains Liberty IDP Url +# for redirection. +# +#=============================================================================== + +sub libertySignOn { + my $this = shift; + + my $lassoLogin = lasso::Login->new( $this->{laServer} ); + + return PE_LA_FAILED + unless ( $lassoLogin and defined($lassoLogin) ); + + # TODO : + # Catching error when retrieving $providerID. + + my $providerID = $this->{LAidps}->{ $this->{idp}->{id} }->{url}; + + if ( + my $error = $lassoLogin->initAuthnRequest( + $providerID, $lasso::HTTP_METHOD_REDIRECT + ) + ) + { + $this->_debug("lassoLogin->initAuthnRequest(...) : error = $error"); + return PE_LA_SSOINITFAILED; + } + + # We do one time federation, IDP doe not have to store nameIdentifier. + + $lassoLogin->{request}->{consent} = $lasso::LIB_CONSENT_OBTAINED; + $lassoLogin->{request}->{nameIdPolicy} = + $lasso::LIB_NAMEID_POLICY_TYPE_ONE_TIME; + + #$lassoLogin->{request}->{nameIdPolicy} = $lasso::LIB_NAMEID_POLICY_TYPE_FEDERATED ; + $lassoLogin->{request}->{isPassive} = 0; + + if ( $this->param('url') ) { + my $url = decode_base64( $this->param('url') ); + chomp $url; + $lassoLogin->{request}->{relayState} = $url; + } + + if ( my $error = $lassoLogin->buildAuthnRequestMsg() ) { + $this->_debug("lassoLogin->buildAuthnRequestMsg(..) : error = $error"); + return PE_LA_SSOINITFAILED; + } + + $this->{urldc} = $lassoLogin->{msgUrl}; + return PE_OK; +} + +#=============================================================================== +# libertySingleLogout +#=============================================================================== +# +# Two cases : +# * Portal or applications requiere singleLogout -> SP request ; +# * IDP requiere singleLogout -> IDP request with $ENV{'QUERY_STRING'} +# specified. +# +#=============================================================================== + +sub libertySingleLogout { + my $this = shift; + + my $lassoLogout = lasso::Logout->new( $this->{laServer} ); + return PE_LA_FAILED + unless ( $lassoLogout + and defined($lassoLogout) + and defined $ENV{'QUERY_STRING'} ); + + if ( lasso::isLibertyQuery( $ENV{'QUERY_STRING'} ) ) { + + # We retrieve query string and verify it. + # If it is OK, we set lemonldap::ng logout parameter, so we can perform + # it in Lemonldap::NG normal process. Then, we remove our stored liberty + # association file. + + $this->param( 'logout' => '1' ); + + if ( my $error = + $lassoLogout->processRequestMsg( $ENV{'QUERY_STRING'} ) ) + { + $this->_debug( + "lassoLogout->processRequestMsg(...) : error = $error"); + return PE_LA_SLOFAILED; + } + + # my $lassoIdentity = lasso::Identity::newFromDump($this->{sessionInfo}->{laIdentityDump}) ; + # $lassoLogout->{identity} = $lassoIdentity ; + my $lassoSession = + lasso::Session::newFromDump( $this->{sessionInfo}->{laSessionDump} ); + $lassoLogout->{session} = $lassoSession; + + # Logout by soap call could failed with those two errors. + if ( my $error = $lassoLogout->validateRequest() ) { + if ( $error != $lasso::PROFILE_ERROR_SESSION_NOT_FOUND + and $error != $lasso::PROFILE_ERROR_IDENTITY_NOT_FOUND ) + { + $this->_debug( + "lassoLogout->validateRequest(...) : error = $error"); + return PE_LA_SLOFAILED; + } + } + + if ( my $error = $lassoLogout->buildResponseMsg() ) { + $this->_debug( + "lassoLogout->buildResponseMsg(...) : error = $error"); + return PE_LA_SLOFAILED; + } + + # Confirm logout by soap request + if ( defined $lassoLogout->{msgBody} ) { + my $soapResponseMsg = $this->_soapRequest( $lassoLogout->{msgUrl}, + $lassoLogout->{msgBody} ); + } + } + + # Fixes redirection. + $this->{urldc} = $lassoLogout->{msgUrl}; + + # If $this->{urldc} empty, then we try to use HTTP referer if it exists + $this->{urldc} = $ENV{'HTTP_REFERER'} + if ( not $this->{urldc} and $ENV{'HTTP_REFERER'} ); + + return PE_OK; +} + +#=============================================================================== +# libertySingleLogoutReturn +#=============================================================================== +# +# SP provides singleLogout, it calls IDP which has done Liberty logout. Then IDP +# requests http://portal/liberty/singleLogoutReturn. +# Here, as there is no more liberty session on IDP, we suppress liberty session +# on Lemon. +# +# TODO : Modifier le redirect pour appeler le handler logout configuré dans la +# directive location (portal ou handler dédié, plus besoin du relaystate). +# +# TO BE DONE. +# +#=============================================================================== + +sub libertySingleLogoutReturn { + my $this = shift; + + $this->{lassoLogout} = lasso::Logout->new( $this->{laServer} ); + return PE_LA_SLOFAILED + unless ( $this->{lassoLogout} and defined( $this->{lassoLogout} ) ); + + $this->_debug("Processing single logout return..."); + + my %cookies = fetch CGI::Cookie; + + # Test if Lemonldap::NG cookie is available + if ( $cookies{ $this->{cookieName} } + and my $id = $cookies{ $this->{cookieName} }->value ) + { + + $this->{session_nb} = $cookies{ $this->{cookieName} }; + + $this->_debug("Cookie: $this->{cookieName} found..."); + $this->_debug("session number: $this->{session_nb}"); + + my $query = $ENV{'QUERY_STRING'}; + return PE_LA_QUERYEMPTY + unless $query; + + $this->_debug("Processing response message..."); + + return PE_LA_SLOFAILED + unless ( $this->{lassoLogout}->processResponseMsg($query) ); + + $this->_debug("lassoLogout->processResponseMsg... OK"); + + $this->delLibertySession(); + + $this->_debug("delete liberty session... OK"); + + my $formRelayState = $this->param('RelayState'); + return PE_LA_SLOFAILED + unless ( $formRelayState and defined($formRelayState) ); + + $this->_debug("formRelayState: $formRelayState"); + $this->{urldc} = $formRelayState . '/logout'; + + return PE_OK; + } + return PE_LA_SLOFAILED; +} + +#=============================================================================== +# libertySoapCall +#=============================================================================== +# +# IDP request defederation by SOAP calls. +# +# TO BE DONE. +# +#=============================================================================== + +sub libertySoapCall { + my $this = shift; + + $this->_debug("Soap call processing..."); + + my $contentType = $ENV{'CONTENT_TYPE'}; + my $soapMsg = $ENV{'QUERY_STRING'}; + + return PE_LA_SOAPFAILED + unless ( $contentType and $soapMsg and $contentType eq 'text/xml' ); + + $this->_debug("contentType: $contentType"); + $this->_debug("soapMsg: $soapMsg"); + + my $requestType = lasso::getRequestTypeFromSoapMsg($soapMsg); + + # Logout request + return $this->libertySingleLogout + if ( $requestType eq $lasso::REQUEST_TYPE_LOGOUT ); + + # Defederation request + return $this->libertyFederationTermination + if ( $requestType eq $lasso::REQUEST_TYPE_DEFEDERATION ); + + return PE_DONE; +} + +#=============================================================================== +# libertySoapEndpoint +#=============================================================================== +# +# Requests arrive in SOAP. We MUST traited them. +# Work as process function : call other functions. +# +#=============================================================================== + +sub libertySoapEndpoint { + my $this = shift; + + $this->_debug("SoapEndpoint processing..."); + + my $soapRequest = $this->param('POSTDATA'); + return PE_LA_SEPFAILED + unless $soapRequest; + + my $soapRequestType = lasso::getRequestTypeFromSoapMsg($soapRequest); + + $this->_debug("RequestType = $soapRequestType"); + + # Logout SOAP request + if ( $soapRequestType == $lasso::REQUEST_TYPE_LOGOUT ) { + $ENV{'QUERY_STRING'} = $soapRequest; + return $this->libertySingleLogout(); + + # Defederation SOAP request + } + elsif ( $soapRequestType == $lasso::REQUEST_TYPE_DEFEDERATION ) { + + # TODO + # Lemonldap do defederation ? + } + + return PE_OK; +} + +#=============================================================================== +#=============================================================================== + +################################################################################ +################################################################################ +## ## +## Private functions ## +## ## +################################################################################ +################################################################################ + +#=============================================================================== +# _getAttributeValuesOfSamlAssertion +#=============================================================================== +# +# Retrieve attribute value from a SAMLP response specified in first parameter. +# Return a table of values corresponding to the attribute name specified in +# second parameter. +# +#=============================================================================== + +sub _getAttributeValuesOfSamlAssertion { + my $this = shift; + my $samlp = shift; + my $attributeName = shift; + my @tab = (); + + # Search the specific attribute. + + my $attribute = undef; + + for ( + my $i = 0 ; + not defined $attribute + and $i < lasso::NodeList::length( $samlp->{assertion} ) ; + $i++ + ) + { + my $assertion = lasso::NodeList::getItem( $samlp->{assertion}, $i ); + my $attributeStatement = $assertion->{attributeStatement}; + + for ( + my $j = 0 ; + not defined $attribute + and $j < + lasso::NodeList::length( $attributeStatement->{attribute} ) ; + $j++ + ) + { + my $attr = + lasso::NodeList::getItem( $attributeStatement->{attribute}, $j ); + + if ( $attr->{attributeName} eq $attributeName ) { + $attribute = $attr; + } + } + } + + return @tab + unless ( defined $attribute ); + + # Then get values + # Values are only lasso::MiscTextNode type. + + for ( + my $k = 0 ; + $k < lasso::NodeList::length( $attribute->{attributeValue} ) ; + $k++ + ) + { + my $attributeValue = + lasso::NodeList::getItem( $attribute->{attributeValue}, $k ); + my $valueList = $attributeValue->{any}; + for ( my $l = 0 ; $l < lasso::NodeList::length($valueList) ; $l++ ) { + my $value = lasso::NodeList::getItem( $valueList, $l ); + push @tab, $value->{content} + if ( isa( $value, "lasso::MiscTextNode" ) ); + } + } + + return @tab; +} + +#=============================================================================== +# _loadXMLIdpFile +#=============================================================================== +# +# Load Identity Providers file. +# File is a XML file which contains providers definition. +# Only one service provider for multiple identity provider. +# +#=============================================================================== + +sub _loadXmlIdpFile { + my $this = shift; + my $file = shift; + + my $xml = XML::Simple::XMLin( $this->{laIdpsFile}, ForceArray => ['idp'] ); + $this->{laIdps} = $xml->{idp}; + + # Adding all IDPs in laIdpsFile in laServer. + # Have to be done one time -> no choice : in constructor. + + foreach ( keys %{ $this->{laIdps} } ) { + my $hash = $this->{laIdps}->{$_}; + $this->{laServer}->addProvider( + $lasso::PROVIDER_ROLE_IDP, $hash->{'metadata'}, + $hash->{'pubkey'}, $hash->{'certificate'}, + ); + } +} + +#=============================================================================== +# _soapRequest +#=============================================================================== +# +# Do soap request with only two parameters : +# - URI string ; +# - Body string ; +# Thus function return body's response message. +# +#=============================================================================== + +sub _soapRequest { + my $this = shift; + my ( $uri, $body ) = @_; + + my $soapHeaders = new HTTP::Headers( Content_Type => "text/xml" ); + my $soapRequest = new HTTP::Request( "POST", $uri, $soapHeaders, $body ); + my $soapAgent = LWP::UserAgent->new( agent => 'Mozilla/5.0 [en]' ); + my $soapResponse = $soapAgent->request($soapRequest); + + return $soapResponse->content(); +} + +#=============================================================================== +# _subProcess +#=============================================================================== +# +# Externalise functions' execution. +# +#=============================================================================== + +sub _subProcess { + my $this = shift; + my @subs = @_; + my $err = undef; + + foreach my $sub (@subs) { + if ( $this->{$sub} ) { + last if ( $err = &{ $this->{$sub} }($this) ); + } + else { + last if ( $err = $this->$sub ); + } + } + + return $err; +} + +#=============================================================================== +# _debug +#=============================================================================== +# +# Private tracing function. +# +#=============================================================================== + +sub _debug { + my $this = shift; + my $str = shift; + my ( + $package, $filename, $line, $subroutine, $hasargs, + $wantarray, $evaltext, $is_require, $hints, $bitmask + ) = caller(1); + print STDERR $subroutine . " : " . $str . "\n"; +} + +#=============================================================================== +#=============================================================================== + +################################################################################ +################################################################################ +## ## +## Documentation ## +## ## +################################################################################ +################################################################################ 1; __END__ =head1 NAME -Lemonldap::NG::Portal::AuthLA - Provide Liberty Alliance Authentication +Lemonldap::NG::Portal::AuthLA - Provide Liberty Alliance Authentication for +FederID project. + =head1 SYNOPSIS + use Lemonldap::NG::Portal::AuthLA; + my $portal = Lemonldap::NG::Portal::AuthLA->new({ + configStorage => { + type => 'DBI', + dbiChain => "dbi:mysql:...", + dbiUser => "lemonldap", + dbiPassword => "password", + dbiTable => "lmConfig", + } , + + # Liberty Parameters + laSp => { + certificate => '/path/to/public/key.pem' , + metadata => '/path/to/metadata.xml' , + privkey => '/path/to/private/key.pem' , + secretkey => '/path/to/private/key.pem' , + } , + laIdpsFile => '/path/to/idps/file.xml' , + laStorage => 'Apache::Session::File', + laStorageOptions => { + Directory => '/path/to/session/directory' , + LockDirectory => '/path/to/lockedsession/directory' , + } , + laDebug => 1 , + laLdapLoginAttribute => 'uid' , + + # Parameters that permit to access lemonldap::NG::Handler local cache + localStorage => 'Cache::FileCache' , + localStorageOptions => {} , + }); + + if( $portal->process() ) { + # Print protected URLs + print $portal->header ; + print " $_
" + foreach ($portal->getProtectedURLs) ; + + } else { + print $portal->header ; + print '...' ; + + # Print simple template + print 'Simple Authentication
' ; + print '' ; + print 'Login :' ; + if ($portal->param('user')) { + print '' ; + } else { + print '' ; + } + print 'Password : ' ; + + # Retrieve IDP list. + my @idps = () ; + foreach ($portal->getIdpIDs) { + my %row_data ; + $row_data{IDPNAME} = $_ ; + push (@idps, \%row_data) ; + } + @idps = sort {$a cmp $b} @idps ; + + # Print SSO template + print 'SSO Authentication
' ; + print '' ; + print '' ; + } + =head1 DESCRIPTION +Lemonldap::NG::Portal::AuthLA is the base module for building Lemonldap::NG +compatible portals using a authentication mechanism based on Liberty Alliance. +You have to use by inheritance. + =head1 SEE ALSO L, L, @@ -180,6 +1438,8 @@ http://wiki.lemonldap.objectweb.org/xwiki/bin/view/NG/Presentation =head1 AUTHOR Clement Oudot, Ecoudot@linagora.comE +Mikaël Ates, Emikael.ates@univ-st-etienne.frE +Thomas Chemineau, Etchemineau@linagora.comE =head1 BUG REPORT @@ -193,10 +1453,11 @@ L =head1 COPYRIGHT AND LICENSE -Copyright (C) 2007 by Clement Oudot, Ecoudot@linagora.comE +Copyright (C) 2007 by FederID Consortium, Email@FederIDE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available. =cut +