diff --git a/build/lemonldap-ng/Makefile b/build/lemonldap-ng/Makefile index 12000cfb2..036dd0092 100644 --- a/build/lemonldap-ng/Makefile +++ b/build/lemonldap-ng/Makefile @@ -31,8 +31,8 @@ LASPPORTALDIR=$(DOCUMENTROOT)/liberty-alliance-sp-portal RLASPPORTALDIR=$(DESTDIR)/$(LASPPORTALDIR) MANAGERDIR=$(DOCUMENTROOT)/manager RMANAGERDIR=$(DESTDIR)/$(MANAGERDIR) -MANAGERDATADIR=$(MANAGERDIR)/imgs -RMANAGERDATADIR=$(DESTDIR)/$(MANAGERDATADIR) +MANAGERSKINSDIR=$(MANAGERDIR)/skins +RMANAGERSKINSDIR=$(DESTDIR)/$(MANAGERSKINSDIR) SESSIONSEXPLORERDIR=$(MANAGERDIR) RSESSIONSEXPLORERDIR=$(DESTDIR)/$(SESSIONSEXPLORERDIR) SESSIONSEXPLORERDATADIR=$(SESSIONSEXPLORERDIR)/images @@ -259,27 +259,33 @@ install_site: install_manager_site install_portal_site install_handler_site inst install_manager_site: install_conf_dir # Manager install - @install -v -d ${RMANAGERDIR} ${RMANAGERDATADIR} \ + @install -v -d ${RMANAGERDIR} ${RMANAGERSKINSDIR} \ ${RSESSIONSEXPLORERDIR} $(RSESSIONSEXPLORERDATADIR) \ - $(RCONFDIR) - @find ${RMANAGERDIR} -type l -name imgs -delete - @find ${RMANAGERDIR} -type l -name images -delete - @cp -pR --remove-destination ${SRCMANAGERDIR}/example/* ${RMANAGERDIR} - @rm -rf $$(find ${RMANAGERDIR} -type d -name .svn) ${RMANAGERDIR}/scripts ${RMANAGERDIR}/mrtg ${RMANAGERDIR}/soapserver.pl - @if [ "${RMANAGERDIR}/imgs/" != "${RMANAGERDATADIR}/" ]; then \ - mv -f ${RMANAGERDIR}/imgs/* ${RMANAGERDATADIR}/; \ - rm -rf ${RMANAGERDIR}/imgs; \ - ln -s $$(echo ${MANAGERDATADIR} | sed -e 's/\/$$//') ${RMANAGERDIR}/imgs; \ + $(RCONFDIR) ${RMANAGERDIR}/skins/ + @for skin in $$(ls lemonldap-ng-manager/example/skins/); do \ + [ -h $(RMANAGERDIR)/skins/$$skin ] && rm -f $(RMANAGERDIR)/skins/$$skin; \ + install -v -d $(RMANAGERSKINSDIR)/$$skin; \ + done + @find ${RSESSIONSEXPLORERDIR} -type l -name images -delete + @cp -pR --remove-destination ${SRCMANAGERDIR}/example/index.pl ${RMANAGERDIR} + @perl -i -pe 's#__SKINDIR__#$(MANAGERDIR)/skins#; \ + s#__APPSXMLFILE__#$(CONFDIR)/apps-list.xml#;' ${RMANAGERDIR}/index.pl + @cp -pR --remove-destination ${SRCMANAGERDIR}/example/skins/* $(RMANAGERSKINSDIR) + @if [ "$(MANAGERDIR)/skins/" != "$(MANAGERSKINSDIR)/" ]; then \ + for skin in $$(ls lemonldap-ng-manager/example/skins/); do \ + rm -rf $(RMANAGERDIR)/skins/$$skin/; \ + ln -s $(MANAGERSKINSDIR)/$$skin $(RMANAGERDIR)/skins/$$skin; \ + done; \ fi @perl -i -pe 's/__DNSDOMAIN__/$(DNSDOMAIN)/g' $(RCONFDIR)/$(CONFFILENAME) # Sessions explorer install - @if [ "${MANAGERDIR}" != "$(SESSIONSEXPLORERDIR)" ]; then mv -f ${RMANAGERDIR}/sessions.pl $(RSESSIONSEXPLORERDIR); fi - @if [ "${MANAGERDIR}/images/" != "${SESSIONSEXPLORERDATADIR}/" ]; then \ - mv -f ${RMANAGERDIR}/images/* ${RSESSIONSEXPLORERDATADIR}; \ + @cp -pR --remove-destination ${SRCMANAGERDIR}/example/{sessions.pl,images} $(RSESSIONSEXPLORERDIR) + @if [ "${SESSIONSEXPLORERDIR}/images/" != "${SESSIONSEXPLORERDATADIR}/" ]; then \ + mv -f ${RSESSIONSEXPLORERDIR}/images/* ${RSESSIONSEXPLORERDATADIR}; \ rm -rf ${RMANAGERDIR}/images; \ ln -s $$(echo ${SESSIONSEXPLORERDATADIR} | sed -e 's/\/$$//') ${RMANAGERDIR}/images; \ fi - @rm -rf $$(find ${RMANAGERDIR} ${RMANAGERDATADIR} \ + @rm -rf $$(find ${RMANAGERDIR} ${RMANAGERSKINSDIR} \ ${RSESSIONSEXPLORERDIR} $(RSESSIONSEXPLORERDATADIR) \ $(RCONFDIR) -type d -name .svn) @@ -344,7 +350,7 @@ install_examples_site: cp -dpR --remove-destination lemonldap-ng-$$i/example $(REXAMPLESDIR)/$$i; \ done @rm -rf $(REXAMPLESDIR)/portal/skins \ - $(REXAMPLESDIR)/manager/imgs \ + $(REXAMPLESDIR)/manager/skins \ $(REXAMPLESDIR)/manager/images \ @rm -rf $$(find $(REXAMPLESDIR) -type d -name .svn) @perl -i -pe 's#__DIR__#$(LASPPORTALDIR)#g' $(REXAMPLESDIR)/portal/AuthLA/index.pl @@ -459,7 +465,7 @@ manager_cpan: manager_conf static_example: example @mkdir -p ${EXAMPLESDIR}/static - @cd ${EXAMPLESDIR}/static/;cp -a ../manager/{imgs,theme} .;cd - + @cd ${EXAMPLESDIR}/static/;cp -a ../manager/{skins} .;cd - @../scripts/make_static_example.pl ${DESTMANAGERDIR}/index.pl ${SCRIPTSDIR}/static/index.html $(EXAMPLELANG) documentation: diff --git a/build/lemonldap-ng/debian/liblemonldap-ng-manager-perl.install b/build/lemonldap-ng/debian/liblemonldap-ng-manager-perl.install index 1b400af35..d4b904069 100644 --- a/build/lemonldap-ng/debian/liblemonldap-ng-manager-perl.install +++ b/build/lemonldap-ng/debian/liblemonldap-ng-manager-perl.install @@ -1,11 +1,7 @@ debian/tmp/usr/share/perl5/Lemonldap/NG/Manager* debian/tmp/usr/share/perl5/auto/Lemonldap/NG/Manager -debian/tmp/usr/share/man/man3/Lemonldap::NG::Manager.3pm -debian/tmp/usr/share/man/man3/Lemonldap::NG::Manager::SOAPServer.3pm -debian/tmp/usr/share/man/man3/Lemonldap::NG::Manager::Restricted.3pm -debian/tmp/etc/lemonldap-ng/apply.conf debian/manager-apache*.conf /etc/lemonldap-ng -debian/tmp/usr/share/lemonldap-ng/manager-imgs +debian/tmp/usr/share/lemonldap-ng/manager-skins debian/tmp/usr/share/lemonldap-ng/sessions-explorer-imgs debian/tmp/var/lib/lemonldap-ng/manager debian/tmp/usr/share/lemonldap-ng/bin/lmConfigEditor diff --git a/build/lemonldap-ng/debian/po/ja.po b/build/lemonldap-ng/debian/po/ja.po index 692b1b869..3ae4bbd82 100644 --- a/build/lemonldap-ng/debian/po/ja.po +++ b/build/lemonldap-ng/debian/po/ja.po @@ -1,131 +1,131 @@ # Copyright (C) 2009 Xavier Guimard # This file is distributed under the same license as lemonldap-ng package. # Hideki Yamane (Debian-JP) , 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: lemonldap-ng 0.9.4.1-2\n" -"Report-Msgid-Bugs-To: x.guimard@free.fr\n" -"POT-Creation-Date: 2007-09-22 13:08+0200\n" -"PO-Revision-Date: 2009-11-24 14:26+0900\n" -"Last-Translator: Hideki Yamane (Debian-JP) \n" -"Language-Team: Japanese \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:1001 -msgid "LDAP server:" -msgstr "LDAP サーバ:" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:1001 -msgid "" -"Set here name or IP address of the LDAP server that has to be used by " -"Lemonldap::NG. You can modify this value later using the Lemonldap::NG " -"manager." -msgstr "" -"Lemonldap::NG が利用する LDAP サーバの名前、あるいは IP アドレスをここで" -"設定してください。Lemonldap::NG マネージャを使えば、後ほどこの値を変更できます。" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:2001 -msgid "Lemonldap::NG DNS domain:" -msgstr "Lemonldap::NG DNS ドメイン名:" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:2001 -msgid "" -"Set here the main domain protected by Lemonldap::NG. You can modify this " -"value later using the Lemonldap::NG manager." -msgstr "" -"ここで、Lemonldap::NG で保護するメインのドメイン名を設定してください。" -"Lemonldap::NG マネージャを使えば、後ほどこの値を変更できます。" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:3001 -msgid "Lemonldap::NG portal:" -msgstr "Lemonldap::NG ポータル::" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:3001 -msgid "" -"Set here the Lemonldap::NG portal URL. You can modify this value later using " -"the Lemonldap::NG manager." -msgstr "" -"ここで、Lemonldap::NG ポータルの URL を設定してください。Lemonldap::NG " -"マネージャを使えば、後ほどこの値を変更できます。" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:4001 -msgid "LDAP server port:" -msgstr "LDAP サーバのポート番号:" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:4001 -msgid "" -"Set here the port used by the LDAP server. You can modify this value later " -"using the Lemonldap::NG manager." -msgstr "" -"ここで、LDAP サーバが使うポート番号を設定してください。Lemonldap::NG マネージャ" -"を使えば、後ほどこの値を変更できます。" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:5001 -msgid "LDAP search base:" -msgstr "LDAP 検索ベース:" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:5001 -msgid "" -"Set here the search base to use in LDAP queries. You can modify this value " -"later using the Lemonldap::NG manager." -msgstr "" -"ここで、LDAP クエリで利用する検索ベースを設定してください。Lemonldap::NG " -"マネージャを使えば、後ほどこの値を変更できます。" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:6001 -msgid "LDAP account:" -msgstr "LDAP アカウント:" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:6001 -msgid "" -"Set here the account that Lemonldap::NG has to use for its LDAP requests. " -"Leaving it blank causes Lemonldap::NG to use anonymous connections. You can " -"modify this value later using the Lemonldap::NG manager." -msgstr "" -"ここで、LDAP のリクエストに対して Lemonldap::NG が使う必要があるアカウントを設定" -"してください。この欄を空白のままにしておくと、Lemonldap::NG は匿名での接続を行う" -"ようになります。Lemonldap::NG マネージャを使えば、後ほどこの値を変更できます。" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:7001 -msgid "LDAP password:" -msgstr "LDAP パスワード:" - -#. Type: string -#. Description -#: ../liblemonldap-ng-conf-perl.templates:7001 -msgid "" -"Set here the password for the Lemonldap::NG LDAP account. You can modify " -"this value later using the Lemonldap::NG manager." -msgstr "" -"Lemonldap::NG の LDAP アカウントのパスワードをここで設定してください。" -"Lemonldap::NG マネージャを使えば、後ほどこの値を変更できます。" - +# +msgid "" +msgstr "" +"Project-Id-Version: lemonldap-ng 0.9.4.1-2\n" +"Report-Msgid-Bugs-To: x.guimard@free.fr\n" +"POT-Creation-Date: 2007-09-22 13:08+0200\n" +"PO-Revision-Date: 2009-11-24 14:26+0900\n" +"Last-Translator: Hideki Yamane (Debian-JP) \n" +"Language-Team: Japanese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:1001 +msgid "LDAP server:" +msgstr "LDAP サーバ:" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:1001 +msgid "" +"Set here name or IP address of the LDAP server that has to be used by " +"Lemonldap::NG. You can modify this value later using the Lemonldap::NG " +"manager." +msgstr "" +"Lemonldap::NG が利用する LDAP サーバの名前、あるいは IP アドレスをここで設定" +"してください。Lemonldap::NG マネージャを使えば、後ほどこの値を変更できます。" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:2001 +msgid "Lemonldap::NG DNS domain:" +msgstr "Lemonldap::NG DNS ドメイン名:" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:2001 +msgid "" +"Set here the main domain protected by Lemonldap::NG. You can modify this " +"value later using the Lemonldap::NG manager." +msgstr "" +"ここで、Lemonldap::NG で保護するメインのドメイン名を設定してください。" +"Lemonldap::NG マネージャを使えば、後ほどこの値を変更できます。" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:3001 +msgid "Lemonldap::NG portal:" +msgstr "Lemonldap::NG ポータル::" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:3001 +msgid "" +"Set here the Lemonldap::NG portal URL. You can modify this value later using " +"the Lemonldap::NG manager." +msgstr "" +"ここで、Lemonldap::NG ポータルの URL を設定してください。Lemonldap::NG マネー" +"ジャを使えば、後ほどこの値を変更できます。" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:4001 +msgid "LDAP server port:" +msgstr "LDAP サーバのポート番号:" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:4001 +msgid "" +"Set here the port used by the LDAP server. You can modify this value later " +"using the Lemonldap::NG manager." +msgstr "" +"ここで、LDAP サーバが使うポート番号を設定してください。Lemonldap::NG マネー" +"ジャを使えば、後ほどこの値を変更できます。" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:5001 +msgid "LDAP search base:" +msgstr "LDAP 検索ベース:" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:5001 +msgid "" +"Set here the search base to use in LDAP queries. You can modify this value " +"later using the Lemonldap::NG manager." +msgstr "" +"ここで、LDAP クエリで利用する検索ベースを設定してください。Lemonldap::NG マ" +"ネージャを使えば、後ほどこの値を変更できます。" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:6001 +msgid "LDAP account:" +msgstr "LDAP アカウント:" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:6001 +msgid "" +"Set here the account that Lemonldap::NG has to use for its LDAP requests. " +"Leaving it blank causes Lemonldap::NG to use anonymous connections. You can " +"modify this value later using the Lemonldap::NG manager." +msgstr "" +"ここで、LDAP のリクエストに対して Lemonldap::NG が使う必要があるアカウントを" +"設定してください。この欄を空白のままにしておくと、Lemonldap::NG は匿名での接" +"続を行うようになります。Lemonldap::NG マネージャを使えば、後ほどこの値を変更" +"できます。" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:7001 +msgid "LDAP password:" +msgstr "LDAP パスワード:" + +#. Type: string +#. Description +#: ../liblemonldap-ng-conf-perl.templates:7001 +msgid "" +"Set here the password for the Lemonldap::NG LDAP account. You can modify " +"this value later using the Lemonldap::NG manager." +msgstr "" +"Lemonldap::NG の LDAP アカウントのパスワードをここで設定してください。" +"Lemonldap::NG マネージャを使えば、後ほどこの値を変更できます。" diff --git a/build/lemonldap-ng/debian/rules b/build/lemonldap-ng/debian/rules index e046a046d..c5cfc10af 100755 --- a/build/lemonldap-ng/debian/rules +++ b/build/lemonldap-ng/debian/rules @@ -61,7 +61,7 @@ install: build EXAMPLESDIR=/examples/ \ HANDLERDIR=$(LMVARDIR)handler/ \ PORTALSKINSDIR=$(LMSHAREDIR)portal-skins/ \ - MANAGERDATADIR=$(LMSHAREDIR)manager-imgs/ \ + MANAGERSKINSDIR=$(LMSHAREDIR)manager-skins/ \ SESSIONSEXPLORERDATADIR=$(LMSHAREDIR)sessions-explorer-imgs/ \ STORAGECONFFILE=/etc/lemonldap-ng/lemonldap-ng.ini \ TOOLSDIR=$(LMSHAREDIR)ressources/ \ @@ -72,9 +72,7 @@ install: build APACHEGROUP=www-data # Since Lenny, jquery.js is provided by libjs-jquery - rm -f $(CURDIR)/debian/tmp$(LMSHAREDIR)portal-skins/*/jquery.js \ - $(CURDIR)/debian/tmp$(LMVARDIR)manager/jquery.js \ - debian/tmp/examples/manager/jquery.js + rm -f $(CURDIR)/debian/tmp$(LMSHAREDIR)*-skins/*/jquery.js perl -i -pe 's#(["'"'"'])[\w-\./]*jquery.js#$$1/javascript/jquery/jquery.js#' \ $(CURDIR)/debian/tmp/examples/manager/*.pl \ $(CURDIR)/debian/tmp$(LMSHAREDIR)portal-skins/pastel/header.tpl diff --git a/modules/lemonldap-ng-common/META.yml b/modules/lemonldap-ng-common/META.yml index c77b7a405..e145cf90f 100644 --- a/modules/lemonldap-ng-common/META.yml +++ b/modules/lemonldap-ng-common/META.yml @@ -13,6 +13,7 @@ build_requires: requires: Cache::Cache: 0 CGI: 3.08 + Config::IniFiles: 0 Crypt::Rijndael: 0 DBI: 0 HTTP::Headers: 0 @@ -20,7 +21,6 @@ requires: Regexp::Assemble: 0 SOAP::Lite: 0 Storable: 0 - Config::IniFiles: 0 no_index: directory: - t diff --git a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/CGI.pm b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/CGI.pm index 68d307a51..1c0732a95 100644 --- a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/CGI.pm +++ b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/CGI.pm @@ -288,6 +288,33 @@ sub _sub { } } +##@method void translate_template(string text_ref, string lang) +# translate_template is used as an HTML::Template filter to tranlate strings in +# the wanted language +#@param text_ref reference to the string to translate +#@param lang optionnal language wanted. Falls to browser language instead. +#@return +sub translate_template { + my $self = shift; + my $text_ref = shift; + my $lang = shift || $ENV{HTTP_ACCEPT_LANGUAGE}; + + # Get the lang code (2 letters) + $lang = lc($lang); + $lang =~ s/-/_/g; + $lang =~ s/^(..).*$/$1/; + + # Test if a translation is available for the selected language + # If not available, return the first translated string + # + if ( $$text_ref =~ m/$lang=\"(.*?)\"/ ) { + $$text_ref =~ s//$1/gx; + } + else { + $$text_ref =~ s//$1/gx; + } +} + ## @method private void quit() # Simply exit. sub quit { diff --git a/modules/lemonldap-ng-manager/MANIFEST b/modules/lemonldap-ng-manager/MANIFEST index 17459fce3..4bd6b2349 100644 --- a/modules/lemonldap-ng-manager/MANIFEST +++ b/modules/lemonldap-ng-manager/MANIFEST @@ -30,73 +30,54 @@ example/images/tree.js example/images/tree_line.gif example/images/vframe.png example/images/xlib.js -example/imgs/_customers.gif -example/imgs/blank.gif -example/imgs/book.gif -example/imgs/book_titel.gif -example/imgs/books_close.gif -example/imgs/books_open.gif -example/imgs/btn_up1.gif -example/imgs/btn_up2.gif -example/imgs/close2.gif -example/imgs/folderClosed.gif -example/imgs/folderOpen.gif -example/imgs/iconCheckAll.gif -example/imgs/iconCheckGray.gif -example/imgs/iconClient.gif -example/imgs/iconDeleteSelected.gif -example/imgs/iconJob.gif -example/imgs/iconReport.gif -example/imgs/iconTask.gif -example/imgs/iconTimeRecordsEdit.gif -example/imgs/iconUncheckAll.gif -example/imgs/item.gif -example/imgs/item2.gif -example/imgs/leaf.gif -example/imgs/line1.gif -example/imgs/line2.gif -example/imgs/line3.gif -example/imgs/line4.gif -example/imgs/magazines_close.gif -example/imgs/magazines_open.gif -example/imgs/minus.gif -example/imgs/minus2.gif -example/imgs/minus3.gif -example/imgs/minus4.gif -example/imgs/minus5.gif -example/imgs/minus_ar.gif -example/imgs/open2.gif -example/imgs/plus.gif -example/imgs/plus2.gif -example/imgs/plus3.gif -example/imgs/plus4.gif -example/imgs/plus5.gif -example/imgs/plus_ar.gif -example/imgs/tombs.gif -example/imgs/tombs_mag.gif example/index.pl -example/jquery.js -example/lemonldap-ng-manager.js example/mrtg/lmng-mrtg example/mrtg/mrtg.cfg.example example/scripts/lmConfigEditor example/sessions.pl -example/theme/default.css -example/theme/hatch.gif -example/theme/logo_lemonldap-ng.png +example/skins/default/arrow_refresh.png +example/skins/default/collapsable-last.gif +example/skins/default/collapsable.gif +example/skins/default/cross.png +example/skins/default/disk.png +example/skins/default/expandable-last.gif +example/skins/default/expandable.gif +example/skins/default/folder_add.png +example/skins/default/folder_delete.png +example/skins/default/folder_edit.png +example/skins/default/hframe.png +example/skins/default/jquery.js +example/skins/default/leaf-last.gif +example/skins/default/leaf.gif +example/skins/default/line_bg.gif +example/skins/default/line_bg_over.gif +example/skins/default/line_bg_over_last.gif +example/skins/default/logo_lemonldap-ng.png +example/skins/default/manager.css +example/skins/default/manager.tpl +example/skins/default/minus.gif +example/skins/default/page_add.png +example/skins/default/page_delete.png +example/skins/default/page_edit.png +example/skins/default/plus.gif +example/skins/default/root.gif +example/skins/default/spacer.gif +example/skins/default/spinner.gif +example/skins/default/tree.js +example/skins/default/tree_line.gif +example/skins/default/vframe.png +example/skins/default/xlib.js lib/Lemonldap/NG/Manager.pm -lib/Lemonldap/NG/Manager/_HTML.pm lib/Lemonldap/NG/Manager/_i18n.pm -lib/Lemonldap/NG/Manager/_Response.pm +lib/Lemonldap/NG/Manager/_Struct.pm +lib/Lemonldap/NG/Manager/Downloader.pm lib/Lemonldap/NG/Manager/Help.pm -lib/Lemonldap/NG/Manager/Restricted.pm lib/Lemonldap/NG/Manager/Sessions.pm -lib/Lemonldap/NG/Manager/SOAPServer.pm +lib/Lemonldap/NG/Manager/Uploader.pm Makefile.PL -MANIFEST -META.yml Module meta-data (added by MakeMaker) +MANIFEST This list of files +META.yml README t/10-Manager.t t/20-Manager-i18n.t t/99-pod.t -TODO diff --git a/modules/lemonldap-ng-manager/META.yml b/modules/lemonldap-ng-manager/META.yml index e5d0688b6..2aa2bf90e 100644 --- a/modules/lemonldap-ng-manager/META.yml +++ b/modules/lemonldap-ng-manager/META.yml @@ -1,6 +1,6 @@ --- #YAML:1.0 name: Lemonldap-NG-Manager -version: 0.91 +version: 0.92 abstract: Perl extension for managing Lemonldap::NG Web-SSO author: - Xavier Guimard diff --git a/modules/lemonldap-ng-manager/TODO b/modules/lemonldap-ng-manager/TODO deleted file mode 100644 index 8242a05e7..000000000 --- a/modules/lemonldap-ng-manager/TODO +++ /dev/null @@ -1,2 +0,0 @@ - * system to alert if configuration as changed between get and update - diff --git a/modules/lemonldap-ng-manager/example/experimental.pl b/modules/lemonldap-ng-manager/example/experimental.pl deleted file mode 100755 index 373047c5b..000000000 --- a/modules/lemonldap-ng-manager/example/experimental.pl +++ /dev/null @@ -1,1119 +0,0 @@ -#!/usr/bin/perl - -#use Lemonldap::NG::Manager; - -my $h = new Lemonldap::NG::Manager::Experimental( - { - jqueryUri => '/javascript/jquery/jquery.js', - imagePath => '/images/', - cssFile => 'theme/default.css', - textareaW => 50, - textareaH => 2, - inputSize => 30, - - # OPTIONAL PARAMETERS - #jsFile => /path/to/lemonldap-ng-manager.js, - - # ACCESS TO CONFIGURATION - - # By default, Lemonldap::NG uses the default lemonldap-ng.ini file to know - # where to find is configuration - # (generaly /etc/lemonldap-ng/lemonldap-ng.ini) - # You can specify by yourself this file : - #configStorage => { confFile => '/path/to/my/file' }, - - # You can also specify directly the configuration - # (see Lemonldap::NG::Handler::SharedConf(3)) - #configStorage => { - # type => 'File', - # dirName => '/usr/local/lemonlda-ng/conf/' - #}, - - # CUSTOM FUNCTION - # If you want to create customFunctions in rules, declare them here: - #customFunctions => 'function1 function2', - #customFunctions => 'Package::func1 Package::func2', - } -) or die "Unable to start"; - -$h->doall(); - -package Lemonldap::NG::Manager::Experimental; - -use strict; -use Lemonldap::NG::Handler::CGI qw(:globalStorage :locationRules); - -our $VERSION = '0.1'; -our @ISA; - -BEGIN { - require Lemonldap::NG::Manager::Help; #inherits - *process = *doall; - @ISA = - qw( - Lemonldap::NG::Handler::CGI - Lemonldap::NG::Manager::Downloader - Lemonldap::NG::Manager::Uploader - Lemonldap::NG::Manager::_Struct - Lemonldap::NG::Manager::_i18n - ); -} - -sub new { - my ( $class, $args ) = @_; - my $self = $class->SUPER::new($args) - or $class->abort( 'Unable to start ' . __PACKAGE__, - 'See Apache logs for more' ); - $self->{imagePath} ||= 'images/'; - return $self; -} - -sub doall { - my $self = shift; - if ( $ENV{PATH_INFO} eq "/css" ) { - print $self->header_public( $ENV{SCRIPT_FILENAME}, -type => 'text/css', - ); - $self->css; - $self->quit(); - } - elsif ( $ENV{PATH_INFO} eq "/js" ) { - print $self->header_public( $ENV{SCRIPT_FILENAME}, - -type => 'text/javascript', ); - $self->js; - $self->quit(); - } - elsif ( $self->param('help') ) { - print $self->header_public( $ENV{SCRIPT_FILENAME}, - -type => 'text/html; charset=utf8' ); - Lemonldap::NG::Manager::Help::import( $self->{language} - || $ENV{HTTP_ACCEPT_LANGUAGE} ) - unless ( $self->can('help_groups') ); - my $chap = $self->param('help'); - eval { no strict "refs"; &{"help_$chap"} }; - $self->quit(); - } - elsif ( my $rdata = $self->rparam('data') ) { - - #require Lemonldap::NG::Manager::Uploader; #inherits - $self->confUpload($rdata); - $self->quit(); - } - elsif ( my $id = $self->param('newNode') ) { - print $self->header( -type => 'text/html; charset=utf8', ); - print '
  • test
  • '; - exit; - } - #require Lemonldap::NG::Manager::Downloader; #inherits - $self->{cfgNum} = - $self->param('cfgNum') - || $self->confObj->lastCfg() - || 'UNAVAILABLE'; - if ( my $p = $self->param('node') ) { - print $self->header( -type => 'text/html; charset=utf8', ); - $self->node($p); - } - else { - $self->start(); - $self->window( "Configuration $self->{cfgNum}", $self->{cfgNum} ); - $self->node(); - $self->end(); - } -} - -## @method protected void start() -# Display HTTP and HTML headers. -sub start { - my $self = shift; - print $self->header( -type => 'text/html; charset=utf8', ); - print $self->start_html( - -title => shift || 'Lemonldap::NG Manager', - -encoding => 'utf8', - -script => [ - { - -language => 'JavaScript1.2', - - #-src => "lemonldap-ng-manager.js", - -src => "$self->{imagePath}/xlib.js", - }, - { - -language => 'JavaScript1.2', - -src => $self->{jqueryUri} || 'jquery.js', - }, - { - -language => 'JavaScript1.2', - -src => "$self->{imagePath}/tree.js", - }, - { - -language => 'JavaScript1.2', - -code => "var scriptname='$ENV{SCRIPT_NAME}';" - . "var imagepath='$self->{imagePath}';", - }, - { - -language => 'JavaScript1.2', - -src => "$self->{imagePath}/manager.js", - }, - ], - -style => { - -src => [ - "$self->{imagePath}/manager.css", - ( $self->{personnalCss} ? $self->{personnalCss} : () ) - ], - }, - ); -} - -sub window { - my ( $self, $root, $data ) = @_; - print '
    -
    -
    - Lemonldap::NG
     
      ' - . $self->li( 'root', 'root' ) - . $self->span( 'root', $root, $data, '', 'none' ) . '
        '; -} - -## @method protected void end() -# Display the end of HTML page. -sub end { - my $self = shift; - print << "EOF"; -
    -
    -
    -
    -

    Lemonldap::NG Manager

    -
    - - - - - - -
    -
    -
    -
    - Default -
    - - - - - -
    -
    -
    -
    -
    -
    -
    -   -
    -
    -
    -
    -
    -
    -
    -EOF - print $self->end_html(); -} - -1; - -package Lemonldap::NG::Manager::Downloader; - -use Lemonldap::NG::Common::Conf::Constants; #inherits -use Lemonldap::NG::Common::Safelib; #link protected safe Safe object -use MIME::Base64; - -# TODO -use Data::Dumper; - -#require Lemonldap::NG::Manager::_Struct; #inherits -#require Lemonldap::NG::Manager::_i18n; #inherits - -sub node { - my ( $self, $node ) = @_; - $node =~ s/^\///; - - #$self->lmLog( "Processing to node: $node", 'debug' ); - if ( my ( $tmp, $help, $js ) = $self->corresp($node) ) { - - # Menu node - if ( ref($tmp) ) { - - # Scan subnodes - foreach ( @{ $tmp->{_nodes} } ) { - my $flag = ( $_ =~ s/^(\w+):// ? $1 : '' ); - my ( $target, $_h, $_j ) = split /:\s*/; - $help ||= $_h; - - # subnode is an ajax subnode - if ( $flag =~ /^(c?)n$/ ) { - $self->ajaxNode( - ( $1 ? $target : "$node/$target" ), - "$target", - "node=$node/$target", - $tmp->{$target}->{_help} || $help, - $tmp->{$target}->{_js} - ); - } - - # subnode is a node - elsif ( ref( $tmp->{$target} ) ) { - print $self->li( "$node/$target", "closed" ) - . $self->span( - "$node/$target", $target, '', - $tmp->{$target}->{_js}, - $tmp->{$target}->{_help} || $help - ) . "
      "; - $self->node("$node/$target"); - print "
    "; - } - - # subnode points to a configuration node - elsif ( $flag =~ /^n?hash$/ ) { - $self->confNode( $node, "$flag:$target", $help, $_j ); - } - - else { - $self->node("$node/$target"); - } - } - } - - # node points to a configuration point - else { - $self->confNode( $node, $tmp, $help, $js ); - } - } - else { - $self->lmLog( "$node was not found in tree\n", 'error' ); - } -} - -sub confNode { - my ( $self, $node, $target, $help, $js ) = @_; - $self->lmLog( "Processing to configuration node: $target", 'debug' ); - $target =~ s/^\///; - if ( $target =~ /^(.+?):(?!\/)(.+?):(?!\/)(.+?)$/ ) { - ( $target, $help, $js ) = ( $1, $2, $3 ); - } - - #my ( $t1, $t2 ) = ( '', '' ); - #( $target, $t1, $t2 ) = split /:(?!\/)/, $target - # if ( $target =~ /:(?!\/)/ ); - #$help ||= $t1; - #$js ||= $t2; - if ( $target =~ s/^nhash:// ) { - my $h = $self->keyToH( $target, $self->conf ); - return unless ($h); - foreach ( sort keys %$h ) { - if ( ref($h) ) { - $self->ajaxNode( "$target/$_", $_, "node=$node/$_\&key=$_", - $help, $js ); - } - else { - $self->confNode( "$target/$_", "btext:$target/$_", $help, $js ); - } - } - } - elsif ( $target =~ s/^hash:// ) { - my $h = $self->keyToH( $target, $self->conf ); - return unless ($h); - foreach ( sort keys %$h ) { - if ( ref( $h->{$_} ) ) { - $self->confNode( "$target/$_", $help, $js ); - } - else { - $js ||= 'btext'; - my $id = "$target/$_"; - $id =~ s/=*$//; - print $self->li($id) - . $self->span( $id, "$_", $h->{$_}, $js, $help, 1 ) . ""; - } - } - } - else { - $target =~ s/^(\w+)://; - my $type = $1 || 'text'; - $js ||= $type; - my $text = $target; - $text =~ s/^.*\///; - my $h = $self->keyToH( $target, $self->conf ); - - $h = $self->keyToH( $target, $self->defaultConf ) unless ( defined $h ); - unless ( defined $h ) { - $self->lmLog( "$target does not exists in menu hash", "warn" ); - return; - } - if ( ref($h) ) { - print $self->li( "$target", "closed" ) - . $self->span( "$target", $text, '', $js, $help ) . "
      "; - foreach ( sort keys %$h ) { - if ( ref( $h->{$_} ) ) { - $self->confNode( '', "btext:$target/$_", $help, $js ); - } - else { - my $id = "$target/$_"; - print $self->li($id) - . $self->span( $id, $_, $h->{$_}, $js, $help ) . ""; - } - } - print '
    '; - } - else { - my $id = "$target"; - print $self->li($id) - . $self->span( $id, $text, $h, $js, $help ) . ""; - } - } -} - -sub keyToH { - my ( $self, $key, $h ) = @_; - $key =~ s/^\///; - foreach ( split /\//, $key ) { - return () unless ( defined( $h->{$_} ) ); - $h = $h->{$_}; - } - return $h; -} - -sub corresp { - my ( $self, $key, $last ) = @_; - $key =~ s/^\///; - my $h = $self->struct(); - return $h unless ($key); - if ( my $k2 = $self->param('key') ) { - $h = $self->cstruct( $h, $k2 ); - } - my @tmp1 = split /\//, $key; - my $help; - my $js; - while ( $_ = shift(@tmp1) ) { - if ( ref($h) and defined $h->{$_} ) { - $help = $h->{_help} if ( $h->{_help} ); - $js = $h->{_js} if ( $h->{_js} ); - $h = $h->{$_}; - } - - # The wanted key does not exists - elsif ( ref($h) ) { - unless ($last) { - $self->param( 'key', $_ ); - return $self->corresp( $key, 1 ); - } - else { - $self->lmLog( "Key $key does not exist in configuration hash", - 'error' ); - return (); - } - } - - # If the key does not exist in manager tree, it must be defined in - # configuration hash - else { - return "$h/" . join( '/', $_, @tmp1 ); - } - } - if ( ref($h) ) { - $help = $h->{_help} if ( $h->{_help} ); - $js = $h->{_js} if ( $h->{_js} ); - } - return $h, $help, $js; -} - -sub conf { - my $self = shift; - return $self->{_conf} if ( $self->{_conf} ); - my $args = { cfgNum => $self->{cfgNum} }; - $args->{noCache} = 1 if ( $self->param('cfgNum') ); - $self->{_conf} = $self->confObj->getConf($args); - $self->abort( 'Unable to get configuration', - $Lemonldap::NG::Common::Conf::msg ) - unless ( $self->{_conf} ); - return $self->{_conf}; -} - -sub confObj { - my $self = shift; - return $self->{_confObj} if ( $self->{_confObj} ); - $self->{_confObj} = - Lemonldap::NG::Common::Conf->new( $self->{configStorage} ); - $self->abort( - 'Unable to access to configuration', - $Lemonldap::NG::Common::Conf::msg - ) unless ( $self->{_confObj} ); - $self->lmLog( $Lemonldap::NG::Common::Conf::msg, 'debug' ) - if ($Lemonldap::NG::Common::Conf::msg); - return $self->{_confObj}; -} - -## @method protected void ajaxnode(string id, string text, string param) -# Display tree node with Ajax functions inside for opening the node. -# @param $id HTML id of the element. -# @param $text text to display -# @param $param Parameters for the Ajax query -sub ajaxNode { - my ( $self, $id, $text, $param, $help, $js, $data, $noT ) = @_; - $param .= "&cfgNum=$self->{cfgNum}"; - print $self->li($id) - . $self->span( $id, $text, $data, undef, $help, $noT ) - . "
      " - . $self->li("sub_$id") - . ".{url:$ENV{SCRIPT_NAME}?$param" - . ( $js ? ",js:$js" : '' ) - . "}
    \n"; -} - -sub span { - my ( $self, $id, $text, $data, $js, $help, $noT ) = @_; - my $tmp = $text; - $data = '' unless ( defined $data ); - $js ||= "none"; - $id = "li_" . encode_base64( $id, '' ); - $id =~ s/(=*)$/length($1)/e; - $data =~ s/"/'/g; - $tmp =~ s/"/'/g; - $text = join ' ', map { $self->translate($_) } split /\s+/, $text unless($noT); - $text = $self->escapeHTML($text); - return -"$text -"; -} - -sub li { - my ( $self, $id, $class ) = @_; - $id = "li_" . encode_base64( $id, '' ); - $id =~ s/(=*)$/length($1)/e; - return "
  • " : ">" ); -} - -1; - -package Lemonldap::NG::Manager::_Struct; - -use strict; -our $VERSION = '0.1'; - -sub cstruct { - shift; - my ( $h, $k ) = @_; - %$h = ( - %$h, - virtualHosts => { - $k => { - _nodes => [qw(rules:rules:rules headers)], - rules => { - _nodes => ["hash:/locationRules/$k:rules:rules"], - _js => 'rulesRoot' - }, - headers => - { _nodes => ["hash:/exportedHeaders/$k"], _js => 'hashRoot' }, - } - } - ); - return $h; -} - -sub struct { - return { - _nodes => [qw(n:generalParameters n:groups n:virtualHosts)], - _help => 'default', - generalParameters => { - _nodes => [ - qw(n:authParams cookieParams cn:exportedVars cn:macros sessionParams ldapParams) - ], - _help => 'default', - authParams => { - _nodes => [qw(portal authentication userDB whatToTrace)], - _help => 'authParams', - authentication => 'text:/authentication', - portal => 'text:/portal', - userDB => 'text:/userDB', - whatToTrace => 'text:/whatToTrace:whatToTrace:text', - }, - cookieParams => { - _nodes => [qw(cookieName domain securedCookie)], - cookieName => 'text:/cookieName:cookieName:text', - domain => 'text:/domain:domain:text', - securedCookie => - 'int:/securedCookie:securedCookie:securedCookieValues', - }, - exportedVars => { - _nodes => ['hash:/exportedVars:vars:btext'], - _js => 'hashRoot' - }, - macros => - { _nodes => ['hash:/macros:macros:btext'], _js => 'hashRoot' }, - sessionParams => { - _nodes => [qw(sessionStorage timeout)], - _help => 'storage', - sessionStorage => { - _nodes => [qw(globalStorage globalStorageOptions)], - globalStorage => 'text:/globalStorage', - globalStorageOptions => { - _nodes => ['hash:/globalStorageOptions'], - _js => 'hashRoot' - }, - }, - timeout => 'text:/timeout:timeout:text', - }, - ldapParams => { - _nodes => - [qw(ldapServer ldapPort ldapBase managerDn managerPassword)], - _help => 'ldap', - ldapServer => 'text:/ldapServer', - ldapPort => 'int:/ldapPort', - ldapBase => 'text:/ldapBase', - managerDn => 'text:/managerDn', - managerPassword => 'text:/managerPassword', - }, - }, - groups => { _nodes => ['hash:/groups:groups:none'], _js => 'hashRoot' }, - virtualHosts => - { _nodes => ['nhash:/locationRules:virtualHosts:none'], }, - }; -} - -sub testStruct { - my $assignTest = qr/(?<=[^=\?])=(?![=~])/; - my $assignMsg = 'containsAnAssignment'; - my $perlExpr = sub { - my $e = shift; - eval "use strict;$e"; - return 1 if ( $@ =~ /Global symbol "\$.*requires explicit package/ ); - return ( $@ ? ( 0, $@ ) : 1 ); - }; - return { - authentication => { - test => qr/^[a-zA-Z][\w\:]*$/, - msgFail => 'Bad module name', - }, - userDB => { - test => qr/^[a-zA-Z][\w\:]*$/, - msgFail => 'Bad module name', - }, - whatToTrace => { - test => qr/^\$?[a-zA-Z]\w*$/, - msgFail => 'Bad value', - }, - portal => { - test => qr/^https?:\/\/\S+$/, - msgFail => 'Bad portal value', - }, - cookieName => { - test => qr/^[a-zA-Z]\w*$/, - msgFail => 'Bad cookie name', - }, - securedCookie => { - test => qr/^(?:0|1|2)$/, - msgFail => 'securedCookie must be 0, 1 or 2', - }, - domain => { - test => qr/^\.?\w+(?:\.[a-zA-Z]\w*)*(?:\.[a-zA-Z]+)$/, - msgFail => 'Bad domain', - }, - timeout => { - test => qr/^\d*$/, - msgFail => 'Bad number' - }, - globalStorage => { - test => qr/^[\w:]+$/, - msgFail => 'Bad module name', - }, - globalStorageOptions => { - keyTest => qr/^\w+$/, - keyMsgFail => 'Bad parameter', - }, - ldapBase => { - test => qr/^(?:\w+=.*|)$/, - msgFail => 'Bad LDAP base', - }, - ldapPort => { - test => qr/^\d*$/, - msgFail => 'Bad port number' - }, - ldapServer => { - test => sub { - my $l = shift; - my @s = split( /[\s,]+/, $l ); - foreach my $s (@s) { - $s =~ -/^(?:ldap(?:s|\+tls|i):\/\/)?\w[\w\-\.]+\w(?::\d{0,5})?\/?$/ - or return ( 0, "Bad ldap uri \"$s\"" ); - } - return 1; - }, - }, - managerDn => { - test => qr/^(?:\w+=.*,\w+=.*)?$/, - msgFail => 'Bad LDAP dn', - }, - managerPassword => {}, - groups => { - keyTest => qr/^\w[\w-]*$/, - keyMsgFail => 'Bad group name', - test => $perlExpr, - warnTest => sub { - my $e = shift; - return ( 0, $assignMsg ) if ( $e =~ $assignTest ); - 1; - }, - }, - exportedVars => { - keyTest => qr/^[a-zA-Z]\w*$/, - keyMsgFail => 'Bad variable name', - test => qr/^[a-zA-Z]\w*$/, - msgFail => 'Bad attribute name', - }, - macros => { - keyTest => qr/^[a-zA-Z]\w*$/, - keyMsgFail => 'Bad macro name', - test => $perlExpr, - warnTest => sub { - my $e = shift; - return ( 0, $assignMsg ) if ( $e =~ $assignTest ); - 1; - }, - }, - locationRules => { - keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/, - msgFail => 'Bad virtual host name', - '*' => { - keyTest => sub { - my $r = shift; - my $q; - eval { $q = qr/$r/ }; - return ( $@ ? ( 0, $@ ) : 1 ); - }, - test => sub { - my $e = shift; - return 1 if ( $e eq 'accept' or $e eq 'deny' ); - if ( $e =~ s/^logout(?:_(?:app|sso|app_sso))?\s*// ) { - return ( - $e =~ /^(?:https?:\/\/\S+)?$/ - ? 1 - : ( 0, "bad url \"$e\"" ) - ); - } - return &$perlExpr($e); - }, - warnTest => sub { - my $e = shift; - return ( 0, $assignMsg ) - if ( $e =~ $assignTest - and $e !~ /^(?:accept|deny|logout)/ ); - 1; - }, - }, - }, - exportedHeaders => { - keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/, - msgFail => 'Bad virtual host name', - '*' => { - keyTest => qr/^\w([\w\-]*\w)?$/, - keyMsgFail => 'Bad header name', - test => $perlExpr, - warnTest => sub { - my $e = shift; - return ( 0, $assignMsg ) if ( $e =~ $assignTest ); - 1; - }, - }, - }, - }; -} - -sub defaultConf { - return { - userDB => 'LDAP', - ldapServer => 'localhost', - }; -} - -sub newNode { - virtualHost => { - '*' => { - exportedHeaders => { 'Auth-User' => '$uid' }, - locationRules => { 'default' => 'deny' }, - } - }, - groups => { - 'NewGroup' => '0', - }, - macro => { - 'NewMacro' => '', - }, - globalStorageOptions => { - 'NewOption' => '', - }, -} - -1; - -package Lemonldap::NG::Manager::_i18n; - -# Developer warning : this file must be utf8 encoded - -use strict; -use AutoLoader qw(AUTOLOAD); -our $VERSION = '0.5'; - -## @fn void import(string lang) -# Import messages -sub translate { - my ( $self, $text, $lang ) = @_; - return $text unless ( $text =~ /[a-z]/ ); - $lang ||= $ENV{HTTP_ACCEPT_LANGUAGE}; - $lang = lc($lang); - $lang =~ s/-/_/g; - foreach ( split( /[,;]/, $lang ), 'en' ) { - next if /=/; - if ( __PACKAGE__->can($_) ) { - no strict 'refs'; - my $r = &$_()->{$text}; - if ($r) { - return $r; - } - else { - print STDERR __PACKAGE__ . ": $text not translated in $_\n"; - return $text; - } - } - } -} - -*fr_fr = *fr; -*en_us = *en; - -1; - -sub en { - return { - authentication => 'Authentication module', - authParams => 'Authentication parameters', - Configuration => 'Configuration', - cookieName => 'Cookie Name', - cookieParams => 'Cookies Parameters', - domain => 'Domain', - exportedVars => 'Exported Variables', - generalParameters => 'General Parameters', - globalStorage => 'Apache::Session module', - globalStorageOptions => 'Apache::Session module parameters', - groups => 'Groups', - headers => 'HTTP Headers', - ldapBase => 'LDAP Search Base', - ldapParams => 'LDAP parameters', - ldapPort => 'LDAP Server Port', - ldapServer => 'LDAP Server', - macros => 'Macros', - managerDn => 'LDAP Account', - managerPassword => 'LDAP Password', - portal => 'Portal', - rules => 'Rules', - securedCookie => 'Secured Cookie (SSL)', - sessionParams => 'Sessions Parameters', - sessionStorage => 'Sessions Storage', - timeout => 'Sessions timeout', - userDB => 'Users database type', - virtualHosts => 'Virtual Hosts', - whatToTrace => "Attribute to use in Apache's logs", - }; -} - -sub fr { - return { - authentication => "Module d'authentification", - authParams => "Paramètres d'authentification", - Configuration => 'Configuration', - cookieName => 'Nom du cookie', - cookieParams => 'Paramètres des cookies', - domain => 'Domaine', - exportedVars => 'Attributs LDAP à exporter', - generalParameters => 'Paramètres généraux', - globalStorage => 'Module Apache::Session', - globalStorageOptions => 'Paramètres du module Apache::Session', - groups => 'Groupes', - headers => 'En-têtes HTTP', - ldapBase => 'Base de recherche LDAP', - ldapParams => 'Paramètres LDAP', - ldapPort => 'Port du serveur LDAP', - ldapServer => 'Serveur LDAP', - macros => 'Macros', - managerDn => 'Compte de connexion LDAP', - managerPassword => 'Mot de passe LDAP', - portal => 'Portail', - rules => 'Règles', - securedCookie => 'Cookie sécurisé (SSL)', - sessionParams => 'Paramètres des Sessions Parameters', - sessionStorage => 'Stockage des sessions', - timeout => 'Durée de vie des sessions', - userDB => "Type de base de données d'utilisateurs", - virtualHosts => 'Hôtes virtuels', - whatToTrace => "Donnée à inscrire dans les journaux d'Apache", - }; -} -package Lemonldap::NG::Manager::Uploader; - -use strict; -use XML::LibXML; -use XML::LibXSLT; -use MIME::Base64; - -# TODO -use Data::Dumper; -#use Lemonldap::NG::Common::Safelib; #link protected safe Safe object -#use Lemonldap::NG::Manager::Downloader; -#use Lemonldap::NG::Manager::_Struct; - -our $VERSION = '0.1'; -our ( $stylesheet, $parser ); - -sub confUpload { - my ( $self, $rdata ) = @_; - $$rdata =~ s///g; - $$rdata =~ s/
  • //g; - - # Apply XSLT stylesheet to returned datas - my $result = - $self->stylesheet->transform( - $self->parser->parse_string( '' . $$rdata . '' ) ) - ->documentElement(); - - # Get configuration number - unless ( $self->{cfgNum} = - $result->getChildrenByTagName('conf')->[0]->getAttribute('value') ) - { - die "No configuration number found"; - } - my $newConf = { cfgNum => $self->{cfgNum} }; - - # Loading returned parameters - my ( %errors, %warnings ); - foreach ( @{ $result->getChildrenByTagName('element') } ) { - my ( $id, $name, $value ) = ( - $_->getAttribute('id'), - $_->getAttribute('name'), - $_->getAttribute('value') - ); - my $NK = 0; - $id =~ - s/^text_(NewID_)?li_(\w+)(\d)(?:_\d+)?$/decode_base64($2.'='x $3)/e; - $NK = 1 if ($1); - $id =~ s/^\///; - $id =~ s/(?:\/[^\/]*)?$/\/$name/ if ($NK); - next if ( $id =~ /^(generalParameters|virtualHosts)/ ); - my ( $confKey, $test ) = $self->getConfTests($id); - my ( $res, $m ); - - if ( !defined($test) ) { - $errors{$name} = - "Key $name: Lemonldap::NG::Manager error, see Apache's logs"; - $self->lmLog( - "Unknown configuration key $id (name: $name, value: $value)", - 'error' ); - next; - } - - if ( $test->{'*'} and $id =~ /\// ) { $test = $test->{'*'} } - - # Tests (no test for hash root nodes) - unless ( $test->{keyTest} and ( $id !~ /\// or $test->{'*'} ) ) { - if ( $test->{keyTest} ) { - ( $res, $m ) = $self->applyTest( $test->{keyTest}, $name ); - unless ($res) { - $errors{$name} = "Value \"$name\" rejected: " - . ( $m || $test->{keyMsgFail} ); - next; - } - } - if ( $test->{test} ) { - ( $res, $m ) = $self->applyTest( $test->{test}, $value ); - unless ($res) { - $errors{$name} = "Value of key \"$name\" rejected: " - . ( $m || $test->{msgFail} ); - next; - } - } - if ( $test->{warnKeyTest} ) { - ( $res, $m ) = $self->applyTest( $test->{warnKeyTest}, $name ); - unless ($res) { - $warnings{$name} = "Warning for value \"$name\": " - . ( $m || $test->{keyMsgWarn} ); - } - } - if ( $test->{warnTest} ) { - ( $res, $m ) = $self->applyTest( $test->{warnTest}, $value ); - unless ($res) { - $warnings{$name} = - "Warning for the value of key \"$name\": " - . ( $m || $test->{keyMsgWarn} ); - } - } - } - $self->setKeyToH( $newConf, $confKey, - $test->{keyTest} - ? ( ( $id !~ /\// or $test->{'*'} ) ? {} : ( $name => $value ) ) - : $value ); - } - - # Loading unchanged parameters (ajax nodes not open) - foreach ( @{ $result->getChildrenByTagName('ignore') } ) { - my $node = $_->getAttribute('value'); - $node =~ s/^.*node=(.*?)(?:&.*)?\}$/$1/; - foreach my $k ( $self->findAllConfKeys( $self->corresp($node) ) ) { - my $v = $self->keyToH( $k, $self->conf ); - $v = $self->keyToH( $k, $self->defaultConf ) unless ( defined $v ); - if ( defined $v ) { - $self->setKeyToH( $newConf, $k, $v ); - } - else { - $self->lmLog( "No default value found for $k", 'warn' ); - } - } - print LOG "Ignore $node\n"; - } - - print STDERR Dumper( $newConf, \%errors, \%warnings ); - close LOG; - $self->start(); - $self->end(); -} - -sub applyTest { - my ( $self, $test, $value ) = @_; - my ( $res, $msg ); - if ( ref($test) eq 'CODE' ) { - ( $res, $msg ) = &$test($value); - } - else { - $res = ( $value =~ $test ? 1 : 0 ); - } - return ( $res, $msg ); -} - -sub getConfTests { - my ( $self, $id ) = @_; - my ( $confKey, $tmp ) = ( $id =~ /^(.*?)(?:\/(.*))?$/ ); - my $h = $self->testStruct()->{$confKey}; - if ( $h and $h->{'*'} and my ( $k, $v ) = ( $tmp =~ /^(.*?)\/(.*)$/ ) ) { - return ( "$confKey/$k", $h->{'*'} ); - } - return ( $confKey, $h ); -} - -sub findAllConfKeys { - my ( $self, $h ) = @_; - my @res = (); - foreach my $n ( @{ $h->{_nodes} } ) { - $n =~ s/^.*?:(.*?)(?:\:.*)?$/$1/; - if ( ref( $h->{$n} ) ) { - push @res, $self->findAllConfKeys( $h->{$n} ); - } - else { - my $m = $h->{$n} || $n; - push @res, ( $m =~ /^(?:.*?:)?(.*?)(?:\:.*)?$/ ? $1 : () ); - } - } - return @res; -} - -sub setKeyToH { - my $value = pop; - my ( $self, $h, $key, $k2 ) = @_; - my $tmp = $h; - $key =~ s/^\///; - while (1) { - if ( $key =~ /\// ) { - my $k = $`; - $key = $'; - $tmp = $tmp->{$k} ||= {}; - } - else { - if ($k2) { - $tmp->{$key} = {} unless ( ref( $tmp->{$key} ) ); - $tmp->{$key}->{$k2} = $value; - } - else { - $tmp->{$key} = $value; - } - last; - } - } -} - -sub parser { - my $self = shift; - return $parser if ($parser); - $parser = XML::LibXML->new(); -} - -sub stylesheet { - my $self = shift; - - return $stylesheet if ($stylesheet); - my $xslt = XML::LibXSLT->new(); - my $style_doc = $self->parser->parse_string( join( '', ) ); - close DATA; - $stylesheet = $xslt->parse_stylesheet($style_doc); -} - -1; -__DATA__ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/lemonldap-ng-manager/example/imgs/_customers.gif b/modules/lemonldap-ng-manager/example/imgs/_customers.gif deleted file mode 100644 index 69fd28447..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/_customers.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/blank.gif b/modules/lemonldap-ng-manager/example/imgs/blank.gif deleted file mode 100644 index d7ae40671..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/blank.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/book.gif b/modules/lemonldap-ng-manager/example/imgs/book.gif deleted file mode 100644 index b0ce63a9d..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/book.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/book_titel.gif b/modules/lemonldap-ng-manager/example/imgs/book_titel.gif deleted file mode 100644 index 31c916d06..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/book_titel.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/books_close.gif b/modules/lemonldap-ng-manager/example/imgs/books_close.gif deleted file mode 100644 index e4bd9d6fe..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/books_close.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/books_open.gif b/modules/lemonldap-ng-manager/example/imgs/books_open.gif deleted file mode 100644 index 020ce728c..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/books_open.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/btn_up1.gif b/modules/lemonldap-ng-manager/example/imgs/btn_up1.gif deleted file mode 100644 index dd7675fd6..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/btn_up1.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/btn_up2.gif b/modules/lemonldap-ng-manager/example/imgs/btn_up2.gif deleted file mode 100644 index a7837e0f7..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/btn_up2.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/close2.gif b/modules/lemonldap-ng-manager/example/imgs/close2.gif deleted file mode 100644 index 94c267d5b..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/close2.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/folderClosed.gif b/modules/lemonldap-ng-manager/example/imgs/folderClosed.gif deleted file mode 100644 index 1ebe3c977..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/folderClosed.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/folderOpen.gif b/modules/lemonldap-ng-manager/example/imgs/folderOpen.gif deleted file mode 100644 index c193e869f..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/folderOpen.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconCheckAll.gif b/modules/lemonldap-ng-manager/example/imgs/iconCheckAll.gif deleted file mode 100644 index d90899259..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconCheckAll.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconCheckGray.gif b/modules/lemonldap-ng-manager/example/imgs/iconCheckGray.gif deleted file mode 100644 index cb54c0a8f..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconCheckGray.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconClient.gif b/modules/lemonldap-ng-manager/example/imgs/iconClient.gif deleted file mode 100644 index 95b3b7591..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconClient.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconDeleteSelected.gif b/modules/lemonldap-ng-manager/example/imgs/iconDeleteSelected.gif deleted file mode 100644 index 1fd762b44..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconDeleteSelected.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconJob.gif b/modules/lemonldap-ng-manager/example/imgs/iconJob.gif deleted file mode 100644 index c073898e9..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconJob.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconReport.gif b/modules/lemonldap-ng-manager/example/imgs/iconReport.gif deleted file mode 100644 index bdcc6a54d..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconReport.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconTask.gif b/modules/lemonldap-ng-manager/example/imgs/iconTask.gif deleted file mode 100644 index a43d60d2b..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconTask.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconTimeRecordsEdit.gif b/modules/lemonldap-ng-manager/example/imgs/iconTimeRecordsEdit.gif deleted file mode 100644 index 1ca8341d2..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconTimeRecordsEdit.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/iconUncheckAll.gif b/modules/lemonldap-ng-manager/example/imgs/iconUncheckAll.gif deleted file mode 100644 index 5e54ec599..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/iconUncheckAll.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/item.gif b/modules/lemonldap-ng-manager/example/imgs/item.gif deleted file mode 100644 index 56c0221a0..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/item.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/item2.gif b/modules/lemonldap-ng-manager/example/imgs/item2.gif deleted file mode 100644 index 47274d09f..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/item2.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/leaf.gif b/modules/lemonldap-ng-manager/example/imgs/leaf.gif deleted file mode 100644 index 1cf40f1e0..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/leaf.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/line1.gif b/modules/lemonldap-ng-manager/example/imgs/line1.gif deleted file mode 100644 index 60f2ccb26..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/line1.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/line2.gif b/modules/lemonldap-ng-manager/example/imgs/line2.gif deleted file mode 100644 index f2d7bdd50..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/line2.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/line3.gif b/modules/lemonldap-ng-manager/example/imgs/line3.gif deleted file mode 100644 index d718be218..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/line3.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/line4.gif b/modules/lemonldap-ng-manager/example/imgs/line4.gif deleted file mode 100644 index 29285e598..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/line4.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/magazines_close.gif b/modules/lemonldap-ng-manager/example/imgs/magazines_close.gif deleted file mode 100644 index 513c01a00..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/magazines_close.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/magazines_open.gif b/modules/lemonldap-ng-manager/example/imgs/magazines_open.gif deleted file mode 100644 index fcda411c7..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/magazines_open.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/minus.gif b/modules/lemonldap-ng-manager/example/imgs/minus.gif deleted file mode 100644 index ef04a5469..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/minus.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/minus2.gif b/modules/lemonldap-ng-manager/example/imgs/minus2.gif deleted file mode 100644 index 0372294cb..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/minus2.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/minus3.gif b/modules/lemonldap-ng-manager/example/imgs/minus3.gif deleted file mode 100644 index d928af639..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/minus3.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/minus4.gif b/modules/lemonldap-ng-manager/example/imgs/minus4.gif deleted file mode 100644 index 30bc7deec..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/minus4.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/minus5.gif b/modules/lemonldap-ng-manager/example/imgs/minus5.gif deleted file mode 100644 index e2e30fcb2..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/minus5.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/minus_ar.gif b/modules/lemonldap-ng-manager/example/imgs/minus_ar.gif deleted file mode 100644 index 4428ba150..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/minus_ar.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/open2.gif b/modules/lemonldap-ng-manager/example/imgs/open2.gif deleted file mode 100644 index 7d8f2f8ba..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/open2.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/plus.gif b/modules/lemonldap-ng-manager/example/imgs/plus.gif deleted file mode 100644 index abb84bdfb..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/plus.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/plus2.gif b/modules/lemonldap-ng-manager/example/imgs/plus2.gif deleted file mode 100644 index ea2816efc..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/plus2.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/plus3.gif b/modules/lemonldap-ng-manager/example/imgs/plus3.gif deleted file mode 100644 index cd6967e52..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/plus3.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/plus4.gif b/modules/lemonldap-ng-manager/example/imgs/plus4.gif deleted file mode 100644 index 185bd9b70..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/plus4.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/plus5.gif b/modules/lemonldap-ng-manager/example/imgs/plus5.gif deleted file mode 100644 index 72fe4e577..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/plus5.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/plus_ar.gif b/modules/lemonldap-ng-manager/example/imgs/plus_ar.gif deleted file mode 100644 index d2fcaf012..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/plus_ar.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/tombs.gif b/modules/lemonldap-ng-manager/example/imgs/tombs.gif deleted file mode 100644 index 25131eeeb..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/tombs.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/imgs/tombs_mag.gif b/modules/lemonldap-ng-manager/example/imgs/tombs_mag.gif deleted file mode 100644 index b58e29a1e..000000000 Binary files a/modules/lemonldap-ng-manager/example/imgs/tombs_mag.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/example/index.pl b/modules/lemonldap-ng-manager/example/index.pl index 36b1675e7..8c692a949 100755 --- a/modules/lemonldap-ng-manager/example/index.pl +++ b/modules/lemonldap-ng-manager/example/index.pl @@ -1,42 +1,30 @@ #!/usr/bin/perl +use strict; use Lemonldap::NG::Manager; +use HTML::Template; +our $skin_dir='skins'; +our $main_dir='/var/lib/lemonldap-ng/manager'; +our $skin='default'; -my $h = new Lemonldap::NG::Manager( +my $manager = new Lemonldap::NG::Manager( { # REQUIRED PARAMETERS - dhtmlXTreeImageLocation => "/imgs/", - cssFile => 'theme/default.css', - textareaW => 50, - textareaH => 2, - inputSize => 30, - - # OPTIONAL PARAMETERS - - ## PROTECTION, choose one of : - # * protection by manager - # protection => 'manager', - # * specify yourself the rule to apply (same as in the manager) - # protection => 'rule: $uid=admin', - # * all authenticate users are granted - # protection => 'authenticate', - # * nothing : not protected - - #jsFile => /path/to/lemonldap-ng-manager.js, + applyConfFile => '/etc/lemonldap-ng//apply.conf', # ACCESS TO CONFIGURATION - # By default, Lemonldap::NG uses the default lemonldap-ng.ini file to know + # By default, Lemonldap::NG uses the default storage.conf file to know # where to find is configuration - # (generaly /etc/lemonldap-ng/lemonldap-ng.ini) + # (generaly /etc/lemonldap-ng/storage.conf) # You can specify by yourself this file : - #configStorage => { confFile => '/path/to/my/file' }, + #configStorage => { type => 'File', dirName => '/path/to/my/file' }, # You can also specify directly the configuration # (see Lemonldap::NG::Handler::SharedConf(3)) #configStorage => { # type => 'File', - # dirName => '/usr/local/lemonldap-ng/data/conf/' + # directory => '/usr/local/lemonlda-ng/conf/' #}, # CUSTOM FUNCTION @@ -44,6 +32,16 @@ my $h = new Lemonldap::NG::Manager( #customFunctions => 'function1 function2', #customFunctions => 'Package::func1 Package::func2', } -) or die "Unable to start"; +) or Lemonldap::NG::Common::CGI->abort('Unable to start manager'); + +my $template = HTML::Template->new( + filename => "$main_dir/$skin_dir/$skin/manager.tpl", + die_on_bad_params => 0, + cache => 0, + filter => sub { $manager->translate_template(@_) }, +); +$template->param(MENU => $manager->menu()); +$template->param(DIR => "$skin_dir/$skin"); +print $manager->header('text/html; charset=utf-8'); +print $template->output; -$h->doall(); diff --git a/modules/lemonldap-ng-manager/example/lemonldap-ng-manager.js b/modules/lemonldap-ng-manager/example/lemonldap-ng-manager.js deleted file mode 100644 index 97ee2dfe6..000000000 --- a/modules/lemonldap-ng-manager/example/lemonldap-ng-manager.js +++ /dev/null @@ -1,25 +0,0 @@ -/* Compiled from dhtmlXTree and X 4.06 with XC 1.01 for Lemonldap::NG::Manager. Copyrights follow below */ /* Copyright 2001-2006 Michael Foster Compiled from X 4.06 with XC 1.01 on 03Nov06 */ -var X={};X.addEventListener=function(e,eT,eL,cap){if(!(e=X.getElementById(e)))return;eT=eT.toLowerCase();if(e==window&&!e.opera&&!document.all){if(eT=='resize'){e.xPCW=X.clientWidth();e.xPCH=X.clientHeight();e.xREL=eL;xResizeEvent();return;}if(eT=='scroll'){e.xPSL=X.scrollLeft();e.xPST=X.scrollTop();e.xSEL=eL;xScrollEvent();return;}}if(e.addEventListener)e.addEventListener(eT,eL,cap);else if(e.attachEvent)e.attachEvent('on'+eT,eL);else e['on'+eT]=eL;};function xResizeEvent(){if(window.xREL)setTimeout('xResizeEvent()',250);var w=window,cw=X.clientWidth(),ch=X.clientHeight();if(w.xPCW!=cw||w.xPCH!=ch){w.xPCW=cw;w.xPCH=ch;if(w.xREL)w.xREL();}}function xScrollEvent(){if(window.xSEL)setTimeout('xScrollEvent()',250);var w=window,sl=X.scrollLeft(),st=X.scrollTop();if(w.xPSL!=sl||w.xPST!=st){w.xPSL=sl;w.xPST=st;if(w.xSEL)w.xSEL();}}X.clientHeight=function(){var v=0,d=document,w=window;if(d.compatMode=='CSS1Compat'&&!w.opera&&d.documentElement&&d.documentElement.clientHeight){v=d.documentElement.clientHeight;}else if(d.body&&d.body.clientHeight){v=d.body.clientHeight;}else if(X.def(w.innerWidth,w.innerHeight,d.width)){v=w.innerHeight;if(d.width>w.innerWidth)v-=16;}return v;};X.clientWidth=function(){var v=0,d=document,w=window;if(d.compatMode=='CSS1Compat'&&!w.opera&&d.documentElement&&d.documentElement.clientWidth){v=d.documentElement.clientWidth;}else if(d.body&&d.body.clientWidth){v=d.body.clientWidth;}else if(X.def(w.innerWidth,w.innerHeight,d.height)){v=w.innerWidth;if(d.height>w.innerHeight)v-=16;}return v;};X.def=function(){for(var i=0;i=0){var pt=0,pb=0,bt=0,bb=0;if(document.compatMode=='CSS1Compat'){var gcs=X.getComputedStyle;pt=gcs(e,'padding-top',1);if(pt!==null){pb=gcs(e,'padding-bottom',1);bt=gcs(e,'border-top-width',1);bb=gcs(e,'border-bottom-width',1);}else if(X.def(e.offsetHeight,e.style.height)){e.style.height=h+'px';pt=e.offsetHeight-h;}}h-=(pt+pb+bt+bb);if(isNaN(h)||h<0)return;else e.style.height=h+'px';}h=e.offsetHeight;}else if(css&&X.def(e.style.pixelHeight)){if(h>=0)e.style.pixelHeight=h;h=e.style.pixelHeight;}return h;};X.left=function(e,iX){if(!(e=X.getElementById(e)))return 0;var css=X.def(e.style);if(css&&X.str(e.style.left)){if(X.num(iX))e.style.left=iX+'px';else{iX=parseInt(e.style.left);if(isNaN(iX))iX=X.getComputedStyle(e,'left',1);if(isNaN(iX))iX=0;}}else if(css&&X.def(e.style.pixelLeft)){if(X.num(iX))e.style.pixelLeft=iX;else iX=e.style.pixelLeft;}return iX;};xLibrary={version:'4.06',license:'GNU LGPL',url:'http://cross-browser.com/'};X.moveTo=function(e,x,y){X.left(e,x);X.top(e,y);};X.nextSib=function(e,t){if(!(e=X.getElementById(e)))return;var s=e?e.nextSibling:null;if(t)while(s&&s.nodeName.toLowerCase()!=t.toLowerCase()){s=s.nextSibling;}else while(s&&s.nodeType!=1){s=s.nextSibling;}return s;};X.num=function(){for(var i=0;isplW-uBarLimit){return;}X.width(pane1,X.width(pane1)+dx);X.left(barEle,X.left(barEle)+dx);X.width(pane2,X.width(pane2)-dx);X.left(pane2,X.left(pane2)+dx);barPos=bp;}else{bp=barPos+dy;if(bpsplH-uBarLimit){return;}X.height(pane1,X.height(pane1)+dy);X.top(barEle,X.top(barEle)+dy);X.height(pane2,X.height(pane2)-dy);X.top(pane2,X.top(pane2)+dy);barPos=bp;}if(oSplChild1){oSplChild1.paint(X.width(pane1),X.height(pane1));}if(oSplChild2){oSplChild2.paint(X.width(pane2),X.height(pane2));}}this.paint=function(uNewW,uNewH,uNewBarPos,uNewBarLim){if(uNewW==0){return;}var w1,h1,w2,h2;splW=uNewW;splH=uNewH;barPos=uNewBarPos||barPos;barLim=uNewBarLim||barLim;X.moveTo(splEle,uSplX,uSplY);X.resizeTo(splEle,uNewW,uNewH);if(bHorizontal){w1=barPos;h1=uNewH-2*uSplBorderW;w2=uNewW-w1-uBarW-2*uSplBorderW;h2=h1;X.moveTo(pane1,0,0);X.resizeTo(pane1,w1,h1);X.moveTo(barEle,w1,0);X.resizeTo(barEle,uBarW,h1);X.moveTo(pane2,w1+uBarW,0);X.resizeTo(pane2,w2,h2);}else{w1=uNewW-2*uSplBorderW;;h1=barPos;w2=w1;h2=uNewH-h1-uBarW-2*uSplBorderW;X.moveTo(pane1,0,0);X.resizeTo(pane1,w1,h1);X.moveTo(barEle,0,h1);X.resizeTo(barEle,w1,uBarW);X.moveTo(pane2,0,h1+uBarW);X.resizeTo(pane2,w2,h2);}if(oSplChild1){pane1.style.overflow='hidden';oSplChild1.paint(w1,h1);}if(oSplChild2){pane2.style.overflow='hidden';oSplChild2.paint(w2,h2);}};splEle=X.getElementById(sSplId);pane1=X.firstChild(splEle,'DIV');pane2=X.nextSib(pane1,'DIV');barEle=X.nextSib(pane2,'DIV');pane1.style.zIndex=2;pane2.style.zIndex=2;barEle.style.zIndex=1;barPos=uBarPos;barLim=uBarLimit;this.paint(uSplW,uSplH);if(bBarEnabled){X.enableDrag(barEle,null,barOnDrag,null);barEle.style.cursor=bHorizontal?'e-resize':'n-resize';}splEle.style.visibility='visible';}X.str=function(s){for(var i=0;i=0){var pl=0,pr=0,bl=0,br=0;if(document.compatMode=='CSS1Compat'){var gcs=X.getComputedStyle;pl=gcs(e,'padding-left',1);if(pl!==null){pr=gcs(e,'padding-right',1);bl=gcs(e,'border-left-width',1);br=gcs(e,'border-right-width',1);}else if(X.def(e.offsetWidth,e.style.width)){e.style.width=w+'px';pl=e.offsetWidth-w;}}w-=(pl+pr+bl+br);if(isNaN(w)||w<0)return;else e.style.width=w+'px';}w=e.offsetWidth;}else if(css&&X.def(e.style.pixelWidth)){if(w>=0)e.style.pixelWidth=w;w=e.style.pixelWidth;}return w;}; -/* Copyright DHTMLX LTD. http://www.dhtmlx.com -You allowed to use this component or parts of it under GPL terms To use it on other terms or get Professional edition of the component please contact us at sales@dhtmlx.com */ -function dtmlXMLLoaderObject(funcObject,dhtmlObject,async,rSeed){this.xmlDoc="";if(typeof(async)!="undefined")this.async=async;else this.async=true;this.onloadAction=funcObject||null;this.mainObject=dhtmlObject||null;this.waitCall=null;this.rSeed=rSeed||false;return this;};dtmlXMLLoaderObject.prototype.waitLoadFunction=function(dhtmlObject){var once=true;this.check=function(){if((dhtmlObject)&&(dhtmlObject.onloadAction!=null)){if((!dhtmlObject.xmlDoc.readyState)||(dhtmlObject.xmlDoc.readyState==4)){if(!once)return;once=false;dhtmlObject.onloadAction(dhtmlObject.mainObject,null,null,null,dhtmlObject);if(dhtmlObject.waitCall){dhtmlObject.waitCall();dhtmlObject.waitCall=null;}}}};return this.check;};dtmlXMLLoaderObject.prototype.getXMLTopNode=function(tagName,oldObj){if(this.xmlDoc.responseXML){var temp=this.xmlDoc.responseXML.getElementsByTagName(tagName);var z=temp[0];}else var z=this.xmlDoc.documentElement;if(z){this._retry=false;return z;}if((_isIE)&&(!this._retry)){var xmlString=this.xmlDoc.responseText;var oldObj=this.xmlDoc;this._retry=true;this.xmlDoc=new ActiveXObject("Microsoft.XMLDOM");this.xmlDoc.async=false;this.xmlDoc["loadXML"](xmlString);return this.getXMLTopNode(tagName,oldObj);}dhtmlxError.throwError("LoadXML","Incorrect XML",[(oldObj||this.xmlDoc),this.mainObject]);return document.createElement("DIV");};dtmlXMLLoaderObject.prototype.loadXMLString=function(xmlString){if(_isKHTML){var z=document.createElement('div');z.innerHTML=xmlString;this.xmlDoc=z;z.responseXML=z;}else{try{var parser=new DOMParser();this.xmlDoc=parser.parseFromString(xmlString,"text/xml");}catch(e){this.xmlDoc=new ActiveXObject("Microsoft.XMLDOM");this.xmlDoc.async=this.async;this.xmlDoc["loadXML"](xmlString);}}this.onloadAction(this.mainObject,null,null,null,this);if(this.waitCall){this.waitCall();this.waitCall=null;}};dtmlXMLLoaderObject.prototype.loadXML=function(filePath,postMode,postVars,rpc){if(this.rSeed)filePath+=((filePath.indexOf("?")!=-1)?"&":"?")+"a_dhx_rSeed="+(new Date()).valueOf();this.filePath=filePath;if((!_isIE)&&(window.XMLHttpRequest))this.xmlDoc=new XMLHttpRequest();else{if(document.implementation&&document.implementation.createDocument){this.xmlDoc=document.implementation.createDocument("","",null);this.xmlDoc.onload=new this.waitLoadFunction(this);this.xmlDoc.load(filePath);return;}else this.xmlDoc=new ActiveXObject("Microsoft.XMLHTTP");}this.xmlDoc.open(postMode?"POST":"GET",filePath,this.async);if(rpc){this.xmlDoc.setRequestHeader("User-Agent","dhtmlxRPC v0.1 ("+navigator.userAgent+")");this.xmlDoc.setRequestHeader("Content-type","text/xml");}else if(postMode)this.xmlDoc.setRequestHeader('Content-type','application/x-www-form-urlencoded');this.xmlDoc.onreadystatechange=new this.waitLoadFunction(this);this.xmlDoc.send(null||postVars);};dtmlXMLLoaderObject.prototype.destructor=function(){this.onloadAction=null;this.mainObject=null;this.xmlDoc=null;return null;};function callerFunction(funcObject,dhtmlObject){this.handler=function(e){if(!e)e=window.event;funcObject(e,dhtmlObject);return true;};return this.handler;};function getAbsoluteLeft(htmlObject){var xPos=htmlObject.offsetLeft;var temp=htmlObject.offsetParent;while(temp!=null){xPos+=temp.offsetLeft;temp=temp.offsetParent;}return xPos;}function getAbsoluteTop(htmlObject){var yPos=htmlObject.offsetTop;var temp=htmlObject.offsetParent;while(temp!=null){yPos+=temp.offsetTop;temp=temp.offsetParent;}return yPos;} -function convertStringToBoolean(inputString){if(typeof(inputString)=="string")inputString=inputString.toLowerCase();switch(inputString){case "1":case "true":case "yes":case "y":case 1:case true:return true;break;default:return false;}}function getUrlSymbol(str){if(str.indexOf("?")!=-1)return "&";else return "?";}function dhtmlDragAndDropObject(){if(window.dhtmlDragAndDrop)return window.dhtmlDragAndDrop;this.lastLanding=0;this.dragNode=0;this.dragStartNode=0;this.dragStartObject=0;this.tempDOMU=null;this.tempDOMM=null;this.waitDrag=0;window.dhtmlDragAndDrop=this;return this;};dhtmlDragAndDropObject.prototype.removeDraggableItem=function(htmlNode){htmlNode.onmousedown=null;htmlNode.dragStarter=null;htmlNode.dragLanding=null;};dhtmlDragAndDropObject.prototype.addDraggableItem=function(htmlNode,dhtmlObject){htmlNode.onmousedown=this.preCreateDragCopy;htmlNode.dragStarter=dhtmlObject;this.addDragLanding(htmlNode,dhtmlObject);};dhtmlDragAndDropObject.prototype.addDragLanding=function(htmlNode,dhtmlObject){htmlNode.dragLanding=dhtmlObject;};dhtmlDragAndDropObject.prototype.preCreateDragCopy=function(e){if(window.dhtmlDragAndDrop.waitDrag){window.dhtmlDragAndDrop.waitDrag=0;document.body.onmouseup=window.dhtmlDragAndDrop.tempDOMU;document.body.onmousemove=window.dhtmlDragAndDrop.tempDOMM;return false;}window.dhtmlDragAndDrop.waitDrag=1;window.dhtmlDragAndDrop.tempDOMU=document.body.onmouseup;window.dhtmlDragAndDrop.tempDOMM=document.body.onmousemove;window.dhtmlDragAndDrop.dragStartNode=this;window.dhtmlDragAndDrop.dragStartObject=this.dragStarter;document.body.onmouseup=window.dhtmlDragAndDrop.preCreateDragCopy;document.body.onmousemove=window.dhtmlDragAndDrop.callDrag;if((e)&&(e.preventDefault)){e.preventDefault();return false;}return false;};dhtmlDragAndDropObject.prototype.callDrag=function(e){if(!e)e=window.event;dragger=window.dhtmlDragAndDrop;if((e.button==0)&&(_isIE))return dragger.stopDrag();if(!dragger.dragNode){dragger.dragNode=dragger.dragStartObject._createDragNode(dragger.dragStartNode,e);if(!dragger.dragNode)return dragger.stopDrag();dragger.gldragNode=dragger.dragNode;document.body.appendChild(dragger.dragNode);document.body.onmouseup=dragger.stopDrag;dragger.waitDrag=0;dragger.dragNode.pWindow=window;dragger.initFrameRoute();}if(dragger.dragNode.parentNode!=window.document.body){var grd=dragger.gldragNode;if(dragger.gldragNode.old)grd=dragger.gldragNode.old;grd.parentNode.removeChild(grd);var oldBody=dragger.dragNode.pWindow;if(_isIE){var div=document.createElement("Div");div.innerHTML=dragger.dragNode.outerHTML;dragger.dragNode=div.childNodes[0];}else dragger.dragNode=dragger.dragNode.cloneNode(true);dragger.dragNode.pWindow=window;dragger.gldragNode.old=dragger.dragNode;document.body.appendChild(dragger.dragNode);oldBody.dhtmlDragAndDrop.dragNode=dragger.dragNode;}dragger.dragNode.style.left=e.clientX+15+(dragger.fx?dragger.fx*(-1):0)+(document.body.scrollLeft||document.documentElement.scrollLeft)+"px";dragger.dragNode.style.top=e.clientY+3+(dragger.fy?dragger.fy*(-1):0)+(document.body.scrollTop||document.documentElement.scrollTop)+"px";if(!e.srcElement)var z=e.target;else z=e.srcElement;dragger.checkLanding(z,e);};dhtmlDragAndDropObject.prototype.calculateFramePosition=function(n){if(window.name){var el=parent.frames[window.name].frameElement.offsetParent;var fx=0;var fy=0;while(el){fx+=el.offsetLeft;fy+=el.offsetTop;el=el.offsetParent;}if((parent.dhtmlDragAndDrop)){var ls=parent.dhtmlDragAndDrop.calculateFramePosition(1);fx+=ls.split('_')[0]*1;fy+=ls.split('_')[1]*1;}if(n)return fx+"_"+fy;else this.fx=fx;this.fy=fy;}return "0_0";};dhtmlDragAndDropObject.prototype.checkLanding=function(htmlObject,e){if((htmlObject)&&(htmlObject.dragLanding)){if(this.lastLanding)this.lastLanding.dragLanding._dragOut(this.lastLanding);this.lastLanding=htmlObject;this.lastLanding=this.lastLanding.dragLanding._dragIn(this.lastLanding,this.dragStartNode,e.clientX,e.clientY,e);this.lastLanding_scr=(_isIE?e.srcElement:e.target);}else{if((htmlObject)&&(htmlObject.tagName!="BODY"))this.checkLanding(htmlObject.parentNode,e);else{if(this.lastLanding)this.lastLanding.dragLanding._dragOut(this.lastLanding,e.clientX,e.clientY,e);this.lastLanding=0;if(this._onNotFound)this._onNotFound();}}};dhtmlDragAndDropObject.prototype.stopDrag=function(e,mode){dragger=window.dhtmlDragAndDrop;if(!mode){dragger.stopFrameRoute();var temp=dragger.lastLanding;dragger.lastLanding=null;if(temp)temp.dragLanding._drag(dragger.dragStartNode,dragger.dragStartObject,temp,(_isIE?event.srcElement:e.target));}dragger.lastLanding=null;if((dragger.dragNode)&&(dragger.dragNode.parentNode==document.body))dragger.dragNode.parentNode.removeChild(dragger.dragNode);dragger.dragNode=0;dragger.gldragNode=0;dragger.fx=0;dragger.fy=0;dragger.dragStartNode=0;dragger.dragStartObject=0;document.body.onmouseup=dragger.tempDOMU;document.body.onmousemove=dragger.tempDOMM;dragger.tempDOMU=null;dragger.tempDOMM=null;dragger.waitDrag=0;};dhtmlDragAndDropObject.prototype.stopFrameRoute=function(win){if(win)window.dhtmlDragAndDrop.stopDrag(1,1);for(var i=0;i0){beforeNode=new Object;beforeNode.tr=parentObject.childNodes[0].tr.previousSibling;}parentObject._has_top=true;for(ik=Count;ik>0;ik--)Nodes[ik]=Nodes[ik-1];Count=0;break;}};};var n;if(!(n=this._idpull[itemId])||n.span!=-1){n=Nodes[Count]=new dhtmlXTreeItemObject(itemId,itemText,parentObject,this,null,1);itemId=Nodes[Count].id;parentObject.childsCount++;}if(!n.htmlNode){n.label=itemText;n.htmlNode=this._createItem((this.checkBoxOff?1:0),n);n.htmlNode.objBelong=n;}if(image1)n.images[0]=image1;if(image2)n.images[1]=image2;if(image3)n.images[2]=image3;var tr=this._drawNewTr(n.htmlNode);if((this.XMLloadingWarning)||(this._hAdI))n.htmlNode.parentNode.parentNode.style.display="none";if((beforeNode)&&(beforeNode.tr.nextSibling))parentObject.htmlNode.childNodes[0].insertBefore(tr,beforeNode.tr.nextSibling);else if(this.parsingOn==parentObject.id){this.parsedArray[this.parsedArray.length]=tr;}else parentObject.htmlNode.childNodes[0].appendChild(tr);if((beforeNode)&&(!beforeNode.span))beforeNode=null;if(this.XMLsource)if((childs)&&(childs!=0))n.XMLload=0;else n.XMLload=1;n.tr=tr;tr.nodem=n;if(parentObject.itemId==0)tr.childNodes[0].className="hiddenRow";if((parentObject._r_logic)||(this._frbtr))this._setSrc(n.htmlNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0],this.imPath+this.radioArray[0]);if(optionStr){var tempStr=optionStr.split(",");for(var i=0;i=2){this._correctPlus(Nodes[parentObject.childsCount-2]);this._correctLine(Nodes[parentObject.childsCount-2]);}if(parentObject.childsCount!=2)this._correctPlus(Nodes[0]);if(this.tscheck)this._correctCheckStates(parentObject);if(this._onradh){if(this.xmlstate==1){var old=this.onXLE;this.onXLE=function(id){this._onradh(itemId);if(old)old(id);};}else this._onradh(itemId);}}return n;};dhtmlXTreeObject.prototype.insertNewItem=function(parentId,itemId,itemText,itemActionHandler,image1,image2,image3,optionStr,children){var parentObject=this._globalIdStorageFind(parentId);if(!parentObject)return(-1);var nodez=this._attachChildNode(parentObject,itemId,itemText,itemActionHandler,image1,image2,image3,optionStr,children);return nodez;};dhtmlXTreeObject.prototype.insertNewChild=function(parentId,itemId,itemText,itemActionHandler,image1,image2,image3,optionStr,children){return this.insertNewItem(parentId,itemId,itemText,itemActionHandler,image1,image2,image3,optionStr,children);};dhtmlXTreeObject.prototype._parseXMLTree=function(a,b,c,d,xml){var p=new xmlPointer(xml.getXMLTopNode("tree"));a._parse(p);a._p=p;};dhtmlXTreeObject.prototype._parseItem=function(c,temp,preNode,befNode){var id;if(this._srnd&&(!this._idpull[id=c.get("id")]||!this._idpull[id].span)){this._addItemSRND(temp.id,id,c);return;}var a=c.get_all();if((typeof(this.waitUpdateXML)=="object")&&(!this.waitUpdateXML[a.id])){this._parse(c,a.id,1);return;}var zST=[];if(a.select)zST.push("SELECT");if(a.top)zST.push("TOP");if(a.call)nodeAskingCall=a.id;if(a.checked==-1)zST.push("HCHECKED");else if(a.checked)zST.push("CHECKED");if(a.open)zST.push("OPEN");if(this.waitUpdateXML){if(this._globalIdStorageFind(a.id))var newNode=this.updateItem(a.id,a.text,a.im0,a.im1,a.im2,a.checked);else{if(this.npl==0)zST.push("TOP");else preNode=temp.childNodes[this.npl];var newNode=this._attachChildNode(temp,a.id,a.text,0,a.im0,a.im1,a.im2,zST.join(","),a.child,0,preNode);preNode=null;}}else var newNode=this._attachChildNode(temp,a.id,a.text,0,a.im0,a.im1,a.im2,zST.join(","),a.child,(befNode||0),preNode);if(a.tooltip)newNode.span.parentNode.parentNode.title=a.tooltip;if(a.style)if(newNode.span.style.cssText)newNode.span.style.cssText+=(";"+a.style);else newNode.span.setAttribute("style",newNode.span.getAttribute("style")+"; "+a.style);if(a.radio)newNode._r_logic=true;if(a.nocheckbox){newNode.span.parentNode.previousSibling.previousSibling.childNodes[0].style.display='none';newNode.nocheckbox=true;}if(a.disabled){if(a.checked!=null)this._setCheck(newNode,convertStringToBoolean(a.checked));this.disableCheckbox(newNode,1);}newNode._acc=a.child||0;if(this.parserExtension)this.parserExtension._parseExtension(node.childNodes[i],this.parserExtension,a.id,parentId);this.setItemColor(newNode,a.aCol,a.sCol);if(a.locked=="1")this._lockItem(newNode,true,true);if((a.imwidth)||(a.imheight))this.setIconSize(a.imwidth,a.imheight,newNode);if((a.closeable=="0")||(a.closeable=="1"))this.setItemCloseable(newNode,a.closeable);var zcall="";if(a.topoffset)this.setItemTopOffset(newNode,a.topoffset);if((!this.slowParse)||(typeof(this.waitUpdateXML)=="object")){if(c.sub_exists("item"))zcall=this._parse(c,a.id,1);}if(zcall!="")this.nodeAskingCall=zcall; -c.each("userdata",function(u){this.setUserData(c.get("id"),u.get("name"),u.content());},this);};dhtmlXTreeObject.prototype._parse=function(p,parentId,level,start){if(this._srnd&&!this.parentObject.offsetHeight){var self=this;return window.setTimeout(function(){self._parse(p,parentId,level,start);},100);}if(!p.exists())return;this.skipLock=true;this.parsCount=this.parsCount?(this.parsCount+1):1;this.XMLloadingWarning=1;this.nodeAskingCall="";if(!parentId){parentId=p.get("id");if(p.get("radio"))this.htmlNode._r_logic=true;this.parsingOn=parentId;this.parsedArray=new Array();this.setCheckList="";}var temp=this._globalIdStorageFind(parentId);if(!temp)return dhtmlxError.throwError("DataStructure","XML reffers to not existing parent");if((temp.childsCount)&&(!start)&&(!this._edsbps)&&(!temp._has_top))var preNode=temp.childNodes[temp.childsCount-1];else var preNode=0;this.npl=0;p.each("item",function(c,i){temp.XMLload=1;if((this._epgps)&&(this._epgpsC==this.npl)){this._setNextPageSign(temp,this.npl+1*(start||0),level,node);return-1;}this._parseItem(c,temp,preNode);this.npl++;},this,start);if(!level){p.each("userdata",function(u){this.setUserData(p.get("id"),u.get("name"),u.content());},this);temp.XMLload=1;if(this.waitUpdateXML){this.waitUpdateXML=false;for(var i=temp.childsCount-1;i>=0;i--)if(temp.childNodes[i]._dmark)this.deleteItem(temp.childNodes[i].id);}var parsedNodeTop=this._globalIdStorageFind(this.parsingOn);for(var i=0;i1){if(((Nodes[1].style.display!="none")||(mode==1))&&(mode!=2)){this.allTree.childNodes[0].border="1";this.allTree.childNodes[0].border="0";nodestyle="none";}else nodestyle="";for(var i=1;i=2){this._correctPlus(Nodes[targetObject.childsCount-2]);this._correctLine(Nodes[targetObject.childsCount-2]);}this._correctPlus(Nodes[targetObject.childsCount-1]);if(this.tscheck)this._correctCheckStates(targetObject);if(oldTree.tscheck)oldTree._correctCheckStates(z);}if(c>1){oldTree._correctPlus(z.childNodes[c-2]);oldTree._correctLine(z.childNodes[c-2]);}oldTree._correctPlus(z);oldTree._correctLine(z);this.callEvent("onDrop",[itemObject.id,targetObject.id,(beforeNode?beforeNode.id:null),oldTree,targetObject.treeNod]);return itemObject.id;};dhtmlXTreeObject.prototype._clearStyles=function(itemObject){var td1=itemObject.htmlNode.childNodes[0].childNodes[0].childNodes[1];var td3=td1.nextSibling.nextSibling;itemObject.span.innerHTML=itemObject.label;itemObject.i_sel=false;if(itemObject._aimgs)this.dragger.removeDraggableItem(td1.nextSibling);if(this.checkBoxOff){td1.childNodes[0].style.display="";td1.childNodes[0].onclick=this.onCheckBoxClick;this._setSrc(td1.childNodes[0],this.imPath+this.checkArray[itemObject.checkstate]);}else td1.childNodes[0].style.display="none";td1.childNodes[0].treeNod=this;this.dragger.removeDraggableItem(td3);if(this.dragAndDropOff)this.dragger.addDraggableItem(td3,this);if(this._aimgs)this.dragger.addDraggableItem(td1.nextSibling,this);td3.childNodes[0].className="standartTreeRow";td3.onclick=this.onRowSelect;td3.ondblclick=this.onRowClick2;td1.previousSibling.onclick=this.onRowClick;this._correctLine(itemObject);this._correctPlus(itemObject);for(var i=0;i0)){if(node.childNodes[i].unParsed)var zb=this._getAllScraggyItemsXML(node.childNodes[i].unParsed,1);else var zb=this._getAllScraggyItems(node.childNodes[i]);if(zb)if(z)z+=this.dlmtr+zb;else z=zb;}else if(!z)z=node.childNodes[i].id;else z+=this.dlmtr+node.childNodes[i].id;}return z;};dhtmlXTreeObject.prototype._getAllFatItems=function(node){var z="";for(var i=0;i0)){if(!z)z=node.childNodes[i].id;else z+=this.dlmtr+node.childNodes[i].id;if(node.childNodes[i].unParsed)var zb=this._getAllFatItemsXML(node.childNodes[i].unParsed,1);else var zb=this._getAllFatItems(node.childNodes[i]);if(zb)z+=this.dlmtr+zb;}}return z;};dhtmlXTreeObject.prototype._getAllSubItems=function(itemId,z,node){if(node)temp=node;else{var temp=this._globalIdStorageFind(itemId);};if(!temp)return 0;z="";for(var i=0;iz.childsCount))return null;return z.childNodes[index].id;};dhtmlXTreeObject.prototype.getChildItemIdByIndex=function(itemId,index){var z=this._globalIdStorageFind(itemId);if((!z)||(index>=z.childsCount))return null;return z.childNodes[index].id;}; -dhtmlXTreeObject.prototype.setDragHandler=function(func){this.attachEvent("onDrag",func);};dhtmlXTreeObject.prototype._clearMove=function(){if(this._lastMark){this._lastMark.className=this._lastMark.className.replace(/dragAndDropRow/g,"");this._lastMark=null;}this.allTree.className=this.allTree.className.replace(" selectionBox","");};dhtmlXTreeObject.prototype.enableDragAndDrop=function(mode,rmode){if(mode=="temporary_disabled"){this.dADTempOff=false;mode=true;}else this.dADTempOff=true;this.dragAndDropOff=convertStringToBoolean(mode);if(this.dragAndDropOff)this.dragger.addDragLanding(this.allTree,this);if(arguments.length>1)this._ddronr=(!convertStringToBoolean(rmode));};dhtmlXTreeObject.prototype._setMove=function(htmlNode,x,y){if(htmlNode.parentObject.span){var a1=getAbsoluteTop(htmlNode);var a2=getAbsoluteTop(this.allTree);this.dadmodec=this.dadmode;this.dadmodefix=0;var zN=htmlNode.parentObject.span;zN.className+=" dragAndDropRow";this._lastMark=zN;}};dhtmlXTreeObject.prototype._autoScroll=function(node,a1,a2){if(this.autoScroll){if(node){a1=getAbsoluteTop(node);a2=getAbsoluteTop(this.allTree);}if((a1-a2-parseInt(this.allTree.scrollTop))>(parseInt(this.allTree.offsetHeight)-50))this.allTree.scrollTop=parseInt(this.allTree.scrollTop)+20;if((a1-a2)<(parseInt(this.allTree.scrollTop)+30))this.allTree.scrollTop=parseInt(this.allTree.scrollTop)-20;}};dhtmlXTreeObject.prototype._createDragNode=function(htmlObject,e){if(!this.dADTempOff)return null;var obj=htmlObject.parentObject;if(!obj.i_sel)this._selectItem(obj,e);var dragSpan=document.createElement('div');var text=new Array();if(this._itim_dg)for(var i=0;i"+this._selected[i].span.innerHTML+"";else text=this.getSelectedItemText().split(this.dlmtr);dragSpan.innerHTML=text.join("");dragSpan.style.position="absolute";dragSpan.className="dragSpanDiv";this._dragged=(new Array()).concat(this._selected);return dragSpan;};dhtmlXTreeObject.prototype._focusNode=function(item){var z=getAbsoluteTop(item.htmlNode)-getAbsoluteTop(this.allTree);if((z>(this.allTree.scrollTop+this.allTree.offsetHeight-30))||(z2)?(sNode.checkstate-3):sNode.checkstate);this._setCheck(sNode);if(sNode.dscheck<3)sNode.dscheck=false;};dhtmlXTreeObject.prototype.setEscapingMode=function(mode){this.utfesc=mode;}; -dhtmlXTreeObject.prototype.enableHighlighting=function(mode){this.ehlt=true;this.ehlta=convertStringToBoolean(mode);};dhtmlXTreeObject.prototype._itemMouseOut=function(){var that=this.childNodes[3].parentObject;var tree=that.treeNod;tree.callEvent("onMouseOut",[that.id]);if(that.id==tree._l_onMSI)tree._l_onMSI=null;if(!tree.ehlta)return;that.span.className=that.span.className.replace("_lor","");};dhtmlXTreeObject.prototype._itemMouseIn=function(){var that=this.childNodes[3].parentObject;var tree=that.treeNod;if(tree._l_onMSI!=that.id)tree.callEvent("onMouseIn",[that.id]);tree._l_onMSI=that.id;if(!tree.ehlta)return;that.span.className=that.span.className.replace("_lor","");that.span.className=that.span.className.replace(/((standart|selected)TreeRow)/,"$1_lor");};dhtmlXTreeObject.prototype.enableActiveImages=function(mode){this._aimgs=convertStringToBoolean(mode);};dhtmlXTreeObject.prototype.focusItem=function(itemId){var sNode=this._globalIdStorageFind(itemId);if(!sNode)return(0);this._focusNode(sNode);};dhtmlXTreeObject.prototype.getAllSubItems=function(itemId){return this._getAllSubItems(itemId);};dhtmlXTreeObject.prototype.getAllChildless=function(){return this._getAllScraggyItems(this.htmlNode);};dhtmlXTreeObject.prototype.getAllLeafs=dhtmlXTreeObject.prototype.getAllChildless;dhtmlXTreeObject.prototype._getAllScraggyItems=function(node){var z="";for(var i=0;i0)){if(node.childNodes[i].unParsed)var zb=this._getAllScraggyItemsXML(node.childNodes[i].unParsed,1);else var zb=this._getAllScraggyItems(node.childNodes[i]);if(zb)if(z)z+=this.dlmtr+zb;else z=zb;}else if(!z)z=node.childNodes[i].id;else z+=this.dlmtr+node.childNodes[i].id;}return z;};dhtmlXTreeObject.prototype._getAllFatItems=function(node){var z="";for(var i=0;i0)){if(!z)z=node.childNodes[i].id;else z+=this.dlmtr+node.childNodes[i].id;if(node.childNodes[i].unParsed)var zb=this._getAllFatItemsXML(node.childNodes[i].unParsed,1);else var zb=this._getAllFatItems(node.childNodes[i]);if(zb)z+=this.dlmtr+zb;}}return z;};dhtmlXTreeObject.prototype.getAllItemsWithKids=function(){return this._getAllFatItems(this.htmlNode);};dhtmlXTreeObject.prototype.getAllFatItems=dhtmlXTreeObject.prototype.getAllItemsWithKids;dhtmlXTreeObject.prototype.getAllChecked=function(){return this._getAllChecked("","",1);};dhtmlXTreeObject.prototype.getAllUnchecked=function(itemId){if(itemId)itemId=this._globalIdStorageFind(itemId);return this._getAllChecked(itemId,"",0);};dhtmlXTreeObject.prototype.getAllPartiallyChecked=function(){return this._getAllChecked("","",2);};dhtmlXTreeObject.prototype.getAllCheckedBranches=function(){var temp=this._getAllChecked("","",1);if(temp!="")temp+=this.dlmtr;return temp+this._getAllChecked("","",2);};dhtmlXTreeObject.prototype._getAllChecked=function(htmlNode,list,mode){if(!htmlNode)htmlNode=this.htmlNode;if(htmlNode.checkstate==mode)if(!htmlNode.nocheckbox){if(list)list+=this.dlmtr+htmlNode.id;else list=htmlNode.id;}var j=htmlNode.childsCount;for(var i=0;i';postVar2="";target=rpc;}var z=function(){var loader=new dtmlXMLLoaderObject(null,window,false);var request=postVar;if(postVar2){for(var i=0;i"+(arguments[i]?arguments[i].toString():"")+"";request+=postVar2;}else for(var i=0;i + + +Lemonldap::NG Manager +/manager.css" /> + + + + + + + + +
    +
    +
    + Lemonldap::NG/logo_lemonldap-ng.png"/>
      + +
    +
    +
    +
    +

    Lemonldap::NG Manager

    +
    + + + + + + + +
    +
    +
    +
    + Default +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +   +
    +
    +
    +
    +
    +
    +
    + + + diff --git a/modules/lemonldap-ng-manager/example/skins/default/minus.gif b/modules/lemonldap-ng-manager/example/skins/default/minus.gif new file mode 100644 index 000000000..e4f90c275 Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/minus.gif differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/page_add.png b/modules/lemonldap-ng-manager/example/skins/default/page_add.png new file mode 100644 index 000000000..d5bfa0719 Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/page_add.png differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/page_delete.png b/modules/lemonldap-ng-manager/example/skins/default/page_delete.png new file mode 100644 index 000000000..3141467c6 Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/page_delete.png differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/page_edit.png b/modules/lemonldap-ng-manager/example/skins/default/page_edit.png new file mode 100644 index 000000000..046811ed7 Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/page_edit.png differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/plus.gif b/modules/lemonldap-ng-manager/example/skins/default/plus.gif new file mode 100644 index 000000000..c253770d2 Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/plus.gif differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/root.gif b/modules/lemonldap-ng-manager/example/skins/default/root.gif new file mode 100644 index 000000000..27012fbd6 Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/root.gif differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/spacer.gif b/modules/lemonldap-ng-manager/example/skins/default/spacer.gif new file mode 100644 index 000000000..1d11fa9ad Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/spacer.gif differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/spinner.gif b/modules/lemonldap-ng-manager/example/skins/default/spinner.gif new file mode 100644 index 000000000..085ccaeca Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/spinner.gif differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/tree.js b/modules/lemonldap-ng-manager/example/skins/default/tree.js new file mode 100644 index 000000000..644597089 --- /dev/null +++ b/modules/lemonldap-ng-manager/example/skins/default/tree.js @@ -0,0 +1,475 @@ +/* +* jQuery SimpleTree Drag&Drop plugin +* Update on 22th May 2008 +* Version 0.3 +* +* Licensed under BSD +* Copyright (c) 2008, Peter Panov , IKEEN Group http://www.ikeen.com +* All rights reserved. +* +* Modified by Xavier Guimard for Lemonldap::NG +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the Peter Panov, IKEEN Group nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY Peter Panov, IKEEN Group ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL Peter Panov, IKEEN Group BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +$.fn.simpleTree = function(opt){ + return this.each(function(){ + var TREE = this; + var ROOT = $('.root',this); + var mousePressed = false; + var mouseMoved = false; + var dragMoveType = false; + var dragNode_destination = false; + var dragNode_source = false; + var dragDropTimer = false; + var ajaxCache = Array(); + + TREE.option = { + drag: true, + animate: false, + autoclose: false, + speed: 'fast', + afterAjax: false, + afterMove: false, + afterClick: false, + afterDblClick: false, + // added by Erik Dohmen (2BinBusiness.nl) to make context menu cliks available + afterContextMenu: false, + docToFolderConvert:false + }; + TREE.option = $.extend(TREE.option,opt); + $.extend(this, {getSelected: function(){ + return $('span.active', this).parent(); + }}); + TREE.closeNearby = function(obj) + { + $(obj).siblings().filter('.folder-open, .folder-open-last').each(function(){ + var childUl = $('>ul',this); + var className = this.className; + this.className = className.replace('open','close'); + if(TREE.option.animate) + { + childUl.animate({height:"toggle"},TREE.option.speed); + }else{ + childUl.hide(); + } + }); + }; + TREE.nodeToggle = function(obj) + { + var childUl = $('>ul',obj); + if(childUl.is(':visible')){ + obj.className = obj.className.replace('open','close'); + + if(TREE.option.animate) + { + childUl.animate({height:"toggle"},TREE.option.speed); + }else{ + childUl.hide(); + } + }else{ + obj.className = obj.className.replace('close','open'); + if(TREE.option.animate) + { + childUl.animate({height:"toggle"},TREE.option.speed, function(){ + if(TREE.option.autoclose)TREE.closeNearby(obj); + if(childUl.is('.ajax'))TREE.setAjaxNodes(childUl, obj.id); + }); + }else{ + childUl.show(); + if(TREE.option.autoclose)TREE.closeNearby(obj); + if(childUl.is('.ajax'))TREE.setAjaxNodes(childUl, obj.id); + } + } + }; + TREE.setAjaxNodes = function(node, parentId, callback) + { + if($.inArray(parentId,ajaxCache) == -1){ + ajaxCache[ajaxCache.length]=parentId; + var url = $.trim($('>li', node).text()); + if(url && url.indexOf('url:')) + { + url=$.trim(url.replace(/.*\{url:(.*)\}/i ,'$1')); + var js=''; + if(url.indexOf(',js:')){ + js=$.trim(url.replace(/.*,js:(.*)/i ,'$1')); + url=$.trim(url.replace(/,js:.*/i ,'')); + } + $.ajax({ + type: "GET", + url: url, + contentType:'html', + cache:false, + success: function(responce){ + node.removeAttr('class'); + node.html(responce); + $.extend(node,{url:url}); + if($('li',node).length==0)TREE.convertToFolder(node.parent()); + TREE.setTreeNodes(node, true); + if(typeof TREE.option.afterAjax == 'function') + { + TREE.option.afterAjax(node); + } + if(typeof callback == 'function') + { + callback(node); + } + if(js.length)$('>span',node.parent()).click(function(){eval(js+'()')}); + } + }); + } + + } + }; + TREE.setTreeNodes = function(obj, useParent){ + obj = useParent? obj.parent():obj; + $('li>span', obj).addClass('text') + .bind('selectstart', function() { + return false; + }).click(function(){ + $('.active',TREE).attr('class','text'); + if(this.className=='text') + { + this.className='active'; + } + if(typeof TREE.option.afterClick == 'function') + { + TREE.option.afterClick($(this).parent()); + } + return false; + }).dblclick(function(){ + mousePressed = false; + TREE.nodeToggle($(this).parent().get(0)); + if(typeof TREE.option.afterDblClick == 'function') + { + TREE.option.afterDblClick($(this).parent()); + } + return false; + // added by Erik Dohmen (2BinBusiness.nl) to make context menu actions + // available + }).bind("contextmenu",function(){ + $('.active',TREE).attr('class','text'); + if(this.className=='text') + { + this.className='active'; + } + if(typeof TREE.option.afterContextMenu == 'function') + { + TREE.option.afterContextMenu($(this).parent()); + } + return false; + }).mousedown(function(event){ + mousePressed = true; + cloneNode = $(this).parent().clone(); + var LI = $(this).parent(); + if(TREE.option.drag) + { + $('>ul', cloneNode).hide(); + $('body').append('
      '); + $('#drag_container').hide().css({opacity:'0.8'}); + $('#drag_container >ul').append(cloneNode); + $("").attr({id : "tree_plus",src : "plus.gif"}).css({width: "7px",display: "block",position: "absolute",left : "5px",top: "5px", display:'none'}).appendTo("body"); + $(document).bind("mousemove", {LI:LI}, TREE.dragStart).bind("mouseup",TREE.dragEnd); + } + return false; + }).mouseup(function(){ + if(mousePressed && mouseMoved && dragNode_source) + { + TREE.moveNodeToFolder($(this).parent()); + } + TREE.eventDestroy(); + }); + $('li', obj).each(function(i){ + var className = this.className; + var open = false; + var cloneNode=false; + var LI = this; + var childNode = $('>ul',this); + if(childNode.size()>0){ + var setClassName = 'folder-'; + if(className && className.indexOf('open')>=0){ + setClassName=setClassName+'open'; + open=true; + }else{ + setClassName=setClassName+'close'; + } + this.className = setClassName + ($(this).is(':last-child')? '-last':''); + + if(!open || className.indexOf('ajax')>=0)childNode.hide(); + + TREE.setTrigger(this); + }else{ + var setClassName = 'doc'; + this.className = setClassName + ($(this).is(':last-child')? '-last':''); + } + }).before('
    •  
    • ') + .filter(':last-child').after('
    • '); + TREE.setEventLine($('.line, .line-last', obj)); + }; + TREE.setTrigger = function(node){ + $('>span',node).before(''); + var trigger = $('>.trigger', node); + trigger.click(function(event){ + TREE.nodeToggle(node); + }); + if(!$.browser.msie) + { + trigger.css('float','left'); + } + }; + TREE.dragStart = function(event){ + var LI = $(event.data.LI); + if(mousePressed) + { + mouseMoved = true; + if(dragDropTimer) clearTimeout(dragDropTimer); + if($('#drag_container:not(:visible)')){ + $('#drag_container').show(); + LI.prev('.line').hide(); + dragNode_source = LI; + } + $('#drag_container').css({position:'absolute', "left" : (event.pageX + 5), "top": (event.pageY + 15) }); + if(LI.is(':visible'))LI.hide(); + var temp_move = false; + if(event.target.tagName.toLowerCase()=='span' && $.inArray(event.target.className, Array('text','active','trigger'))!= -1) + { + var parent = event.target.parentNode; + var offs = $(parent).offset({scroll:false}); + var screenScroll = {x : (offs.left - 3),y : event.pageY - offs.top}; + var isrc = $("#tree_plus").attr('src'); + var ajaxChildSize = $('>ul.ajax',parent).size(); + var ajaxChild = $('>ul.ajax',parent); + screenScroll.x += 19; + screenScroll.y = event.pageY - screenScroll.y + 5; + + if(parent.className.indexOf('folder-close')>=0 && ajaxChildSize==0) + { + if(isrc.indexOf('minus')!=-1)$("#tree_plus").attr('src','plus.gif'); + $("#tree_plus").css({"left": screenScroll.x, "top": screenScroll.y}).show(); + dragDropTimer = setTimeout(function(){ + parent.className = parent.className.replace('close','open'); + $('>ul',parent).show(); + }, 700); + }else if(parent.className.indexOf('folder')>=0 && ajaxChildSize==0){ + if(isrc.indexOf('minus')!=-1)$("#tree_plus").attr('src','plus.gif'); + $("#tree_plus").css({"left": screenScroll.x, "top": screenScroll.y}).show(); + }else if(parent.className.indexOf('folder-close')>=0 && ajaxChildSize>0) + { + mouseMoved = false; + $("#tree_plus").attr('src','minus.gif'); + $("#tree_plus").css({"left": screenScroll.x, "top": screenScroll.y}).show(); + + $('>ul',parent).show(); + /* + Thanks for the idea of Erik Dohmen + */ + TREE.setAjaxNodes(ajaxChild,parent.id, function(){ + parent.className = parent.className.replace('close','open'); + mouseMoved = true; + $("#tree_plus").attr('src','plus.gif'); + $("#tree_plus").css({"left": screenScroll.x, "top": screenScroll.y}).show(); + }); + + }else{ + if(TREE.option.docToFolderConvert) + { + $("#tree_plus").css({"left": screenScroll.x, "top": screenScroll.y}).show(); + }else{ + $("#tree_plus").hide(); + } + } + }else{ + $("#tree_plus").hide(); + } + return false; + } + return true; + }; + TREE.dragEnd = function(){ + if(dragDropTimer) clearTimeout(dragDropTimer); + TREE.eventDestroy(); + }; + TREE.setEventLine = function(obj){ + obj.mouseover(function(){ + if(this.className.indexOf('over')<0 && mousePressed && mouseMoved) + { + this.className = this.className.replace('line','line-over'); + } + }).mouseout(function(){ + if(this.className.indexOf('over')>=0) + { + this.className = this.className.replace('-over',''); + } + }).mouseup(function(){ + if(mousePressed && dragNode_source && mouseMoved) + { + dragNode_destination = $(this).parents('li:first'); + TREE.moveNodeToLine(this); + TREE.eventDestroy(); + } + }); + }; + TREE.checkNodeIsLast = function(node) + { + if(node.className.indexOf('last')>=0) + { + var prev_source = dragNode_source.prev().prev(); + if(prev_source.size()>0) + { + prev_source[0].className+='-last'; + } + node.className = node.className.replace('-last',''); + } + }; + TREE.checkLineIsLast = function(line) + { + if(line.className.indexOf('last')>=0) + { + var prev = $(line).prev(); + if(prev.size()>0) + { + prev[0].className = prev[0].className.replace('-last',''); + } + dragNode_source[0].className+='-last'; + } + }; + TREE.eventDestroy = function() + { + // added by Erik Dohmen (2BinBusiness.nl), the unbind mousemove TREE.dragStart action + // like this other mousemove actions binded through other actions ain't removed (use it myself + // to determine location for context menu) + $(document).unbind('mousemove',TREE.dragStart).unbind('mouseup').unbind('mousedown'); + $('#drag_container, #tree_plus').remove(); + if(dragNode_source) + { + $(dragNode_source).show().prev('.line').show(); + } + dragNode_destination = dragNode_source = mousePressed = mouseMoved = false; + //ajaxCache = Array(); + }; + TREE.convertToFolder = function(node){ + node[0].className = node[0].className.replace('doc','folder-open'); + node.append('
      '); + TREE.setTrigger(node[0]); + TREE.setEventLine($('.line, .line-last', node)); + }; + TREE.convertToDoc = function(node){ + $('>ul', node).remove(); + $('img', node).remove(); + node[0].className = node[0].className.replace(/folder-(open|close)/gi , 'doc'); + }; + TREE.moveNodeToFolder = function(node) + { + if(!TREE.option.docToFolderConvert && node[0].className.indexOf('doc')!=-1) + { + return true; + }else if(TREE.option.docToFolderConvert && node[0].className.indexOf('doc')!=-1){ + TREE.convertToFolder(node); + } + TREE.checkNodeIsLast(dragNode_source[0]); + var lastLine = $('>ul >.line-last', node); + if(lastLine.size()>0) + { + TREE.moveNodeToLine(lastLine[0]); + } + }; + TREE.moveNodeToLine = function(node){ + TREE.checkNodeIsLast(dragNode_source[0]); + TREE.checkLineIsLast(node); + var parent = $(dragNode_source).parents('li:first'); + var line = $(dragNode_source).prev('.line'); + $(node).before(dragNode_source); + $(dragNode_source).before(line); + node.className = node.className.replace('-over',''); + var nodeSize = $('>ul >li', parent).not('.line, .line-last').filter(':visible').size(); + if(TREE.option.docToFolderConvert && nodeSize==0) + { + TREE.convertToDoc(parent); + }else if(nodeSize==0) + { + parent[0].className=parent[0].className.replace('open','close'); + $('>ul',parent).hide(); + } + + // added by Erik Dohmen (2BinBusiness.nl) select node + if($('span:first',dragNode_source).attr('class')=='text') + { + $('.active',TREE).attr('class','text'); + $('span:first',dragNode_source).attr('class','active'); + } + + if(typeof(TREE.option.afterMove) == 'function') + { + var pos = $(dragNode_source).prevAll(':not(.line)').size(); + TREE.option.afterMove($(node).parents('li:first'), $(dragNode_source), pos); + } + }; + + TREE.addNode = function(id, text, callback) + { + var temp_node = $('
      • '+text+'
    • '); + TREE.setTreeNodes(temp_node); + dragNode_destination = TREE.getSelected(); + dragNode_source = $('.doc-last',temp_node); + TREE.moveNodeToFolder(dragNode_destination); + temp_node.remove(); + if(typeof(callback) == 'function') + { + callback(dragNode_destination, dragNode_source); + } + }; + TREE.newNodeAfter = function(id, text, callback) + { + var temp_node = $('
      • '+text+'
      • '); + TREE.setTreeNodes(temp_node,true); + destination = TREE.getSelected().parent().parent(); + dragNode_source = $('.doc-last',temp_node); + TREE.moveNodeToFolder(destination); + temp_node.remove(); + if(typeof(callback) == 'function') + { + callback(dragNode_destination, dragNode_source); + } + //existing.after(temp_node); + //temp_node.remove(); + }; + TREE.delNode = function(callback) + { + dragNode_source = TREE.getSelected(); + TREE.checkNodeIsLast(dragNode_source[0]); + dragNode_source.prev().remove(); + dragNode_source.remove(); + if(typeof(callback) == 'function') + { + callback(dragNode_destination); + } + }; + + TREE.init = function(obj) + { + TREE.setTreeNodes(obj, false); + }; + TREE.init(ROOT); + }); +} diff --git a/modules/lemonldap-ng-manager/example/skins/default/tree_line.gif b/modules/lemonldap-ng-manager/example/skins/default/tree_line.gif new file mode 100644 index 000000000..2d6fa89c6 Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/tree_line.gif differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/vframe.png b/modules/lemonldap-ng-manager/example/skins/default/vframe.png new file mode 100644 index 000000000..e139ba3b8 Binary files /dev/null and b/modules/lemonldap-ng-manager/example/skins/default/vframe.png differ diff --git a/modules/lemonldap-ng-manager/example/skins/default/xlib.js b/modules/lemonldap-ng-manager/example/skins/default/xlib.js new file mode 100644 index 000000000..7e586bb2a --- /dev/null +++ b/modules/lemonldap-ng-manager/example/skins/default/xlib.js @@ -0,0 +1,196 @@ +/* Compiled from X 4.18 by XC 1.07 on 17Feb09 */ +function xEvent(evt){var e=evt||window.event;if(!e)return;this.type=e.type;this.target=e.target||e.srcElement;this.relatedTarget=e.relatedTarget;/*@cc_on if(e.type=='mouseover')this.relatedTarget=e.fromElement;else if(e.type=='mouseout')this.relatedTarget=e.toElement;@*/if(xDef(e.pageX)){this.pageX=e.pageX;this.pageY=e.pageY;}else if(xDef(e.clientX)){this.pageX=e.clientX+xScrollLeft();this.pageY=e.clientY+xScrollTop();}if(xDef(e.offsetX)){this.offsetX=e.offsetX;this.offsetY=e.offsetY;}else if(xDef(e.layerX)){this.offsetX=e.layerX;this.offsetY=e.layerY;}else{this.offsetX=this.pageX-xPageX(this.target);this.offsetY=this.pageY-xPageY(this.target);}this.keyCode=e.keyCode||e.which||0;this.shiftKey=e.shiftKey;this.ctrlKey=e.ctrlKey;this.altKey=e.altKey;if(typeof e.type=='string'){if(e.type.indexOf('click')!=-1){this.button=0;}else if(e.type.indexOf('mouse')!=-1){this.button=e.button;/*@cc_on if(e.button&1)this.button=0;else if(e.button&4)this.button=1;else if(e.button&2)this.button=2;@*/}}}xLibrary={version:'4.18',license:'GNU LGPL',url:'http://cross-browser.com/'};function xAddEventListener(e,eT,eL,cap){if(!(e=xGetElementById(e)))return;eT=eT.toLowerCase();if(e.addEventListener)e.addEventListener(eT,eL,cap||false);else if(e.attachEvent)e.attachEvent('on'+eT,eL);else{var o=e['on'+eT];e['on'+eT]=typeof o=='function'?function(v){o(v);eL(v);}:eL;}}function xCamelize(cssPropStr){var i,c,a=cssPropStr.split('-');var s=a[0];for(i=1;iw.innerWidth)v-=16;}return v;}function xClientWidth(){var v=0,d=document,w=window;if((!d.compatMode||d.compatMode=='CSS1Compat')&&!w.opera&&d.documentElement&&d.documentElement.clientWidth){v=d.documentElement.clientWidth;}else if(d.body&&d.body.clientWidth){v=d.body.clientWidth;}else if(xDef(w.innerWidth,w.innerHeight,d.height)){v=w.innerWidth;if(d.height>w.innerHeight)v-=16;}return v;}function xDef(){for(var i=0;i=eX+l&&x<=eX+xWidth(e)-r&&y>=eY+t&&y<=eY+xHeight(e)-b);}function xHeight(e,h){if(!(e=xGetElementById(e)))return 0;if(xNum(h)){if(h<0)h=0;else h=Math.round(h);}else h=-1;var css=xDef(e.style);if(e==document||e.tagName.toLowerCase()=='html'||e.tagName.toLowerCase()=='body'){h=xClientHeight();}else if(css&&xDef(e.offsetHeight)&&xStr(e.style.height)){if(h>=0){var pt=0,pb=0,bt=0,bb=0;if(document.compatMode=='CSS1Compat'){var gcs=xGetComputedStyle;pt=gcs(e,'padding-top',1);if(pt!==null){pb=gcs(e,'padding-bottom',1);bt=gcs(e,'border-top-width',1);bb=gcs(e,'border-bottom-width',1);}else if(xDef(e.offsetHeight,e.style.height)){e.style.height=h+'px';pt=e.offsetHeight-h;}}h-=(pt+pb+bt+bb);if(isNaN(h)||h<0)return;else e.style.height=h+'px';}h=e.offsetHeight;}else if(css&&xDef(e.style.pixelHeight)){if(h>=0)e.style.pixelHeight=h;h=e.style.pixelHeight;}return h;}function xLeft(e,iX){if(!(e=xGetElementById(e)))return 0;var css=xDef(e.style);if(css&&xStr(e.style.left)){if(xNum(iX))e.style.left=iX+'px';else{iX=parseInt(e.style.left);if(isNaN(iX))iX=xGetComputedStyle(e,'left',1);if(isNaN(iX))iX=0;}}else if(css&&xDef(e.style.pixelLeft)){if(xNum(iX))e.style.pixelLeft=iX;else iX=e.style.pixelLeft;}return iX;}function xMoveTo(e,x,y){xLeft(e,x);xTop(e,y);}function xNum(){for(var i=0;i=0){var pl=0,pr=0,bl=0,br=0;if(document.compatMode=='CSS1Compat'){var gcs=xGetComputedStyle;pl=gcs(e,'padding-left',1);if(pl!==null){pr=gcs(e,'padding-right',1);bl=gcs(e,'border-left-width',1);br=gcs(e,'border-right-width',1);}else if(xDef(e.offsetWidth,e.style.width)){e.style.width=w+'px';pl=e.offsetWidth-w;}}w-=(pl+pr+bl+br);if(isNaN(w)||w<0)return;else e.style.width=w+'px';}w=e.offsetWidth;}else if(css&&xDef(e.style.pixelWidth)){if(w>=0)e.style.pixelWidth=w;w=e.style.pixelWidth;}return w;}/* Compiled from X 4.18 by XC 1.07 on 17Feb09 */ +function xEvent(evt){var e=evt||window.event;if(!e)return;this.type=e.type;this.target=e.target||e.srcElement;this.relatedTarget=e.relatedTarget;/*@cc_on if(e.type=='mouseover')this.relatedTarget=e.fromElement;else if(e.type=='mouseout')this.relatedTarget=e.toElement;@*/if(xDef(e.pageX)){this.pageX=e.pageX;this.pageY=e.pageY;}else if(xDef(e.clientX)){this.pageX=e.clientX+xScrollLeft();this.pageY=e.clientY+xScrollTop();}if(xDef(e.offsetX)){this.offsetX=e.offsetX;this.offsetY=e.offsetY;}else if(xDef(e.layerX)){this.offsetX=e.layerX;this.offsetY=e.layerY;}else{this.offsetX=this.pageX-xPageX(this.target);this.offsetY=this.pageY-xPageY(this.target);}this.keyCode=e.keyCode||e.which||0;this.shiftKey=e.shiftKey;this.ctrlKey=e.ctrlKey;this.altKey=e.altKey;if(typeof e.type=='string'){if(e.type.indexOf('click')!=-1){this.button=0;}else if(e.type.indexOf('mouse')!=-1){this.button=e.button;/*@cc_on if(e.button&1)this.button=0;else if(e.button&4)this.button=1;else if(e.button&2)this.button=2;@*/}}}xLibrary={version:'4.18',license:'GNU LGPL',url:'http://cross-browser.com/'};function xAddEventListener(e,eT,eL,cap){if(!(e=xGetElementById(e)))return;eT=eT.toLowerCase();if(e.addEventListener)e.addEventListener(eT,eL,cap||false);else if(e.attachEvent)e.attachEvent('on'+eT,eL);else{var o=e['on'+eT];e['on'+eT]=typeof o=='function'?function(v){o(v);eL(v);}:eL;}}function xPreventDefault(e){if(e&&e.preventDefault)e.preventDefault();else if(window.event)window.event.returnValue=false;}function xRemoveEventListener(e,eT,eL,cap){if(!(e=xGetElementById(e)))return;eT=eT.toLowerCase();if(e.removeEventListener)e.removeEventListener(eT,eL,cap||false);else if(e.detachEvent)e.detachEvent('on'+eT,eL);else e['on'+eT]=null;}function xStopPropagation(evt){if(evt&&evt.stopPropagation)evt.stopPropagation();else if(window.event)window.event.cancelBubble=true;}// xEnableDrag r8, Copyright 2002-2007 Michael Foster (Cross-Browser.com) +// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL + +function xEnableDrag(id,fS,fD,fE) +{ + var mx = 0, my = 0, el = xGetElementById(id); + if (el) { + el.xDragEnabled = true; + xAddEventListener(el, 'mousedown', dragStart, false); + } + // Private Functions + function dragStart(e) + { + if (el.xDragEnabled) { + var ev = new xEvent(e); + xPreventDefault(e); + mx = ev.pageX; + my = ev.pageY; + xAddEventListener(document, 'mousemove', drag, false); + xAddEventListener(document, 'mouseup', dragEnd, false); + if (fS) { + fS(el, ev.pageX, ev.pageY, ev); + } + } + } + function drag(e) + { + var ev, dx, dy; + xPreventDefault(e); + ev = new xEvent(e); + dx = ev.pageX - mx; + dy = ev.pageY - my; + mx = ev.pageX; + my = ev.pageY; + if (fD) { + fD(el, dx, dy, ev); + } + else { + xMoveTo(el, xLeft(el) + dx, xTop(el) + dy); + } + } + function dragEnd(e) + { + var ev = new xEvent(e); + xPreventDefault(e); + xRemoveEventListener(document, 'mouseup', dragEnd, false); + xRemoveEventListener(document, 'mousemove', drag, false); + if (fE) { + fE(el, ev.pageX, ev.pageY, ev); + } + if (xEnableDrag.drop) { + xEnableDrag.drop(el, ev); + } + } +} + +xEnableDrag.drops = []; // static property +// xFirstChild r4, Copyright 2004-2007 Michael Foster (Cross-Browser.com) +// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL + +function xFirstChild(e,t) +{ + e = xGetElementById(e); + var c = e ? e.firstChild : null; + while (c) { + if (c.nodeType == 1 && (!t || c.nodeName.toLowerCase() == t.toLowerCase())){break;} + c = c.nextSibling; + } + return c; +} +// xNextSib r4, Copyright 2005-2007 Michael Foster (Cross-Browser.com) +// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL + +function xNextSib(e,t) +{ + e = xGetElementById(e); + var s = e ? e.nextSibling : null; + while (s) { + if (s.nodeType == 1 && (!t || s.nodeName.toLowerCase() == t.toLowerCase())){break;} + s = s.nextSibling; + } + return s; +} +// xSplitter r3, Copyright 2006-2007 Michael Foster (Cross-Browser.com) +// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL + +function xSplitter(sSplId, uSplX, uSplY, uSplW, uSplH, bHorizontal, uBarW, uBarPos, uBarLimit1, uBarLimit2, bBarEnabled, uSplBorderW, oSplChild1, oSplChild2) +{ + // Private + + var pane1, pane2, splW, splH; + var splEle, barPos, barLim1, barLim2, barEle; + + function barOnDrag(ele, dx, dy) + { + var bp; + if (bHorizontal) + { + bp = barPos + dx; + if (bp < barLim1 || bp > splW - barLim2) { return; } + xWidth(pane1, xWidth(pane1) + dx); + xLeft(barEle, xLeft(barEle) + dx); + xWidth(pane2, xWidth(pane2) - dx); + xLeft(pane2, xLeft(pane2) + dx); + barPos = bp; + } + else + { + bp = barPos + dy; + if (bp < barLim1 || bp > splH - barLim2) { return; } + xHeight(pane1, xHeight(pane1) + dy); + xTop(barEle, xTop(barEle) + dy); + xHeight(pane2, xHeight(pane2) - dy); + xTop(pane2, xTop(pane2) + dy); + barPos = bp; + } + if (oSplChild1) { oSplChild1.paint(xWidth(pane1), xHeight(pane1)); } + if (oSplChild2) { oSplChild2.paint(xWidth(pane2), xHeight(pane2)); } + } + + // Public + + this.paint = function(uNewW, uNewH, uNewBarPos, uNewBarLim1, uNewBarLim2) // uNewBarPos and uNewBarLim are optional + { + if (uNewW == 0) { return; } + var w1, h1, w2, h2; + splW = uNewW; + splH = uNewH; + barPos = uNewBarPos || barPos; + barLim1 = uNewBarLim1 || barLim1; + barLim2 = uNewBarLim2 || barLim2; + xMoveTo(splEle, uSplX, uSplY); + xResizeTo(splEle, uNewW, uNewH); + if (bHorizontal) + { + w1 = barPos; + h1 = uNewH - 2 * uSplBorderW; + w2 = uNewW - w1 - uBarW - 2 * uSplBorderW; + h2 = h1; + xMoveTo(pane1, 0, 0); + xResizeTo(pane1, w1, h1); + xMoveTo(barEle, w1, 0); + xResizeTo(barEle, uBarW, h1); + xMoveTo(pane2, w1 + uBarW, 0); + xResizeTo(pane2, w2, h2); + } + else + { + w1 = uNewW - 2 * uSplBorderW;; + h1 = barPos; + w2 = w1; + h2 = uNewH - h1 - uBarW - 2 * uSplBorderW; + xMoveTo(pane1, 0, 0); + xResizeTo(pane1, w1, h1); + xMoveTo(barEle, 0, h1); + xResizeTo(barEle, w1, uBarW); + xMoveTo(pane2, 0, h1 + uBarW); + xResizeTo(pane2, w2, h2); + } + if (oSplChild1) + { + pane1.style.overflow = 'hidden'; + oSplChild1.paint(w1, h1); + } + if (oSplChild2) + { + pane2.style.overflow = 'hidden'; + oSplChild2.paint(w2, h2); + } + }; + + // Constructor + + splEle = xGetElementById(sSplId); // we assume the splitter has 3 DIV children and in this order: + pane1 = xFirstChild(splEle, 'DIV'); + pane2 = xNextSib(pane1, 'DIV'); + barEle = xNextSib(pane2, 'DIV'); + // --- slightly dirty hack + pane1.style.zIndex = 2; + pane2.style.zIndex = 2; + barEle.style.zIndex = 1; + // --- + barPos = uBarPos; + barLim1 = uBarLimit1; + barLim2 = uBarLimit2; + this.paint(uSplW, uSplH); + if (bBarEnabled) + { + xEnableDrag(barEle, null, barOnDrag, null); + barEle.style.cursor = bHorizontal ? 'e-resize' : 'n-resize'; + } + splEle.style.visibility = 'visible'; + +} // end xSplitter diff --git a/modules/lemonldap-ng-manager/example/theme/default.css b/modules/lemonldap-ng-manager/example/theme/default.css deleted file mode 100644 index 5c104fa56..000000000 --- a/modules/lemonldap-ng-manager/example/theme/default.css +++ /dev/null @@ -1,67 +0,0 @@ -/* CSS for LemonLDAP::NG Manager */ - -body { - font-family: Arial, Helvetica, Verdana; - margin: 0; - padding: 0; -} - -#gauche { - background: #dfdfdf url(hatch.gif); -} - -#haut { - background: #eee; -} - -#bas { - background: #ccc url(hatch.gif); -} - -#treeBox { - background: url(logo_lemonldap-ng.png) no-repeat center 5px; - padding: 50px 0 0 0; - font-weight: bold; -} - -#buttons { - margin: 20px 40px; - padding: 5px; - background: #fff; - border: 1px #ccc dashed; -} - -#formulaire { - margin: 20px 40px; -} - -input, textarea { - border: 1px #ccc solid; - padding: 3px; -} - -table { - border-collapse: collapse; -} - -#formulaire th { - background: #ddd url(hatch.gif); -} - -#formulaire td { - padding: 5px; - text-align: center; -} - -h1, h2, h3, h4, h5, h6, dt { - color: #d9b500; - font-weight: bold; -} - -pre, code { - font: 10pt monospace; - border-left: 5px gray solid; - padding: 5px; - margin: 0 10px; - background: #ccc; -} diff --git a/modules/lemonldap-ng-manager/example/theme/hatch.gif b/modules/lemonldap-ng-manager/example/theme/hatch.gif deleted file mode 100644 index 0de8e2c3f..000000000 Binary files a/modules/lemonldap-ng-manager/example/theme/hatch.gif and /dev/null differ diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm index da1d92d39..e1c87be9f 100644 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm @@ -1,1022 +1,79 @@ -## @file -# Lemonldap::NG Management interface - -## @class -# Lemonldap::NG Management interface package Lemonldap::NG::Manager; use strict; +use Lemonldap::NG::Handler::CGI qw(:globalStorage :locationRules); +use Lemonldap::NG::Manager::Help; #inherits -use XML::Simple; +our $VERSION = '0.1'; +our @ISA = qw( + Lemonldap::NG::Handler::CGI + Lemonldap::NG::Manager::Downloader + Lemonldap::NG::Manager::Uploader + Lemonldap::NG::Manager::_Struct + Lemonldap::NG::Manager::_i18n +); -use Lemonldap::NG::Common::CGI; -use Lemonldap::NG::Common::Conf; #link protected conf Configuration -use Lemonldap::NG::Manager::_HTML; #inherits -require Lemonldap::NG::Manager::_Response; #inherits -require Lemonldap::NG::Manager::_i18n; #inherits -require Lemonldap::NG::Manager::Help; #inherits -use Lemonldap::NG::Common::Conf::Constants; #inherits -use Lemonldap::NG::Common::Safelib; #link protected msafe Safe object -use LWP::UserAgent; -use Safe; -use MIME::Base64; - -#inherits Lemonldap::NG::Handler::CGI - -use base qw(Lemonldap::NG::Common::CGI); -our @ISA; - -our $VERSION = '0.92'; - -# Secure jail -our $msafe; - -##@method private object msafe() -# Provide the security jail. -#@return Safe object -sub msafe { - my $self = shift; - return $msafe if ($msafe); - $msafe = new Safe; - my @t = - $self->{customFunctions} ? split( /\s+/, $self->{customFunctions} ) : (); - foreach (@t) { - s/^.*:://; - next if ( $self->can($_) ); - eval "sub $_ {1}"; - $self->lmLog( $@, 'error' ) if ($@); - } - $msafe->share_from( 'main', ['%ENV'] ); - $msafe->share_from( 'Lemonldap::NG::Common::Safelib', - $Lemonldap::NG::Common::Safelib::functions ); - $msafe->share( '&encode_base64', @t ); - return $msafe; +BEGIN { + *process = *doall; } -## @cmethod Lemonldap::NG::Manager new(hashref args) -# Constructor. -# @param $args hash reference containing parameters sub new { my ( $class, $args ) = @_; - my $self = $class->SUPER::new(); - %$self = ( %$self, %$args ); - - # TODO load global configuration parameters ? - - # Try to load local configuration parameters to get 'protection' - my $localconf = $self->config->getLocalConf( MANAGERSECTION ); - if ( $localconf ) { - $args->{protection} ||= $localconf->{protection}; - } - - if ( $args->{protection} ) { - require Lemonldap::NG::Handler::CGI; - unshift @ISA, "Lemonldap::NG::Handler::CGI"; - $self = $class->SUPER::new($args); - } - - # Now push all local configuration parameters - if ( $localconf ) { - $self->{$_} = $args->{$_} || $localconf->{$_} foreach ( keys %$localconf ); - } - - foreach (qw(dhtmlXTreeImageLocation)) { - unless ( $self->{$_} ) { - $self->abort( "Unable to start", - qq/The "$_" parameter is required/ ); - } - } - $self->{jsFile} ||= $self->_dir . "lemonldap-ng-manager.js"; - unless ( -r $self->{jsFile} ) { - $self->abort( -qq#Unable to read $self->{jsFile}. You have to set "jsFile" parameter to /path/to/lemonldap-ng-manager.js# + my $self = $class->SUPER::new($args) + or $class->abort( 'Unable to start ' . __PACKAGE__, + 'See Apache logs for more' ); + if ( $ENV{PATH_INFO} eq "/css" ) { + print $self->header_public( $ENV{SCRIPT_FILENAME}, -type => 'text/css', ); + $self->css; + $self->quit(); } - $self->{pageTitle} ||= "LemonLDAP::NG Administration"; - $self->{textareaW} ||= 50; - $self->{textareaH} ||= 5; - $self->{inputSize} ||= 30; - unless ( __PACKAGE__->can('ldapServer') ) { - Lemonldap::NG::Manager::_i18n::import( $self->{language} - || $ENV{HTTP_ACCEPT_LANGUAGE} ); + elsif ( $ENV{PATH_INFO} eq "/js" ) { + print $self->header_public( $ENV{SCRIPT_FILENAME}, + -type => 'text/javascript', ); + $self->js; + $self->quit(); } - if ( $self->param('lmQuery') ) { - my $tmp = "print_" . $self->param('lmQuery'); - $self->$tmp; + elsif ( $self->param('help') ) { + print $self->header_public( $ENV{SCRIPT_FILENAME}, + -type => 'text/html; charset=utf8' ); + Lemonldap::NG::Manager::Help::import( $self->{language} + || $ENV{HTTP_ACCEPT_LANGUAGE} ) + unless ( $self->can('help_groups') ); + my $chap = $self->param('help'); + eval { no strict "refs"; &{"help_$chap"} }; + $self->quit(); } - else { - my $datas; - if ( $datas = $self->param('POSTDATA') ) { - $self->print_upload( \$datas ); - } - else { - return $self; - } + elsif ( my $rdata = $self->rparam('data') ) { + + require Lemonldap::NG::Manager::Uploader; #inherits + $self->confUpload($rdata); + $self->quit(); } - exit; + require Lemonldap::NG::Manager::Downloader; #inherits + $self->{cfgNum} = + $self->param('cfgNum') + || $self->confObj->lastCfg() + || 'UNAVAILABLE'; + if ( my $p = $self->param('node') ) { + print $self->header( -type => 'text/html; charset=utf8', ); + print $self->node($p); + $self->quit(); + } + return $self; } -## @method void doall() -# Launch : -# - Lemonldap::NG::Manager::_HTML::start_html() -# - Lemonldap::NG::Manager::_HTML::main() -# - CGI::end_html() -sub doall { +sub menu { my $self = shift; - - print $self->header( -type => 'text/html; charset=utf8' ); - - # Test if we have to use specific CSS - if ( defined $self->{cssFile} ) { - print $self->start_html( - -style => $self->{cssFile}, - -title => $self->{pageTitle}, - ); - } - else { - print $self->start_html( -title => $self->{pageTitle}, ); - } - print $self->main; - print $self->end_html; + require Lemonldap::NG::Manager::Downloader; #inherits + return + '
          ' + . $self->li( 'root', 'root' ) + . $self->span( 'root', "Configuration $self->{cfgNum}", + $self->{cfgNum}, 'none' ) + . '
            ' + . $self->node() + . '
        '; } -## @method void print_css() -# Print HTTP headers using header_public() and call -# Lemonldap::NG::Manager::_HTML::css() -sub print_css { - my $self = shift; - print $self->header_public( $ENV{SCRIPT_FILENAME}, -type => 'text/css' ); - $self->css; -} - -## @method void print_libjs() -# Print HTTP headers using header_public() and display $self->{jsFile} -# javascript file. -sub print_libjs { - my $self = shift; - print $self->header_public( $self->{jsFile}, - -type => 'application/x-javascript' ); - open F, $self->{jsFile}; - while () { - print; - } - close F; -} - -## @method void print_lmjs() -# Print HTTP headers using header_public() and call -# Lemonldap::NG::Manager::_HTML::javascript() -sub print_lmjs { - my $self = shift; - print $self->header_public( $ENV{SCRIPT_FILENAME}, - -type => 'text/javascript; charset=utf8' ); - $self->javascript; -} - -## @method void print_help() -# AJAX method that display help chapter. -# Print HTTP headers using header_public() and display asked help chapter. -sub print_help { - my $self = shift; - print $self->header_public( $ENV{SCRIPT_FILENAME}, - -type => 'text/html; charset=utf8' ); - Lemonldap::NG::Manager::Help::import( $self->{language} - || $ENV{HTTP_ACCEPT_LANGUAGE} ) - unless ( $self->can('help_groups') ); - my $chap = $self->param('help'); - eval { no strict "refs"; &{"help_$chap"} }; -} - -## @method void print_delete() -# Print HTTP headers and call Lemonldap::NG::Common::Conf::delete() -sub print_delete { - my $self = shift; - print $self->header( -type => 'text/html; charset=utf8' ); - Lemonldap::NG::Manager::Help::import( $self->{language} - || $ENV{HTTP_ACCEPT_LANGUAGE} ) - unless ( $self->can('help_groups') ); - if ( $self->config->delete( $self->param('cfgNum') ) ) { - print &txt_configurationDeleted; - } - else { - print &txt_configurationNotDeleted; - } - exit; -} - -## @method void print_conf() -# Print HTTP headers using header_public() and call printXmlConf() -sub print_conf { - my $self = shift; - print $self->header( - -type => "text/xml; charset=utf8", - '-Cache-Control' => 'private' - ); - $self->printXmlConf( { cfgNum => $self->param('cfgNum'), noCache => 1 } ); - exit; -} - -## @fn protected hashref default() -# Build a minimum configuration if no configuration is available. -# @return Lemonldap::NG configuration hash reference. -sub default { - return { - cfgNum => 0, - ldapBase => "dc=example,dc=com", - }; -} - -## @method protected string printXmlConf(array p) -# Call buildTree() then XML::Simple::XMLout to build the XML datas used by -# javascript library to display the tree. -# @param @p parameters given to buildTree() -# @return XML string -sub printXmlConf { - my $self = shift; - print XMLout( - $self->buildTree(@_), - - #XMLDecl => "", - RootName => 'tree', - KeyAttr => { item => 'id', username => 'name' }, - NoIndent => 1, - NoSort => 0, - XMLDecl => '', - ); -} - -## @method protected hashRef buildTree(array p) -# Transform Lemonldap::NG configuration into a tree that javascript library can -# understand. -# @param @p parameters given to Lemonldap::NG::Common::Conf::getConf() -# @return hash reference to the javascript tree structure -sub buildTree { - my $self = shift; - my $config = $self->config->getConf(@_); - $config = $self->default unless ( $config and $config->{cfgNum} ); - my $indice = 1; - my $tree = { - id => '0', - item => { - id => 'root', - open => 1, - text => &txt_configuration . " $config->{cfgNum}", - item => { - generalParameters => { - text => &txt_generalParameters, - item => { - exportedVars => { - text => &txt_exportedVars, - item => {}, - }, - macros => { text => &txt_macros, }, - ldapParameters => { - text => &txt_ldapParameters, - item => {}, - }, - sessionStorage => { - text => &txt_sessionStorage, - item => { - globalStorageOptions => - { text => &txt_globalStorageOptions, } - }, - }, - authParams => { - text => &txt_authParams, - item => {}, - }, - }, - }, - groups => { text => &txt_userGroups, }, - virtualHosts => { - text => &txt_virtualHosts, - open => 1, - select => 1, - }, - }, - }, - }; - my $generalParameters = $tree->{item}->{item}->{generalParameters}->{item}; - my $exportedVars = - $tree->{item}->{item}->{generalParameters}->{item}->{exportedVars} - ->{item}; - my $ldapParameters = - $tree->{item}->{item}->{generalParameters}->{item}->{ldapParameters} - ->{item}; - my $sessionStorage = - $tree->{item}->{item}->{generalParameters}->{item}->{sessionStorage} - ->{item}; - my $globalStorageOptions = - $tree->{item}->{item}->{generalParameters}->{item}->{sessionStorage} - ->{item}->{globalStorageOptions}->{item}; - my $authParams = - $tree->{item}->{item}->{generalParameters}->{item}->{authParams}->{item}; - $authParams->{authentication} = - $self->xmlField( "value", $config->{authentication} || 'ldap', - &txt_authenticationType, ); - $authParams->{portal} = - $self->xmlField( "value", $config->{portal} || 'http://portal/', - &txt_portal ); - $authParams->{securedCookie} = - $self->xmlField( "value", $config->{securedCookie} || 0, - &txt_securedCookie ); - $generalParameters->{whatToTrace} = - $self->xmlField( "value", $config->{whatToTrace} || '$uid', - &txt_whatToTrace ); - - $generalParameters->{domain} = - $self->xmlField( "value", $config->{domain} || 'example.com', &txt_domain, - ); - $generalParameters->{cookieName} = - $self->xmlField( "value", $config->{cookieName} || 'lemonldap', - &txt_cookieName, ); - $generalParameters->{timeout} = - $self->xmlField( "value", $config->{timeout} || 7200, - &txt_sessionTimeout, ); - - $sessionStorage->{globalStorage} = - $self->xmlField( "value", - $config->{globalStorage} || 'Apache::Session::File', - &txt_apacheSessionModule, ); - - $ldapParameters->{ldapServer} = - $self->xmlField( "value", $config->{ldapServer} || 'localhost', - &txt_ldapServer, ); - $ldapParameters->{ldapPort} = - $self->xmlField( "value", $config->{ldapPort} || 389, &txt_ldapPort, ); - $ldapParameters->{ldapBase} = - $self->xmlField( "value", $config->{ldapBase} || ' ', &txt_ldapBase, ); - $ldapParameters->{managerDn} = - $self->xmlField( "value", $config->{managerDn} || ' ', &txt_managerDn, ); - $ldapParameters->{managerPassword} = - $self->xmlField( "value", $config->{managerPassword} || ' ', - &txt_managerPassword, ); - - if ( $config->{exportedVars} ) { - foreach my $n ( sort keys %{ $config->{exportedVars} } ) { - $exportedVars->{ sprintf( "ev_%010d", $indice ) } = - $self->xmlField( "both", $config->{exportedVars}->{$n}, $n ); - $indice++; - } - } - else { - foreach (qw(cn mail uid)) { - $exportedVars->{ sprintf( "ev_%010d", $indice ) } = - $self->xmlField( 'both', $_, $_ ); - $indice++; - } - } - - if ( $config->{globalStorageOptions} - and %{ $config->{globalStorageOptions} } ) - { - $tree->{item}->{item}->{generalParameters}->{item}->{sessionStorage} - ->{item}->{globalStorageOptions}->{item} = {}; - $globalStorageOptions = - $tree->{item}->{item}->{generalParameters}->{item}->{sessionStorage} - ->{item}->{globalStorageOptions}->{item}; - foreach my $n ( sort keys %{ $config->{globalStorageOptions} } ) { - $globalStorageOptions->{ sprintf( "go_%010d", $indice ) } = - $self->xmlField( "both", $config->{globalStorageOptions}->{$n}, - $n ); - $indice++; - } - } - - if ( $config->{locationRules} and %{ $config->{locationRules} } ) { - $tree->{item}->{item}->{virtualHosts}->{item} = {}; - my $virtualHost = $tree->{item}->{item}->{virtualHosts}->{item}; - - # TODO: split locationRules into 2 arrays - foreach my $host ( sort keys %{ $config->{locationRules} } ) { - my $rules = $config->{locationRules}->{$host}; - my $vh_id = sprintf( "vh_%010d", $indice ); - $indice++; - $virtualHost->{$vh_id} = $self->xmlField( "text", 'i', $host ); - my ( $ih, $ir ) = - ( "exportedHeaders_$indice", "locationRules_$indice" ); - $virtualHost->{$vh_id}->{item} = { - "$ih" => { text => &txt_httpHeaders, }, - "$ir" => { text => &txt_locationRules, }, - }; - foreach my $reg ( sort keys %$rules ) { - my $type = ( $reg eq 'default' ) ? 'value' : 'both'; - $virtualHost->{$vh_id}->{item}->{$ir}->{item} - ->{ sprintf( "r_%010d", $indice ) } = - $self->xmlField( $type, $rules->{$reg}, $reg ); - $indice++; - } - my $headers = $config->{exportedHeaders}->{$host}; - foreach my $h ( sort keys %$headers ) { - $virtualHost->{$vh_id}->{item}->{$ih}->{item} - ->{ sprintf( "h_%010d", $indice ) } = - $self->xmlField( "both", $headers->{$h}, $h ); - $indice++; - } - } - } - if ( $config->{groups} and %{ $config->{groups} } ) { - $tree->{item}->{item}->{groups}->{item} = {}; - my $groups = $tree->{item}->{item}->{groups}->{item}; - foreach my $group ( sort keys %{ $config->{groups} } ) { - $groups->{ sprintf( "g_%010d", $indice ) } = - $self->xmlField( 'both', $config->{groups}->{$group}, $group ); - $indice++; - } - } - if ( $config->{macros} and %{ $config->{macros} } ) { - $tree->{item}->{item}->{generalParameters}->{item}->{macros}->{item} = - {}; - my $macros = - $tree->{item}->{item}->{generalParameters}->{item}->{macros}->{item}; - foreach my $macro ( sort keys %{ $config->{macros} } ) { - $macros->{"m_$indice"} = - $self->xmlField( 'both', $config->{macros}->{$macro}, $macro ); - $indice++; - } - } - return $tree; -} - -## @method protected hashref xmlField(string type, string value, string text) -# Little method used by buildTree to build javascript tree nodes. -# @param $type type of field (key and value can be both modified or not) -# @param $value value of the node -# @param $text text to display for the node -sub xmlField { - my ( $self, $type, $value, $text ) = @_; - $value =~ s/"/\"/g; - $text =~ s/"/\"/g; - return { - text => $text, - aCol => "#000000", - sCol => "#0000FF", - userdata => [ - { name => 'value', content => $value }, - { name => 'modif', content => $type }, - ], - }; -} - -# Upload subroutines -## @method void print_upload(string datas) -# Print HTTP headers, and call upload() to store the new configuration. -# Then call Lemonldap::NG::Manager::_Response::send() to display the response -# @param $datas new configuration in javascript XML format -sub print_upload { - my $self = shift; - my $datas = shift; - print $self->header( -type => "text/javascript; charset=utf8" ); - my $r = Lemonldap::NG::Manager::_Response->new(); - my $tmp = $self->upload( $datas, $r ); - if ( $tmp == 0 ) { - $r->message( &txt_unknownError, &txt_checkLogs ); - } - elsif ( $tmp > 0 ) { - $r->setConfiguration($tmp); - $r->message( &txt_confSaved . " $tmp", &txt_warningConfNotApplied ); - } - elsif ( $tmp == CONFIG_WAS_CHANGED ) { - $r->message( &txt_saveFailure, &txt_configurationWasChanged ); - } - elsif ( $tmp == SYNTAX_ERROR ) { - $r->message( &txt_saveFailure, &txt_syntaxError ); - } - $r->send; -} - -## @method protected int upload(string tree, Lemonldap::NG::Manager::_Response response) -# Transform $tree in a hash reference using tree2conf(), verify it using -# checkConf() then save configuration using saveConf() -# @param $tree configuration in XML format -# @param $response response object -# @return error code -sub upload { - my ( $self, $tree, $response ) = @_; - my $config = $self->tree2conf( $tree, $response ); - return SYNTAX_ERROR unless ( $self->checkConf( $config, $response ) ); - return $self->config->saveConf($config); -} - -## @method protected hashref tree2conf(string tree, Lemonldap::NG::Manager::_Response response) -# Transform $tree into a Lemonldap::NG configuration hash reference. -# @param $tree configuration in XML format -# @param $response response object -# @return $tree transformed in hash reference -sub tree2conf { - my ( $self, $tree, $response ) = @_; - $tree = XMLin($$tree); - my $config = {}; - - # Load config number - ( $config->{cfgNum} ) = ( $tree->{text} =~ /(\d+)$/ ); - - # Load groups - while ( my ( $g, $h ) = each( %{ $tree->{groups} } ) ) { - next unless ( ref($h) ); - $config->{groups}->{ $h->{text} } = $h->{value}; - } - - # Load virtualHosts - while ( my ( $k, $h ) = each( %{ $tree->{virtualHosts} } ) ) { - next unless ( ref($h) ); - my $lr; - my $eh; - foreach ( keys(%$h) ) { - $lr = $h->{$_} if ( $_ =~ /locationRules/ ); - $eh = $h->{$_} if ( $_ =~ /exportedHeaders/ ); - } - my $vh = $h->{text}; - - # TODO: split locationRules into 2 arrays - LR: foreach my $r ( values(%$lr) ) { - next LR unless ( ref($r) ); - $config->{locationRules}->{$vh}->{ $r->{text} } = $r->{value}; - } - EH: foreach my $h ( values(%$eh) ) { - next EH unless ( ref($h) ); - $config->{exportedHeaders}->{$vh}->{ $h->{text} } = $h->{value}; - } - } - - # General parameters - $config->{cookieName} = $tree->{generalParameters}->{cookieName}->{value}; - $config->{timeout} = $tree->{generalParameters}->{timeout}->{value}; - $config->{whatToTrace} = $tree->{generalParameters}->{whatToTrace}->{value}; - $config->{domain} = $tree->{generalParameters}->{domain}->{value}; - $config->{globalStorage} = - $tree->{generalParameters}->{sessionStorage}->{globalStorage}->{value}; - while ( - my ( $v, $h ) = each( - %{ - $tree->{generalParameters}->{sessionStorage} - ->{globalStorageOptions} - } - ) - ) - { - next unless ( ref($h) ); - $config->{globalStorageOptions}->{ $h->{text} } = $h->{value}; - } - while ( my ( $v, $h ) = each( %{ $tree->{generalParameters}->{macros} } ) ) - { - next unless ( ref($h) ); - $config->{macros}->{ $h->{text} } = $h->{value}; - } - foreach (qw(ldapBase ldapPort ldapServer managerDn managerPassword)) { - $config->{$_} = - $tree->{generalParameters}->{ldapParameters}->{$_}->{value}; - $config->{$_} = '' if ( ref( $config->{$_} ) ); - $config->{$_} =~ s/^\s*(.*?)\s*/$1/; - } - foreach (qw(authentication portal securedCookie)) { - $config->{$_} = $tree->{generalParameters}->{authParams}->{$_}->{value}; - $config->{$_} = '' if ( ref( $config->{$_} ) ); - $config->{$_} =~ s/^\s*(.*?)\s*/$1/; - } - while ( my ( $v, $h ) = - each( %{ $tree->{generalParameters}->{exportedVars} } ) ) - { - next unless ( ref($h) ); - $config->{exportedVars}->{ $h->{text} } = $h->{value}; - } - return $config; -} - -## @method protected boolean checkConf(hashref config,Lemonldap::NG::Manager::_Response response) -# Try to find faults in new uploaded configuration. -# @param $config Lemonldap::NG configuration hash reference -# @param $response response object -sub checkConf { - my $self = shift; - my $config = shift; - my $response = shift; - my $expr = ''; - my $result = 1; - my $assign = qr/(?<=[^=\?])=(?![=~])/; - - # Check cookie name - unless ( $config->{cookieName} =~ /^[a-zA-Z]\w*$/ ) { - $result = 0; - $response->error( - '"' . $config->{cookieName} . '" ' . &txt_isNotAValidCookieName ); - } - - # Check session timeout - unless ( $config->{timeout} =~ /^\d+$/ ) { - $result = 0; - $response->error( '"' . $config->{timeout} . '" ' . &txt_isNotANumber ); - } - - # Check domain name - unless ( $config->{domain} =~ - /^(?=^.{1,254}$)\.?(?:(?!\d+\.)[\w\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$/ ) - { - $result = 0; - $response->error( - '"' . $config->{domain} . '" ' . &txt_isNotAValidCookieName ); - } - - # Customized variables - foreach ( @{ $self->{customVars} } ) { - $expr .= "my \$$_ = '1';"; - } - - # Load variables - foreach ( keys %{ $config->{exportedVars} } ) { - - # Reserved words - if ( $_ eq 'groups' or $_ !~ /^\w+$/ ) { - $response->error( "\"$_\" " . &txt_isNotAValidAttributeName ); - $result = 0; - } - if ( $config->{exportedVars}->{$_} !~ /^\w+$/ ) { - $response->error( "\"$config->{exportedVars}->{$_}\" " - . &txt_isNotAValidLDAPAttributeName ); - $result = 0; - } - $expr .= "my \$$_ = '1';"; - } - - # Load and check macros - $self->msafe->reval($expr); - if ($@) { - $result = 0; - $response->error( &txt_unknownErrorInVars . " ($@)" ); - } - while ( my ( $k, $v ) = each( %{ $config->{macros} } ) ) { - - # Syntax - if ( $k eq 'groups' or $k !~ /^[a-zA-Z]\w*$/ ) { - $response->error( "\"$k\" " . &txt_isNotAValidMacroName ); - $result = 0; - } - - # "=" may be a fault ("==") - if ( $v =~ $assign ) { - $response->warning( - &txt_macro . " $k " . &txt_containsAnAssignment ); - } - - # Test macro values; - $expr .= "my \$$k = $v;"; - $self->msafe->reval($expr); - if ($@) { - $response->error( - &txt_macro . " $k : " . &txt_syntaxError . " : $@" ); - $result = 0; - } - } - - # TODO: check module name - # Check whatToTrace - unless ( $config->{whatToTrace} =~ /^\$?[a-zA-Z]\w*$/ ) { - $response->error(&txt_invalidWhatToTrace); - $result = 0; - } - - # Test groups - $expr .= 'my $groups;'; - while ( my ( $k, $v ) = each( %{ $config->{groups} } ) ) { - - # Name syntax - if ( $k !~ /^[\w-]+$/ ) { - $response->error( "\"$k\" " . &txt_isNotAValidGroupName ); - $result = 0; - } - - # "=" may be a fault (but not "==") - if ( $v =~ $assign ) { - $response->warning( - &txt_group . " $k " . &txt_containsAnAssignment ); - } - - # Test boolean expression - $self->msafe->reval( $expr . "\$groups = '$k' if($v);" ); - if ($@) { - $response->error( &txt_group . " $k " . &txt_syntaxError ); - $result = 0; - } - } - - # Test rules - while ( my ( $vh, $rules ) = each( %{ $config->{locationRules} } ) ) { - - # Virtual host name has to be a fully qualified name or an IP address (CDA) - unless ( $vh =~ -/^(?:(?=^.{1,254}$)(?:(?!\d+\.)[\w\-]{1,63}\.?)+(?:[a-zA-Z]{2,})|(?:\d{1,3}\.){3}\d{1,3})$/ - ) - { - $response->error( "\"$vh\" " . &txt_isNotAValidVirtualHostName ); - $result = 0; - } - while ( my ( $reg, $v ) = each( %{$rules} ) ) { - - # Test regular expressions - unless ( $reg eq 'default' ) { - $reg =~ s/#/\\#/g; - $self->msafe->reval( $expr . "my \$r = qr#$reg#;" ); - if ($@) { - $response->error( - &txt_rule . " $vh -> \"$reg\" : " . &txt_syntaxError ); - $result = 0; - } - } - - # Test boolean expressions - unless ( $v =~ /^(?:accept$|deny$|logout)/ ) { - - # "=" may be a fault (but not "==") - if ( $v =~ $assign ) { - $response->warning( &txt_rule - . " $vh -> \"$reg\" : " - . &txt_containsAnAssignment ); - } - - $self->msafe->reval( $expr . "my \$r=1 if($v);" ); - if ($@) { - $response->error( - &txt_rule . " $vh -> \"$reg\" : " . &txt_syntaxError ); - $result = 0; - } - } - } - } - - # Test exported headers - while ( my ( $vh, $headers ) = each( %{ $config->{exportedHeaders} } ) ) { - - # Virtual host name has to be a fully qualified name or an IP address (CDA) - unless ( $vh =~ -/^(?:(?=^.{1,254}$)(?:(?!\d+\.)[\w\-]{1,63}\.?)+(?:[a-zA-Z]{2,})|(?:\d{1,3}\.){3}\d{1,3})$/ - ) - { - $response->error( "\"$vh\" " . &txt_isNotAValidVirtualHostName ); - $result = 0; - } - while ( my ( $header, $v ) = each( %{$headers} ) ) { - - # Header name syntax - unless ( $header =~ /^[\w][-\w]*$/ ) { - $response->error( - "\"$header\" ($vh) " . &txt_isNotAValidHTTPHeaderName ); - $result = 0; - } - - # "=" may be a fault ("==") - if ( $v =~ $assign ) { - $response->warning( &txt_header - . " $vh -> $header " - . &txt_containsAnAssignment ); - } - - # Perl expression - $self->msafe->reval( $expr . "my \$r = $v;" ); - if ($@) { - $response->error( - &txt_header . " $vh -> $header " . &txt_syntaxError ); - $result = 0; - } - } - } - return $result; -} - -# Apply subroutines -# TODO: Credentials in APPLYSECTION - -## @method void print_apply() -# Call all Lemonldap::NG handlers declared in local ini file to -# ask them to reload Lemonldap::NG configuration. -sub print_apply { - my $self = shift; - - # Read APPLYSECTION from local ini file - my $applyconf = $self->config->getLocalConf( APPLYSECTION, "", 0 ); - - # Test if section was read - print $self->header( -type => "text/html; charset=utf8" ); - unless ( ref $applyconf ) { - print "

        " . &txt_canNotReadApplyConfFile . "

        "; - return; - } - - # Call all reload routines on configured handlers - print '

        ' . &txt_result . ' :

          '; - - # Initiate User Agent - my $ua = new LWP::UserAgent( requests_redirectable => [] ); - $ua->timeout(10); - - # Loop on defined handlers in APPLYSECTION - foreach my $host ( keys %$applyconf ) { - - # Request must be like method://vhost/uri/ - my $request = $applyconf->{$host}; - - my ( $method, $vhost, $uri ) = - ( $request =~ /^(https?):\/\/([^\/]+)(.*)$/ ); - - # If no vhost value, set - # - method to http - # - vhost to host - # - uri to request - unless ($vhost) { - $method = "http"; - $vhost = $host; - $uri = $request; - } - - # GET HTTP request on handlers - print "
        • $host ... "; - my $r = - HTTP::Request->new( 'GET', "$method://$host$uri", - HTTP::Headers->new( Host => $vhost ) ); - - # Display responses - my $response = $ua->request($r); - if ( $response->code != 200 ) { - print join( ' ', - &txt_error, ":", $response->code, $response->message, "
        • " ); - } - else { - print "OK"; - } - } - print "

        " . &txt_changesAppliedLater . "

        "; -} - -## @fn private string _dir() -# Return the path to the manager script -sub _dir { - my $d = $ENV{SCRIPT_FILENAME}; - $d =~ s/[^\/]*$//; - return $d; -} - -## @method Lemonldap::NG::Common::Conf config() -# Return Lemonldap::NG::Common::Conf object if exists else, build it. -# @return Lemonldap::NG::Common::Conf object -sub config { - my $self = shift; - return $self->{_config} if $self->{_config}; - $self->{_config} = - Lemonldap::NG::Common::Conf->new( $self->{configStorage} ); - unless ( $self->{_config} ) { - $self->abort( "Unable to start", - "Configuration not loaded\n" . $Lemonldap::NG::Common::Conf::msg ); - } - return $self->{_config}; -} - -# Those sub are loaded en demand. With &header_public, they are not loaded each -# time. -*css = *Lemonldap::NG::Manager::_HTML::css; -*javascript = *Lemonldap::NG::Manager::_HTML::javascript; -*main = *Lemonldap::NG::Manager::_HTML::main; -*start_html = *Lemonldap::NG::Manager::_HTML::start_html; - -__END__ - -=head1 NAME - -Lemonldap::NG::Manager - Perl extension for managing Lemonldap::NG Web-SSO -system. - -=head1 SYNOPSIS - - use Lemonldap::NG::Manager; - my $h=new Lemonldap::NG::Manager( - { - configStorage=>{ - type=>'File', - dirName=>"/tmp/", - }, - dhtmlXTreeImageLocation=> "/devel/img/", - # uncomment this only if lemonldap-ng-manager.js is not in the same - # directory than your script. - # jsFile => /path/to/lemonldap-ng-manager.js, - } - ) or die "Unable to start, see Apache logs"; - # Simple - $h->doall(); - -You can also peersonalize the HTML code instead of using C: - - print $self->header_public( $ENV{SCRIPT_FILENAME} ); - print $self->start_html ( # See CGI(3) for more about start_html - -style => "/location/to/my.css", - -title => "Example.com SSO configuration", - ); - # optional HTML code for the top of the page - print "main; - # optional HTML code for the footer of the page - print "end_html; - -=head1 DESCRIPTION - -Lemonldap::NG::Manager provides a web interface to manage Lemonldap::NG Web-SSO -system. - -=head2 SUBROUTINES - -=over - -=item * B (constructor): new instanciates the manager object. It takes the -following arguments: - -=over - -=item * B (required): a hash reference to the description of the -configuration database system. the key 'type' must be set. Example: - - configStorage => { - type => "DBI", - dbiChain => "DBI:mysql:database=session;host=1.2.3.4", - dbiUser => "lemonldap-ng", - dbiPassword => "pass", - } - -See L or -L to know which keys are required. - -=item * B (required): the location of the directory -containing dhtmlXTree images (provided in example/imgs). If this parameter -isn't correct, the tree will not appear and you will have sone error in Apache -error logs. - -=item * B (optional): the path to the file C. -It is required only if this file is not in the same directory than your script. - -=back - -=item * B: subroutine that provide headers and the full html code. Il -simply calls C, C, C
        and C in this -order. - -=item * B
        : print HTTP headers. See L for more. - -=item * B: print HTTP headers and manage the -C HTTP header. If it match to the age of the file passed -in first argument, it returns C end exit. Else, it -calls C
        with the other arguments. By default, all elements of the -manager use this mecanism except the configuration itself. - -=item * B: subroutine that print the HTML headers. you can add -parameters to it; example; - - print start_html(-title => 'My SSO configuration', - -author => 'fred@capricorn.org', - -target => '_blank', - -meta => {'keywords'=>'pharaoh secret mummy', - 'copyright' => 'copyright 1996 King Tut'}, - -style => {'src'=>'/styles/style1.css'}, - -BGCOLOR => 'blue'); - -See start_html description in L for more. Bee carefull with C<-style> -argument. You have to call it like the example above or simply like this: - -style=> '/styles/style1.css', -All other forms will not work. - -=item * B
        : il produce the main HTML code needed to build the -configuration interface. - -=item * B: close the HTML code by writing C<'E/bodyEE/htmlE'> - -=back - -Other subroutines manage the produce of CSS, Javascripts and of course the -configuration tree (called with AJAX). - -=head1 SEE ALSO - -L, L, L, -http://wiki.lemonldap.objectweb.org/xwiki/bin/view/NG/Presentation - -=head1 AUTHOR - -Xavier Guimard, Ex.guimard@free.frE - -=head1 BUG REPORT - -Use OW2 system to report bug or ask for features: -L - -=head1 DOWNLOAD - -Lemonldap::NG is available at -L - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2006-2007 by Xavier Guimard - -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.8 or, -at your option, any later version of Perl 5 you may have available. - -=cut - +1; diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Downloader.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Downloader.pm new file mode 100644 index 000000000..67cd5253d --- /dev/null +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Downloader.pm @@ -0,0 +1,276 @@ +package Lemonldap::NG::Manager::Downloader; + +use MIME::Base64; + +# TODO +use Data::Dumper; + +require Lemonldap::NG::Manager::_Struct; #inherits +require Lemonldap::NG::Manager::_i18n; #inherits + +sub node { + my ( $self, $node ) = @_; + my $res; + $node =~ s/^\///; + + #$self->lmLog( "Processing to node: $node", 'debug' ); + if ( my ( $tmp, $help, $js ) = $self->corresp($node) ) { + + # Menu node + if ( ref($tmp) ) { + + # Scan subnodes + foreach ( @{ $tmp->{_nodes} } ) { + my $flag = ( $_ =~ s/^(\w+):// ? $1 : '' ); + my ( $target, $_h, $_j ) = split /:\s*/; + $help ||= $_h; + + # subnode is an ajax subnode + if ( $flag =~ /^(c?)n$/ ) { + $res .= $self->ajaxNode( + ( $1 ? $target : "$node/$target" ), + "$target", + "node=$node/$target", + $tmp->{$target}->{_help} || $help, + $tmp->{$target}->{_js} + ); + } + + # subnode is a node + elsif ( ref( $tmp->{$target} ) ) { + $res .= $self->li( "$node/$target", "closed" ) + . $self->span( + "$node/$target", $target, '', + $tmp->{$target}->{_js}, + $tmp->{$target}->{_help} || $help + ) . "
          "; + $res .= $self->node("$node/$target"); + $res .= "
        "; + } + + # subnode points to a configuration node + elsif ( $flag =~ /^n?hash$/ ) { + $res .= $self->confNode( $node, "$flag:$target", $help, $_j ); + } + + else { + $res .= $self->node("$node/$target"); + } + } + } + + # node points to a configuration point + else { + $res .= $self->confNode( $node, $tmp, $help, $js ); + } + } + else { + $self->lmLog( "$node was not found in tree\n", 'error' ); + } + return $res; +} + +sub confNode { + my ( $self, $node, $target, $help, $js ) = @_; + my $res; + $self->lmLog( "Processing to configuration node: $target", 'debug' ); + $target =~ s/^\///; + if ( $target =~ /^(.+?):(?!\/)(.+?):(?!\/)(.+?)$/ ) { + ( $target, $help, $js ) = ( $1, $2, $3 ); + } + + # Hash datas downloaded later by ajax if needed + if ( $target =~ s/^nhash:// ) { + my $h = $self->keyToH( $target, $self->conf ); + return unless ($h); + foreach ( sort keys %$h ) { + if ( ref($h) ) { + $res .= $self->ajaxNode( "$target/$_", $_, "node=$node/$_\&key=$_", + $help, $js, undef, 1 ); + } + else { + $res .= $self->confNode( "$target/$_", "btext:$target/$_", $help, $js ); + } + } + } + + # Hash datas + elsif ( $target =~ s/^hash:// ) { + my $h = $self->keyToH( $target, $self->conf ); + return unless ($h); + foreach ( sort keys %$h ) { + if ( ref( $h->{$_} ) ) { + $res .= $self->confNode( "$target/$_", $help, $js ); + } + else { + $js ||= 'btext'; + my $id = "$target/$_"; + $id =~ s/=*$//; + + # Here, "notranslate" is set to true : hash values must not be + # translated + $res .= $self->li($id) + . $self->span( $id, "$_", $h->{$_}, $js, $help, 1 ) . ""; + } + } + } + else { + $target =~ s/^(\w+)://; + my $type = $1 || 'text'; + $js ||= $type; + my $text = $target; + $text =~ s/^.*\///; + my $h = $self->keyToH( $target, $self->conf ); + + $h = $self->keyToH( $target, $self->defaultConf ) unless ( defined $h ); + unless ( defined $h ) { + $self->lmLog( "$target does not exists in menu hash", "warn" ); + return; + } + if ( ref($h) ) { + $res .= $self->li( "$target", "closed" ) + . $self->span( "$target", $text, '', $js, $help ) . "
          "; + foreach ( sort keys %$h ) { + if ( ref( $h->{$_} ) ) { + $res .= $self->confNode( '', "btext:$target/$_", $help, $js ); + } + else { + my $id = "$target/$_"; + $res .= $self->li($id) + . $self->span( $id, $_, $h->{$_}, $js, $help ) . ""; + } + } + $res .= '
        '; + } + else { + my $id = "$target"; + $res .= $self->li($id) + . $self->span( $id, $text, $h, $js, $help ) . ""; + } + } + return $res; +} + +sub keyToH { + my ( $self, $key, $h ) = @_; + $key =~ s/^\///; + foreach ( split /\//, $key ) { + return () unless ( defined( $h->{$_} ) ); + $h = $h->{$_}; + } + return $h; +} + +sub corresp { + my ( $self, $key, $last ) = @_; + $key =~ s/^\///; + my $h = $self->struct(); + return $h unless ($key); + if ( my $k2 = $self->param('key') ) { + $h = $self->cstruct( $h, $k2 ); + } + my @tmp1 = split /\//, $key; + my $help; + my $js; + while ( $_ = shift(@tmp1) ) { + if ( ref($h) and defined $h->{$_} ) { + $help = $h->{_help} if ( $h->{_help} ); + $js = $h->{_js} if ( $h->{_js} ); + $h = $h->{$_}; + } + + # The wanted key does not exists + elsif ( ref($h) ) { + unless ($last) { + $self->param( 'key', $_ ); + return $self->corresp( $key, 1 ); + } + else { + $self->lmLog( "Key $key does not exist in configuration hash", + 'error' ); + return (); + } + } + + # If the key does not exist in manager tree, it must be defined in + # configuration hash + else { + return "$h/" . join( '/', $_, @tmp1 ); + } + } + if ( ref($h) ) { + $help = $h->{_help} if ( $h->{_help} ); + $js = $h->{_js} if ( $h->{_js} ); + } + return $h, $help, $js; +} + +sub conf { + my $self = shift; + return $self->{_conf} if ( $self->{_conf} ); + my $args = { cfgNum => $self->{cfgNum} }; + $args->{noCache} = 1 if ( $self->param('cfgNum') ); + $self->{_conf} = $self->confObj->getConf($args); + $self->abort( 'Unable to get configuration', + $Lemonldap::NG::Common::Conf::msg ) + unless ( $self->{_conf} ); + return $self->{_conf}; +} + +sub confObj { + my $self = shift; + return $self->{_confObj} if ( $self->{_confObj} ); + $self->{_confObj} = + Lemonldap::NG::Common::Conf->new( $self->{configStorage} ); + $self->abort( + 'Unable to access to configuration', + $Lemonldap::NG::Common::Conf::msg + ) unless ( $self->{_confObj} ); + $self->lmLog( $Lemonldap::NG::Common::Conf::msg, 'debug' ) + if ($Lemonldap::NG::Common::Conf::msg); + return $self->{_confObj}; +} + +## @method protected void ajaxnode(string id, string text, string param) +# Display tree node with Ajax functions inside for opening the node. +# @param $id HTML id of the element. +# @param $text text to display +# @param $param Parameters for the Ajax query +sub ajaxNode { + my ( $self, $id, $text, $param, $help, $js, $data, $noT ) = @_; + $param .= "&cfgNum=$self->{cfgNum}"; + return $self->li($id) + . $self->span( $id, $text, $data, undef, $help, $noT ) + . "
          " + . $self->li("sub_$id") + . ".{url:$ENV{SCRIPT_NAME}?$param" + . ( $js ? ",js:$js" : '' ) + . "}
        \n"; +} + +sub span { + my ( $self, $id, $text, $data, $js, $help, $noT ) = @_; + use Carp qw(cluck); + cluck('dd') if ( $js eq 'default' ); + my $tmp = $text; + $data = '' unless ( defined $data ); + $js ||= "none"; + $id = "li_" . encode_base64( $id, '' ); + $id =~ s/(=*)$/length($1)/e; + $data =~ s/"/'/g; + $tmp =~ s/"/'/g; + $text = join ' ', map { $self->translate($_) } split /\s+/, $text unless($noT); + $text = $self->escapeHTML($text); + return +"$text +"; +} + +sub li { + my ( $self, $id, $class ) = @_; + $id = "li_" . encode_base64( $id, '' ); + $id =~ s/(=*)$/length($1)/e; + return "
      • " : ">" ); +} + +1; diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Help.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Help.pm index ada4138d7..078c2f29c 100644 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Help.pm +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Help.pm @@ -6,7 +6,7 @@ package Lemonldap::NG::Manager::Help; use AutoLoader qw(AUTOLOAD); -our $VERSION = '0.4'; +our $VERSION = '0.5'; ## @fn void import(string lang) # Import help messages subroutines in Lemonldap::NG::Manager in the wanted language. diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Restricted.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Restricted.pm deleted file mode 100644 index e2a4ab72a..000000000 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Restricted.pm +++ /dev/null @@ -1,174 +0,0 @@ -## @file -# Restricted manager - -## @class -# Restrict Lemonldap::NG::Manager to build custom manager interfaces. -package Lemonldap::NG::Manager::Restricted; - -use strict; - -use Lemonldap::NG::Manager; -use Lemonldap::NG::Common::Conf::Constants; #inherits - -use base qw(Lemonldap::NG::Manager); -our $VERSION = '0.11'; - -## @cmethod Lemonldap::NG::Manager::Restricted new(hashref args) -# Constructor -# @param $args parameters for Lemonldap::NG::Manager::new() and for this -# module -sub new { - my ( $class, $args ) = @_; - my $self = $class->SUPER::new($args); - unless ( $self->{read} ) { - print STDERR - qq#Warning, "read" parameter is not set, nothing will be displayed\n#; - } - return $self; -} - -## @method hashref buildTree() -# Overload Lemonldap::NG::Manager::buildTree() to hide unwanted parts -# @return hash reference to a tree for the javascript library -sub buildTree { - my $self = shift; - my $tree = $self->SUPER::buildTree(); - - # Display only VirtualHosts - delete $tree->{item}->{item}->{groups}; - delete $tree->{item}->{item}->{generalParameters}; - my $vh = $tree->{item}->{item}->{virtualHosts}->{item}; - - # Display only authorized virtual hosts - foreach my $k ( keys %$vh ) { - unless ( grep { $_ eq $k } @{ $self->{read} } ) { - delete $vh->{$k}; - next; - } - - # and suppress write possibilities - unless ( grep { $_ eq $k } @{ $self->{write} } ) { - foreach ( @{ $vh->{$k}->{userdata} } ) { - $_->{content} = 'none' if ( $_->{name} eq 'modif' ); - } - foreach my $type ( keys( %{ $vh->{$k}->{item} } ) ) { - foreach my $i ( keys( %{ $vh->{$k}->{item}->{$type}->{item} } ) ) { - foreach ( @{ $vh->{$k}->{item}->{$type}->{item}->{$i}->{userdata} } ) { - $_->{content} = 'ro' if ( $_->{name} eq 'modif' ); - } - } - } - } - } - return $tree; -} - -## @method boolean upload() -# Overload Lemonldap::NG::Manager::upload() to restrict upload datas to the -# authorized nodes. -sub upload { - my $self = shift; - return UPLOAD_DENIED unless ( @{ $self->{write} } ); - - # Convert new config - my $newConfig = $self->tree2conf(@_); - - # Load current config - my $config = $self->config->getConf(); - - # Compare new and old config - return CONFIG_WAS_CHANGED - unless ( $config->{cfgNum} == $newConfig->{cfgNum} ); - - # Merge config - foreach my $vh ( @{ $self->{write} } ) { - if ( $newConfig->{locationRules}->{$vh} ) { - $config->{locationRules}->{$vh} = - $newConfig->{locationRules}->{$vh}; - delete $newConfig->{locationRules}->{$vh}; - } - if ( $newConfig->{exportedHeaders}->{$vh} ) { - $config->{exportedHeaders}->{$vh} = - $newConfig->{exportedHeaders}->{$vh}; - delete $newConfig->{exportedHeaders}->{$vh}; - } - } - - # and save config - return $self->config->saveConf($config); -} - -1; -__END__ - -=head1 NAME - -Lemonldap::NG::Manager::Restricted - Restricted version of -Lemonldap::NG::Manager to show only parts of protected virtual hosts. - -=head1 SYNOPSIS - - use Lemonldap::NG::Manager::Restrited; - my $h=new Lemonldap::NG::Manager::Restricted ( - { - configStorage=>{ - type=>'File', - dirName=>"/tmp/", - }, - dhtmlXTreeImageLocation=> "/devel/img/", - # uncomment this only if lemonldap-ng-manager.js is not in the same - # directory than your script. - # jsFile => /path/to/lemonldap-ng-manager.js, - read => [ 'test.example.com', 'test2.example.com' ], - write => [ 'test.example.com' ], - } - ) or die "Unable to start, see Apache logs"; - $h->doall(); - -=head1 DESCRIPTION - -This module can be used to give access to a part of the Lemonldap::NG Web-SSO -configuration. You can use it to simply show or give write access to some of -the protected vortual hosts. - -=head2 PARAMETERS - -Lemonldap::NG::Manager::Restricted works like L but -uses 2 new parameters in the constructor: - -=over - -=item * read : an array reference to the list of authorized virtual host to -display, - -=item * write : an array reference to the list of virtual hosts that can been -updated. - -=back - -=head1 SEE ALSO - -L, -http://wiki.lemonldap.objectweb.org/xwiki/bin/view/NG/Presentation - -=head1 AUTHOR - -Xavier Guimard, Ex.guimard@free.frE - -=head1 BUG REPORT - -Use OW2 system to report bug or ask for features: -L - -=head1 DOWNLOAD - -Lemonldap::NG is available at -L - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2007 by Xavier Guimard - -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.8 or, -at your option, any later version of Perl 5 you may have available. diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/SOAPServer.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/SOAPServer.pm deleted file mode 100644 index bcaf7a1e9..000000000 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/SOAPServer.pm +++ /dev/null @@ -1,219 +0,0 @@ -package Lemonldap::NG::Manager::SOAPServer; - -use strict; - -our $VERSION = '0.31'; - -die 'This module is now obsolete. You have to use the portal as "proxy". -See http://wiki.lemonldap.ow2.org/xwiki/bin/view/NG/DocSOAP'; - -use SOAP::Transport::HTTP; -use Lemonldap::NG::Common::Conf; #link protected config Configuration hash reference -use UNIVERSAL qw(isa); - -our $VERSION = "0.3"; - -# Initialization - -sub new { - my ( $class, @args ) = @_; - my $self; - if ( ref( $args[0] ) ) { - $self = $args[0]; - } - else { - %$self = @args; - } - bless $self, $class; - # Arguments verification - if( $self->{type} eq 'sessions' ) { - unless( $self->{realSessionStorage} ) { - die qq/The "realSessionStorage" parameter is required/; - return (); - } - eval "use " . $self->{realSessionStorage}; - die $@ if($@); - } - else { - unless ( $self->{configStorage} ) { - die qq/The "configStorage" parameter is required\n/; - return (); - } - $self->{config} = Lemonldap::NG::Common::Conf->new( $self->{configStorage} ); - die "Configuration not loaded" unless $self->{config}; - } - return $self; -} - -sub init { - my $self = shift; - if( $self->{type} eq 'sessions' ) { - $Lemonldap::NG::Manager::SOAPService::Sessions::authorizedFunctions = - $self->{AuthorizedFunctions} || 'get'; - $Lemonldap::NG::Manager::SOAPService::Sessions::config = $self; - } - else { - $Lemonldap::NG::Manager::SOAPService::Config::config = $self->{config}; - } -} - -# Main process - -*process = \&start; - -sub start { - my $self; - if ( ref( $_[0] ) and isa( $_[0], __PACKAGE__ ) ) { - $self = shift; - } - else { - $self = shift->new(@_); - } - $self->init(); - my $service = ($self->{type} eq 'sessions') - ? 'Lemonldap::NG::Manager::SOAPService::Sessions' - : 'Lemonldap::NG::Manager::SOAPService::Config'; - SOAP::Transport::HTTP::CGI->dispatch_to($service)->handle; -} - -# Description of SOAP service -package Lemonldap::NG::Manager::SOAPService::Config; - -our $config; - -sub available { - shift; - my @t = $config->available(@_); - return \@t; -} - -sub lastCfg { - shift; - return $config->lastCfg(@_); -} - -sub store { - shift; - return $config->store(@_); -} - -sub load { - shift; - return $config->load(@_); -} - -package Lemonldap::NG::Manager::SOAPService::Sessions; - -our $config; -our $authorizedFunctions = 'get'; - -sub newsession { - unless( $authorizedFunctions =~ /\bnew\b/ ) { - print STDERR "Lemonldap::NG::Manager::SOAPService: 'new' is not authorized. Set 'AuthorizedFunctions' parameter if needed.\n"; - return 0; - } - my( $class, $args ) = @_; - $args ||= {}; - my %h; - eval { - tie %h, $config->{realSessionStorage}, undef, $config->{realSessionStorageOptions}; - }; - if ($@) { - print STDERR "Lemonldap::NG::Manager::SOAPService: $@\n"; - return 0; - } - $h{$_} = $args->{$_} foreach ( keys %{ $args } ); - $h{_utime} = time(); - $args->{$_} = $h{$_} foreach ( keys %h ); - untie %h; - return $args; -} - -sub get { - return 0 unless( $authorizedFunctions =~ /\bget\b/ ); - my( $class, $id ) = @_; - my %h; - eval { - tie %h, $config->{realSessionStorage}, $id, $config->{realSessionStorageOptions}; - }; - if ($@) { - print STDERR "Lemonldap::NG::Manager::SOAPService: $@\n"; - return 0; - } - my $args; - $args->{$_} = $h{$_} foreach ( keys %h ); - untie %h; - return $args; -} - -sub set { - return 0 unless( $authorizedFunctions =~ /\bset\b/ ); - my( $class, $id, $args ) = @_; - my %h; - eval { - tie %h, $config->{realSessionStorage}, $id, $config->{realSessionStorageOptions}; - }; - if ($@) { - print STDERR "Lemonldap::NG::Manager::SOAPService: $@\n"; - return 0; - } - $h{$_} = $args->{$_} foreach ( keys %{ $args } ); - untie %h; - return $args; -} - -sub delete { - return 0 unless( $authorizedFunctions =~ /\bdelete\b/ ); - my( $class, $id ) = @_; - my %h; - eval { - tie %h, $config->{realSessionStorage}, $id, $config->{realSessionStorageOptions}; - }; - if ($@) { - print STDERR "Lemonldap::NG::Manager::SOAPService: $@\n"; - return 0; - } - tied(%h)->delete; -} - -1; -__END__ - -=head1 NAME - -Lemonldap::NG::Manager::SOAPServer - Obsolete : now SOAP services are included -in the Lemonldap::NG portal. - -=head1 SYNOPSIS - -=head1 DESCRIPTION - -This module is obsolete. Now, use the portal. - -=head1 SEE ALSO - -L, - -=head1 AUTHOR - -Xavier Guimard, Ex.guimard@free.frE - -=head1 BUG REPORT - -Use OW2 system to report bug or ask for features: -L - -=head1 DOWNLOAD - -Lemonldap::NG is available at -L - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2007 by Xavier Guimard - -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.8 or, -at your option, any later version of Perl 5 you may have available. - -=cut diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Uploader.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Uploader.pm new file mode 100644 index 000000000..eee5dc6a9 --- /dev/null +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Uploader.pm @@ -0,0 +1,260 @@ +package Lemonldap::NG::Manager::Uploader; + +use strict; +use XML::LibXML; +use XML::LibXSLT; +use MIME::Base64; + +# TODO +use Data::Dumper; +use Lemonldap::NG::Common::Safelib; #link protected safe Safe object +use Lemonldap::NG::Manager::Downloader; +use Lemonldap::NG::Manager::_Struct; + +our $VERSION = '0.1'; +our ( $stylesheet, $parser ); + +sub confUpload { + my ( $self, $rdata ) = @_; + $$rdata =~ s///g; + $$rdata =~ s/
      • //g; + + # Apply XSLT stylesheet to returned datas + my $result = + $self->stylesheet->transform( + $self->parser->parse_string( '' . $$rdata . '' ) ) + ->documentElement(); + + # Get configuration number + unless ( $self->{cfgNum} = + $result->getChildrenByTagName('conf')->[0]->getAttribute('value') ) + { + die "No configuration number found"; + } + my $newConf = { cfgNum => $self->{cfgNum} }; + + # Loading returned parameters + my $res; + foreach ( @{ $result->getChildrenByTagName('element') } ) { + my ( $id, $name, $value ) = ( + $_->getAttribute('id'), + $_->getAttribute('name'), + $_->getAttribute('value') + ); + my $NK = 0; + $id =~ + s/^text_(NewID_)?li_(\w+)(\d)(?:_\d+)?$/decode_base64($2.'='x $3)/e; + $NK = 1 if ($1); + $id =~ s/^\///; + print STDERR "################ $id\n" if ($NK); + $id =~ s/(?:\/[^\/]*)?$/\/$name/ if ($NK); + print STDERR "################ $id\n" if ($NK); + next if ( $id =~ /^(generalParameters|virtualHosts)/ ); + my ( $confKey, $test ) = $self->getConfTests($id); + my ( $res, $m ); + + if ( !defined($test) ) { + $res->{errors}->{$name} = + "Key $name: Lemonldap::NG::Manager error, see Apache's logs"; + $self->lmLog( + "Unknown configuration key $id (name: $name, value: $value)", + 'error' ); + next; + } + + if ( $test->{'*'} and $id =~ /\// ) { $test = $test->{'*'} } + + # Tests (no test for hash root nodes) + unless ( $test->{keyTest} and ( $id !~ /\// or $test->{'*'} ) ) { + if ( $test->{keyTest} ) { + ( $res, $m ) = $self->applyTest( $test->{keyTest}, $name ); + unless ($res) { + $res->{errors}->{$name} = "Value \"$name\" rejected: " + . ( $m || $test->{keyMsgFail} ); + next; + } + } + if ( $test->{test} ) { + ( $res, $m ) = $self->applyTest( $test->{test}, $value ); + unless ($res) { + $res->{errors}->{$name} = + "Value of key \"$name\" rejected: " + . ( $m || $test->{msgFail} ); + next; + } + } + if ( $test->{warnKeyTest} ) { + ( $res, $m ) = $self->applyTest( $test->{warnKeyTest}, $name ); + unless ($res) { + $res->{warnings}->{$name} = "Warning for value \"$name\": " + . ( $m || $test->{keyMsgWarn} ); + } + } + if ( $test->{warnTest} ) { + ( $res, $m ) = $self->applyTest( $test->{warnTest}, $value ); + unless ($res) { + $res->{warnings}->{$name} = + "Warning for the value of key \"$name\": " + . ( $m || $test->{keyMsgWarn} ); + } + } + } + print STDERR + "$confKey, $test->{keyTest}, $id, $test->{'*'}, $name => $value\n" + if ($NK); + print STDERR ( ( $id !~ /\// or $test->{'*'} ) ? "a\n" : "b\n" ) + if ($NK); + $self->setKeyToH( $newConf, $confKey, + $test->{keyTest} + ? ( ( $id !~ /\// or $test->{'*'} ) ? {} : ( $name => $value ) ) + : $value ); + } + + # Loading unchanged parameters (ajax nodes not open) + foreach ( @{ $result->getChildrenByTagName('ignore') } ) { + my $node = $_->getAttribute('value'); + $node =~ s/^.*node=(.*?)(?:&.*)?\}$/$1/; + foreach my $k ( $self->findAllConfKeys( $self->corresp($node) ) ) { + my $v = $self->keyToH( $k, $self->conf ); + $v = $self->keyToH( $k, $self->defaultConf ) unless ( defined $v ); + if ( defined $v ) { + $self->setKeyToH( $newConf, $k, $v ); + } + else { + $self->lmLog( "No default value found for $k", 'warn' ); + } + } + print LOG "Ignore $node\n"; + } + + #print STDERR Dumper( $newConf, \%errors, \%warnings ); + close LOG; + my $buf = '{'; + my $i=0; + while ( my ( $type, $h ) = each %$res ) { + $buf .= ',' if($i); + $buf .= "$type:{"; + $buf .= join( ',', map { "$_:$h->{$_}" } keys %$h ); + $buf .= '}'; + $i++; + } + $buf .= '}'; + print $self->header( -type => 'text/javascript', -Content_Length => length($buf) ).$buf; + $self->quit(); +} + +sub applyTest { + my ( $self, $test, $value ) = @_; + my ( $res, $msg ); + if ( ref($test) eq 'CODE' ) { + ( $res, $msg ) = &$test($value); + } + else { + $res = ( $value =~ $test ? 1 : 0 ); + } + return ( $res, $msg ); +} + +sub getConfTests { + my ( $self, $id ) = @_; + my ( $confKey, $tmp ) = ( $id =~ /^(.*?)(?:\/(.*))?$/ ); + my $h = $self->testStruct()->{$confKey}; + if ( $h and $h->{'*'} and my ( $k, $v ) = ( $tmp =~ /^(.*?)\/(.*)$/ ) ) { + return ( "$confKey/$k", $h->{'*'} ); + } + return ( $confKey, $h ); +} + +sub findAllConfKeys { + my ( $self, $h ) = @_; + my @res = (); + foreach my $n ( @{ $h->{_nodes} } ) { + $n =~ s/^.*?:(.*?)(?:\:.*)?$/$1/; + if ( ref( $h->{$n} ) ) { + push @res, $self->findAllConfKeys( $h->{$n} ); + } + else { + my $m = $h->{$n} || $n; + push @res, ( $m =~ /^(?:.*?:)?(.*?)(?:\:.*)?$/ ? $1 : () ); + } + } + return @res; +} + +sub setKeyToH { + my $value = pop; + my ( $self, $h, $key, $k2 ) = @_; + my $tmp = $h; + $key =~ s/^\///; + while (1) { + if ( $key =~ /\// ) { + my $k = $`; + $key = $'; + $tmp = $tmp->{$k} ||= {}; + } + else { + if ($k2) { + $tmp->{$key} = {} unless ( ref( $tmp->{$key} ) ); + $tmp->{$key}->{$k2} = $value; + } + else { + $tmp->{$key} = $value; + } + last; + } + } +} + +sub parser { + my $self = shift; + return $parser if ($parser); + $parser = XML::LibXML->new(); +} + +sub stylesheet { + my $self = shift; + + return $stylesheet if ($stylesheet); + my $xslt = XML::LibXSLT->new(); + my $style_doc = $self->parser->parse_string( join( '', ) ); + close DATA; + $stylesheet = $xslt->parse_stylesheet($style_doc); +} + +1; +__DATA__ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_HTML.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_HTML.pm deleted file mode 100644 index 11a858a8c..000000000 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_HTML.pm +++ /dev/null @@ -1,502 +0,0 @@ -## @file -# Display HTML parts of Lemonldap::NG::Manager - -## @class -# Display HTML parts of Lemonldap::NG::Manager -package Lemonldap::NG::Manager::_HTML; - -# This package contains all subroutines that are provided after a -# 'header_public' call. So those functions are called only if the browser -# comes for the first time. - -use AutoLoader qw(AUTOLOAD); -require Lemonldap::NG::Manager::_i18n; #inherits -use Lemonldap::NG::Common::Conf::Constants; #inherits - -our $VERSION = '0.32'; - -# TODO: Delete buttons in headers and rules if 'read-only' - -# TODO: Display errors in saveConf -1; -__END__ - -=pod -=cut - -## @method void css() -# Display Lemonldap::NG::Manager CSS file. -sub css { - print <{language} || $ENV{HTTP_ACCEPT_LANGUAGE} ) - unless ( __PACKAGE__->can('txt_newVirtualHost') ); - my %text; - foreach ( - qw(newVirtualHost newMacro newGroup newVar newGSOpt saveConf - deleteNode locationRules unableToSave confSaved saveFailure - newRule newHeader httpHeaders waitingResult unknownError - configurationWasChanged configLoaded warningConfNotApplied - applyConf prevConf lastConf nextConf deleteVirtualHost - areYouSure syntaxError deleteConf confirmDeleteConf - invalidVirtualHostName) - ) - { - $text{$_} = &{"txt_$_"}; - $text{$_} =~ s/'/\\'/g; - } - print qq# -function loadConf(n) { - document.body.style.cursor='wait'; - document.getElementById('treeBox').innerHTML=''; - tree=new dhtmlXTreeObject(document.getElementById('treeBox'),"100%","100%",0); - tree.setImagePath("$self->{dhtmlXTreeImageLocation}"); - tree.setXMLAutoLoading("$ENV{SCRIPT_NAME}?lmQuery=conf"); - tree.loadXML("$ENV{SCRIPT_NAME}?lmQuery=conf&cfgNum="+n); - tree.setOnClickHandler(onNodeSelect); - tree.selectItem('virtualHosts',true,false); - document.getElementById('help').innerHTML='

        $text{configLoaded}

        '; - window.setTimeout("document.body.style.cursor='auto'",1000); -} - -var s3,s32; - -window.onload=function(){ - var w=X.clientWidth()-12; - var h=X.clientHeight()-12; - //var h=window.outerHeight; - s32=new xSplitter('idSplitter32',0,0,0,0,false,4,h/2,h/8,true,0); - s3=new xSplitter('idSplitter3',0,0,w,h,true,4,w/4,w/8,true,4,null,s32); - X.addEventListener(window,'resize',win_onresize,false); - document.getElementById('help').innerHTML='

        $text{waitingResult}

        '; - loadConf(0); -}; - -function win_onresize(){ - var cw=X.clientWidth(); - var w=X.clientWidth()-12; - var h=X.clientHeight()-12; - s3.paint(w,h,w/4,w/5); -} - -var indice=1; - -function onNodeSelect(nodeId) { - var k,v; - if(tree.getUserData(nodeId,"modif")) { - switch(tree.getUserData(nodeId,"modif")) { - case 'text': - k='valeur'; - v=''; - break; - case 'both': - k=''; - v=''; - break; - case 'value': - k=tree.getItemText(nodeId); - v=''; - break; - case 'ro': - k=tree.getItemText(nodeId); - v='

        '+tree.getUserData(nodeId,'value')+'

        '; - break; - case 'none': - k=tree.getItemText(nodeId); - v='

         

        '; - break; - } - document.getElementById('formulaire').style.display='block'; - document.getElementById('name').innerHTML = k; - document.getElementById('value').innerHTML = v; - } - else { - document.getElementById('formulaire').style.display='none'; - } - var but=''; - if(nodeIs(nodeId,"virtualHosts") && tree.getUserData(nodeId,"modif") != "none" && tree.getUserData(nodeId,"modif") != 'ro' ){ - but+=button('$text{newVirtualHost}','newVirtualHost',nodeId); - if(nodeIs(nodeId,"virtualHost")){ - but+=button('$text{deleteVirtualHost}','deleteVirtualHost',nodeId); - but+=button('$text{newRule}','newRule',nodeId); - but+=button('$text{newHeader}','newHeader',nodeId); - } - help('virtualHosts'); - } - else if(nodeIs(nodeId,"macros")){ - but+=button('$text{newMacro}','newMacro',nodeId); - help('macros'); - } - else if(nodeIs(nodeId,"groups")){ - but+=button('$text{newGroup}','newGroup',nodeId); - help('groups'); - } - else if(nodeIs(nodeId,"whatToTrace")){ - help('whatToTrace'); - } - else if(nodeIs(nodeId,"generalParameters")){ - if(nodeIs(nodeId,"ldapParameters")){ - help('ldap'); - } - else if(nodeIs(nodeId,"exportedVars")){ - but+=button('$text{newVar}','newVar',nodeId); - help('vars'); - } - else if(nodeIs(nodeId,'sessionStorage')){ - if(nodeIs(nodeId,"globalStorageOptions")){ - but+=button('$text{newGSOpt}','newGSOpt',nodeId); - } - help('storage'); - } - else if(nodeIs(nodeId,'authParams')){ - help('authParams'); - } - else if(nodeIs(nodeId,'cookieName')){ - help('cookieName'); - } - else if(nodeIs(nodeId,'timeout')){ - help('timeout'); - } - else if(nodeIs(nodeId,'domain')){ - help('domain'); - } - } - if(tree.getUserData(nodeId,"modif")=='both') but+=button('$text{deleteNode}','deleteNode',nodeId); - but+=button('$text{saveConf}','saveConf',nodeId); - if(nodeId == 'root') but+=button('$text{prevConf}','prevConf',nodeId) - +button('$text{nextConf}','nextConf',nodeId) - +button('$text{lastConf}','lastConf',nodeId) - +button('$text{deleteConf}','deleteConf',nodeId); - #; - print "but+=button('$text{applyConf}','applyConf',nodeId);"; - print qq# - document.getElementById('buttons').innerHTML = but; -} - -function nodeIs(id,type) { - if(id==type)return 1; - if(id=="root")return 0; - var next=tree.getParentId(id); - if(type=="virtualHost" && next=="virtualHosts")return 1; - return nodeIs(next,type); -} - -function vhostId(id){ - var next=tree.getParentId(id); - if(next=="virtualHosts") return id; - return vhostId(next); -} - -function button(text,func,nodeId){ - return '   '; -} - -function insertNewChild(a,c) { - indice++; - tree.insertNewChild(a,'js_'+indice,c); - tree.setItemColor('js_'+indice,"\#000000","\#0000FF"); - return 'js_'+indice; -} - -function newVirtualHost() { - var rep=prompt("$text{newVirtualHost}"); - if(rep) { - if(!rep.match(/^\\w[\\w\\.\\-]*\\w\$/)){ - alert('$text{invalidVirtualHostName}'); - return 0; - } - var tmp=insertNewChild('virtualHosts',rep) - tree.setUserData(tmp,'modif','text'); - //var tmp_eh=insertNewChild(tmp,'$text{httpHeaders}'); - var tmp_eh=tmp+'_exportedHeaders'; - tree.insertNewChild(tmp,tmp_eh,'$text{httpHeaders}'); - tree.setItemColor(tmp_eh,"\#000000","\#0000FF"); - var tmp_eh1=insertNewChild(tmp_eh,'Auth-User'); - tree.setUserData(tmp_eh1,'modif','both'); - tree.setUserData(tmp_eh1,'value','\$uid'); - var tmp_lr=tmp+'_locationRules'; - tree.insertNewChild(tmp,tmp_lr,'$text{locationRules}'); - tree.setItemColor(tmp_lr,"\#000000","\#0000FF"); - var tmp_lr1=insertNewChild(tmp_lr,'default'); - tree.setUserData(tmp_lr1,'modif','value'); - tree.setUserData(tmp_lr1,'value','deny'); - } -} - -function deleteVirtualHost(id) { - var vh=vhostId(id); - if(confirm('$text{areYouSure}')) tree.deleteItem(vh); -} - -function newValue(id,text,type,value){ - var tmp=insertNewChild(id,text); - tree.setUserData(tmp,'modif',type); - tree.setUserData(tmp,'value',value); - tree.selectItem(tmp,true); -} - -function newRule(id){ - var lr=tree.getItemIdByIndex(vhostId(id),1); - newValue(lr,'^/New/rule','both','deny'); -} - -function newHeader(id){ - var eh=tree.getItemIdByIndex(vhostId(id),0); - newValue(eh,'New-Header','both','\$uid'); -} - -function newGroup(id){ - newValue('groups','NewGroup','both',''); -} - -function newMacro(id){ - newValue('macros','NewMacro','both',''); -} - -function newVar(id){ - newValue('exportedVars','NewVar','both','uid'); -} - -function newGSOpt(id){ - newValue('globalStorageOptions','NewOpt','both',''); -} - -function deleteNode(id){ - tree.deleteItem(id); -} - -var xhr_object = null; - -if(window.XMLHttpRequest) // Firefox - xhr_object = new XMLHttpRequest(); -else if(window.ActiveXObject) // Internet Explorer - xhr_object = new ActiveXObject("Microsoft.XMLHTTP"); -else { // XMLHttpRequest non support par le navigateur - alert('$text{unableToSave}'); -} - -function help(s){ - xhr_object.open("GET", "$ENV{SCRIPT_NAME}?lmQuery=help&help="+s, true); - xhr_object.onreadystatechange = function() { - if(xhr_object.readyState == 4) document.getElementById('help').innerHTML=xhr_object.responseText; - } - xhr_object.send(null); -} - -function saveConf(){ - var h=tree2txt('root'); - xhr_object.open("POST", "$ENV{SCRIPT_NAME}?lmQuery=upload",true); - xhr_object.setRequestHeader("Content-type", "text/xml"); - xhr_object.setRequestHeader("Content-length", h.length); - xhr_object.onreadystatechange = function() { - if(xhr_object.readyState == 4){ - window.setTimeout(xhr_object.responseText,0); - } - else document.getElementById('help').innerHTML='

        $text{waitingResult}

        '; - } - xhr_object.send(h); -} - -function tree2txt(id){ - var s=tree.getSubItems(id); - var c; - id = id.replace(/^[0-9]*_/,''); - var r='<'+id+">"+ec(tree.getItemText(id))+"\\n"; - if((!s) || s==''){ - r+= ''+ec(tree.getUserData(id,'value'))+"\\n"; - } - else { - c=s.split(','); - for(var i=0;i\\n"; - return r; -} - -function applyConf(){ - xhr_object.open('GET', "$ENV{SCRIPT_NAME}?lmQuery=apply",true); - xhr_object.onreadystatechange = function() { - if(xhr_object.readyState == 4) document.getElementById('help').innerHTML=xhr_object.responseText; - } - xhr_object.send(null); -} - -var previous = 0; -function prevConf(){ - previous--; - loadConf(previous); -} - -function nextConf(){ - if(previous<0){ - previous++; - loadConf(previous); - } -} - -function lastConf(){ - previous=0; - loadConf(0); -} - -function deleteConf(){ - if(!(confirm('$text{confirmDeleteConf}'))) return 0; - previous=0; - xhr_object.open('GET', "$ENV{SCRIPT_NAME}?lmQuery=delete&cfgNum="+previous,true); - xhr_object.onreadystatechange = function() { - if(xhr_object.readyState == 4){ - document.getElementById('help').innerHTML=xhr_object.responseText; - loadConf(0); - } - } - xhr_object.send(null); -} - -function ec(s){ - if((!s) || s=='') return s; - return s.replace(/>/g,'>').replace(/ [ $args{'-style'} ] } - if ( $args{'-style'} and !ref( $args{'-style'} ) ); - unshift @{ $args{'-style'}->{'-src'} }, "$ENV{SCRIPT_NAME}?lmQuery=css"; - $args{'-title'} ||= 'Lemonldap::NG Configuration'; - $args{'-encoding'} ||= 'utf8'; - $self->CGI::start_html(%args); -} - -## @method void main() -# Display main HTML code. -sub main { - my $self = shift; - Lemonldap::NG::Manager::_i18n::import( $self->{language} || $ENV{HTTP_ACCEPT_LANGUAGE} ) - unless ( __PACKAGE__->can('txt_field') ); - my %text; - foreach (qw(field value)) { - $text{$_} = &{"txt_$_"}; - $text{$_} =~ s/'/\\'/g; - } - - # Lemonldap::Manager javascripts; - print -qq#\n#; - print -qq#\n#; - - # HTML code - print < -
        -
        -
        -
        -
        - -
        -
        -
        -
        -
    • - - - - - - - - -
      $text{field}$text{value}
      -
       
      -
      -
       
      -
      - - - - -
      -
      -
      - -
      -   -
      - - - -
      -   -
      - - - -EOT -} - diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Response.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Response.pm deleted file mode 100644 index a98d7c185..000000000 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Response.pm +++ /dev/null @@ -1,94 +0,0 @@ -## @file -# Prepare Lemonldap::NG::Manager response for new configurations - -## @class -# Prepare Lemonldap::NG::Manager response for new configurations -package Lemonldap::NG::Manager::_Response; - -our $VERSION = '0.11'; - -## @cmethod Lemonldap::NG::Manager::_Response new() -# Constructor -# @return Lemonldap::NG::Manager::_Response object -sub new { - my $class = shift; - return bless { errors => [], warnings => [] }, $class; -} - -## @method void print(array p) -# Join all stings in @p into $self->{txt} -sub print { - my $self = shift; - $self->{txt} .= $_ foreach(@_); -} - -## @method void message(string title,string txt) -# Build HTML part to display. -# @param $title title of the message -# @param $txt text of the message -sub message { - my $self = shift; - my ($title, $txt) = @_; - $self->{txt} = "

      $title

      $txt

      " . $self->{txt}; -} - -## @method private void warning(array warnings) -# Store warnings in $self->{warnings} -# @param @warnings array of string -sub warning { - my $self = shift; - push @{$self->{warnings}}, @_; -} - -## @method private void error(array errors) -# Store warnings in $self->{errors} -# @param @errors array of string -sub error { - my $self = shift; - return scalar @{$self->{errors}} unless(@_); - push @{$self->{errors}}, @_; -} - -## @method protected void setConfiguration(hashref configuration) -# Store $configuration in $self->{configuration} -# @param $configuration Lemonldap::NG configuration -sub setConfiguration { - my $self = shift; - $self->{configuration} = shift; -} - -## @method void send() -# Display upload response. -sub send { - my $self = shift; - my $buf; - $buf = "tree.setItemText('root','Configuration $self->{configuration}');" - if($self->{configuration}); - if ( $self->error ) { - $self->{txt} .= "

      Errors

        "; - foreach ( @{$self->{errors}} ) { - s//>/g; - $self->{txt} .= "
      • $_
      • " - } - $self->{txt} .= "
      "; - } - if ( $self->warning ) { - $self->{txt} .= "

      Warnings

        "; - foreach ( @{$self->{warnings}} ) { - s//>/g; - $self->{txt} .= "
      • $_
      • " - } - $self->{txt} .= "
      "; - } - if($self->{txt}) { - $self->{txt} =~ s/'/\\'/g; - $self->{txt} =~ s/[\r\n]//g; - $buf .= "document.getElementById('help').innerHTML='$self->{txt}';"; - } - print $buf; -} - -1; -__END__ diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm new file mode 100644 index 000000000..8463e1e3b --- /dev/null +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_Struct.pm @@ -0,0 +1,255 @@ +package Lemonldap::NG::Manager::_Struct; + +use strict; +our $VERSION = '0.1'; + +sub cstruct { + shift; + my ( $h, $k ) = @_; + %$h = ( + %$h, + virtualHosts => { + $k => { + _nodes => [qw(rules:rules:rules headers)], + rules => { + _nodes => ["hash:/locationRules/$k:rules:rules"], + _js => 'rulesRoot' + }, + headers => + { _nodes => ["hash:/exportedHeaders/$k"], _js => 'hashRoot' }, + } + } + ); + return $h; +} + +sub struct { + return { + _nodes => [qw(n:generalParameters n:groups n:virtualHosts)], + _help => 'default', + generalParameters => { + _nodes => [ + qw(n:authParams cookieParams cn:exportedVars cn:macros sessionParams ldapParams) + ], + _help => 'default', + authParams => { + _nodes => [qw(portal authentication userDB whatToTrace)], + _help => 'authParams', + authentication => 'text:/authentication', + portal => 'text:/portal', + userDB => 'text:/userDB', + whatToTrace => 'text:/whatToTrace:whatToTrace:text', + }, + cookieParams => { + _nodes => [qw(cookieName domain securedCookie)], + cookieName => 'text:/cookieName:cookieName:text', + domain => 'text:/domain:domain:text', + securedCookie => + 'int:/securedCookie:securedCookie:securedCookieValues', + }, + exportedVars => { + _nodes => ['hash:/exportedVars:vars:btext'], + _js => 'hashRoot' + }, + macros => + { _nodes => ['hash:/macros:macros:btext'], _js => 'hashRoot' }, + sessionParams => { + _nodes => [qw(sessionStorage timeout)], + _help => 'storage', + sessionStorage => { + _nodes => [qw(globalStorage globalStorageOptions)], + globalStorage => 'text:/globalStorage', + globalStorageOptions => { + _nodes => ['hash:/globalStorageOptions'], + _js => 'hashRoot' + }, + }, + timeout => 'text:/timeout:timeout:text', + }, + ldapParams => { + _nodes => + [qw(ldapServer ldapPort ldapBase managerDn managerPassword)], + _help => 'ldap', + ldapServer => 'text:/ldapServer', + ldapPort => 'int:/ldapPort', + ldapBase => 'text:/ldapBase', + managerDn => 'text:/managerDn', + managerPassword => 'text:/managerPassword', + }, + }, + groups => { _nodes => ['hash:/groups:groups:btext'], _js => 'hashRoot' }, + virtualHosts => + { _nodes => ['nhash:/locationRules:virtualHosts:none'], }, + }; +} + +sub testStruct { + my $assignTest = qr/(?<=[^=\?])=(?![=~])/; + my $assignMsg = 'containsAnAssignment'; + my $perlExpr = sub { + my $e = shift; + eval "use strict;$e"; + return 1 if ( $@ =~ /Global symbol "\$.*requires explicit package/ ); + return ( $@ ? ( 0, $@ ) : 1 ); + }; + return { + authentication => { + test => qr/^[a-zA-Z][\w\:]*$/, + msgFail => 'Bad module name', + }, + userDB => { + test => qr/^[a-zA-Z][\w\:]*$/, + msgFail => 'Bad module name', + }, + whatToTrace => { + test => qr/^\$?[a-zA-Z]\w*$/, + msgFail => 'Bad value', + }, + portal => { + test => qr/^https?:\/\/\S+$/, + msgFail => 'Bad portal value', + }, + cookieName => { + test => qr/^[a-zA-Z]\w*$/, + msgFail => 'Bad cookie name', + }, + securedCookie => { + test => qr/^(?:0|1|2)$/, + msgFail => 'securedCookie must be 0, 1 or 2', + }, + domain => { + test => qr/^\.?\w+(?:\.[a-zA-Z]\w*)*(?:\.[a-zA-Z]+)$/, + msgFail => 'Bad domain', + }, + timeout => { + test => qr/^\d*$/, + msgFail => 'Bad number' + }, + globalStorage => { + test => qr/^[\w:]+$/, + msgFail => 'Bad module name', + }, + globalStorageOptions => { + keyTest => qr/^\w+$/, + keyMsgFail => 'Bad parameter', + }, + ldapBase => { + test => qr/^(?:\w+=.*|)$/, + msgFail => 'Bad LDAP base', + }, + ldapPort => { + test => qr/^\d*$/, + msgFail => 'Bad port number' + }, + ldapServer => { + test => sub { + my $l = shift; + my @s = split( /[\s,]+/, $l ); + foreach my $s (@s) { + $s =~ +/^(?:ldap(?:s|\+tls|i):\/\/)?\w[\w\-\.]+\w(?::\d{0,5})?\/?$/ + or return ( 0, "Bad ldap uri \"$s\"" ); + } + return 1; + }, + }, + managerDn => { + test => qr/^(?:\w+=.*,\w+=.*)?$/, + msgFail => 'Bad LDAP dn', + }, + managerPassword => {}, + groups => { + keyTest => qr/^\w[\w-]*$/, + keyMsgFail => 'Bad group name', + test => $perlExpr, + warnTest => sub { + my $e = shift; + return ( 0, $assignMsg ) if ( $e =~ $assignTest ); + 1; + }, + }, + exportedVars => { + keyTest => qr/^[a-zA-Z]\w*$/, + keyMsgFail => 'Bad variable name', + test => qr/^[a-zA-Z]\w*$/, + msgFail => 'Bad attribute name', + }, + macros => { + keyTest => qr/^[a-zA-Z]\w*$/, + keyMsgFail => 'Bad macro name', + test => $perlExpr, + warnTest => sub { + my $e = shift; + return ( 0, $assignMsg ) if ( $e =~ $assignTest ); + 1; + }, + }, + locationRules => { + keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/, + msgFail => 'Bad virtual host name', + '*' => { + keyTest => sub { + my $r = shift; + my $q; + eval { $q = qr/$r/ }; + return ( $@ ? ( 0, $@ ) : 1 ); + }, + test => sub { + my $e = shift; + return 1 if ( $e eq 'accept' or $e eq 'deny' ); + if ( $e =~ s/^logout(?:_(?:app|sso|app_sso))?\s*// ) { + return ( + $e =~ /^(?:https?:\/\/\S+)?$/ + ? 1 + : ( 0, "bad url \"$e\"" ) + ); + } + return &$perlExpr($e); + }, + warnTest => sub { + my $e = shift; + return ( 0, $assignMsg ) + if ( $e =~ $assignTest + and $e !~ /^(?:accept|deny|logout)/ ); + 1; + }, + }, + }, + exportedHeaders => { + keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/, + msgFail => 'Bad virtual host name', + '*' => { + keyTest => qr/^\w([\w\-]*\w)?$/, + keyMsgFail => 'Bad header name', + test => $perlExpr, + warnTest => sub { + my $e = shift; + return ( 0, $assignMsg ) if ( $e =~ $assignTest ); + 1; + }, + }, + }, + }; +} + +sub defaultConf { + return { + userDB => 'LDAP', + ldapServer => 'localhost', + }; +} + +sub newNode { + virtualHost => { + '*' => { + exportedHeaders => { 'Auth-User' => '$uid' }, + locationRules => { 'default' => 'deny' }, + } + }, + groups => { 'NewGroup' => '0', }, + macro => { 'NewMacro' => '', }, + globalStorageOptions => { 'NewOption' => '', }, + ; +} + +1; diff --git a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm index e4817e458..0dfd27e2d 100644 --- a/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm +++ b/modules/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/_i18n.pm @@ -7,27 +7,32 @@ package Lemonldap::NG::Manager::_i18n; # Developer warning : this file must be utf8 encoded +use strict; use AutoLoader qw(AUTOLOAD); -our $VERSION = '0.34'; +our $VERSION = '0.5'; ## @fn void import(string lang) # Import messages -sub import { - my ($caller_package) = caller; - my $lang = pop; +sub translate { + my ( $self, $text, $lang ) = @_; + return $text unless ( $text =~ /[a-z]/ ); + $lang ||= $ENV{HTTP_ACCEPT_LANGUAGE}; $lang = lc($lang); $lang =~ s/-/_/g; - foreach ( split( /[,;]/, $lang ) ) { + foreach ( split( /[,;]/, $lang ), 'en' ) { next if /=/; if ( __PACKAGE__->can($_) ) { - $functions = &$_; - last; + no strict 'refs'; + my $r = &$_()->{$text}; + if ($r) { + return $r; + } + else { + print STDERR __PACKAGE__ . ": $text not translated in $_\n"; + return $text; + } } } - $functions ||= &en; - while ( my ( $f, $v ) = each(%$functions) ) { - *{"${caller_package}::txt_$f"} = sub { $v }; - } } *fr_fr = *fr; @@ -35,6 +40,72 @@ sub import { 1; +sub en { + return { + authentication => 'Authentication module', + authParams => 'Authentication parameters', + Configuration => 'Configuration', + cookieName => 'Cookie Name', + cookieParams => 'Cookies Parameters', + domain => 'Domain', + exportedVars => 'Exported Variables', + generalParameters => 'General Parameters', + globalStorage => 'Apache::Session module', + globalStorageOptions => 'Apache::Session module parameters', + groups => 'Groups', + headers => 'HTTP Headers', + ldapBase => 'LDAP Search Base', + ldapParams => 'LDAP parameters', + ldapPort => 'LDAP Server Port', + ldapServer => 'LDAP Server', + macros => 'Macros', + managerDn => 'LDAP Account', + managerPassword => 'LDAP Password', + portal => 'Portal', + rules => 'Rules', + securedCookie => 'Secured Cookie (SSL)', + sessionParams => 'Sessions Parameters', + sessionStorage => 'Sessions Storage', + timeout => 'Sessions timeout', + userDB => 'Users database type', + virtualHosts => 'Virtual Hosts', + whatToTrace => "Attribute to use in Apache's logs", + }; +} + +sub fr { + return { + authentication => "Module d'authentification", + authParams => "Paramètres d'authentification", + Configuration => 'Configuration', + cookieName => 'Nom du cookie', + cookieParams => 'Paramètres des cookies', + domain => 'Domaine', + exportedVars => 'Attributs LDAP à exporter', + generalParameters => 'Paramètres généraux', + globalStorage => 'Module Apache::Session', + globalStorageOptions => 'Paramètres du module Apache::Session', + groups => 'Groupes', + headers => 'En-têtes HTTP', + ldapBase => 'Base de recherche LDAP', + ldapParams => 'Paramètres LDAP', + ldapPort => 'Port du serveur LDAP', + ldapServer => 'Serveur LDAP', + macros => 'Macros', + managerDn => 'Compte de connexion LDAP', + managerPassword => 'Mot de passe LDAP', + portal => 'Portail', + rules => 'Règles', + securedCookie => 'Cookie sécurisé (SSL)', + sessionParams => 'Paramètres des Sessions Parameters', + sessionStorage => 'Stockage des sessions', + timeout => 'Durée de vie des sessions', + userDB => "Type de base de données d'utilisateurs", + virtualHosts => 'Hôtes virtuels', + whatToTrace => "Donnée à inscrire dans les journaux d'Apache", + }; +} + __END__ =pod @@ -42,168 +113,123 @@ __END__ sub en { return { - apacheSessionModule => "Apache::Session module", - applyConf => "Apply", - areYouSure => "Are you sure ?", - authParams => "Authentication Parameters", - authenticationType => "Authentication Type", - canNotReadApplyConfFile => "Configuration not applied: cannot read configuration file", - changesAppliedLater => 'Changes will be effective within 10 minutes. Use "apachectl reload" on concerned servers for immediate reloading', - checkLogs => "Check Apache logs", - confSaved => "Configuration saved with number", - configLoaded => "Configuration loaded", - configuration => "Configuration", - configurationDeleted => "Configuration deleted", - configurationNotDeleted => "Configuration not deleted", - configurationWasChanged => "Configuration has been changed since you got it", - confirmDeleteConf => "You're going to delete configuration. Do you confirm ?", - cookieName => "Cookie Name", - containsAnAssignment => 'contains an assignment ("="). Possible confusion with "==".', - deleteConf => "Delete", - deleteNode => "Delete", - deleteVirtualHost => "Delete virtual host", - domain => "Domain", - error => "Error", - exportedVars => "Exported Variables", - field => "Field", - generalParameters => "General Parameters", - globalStorageOptions => "Session Storage Parameters", - group => "Group", - header => "Header", - httpHeaders => "HTTP Headers", - invalidLine => "Invalid Line", - invalidVirtualHostName => "Invalid virtual host name", - invalidWhatToTrace => "Data to use in Apache's logs can contain only an exported attribute or a macro", - isNotANumber => "is not a number", - isNotAValidAttributeName => "is not a valid attribute name", - isNotAValidCookieName => "is not a valid cookie name", - isNotAValidDomainName => "is not a valid domain name", - isNotAValidGroupName => "is not a valid group name", - isNotAValidHTTPHeaderName => "is not a valid HTTP header name", - isNotAValidLDAPAttributeName => "is not a valid LDAP attribute name", - isNotAValidMacroName => "is not a valid macro name", - isNotAValidVirtualHostName => "is not a valid virtual host name", - lastConf => "Last", - ldapBase => "LDAP Search Base", - ldapParameters => "LDAP Parameters", - ldapPort => "LDAP Server Port", - ldapServer => "LDAP Server", - locationRules => "Rules", - macro => "Macro", - macros => "Macros", - managerDn => "LDAP Account", - managerPassword => "LDAP Password", - newGSOpt => "New Option", - newGroup => "New Group", - newHeader => "New Header", - newMacro => "New Macro", - newRule => "New Rule", - newVar => "New Variable", - newVirtualHost => "New Virtual Host", - nextConf => "Next", - portal => "Portal", - prevConf => "Previous", - result => "Result", - rule => "Rule", - rules => "Rules", - saveConf => "Save", - saveFailure => "Save failure", - securedCookie => "Secured Cookie (SSL)", - sessionStorage => "Session Storage", - sessionTimeout => "Session timeout", - syntaxError => "Syntax error", - unableToSave => "Your browser does not support XMLHTTPRequest objects: fail to save.", - unknownError => "Unknown error", - unknownErrorInVars => "Unknown error in exported attributes", - userGroups => "User Groups", - value => "Value", - virtualHosts => "Virtual Hosts", - waitingResult => "Waiting result...", - warningConfNotApplied => "You have to reload handlers to take the saved configuration in account", - whatToTrace => "Attribute to use in Apache's logs", + apacheSessionModule => 'Apache::Session module', + applyConf => 'Apply', + areYouSure => 'Are you sure ?', + authenticationType => 'Authentication Type', + canNotReadApplyConfFile => 'Configuration not applied: cannot read configuration file', + changesAppliedLater => 'Changes will be effective within 10 minutes. Use "apachectl reload" on concerned servers for immediate reloading', + checkLogs => 'Check Apache logs', + confSaved => 'Configuration saved with number', + configLoaded => 'Configuration loaded', + configurationDeleted => 'Configuration deleted', + configurationNotDeleted => 'Configuration not deleted', + configurationWasChanged => 'Configuration has been changed since you got it', + confirmDeleteConf => "You're going to delete configuration. Do you confirm ?", + containsAnAssignment => 'contains an assignment ("="). Possible confusion with "==".', + deleteConf => 'Delete', + deleteNode => 'Delete', + deleteVirtualHost => 'Delete virtual host', + error => 'Error', + field => 'Field', + group => 'Group', + httpHeaders => 'HTTP Headers', + invalidLine => 'Invalid Line', + invalidVirtualHostName => 'Invalid virtual host name', + invalidWhatToTrace => "Data to use in Apache's logs can contain only an exported attribute or a macro", + isNotANumber => 'is not a number', + isNotAValidAttributeName => 'is not a valid attribute name', + isNotAValidCookieName => 'is not a valid cookie name', + isNotAValidDomainName => 'is not a valid domain name', + isNotAValidGroupName => 'is not a valid group name', + isNotAValidHTTPHeaderName => 'is not a valid HTTP header name', + isNotAValidLDAPAttributeName => 'is not a valid LDAP attribute name', + isNotAValidMacroName => 'is not a valid macro name', + isNotAValidVirtualHostName => 'is not a valid virtual host name', + lastConf => 'Last', + locationRules => 'Rules', + macro => 'Macro', + newGSOpt => 'New Option', + newGroup => 'New Group', + newHeader => 'New Header', + newMacro => 'New Macro', + newVar => 'New Variable', + newVirtualHost => 'New Virtual Host', + nextConf => 'Next', + prevConf => 'Previous', + result => 'Result', + rule => 'Rule', + saveConf => 'Save', + saveFailure => 'Save failure', + syntaxError => 'Syntax error', + unableToSave => 'Your browser does not support XMLHTTPRequest objects: fail to save.', + unknownError => 'Unknown error', + unknownErrorInVars => 'Unknown error in exported attributes', + userGroups => 'User Groups', + value => 'Value', + waitingResult => 'Waiting result...', + warningConfNotApplied => 'You have to reload handlers to take the saved configuration in account', }; } sub fr { return { - apacheSessionModule => "Module Apache::Session", - applyConf => "Appliquer", - areYouSure => "Êtes vous sur ?", - authParams => "Paramètres d'authentification", - authenticationType => "Type d'authentification", - canNotReadApplyConfFile => "Configuration non appliquée: impossible de lire le fichier de configuration", - changesAppliedLater => "Les changements seront effectifs d'ici 10 minutes. Utilisez \"apachectl reload\" sur les serveurs concernés pour forcer la prise en compte immédiate", - checkLogs => "Consultez les journaux d'Apache", - confSaved => "Configuration sauvegardée sous le numéro", - configLoaded => "Configuration chargée", - configuration => "Configuration", - configurationDeleted => "Configuration éffacée", - configurationNotDeleted => "Configuration non éffacée", - configurationWasChanged => "configuration modifiée depuis que vous l'avez téléchargée", - confirmDeleteConf => "Vous allez effacer cette configuration. Confirmez-vous ?", - cookieName => "Nom du cookie", - containsAnAssignment => 'contient une affectation ("="). Confusion possible avec "==".', - deleteConf => "Effacer", - deleteNode => "Supprimer", - deleteVirtualHost => "Supprimer l'hôte virtuel", - domain => "Domaine", - error => "Erreur", - exportedVars => "Attributs LDAP à exporter", - field => "Champ", - generalParameters => "Paramètres généraux", - globalStorageOptions => "Paramètres du module Apache::Session", - group => "Groupe", - header => "En-tête", - httpHeaders => "En-têtes HTTP", - invalidLine => "Ligne invalide", - invalidVirtualHostName => "Nom de d'hôte virtuel incorrect", - invalidWhatToTrace => "La donnée à inscrire dans les journaux ne peut contenir qu'un attribut exporté ou une macro", - isNotANumber => "n'est pas un nombre", - isNotAValidAttributeName => "n'est pas un nom d'attribut valide", - isNotAValidCookieName => "n'est pas un nom de cookie valide", - isNotAValidDomainName => "n'est pas un nom de domaine valide", - isNotAValidGroupName => "n'est pas un nom de groupe valide", - isNotAValidHTTPHeaderName => "n'est pas un nom d'en-tête HTTP valide", + apacheSessionModule => 'Module Apache::Session', + applyConf => 'Appliquer', + areYouSure => 'Êtes vous sur ?', + authenticationType => "Type d'authentification", + canNotReadApplyConfFile => 'Configuration non appliquée: impossible de lire le fichier de configuration', + changesAppliedLater => "Les changements seront effectifs d'ici 10 minutes. Utilisez \"apachectl reload\" sur les serveurs concernés pour forcer la prise en compte immédiate", + checkLogs => "Consultez les journaux d'Apache", + confSaved => 'Configuration sauvegardée sous le numéro', + configLoaded => 'Configuration chargée', + configurationDeleted => 'Configuration éffacée', + configurationNotDeleted => 'Configuration non éffacée', + configurationWasChanged => "configuration modifiée depuis que vous l'avez téléchargée", + confirmDeleteConf => 'Vous allez effacer cette configuration. Confirmez-vous ?', + containsAnAssignment => 'contient une affectation ("="). Confusion possible avec "==".', + deleteConf => 'Effacer', + deleteNode => 'Supprimer', + deleteVirtualHost => "Supprimer l'hôte virtuel", + error => 'Erreur', + field => 'Champ', + group => 'Groupe', + httpHeaders => 'En-têtes HTTP', + invalidLine => 'Ligne invalide', + invalidVirtualHostName => "Nom de d'hôte virtuel incorrect", + invalidWhatToTrace => "La donnée à inscrire dans les journaux ne peut contenir qu'un attribut exporté ou une macro", + isNotANumber => "n'est pas un nombre", + isNotAValidAttributeName => "n'est pas un nom d'attribut valide", + isNotAValidCookieName => "n'est pas un nom de cookie valide", + isNotAValidDomainName => "n'est pas un nom de domaine valide", + isNotAValidGroupName => "n'est pas un nom de groupe valide", + isNotAValidHTTPHeaderName => "n'est pas un nom d'en-tête HTTP valide", isNotAValidLDAPAttributeName => "n'est pas un nom d'attribut LDAP valide", - isNotAValidMacroName => "n'est pas un nom de macro valide", - isNotAValidVirtualHostName => "n'est pas un nom d'hôte virtuel valide", - lastConf => "Dernière", - ldapBase => "Base de recherche LDAP", - ldapParameters => "Paramètres LDAP", - ldapPort => "Port du serveur LDAP", - ldapServer => "Serveur LDAP", - locationRules => "Règles", - macro => "Macro", - macros => "Macros", - managerDn => "Compte de connexion LDAP", - managerPassword => "Mot de passe LDAP", - newGSOpt => "Nouvelle option", - newGroup => "Nouveau groupe", - newHeader => "Nouvel en-tête", - newMacro => "Nouvelle macro", - newRule => "Nouvelle règle", - newVar => "Nouvelle variable", - newVirtualHost => "Nouvel hôte virtuel", - nextConf => "Suivante", - portal => "Portail", - prevConf => "Précédente", - result => "Résultat", - rule => "Règle", - rules => "Règles", - saveConf => "Sauvegarder", - saveFailure => "Échec de la sauvegarde", - securedCookie => "Cookie sécurisé (SSL)", - sessionStorage => "Stockage des sessions", - sessionTimeout => "Durée de vie des sessions", - syntaxError => "Erreur de syntaxe", - unableToSave => "Votre navigateur ne supporte pas les objets XMLHTTPRequest: sauvegarde impossible.", - unknownError => "Erreur inconnue", - unknownErrorInVars => "Erreur inconnue dans les attributs exportés", - userGroups => "Groupes d'utilisateurs", - value => "Valeur", - virtualHosts => "Hôtes virtuels", - waitingResult => "En attente...", - warningConfNotApplied => "Vous devez recharger les agents pour que la configuration sauvegardée soit appliquée", - whatToTrace => "Donnée à inscrire dans les journaux d'Apache", + isNotAValidMacroName => "n'est pas un nom de macro valide", + isNotAValidVirtualHostName => "n'est pas un nom d'hôte virtuel valide", + lastConf => 'Dernière', + locationRules => 'Règles', + macro => 'Macro', + macros => 'Macros', + newGSOpt => 'Nouvelle option', + newGroup => 'Nouveau groupe', + newHeader => 'Nouvel en-tête', + newMacro => 'Nouvelle macro', + newVar => 'Nouvelle variable', + newVirtualHost => 'Nouvel hôte virtuel', + nextConf => 'Suivante', + prevConf => 'Précédente', + result => 'Résultat', + rule => 'Règle', + saveConf => 'Sauvegarder', + saveFailure => 'Échec de la sauvegarde', + syntaxError => 'Erreur de syntaxe', + unableToSave => 'Votre navigateur ne supporte pas les objets XMLHTTPRequest: sauvegarde impossible.', + unknownError => 'Erreur inconnue', + unknownErrorInVars => 'Erreur inconnue dans les attributs exportés', + userGroups => "Groupes d'utilisateurs", + value => 'Valeur', + waitingResult => 'En attente...', + warningConfNotApplied => 'Vous devez recharger les agents pour que la configuration sauvegardée soit appliquée', }; } diff --git a/modules/lemonldap-ng-manager/t/10-Manager.t b/modules/lemonldap-ng-manager/t/10-Manager.t index 3768a59aa..89f48932e 100644 --- a/modules/lemonldap-ng-manager/t/10-Manager.t +++ b/modules/lemonldap-ng-manager/t/10-Manager.t @@ -5,7 +5,7 @@ # change 'tests => 1' to 'tests => last_test_to_print'; -use Test::More tests => 11; +use Test::More tests => 1; use IO::String; use strict; BEGIN { use_ok('Lemonldap::NG::Manager') } @@ -22,139 +22,3 @@ our $buf; tie *STDOUT, 'IO::String', $buf; our $lastpos = 0; - -sub diff { - my $str = $buf; - $str =~ s/^.{$lastpos}//s if ($lastpos); - $str =~ s/\r//gs; - $lastpos = length $buf; - return $str; -} - -@ARGV = ("help=groups"); -ok( - $h = new Lemonldap::NG::Manager( - { - configStorage => { - type => 'File', - dirName => ".", - }, - dhtmlXTreeImageLocation => "/imgs/", - jsFile => 'example/lemonldap-ng-manager.js', - } - ), - 'New object' -); -ok( $h->header_public('example/index.pl') =~ /Cache-control:\s+public/s, - 'header_public' ); -ok( $h->start_html() =~ /main() and diff() =~ m#