Import and adapt https://github.com/guimard/angular-lemonldap-ng-manager.git
|
@ -11,10 +11,11 @@ use strict;
|
||||||
use AutoLoader 'AUTOLOAD';
|
use AutoLoader 'AUTOLOAD';
|
||||||
use Apache::Session;
|
use Apache::Session;
|
||||||
use base qw(Apache::Session);
|
use base qw(Apache::Session);
|
||||||
|
use Lemonldap::NG::Common::Apache::Session::Serialize::JSON;
|
||||||
use Lemonldap::NG::Common::Apache::Session::Store;
|
use Lemonldap::NG::Common::Apache::Session::Store;
|
||||||
use Lemonldap::NG::Common::Apache::Session::Lock;
|
use Lemonldap::NG::Common::Apache::Session::Lock;
|
||||||
|
|
||||||
our $VERSION = '1.4.4';
|
our $VERSION = '1.5.99';
|
||||||
|
|
||||||
sub _load {
|
sub _load {
|
||||||
my $backend = shift;
|
my $backend = shift;
|
||||||
|
@ -34,7 +35,6 @@ sub populate {
|
||||||
$self = $self->$backend(@_);
|
$self = $self->$backend(@_);
|
||||||
}
|
}
|
||||||
if ( $self->{args}->{jsonSerialize} ) {
|
if ( $self->{args}->{jsonSerialize} ) {
|
||||||
require Lemonldap::NG::Common::Apache::Session::Serialize::JSON;
|
|
||||||
$self->{serialize} =
|
$self->{serialize} =
|
||||||
\&Lemonldap::NG::Common::Apache::Session::Serialize::JSON::serialize;
|
\&Lemonldap::NG::Common::Apache::Session::Serialize::JSON::serialize;
|
||||||
$self->{unserialize} =
|
$self->{unserialize} =
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
#######################################################
|
|
||||||
#
|
|
||||||
# Lemonldap::NG::Common::Apache::Session::Serialize::JSON
|
|
||||||
# Serializes session objects using JSON
|
|
||||||
# Copyright(c) 2015 Xavier Guimard (x.guimard@free.fr)
|
|
||||||
# Distribute under the GPL2 License
|
|
||||||
#
|
|
||||||
#######################################################
|
|
||||||
|
|
||||||
package Lemonldap::NG::Common::Apache::Session::Serialize::JSON;
|
package Lemonldap::NG::Common::Apache::Session::Serialize::JSON;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
@ -35,6 +26,8 @@ sub unserialize {
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
Lemonldap::NG::Common::Apache::Session::Serialize::JSON - Use JSON to zip up data
|
Lemonldap::NG::Common::Apache::Session::Serialize::JSON - Use JSON to zip up data
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
@ -50,11 +43,54 @@ This module fulfills the serialization interface of Apache::Session.
|
||||||
It serializes the data in the session object by use of JSON C<encode_json>
|
It serializes the data in the session object by use of JSON C<encode_json>
|
||||||
and C<decode_json>. The serialized data is UTF-8 text.
|
and C<decode_json>. The serialized data is UTF-8 text.
|
||||||
|
|
||||||
=head1 AUTHOR
|
|
||||||
|
|
||||||
This module was written by Xavier Guimard <x.guimard@free.fr> using other
|
|
||||||
Apache::Session serializer written by Jeffrey William Baker <jwbaker@acm.org>.
|
|
||||||
|
|
||||||
=head1 SEE ALSO
|
=head1 SEE ALSO
|
||||||
|
|
||||||
L<JSON>, L<Apache::Session>
|
L<JSON>, L<Apache::Session>
|
||||||
|
|
||||||
|
=head1 AUTHORS
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item Clement Oudot, E<lt>clem.oudot@gmail.comE<gt>
|
||||||
|
|
||||||
|
=item François-Xavier Deltombe, E<lt>fxdeltombe@gmail.com.E<gt>
|
||||||
|
|
||||||
|
=item Xavier Guimard, E<lt>x.guimard@free.frE<gt>
|
||||||
|
|
||||||
|
=item Thomas Chemineau, E<lt>thomas.chemineau@gmail.comE<gt>
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 BUG REPORT
|
||||||
|
|
||||||
|
Use OW2 system to report bug or ask for features:
|
||||||
|
L<http://jira.ow2.org>
|
||||||
|
|
||||||
|
=head1 DOWNLOAD
|
||||||
|
|
||||||
|
Lemonldap::NG is available at
|
||||||
|
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
|
||||||
|
|
||||||
|
=head1 COPYRIGHT AND LICENSE
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item Copyright (C) 2015 by Xavier Guimard, E<lt>x.guimard@free.frE<gt>
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see L<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
|
@ -10,7 +10,9 @@ package Lemonldap::NG::Common::Conf;
|
||||||
use strict;
|
use strict;
|
||||||
no strict 'refs';
|
no strict 'refs';
|
||||||
use Lemonldap::NG::Common::Conf::Constants; #inherits
|
use Lemonldap::NG::Common::Conf::Constants; #inherits
|
||||||
use Lemonldap::NG::Common::Conf::Attributes; #inherits
|
|
||||||
|
# TODO: don't import this big file, use a proxy
|
||||||
|
use Lemonldap::NG::Common::Conf::DefaultValues; #inherits
|
||||||
use Lemonldap::NG::Common::Crypto
|
use Lemonldap::NG::Common::Crypto
|
||||||
; #link protected cipher Object "cypher" in configuration hash
|
; #link protected cipher Object "cypher" in configuration hash
|
||||||
use Config::IniFiles;
|
use Config::IniFiles;
|
||||||
|
@ -20,7 +22,7 @@ use Config::IniFiles;
|
||||||
#inherits Lemonldap::NG::Common::Conf::SOAP
|
#inherits Lemonldap::NG::Common::Conf::SOAP
|
||||||
#inherits Lemonldap::NG::Common::Conf::LDAP
|
#inherits Lemonldap::NG::Common::Conf::LDAP
|
||||||
|
|
||||||
our $VERSION = '1.4.4';
|
our $VERSION = '1.5.99';
|
||||||
our $msg = '';
|
our $msg = '';
|
||||||
our $iniObj;
|
our $iniObj;
|
||||||
|
|
||||||
|
@ -108,12 +110,12 @@ sub new {
|
||||||
# @param $conf Lemonldap::NG configuration hashRef
|
# @param $conf Lemonldap::NG configuration hashRef
|
||||||
# @return Number of the saved configuration, 0 if case of error.
|
# @return Number of the saved configuration, 0 if case of error.
|
||||||
sub saveConf {
|
sub saveConf {
|
||||||
my ( $self, $conf ) = @_;
|
my ( $self, $conf, %args ) = @_;
|
||||||
|
|
||||||
my $last = $self->lastCfg;
|
my $last = $self->lastCfg;
|
||||||
|
|
||||||
# If configuration was modified, return an error
|
# If configuration was modified, return an error
|
||||||
if ( not $self->{force} ) {
|
if ( not $args{force} ) {
|
||||||
return CONFIG_WAS_CHANGED if ( $conf->{cfgNum} != $last );
|
return CONFIG_WAS_CHANGED if ( $conf->{cfgNum} != $last );
|
||||||
return DATABASE_LOCKED if ( $self->isLocked() or not $self->lock() );
|
return DATABASE_LOCKED if ( $self->isLocked() or not $self->lock() );
|
||||||
}
|
}
|
||||||
|
@ -169,24 +171,31 @@ sub getConf {
|
||||||
else {
|
else {
|
||||||
eval { $r = $self->{refLocalStorage}->get('conf') } if ($>);
|
eval { $r = $self->{refLocalStorage}->get('conf') } if ($>);
|
||||||
$msg = "Warn: $@" if ($@);
|
$msg = "Warn: $@" if ($@);
|
||||||
if ( ref($r) and $r->{cfgNum} == $args->{cfgNum} ) {
|
if ( ref($r)
|
||||||
|
and $r->{cfgNum}
|
||||||
|
and $args->{cfgNum}
|
||||||
|
and $r->{cfgNum} == $args->{cfgNum} )
|
||||||
|
{
|
||||||
$msg .=
|
$msg .=
|
||||||
"Configuration unchanged, get configuration from cache.\n";
|
"Configuration unchanged, get configuration from cache.\n";
|
||||||
$args->{noCache} = 1;
|
$args->{noCache} = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$r = $self->getDBConf($args);
|
$r = $self->getDBConf($args);
|
||||||
return undef unless ( ref($r) );
|
return undef unless ( $r->{cfgNum} );
|
||||||
|
|
||||||
# Adapt some values before storing in local cache
|
# TODO: default values may not be set here
|
||||||
# Get default values
|
unless ( $args->{raw} ) {
|
||||||
my $confAttributes =
|
|
||||||
Lemonldap::NG::Common::Conf::Attributes->new();
|
|
||||||
|
|
||||||
my @attributes = $confAttributes->meta()->get_attribute_list();
|
# Adapt some values before storing in local cache
|
||||||
|
# Get default values
|
||||||
|
my $defaultValues =
|
||||||
|
Lemonldap::NG::Common::Conf::DefaultValues
|
||||||
|
->defaultValues();
|
||||||
|
|
||||||
foreach my $name (@attributes) {
|
foreach my $k ( keys %$defaultValues ) {
|
||||||
$r->{$name} //= $confAttributes->$name;
|
$r->{$k} //= $defaultValues->{$k};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Convert old option useXForwardedForIP into trustedProxies
|
# Convert old option useXForwardedForIP into trustedProxies
|
||||||
|
@ -211,15 +220,20 @@ sub getConf {
|
||||||
|
|
||||||
# Store modified configuration in cache
|
# Store modified configuration in cache
|
||||||
$self->setLocalConf($r)
|
$self->setLocalConf($r)
|
||||||
if ( $self->{refLocalStorage} and not( $args->{noCache} ) );
|
if ( $self->{refLocalStorage}
|
||||||
|
and not( $args->{noCache} or $args->{raw} ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create cipher object
|
# Create cipher object
|
||||||
eval { $r->{cipher} = Lemonldap::NG::Common::Crypto->new( $r->{key} ); };
|
unless ( $args->{raw} ) {
|
||||||
if ($@) {
|
eval {
|
||||||
$msg .= "Bad key: $@. \n";
|
$r->{cipher} = Lemonldap::NG::Common::Crypto->new( $r->{key} );
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
$msg .= "Bad key: $@. \n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return configuration hash
|
# Return configuration hash
|
||||||
|
@ -345,7 +359,8 @@ sub getDBConf {
|
||||||
: $a[0];
|
: $a[0];
|
||||||
}
|
}
|
||||||
my $conf = $self->load( $args->{cfgNum} );
|
my $conf = $self->load( $args->{cfgNum} );
|
||||||
$msg .= "Get configuration $conf->{cfgNum}.\n";
|
$msg .= "Get configuration $conf->{cfgNum}.\n"
|
||||||
|
if ( defined $conf->{cfgNum} );
|
||||||
$self->setLocalConf($conf)
|
$self->setLocalConf($conf)
|
||||||
if ( ref($conf)
|
if ( ref($conf)
|
||||||
and $self->{refLocalStorage}
|
and $self->{refLocalStorage}
|
||||||
|
@ -418,7 +433,7 @@ sub load {
|
||||||
sub delete {
|
sub delete {
|
||||||
my ( $self, $c ) = @_;
|
my ( $self, $c ) = @_;
|
||||||
my @a = $self->available();
|
my @a = $self->available();
|
||||||
return 0 unless ( grep {$_ eq $c} @a );
|
return 0 unless ( grep { $_ eq $c } @a );
|
||||||
return &{ $self->{type} . '::delete' }( $self, $c );
|
return &{ $self->{type} . '::delete' }( $self, $c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,315 @@
|
||||||
|
# This file is generated by scripts/jsongenerator.pl. Don't modify it by hand
|
||||||
|
package Lemonldap::NG::Common::Conf::DefaultValues;
|
||||||
|
|
||||||
|
our $VERSION = '1.5.99';
|
||||||
|
|
||||||
|
sub defaultValues {
|
||||||
|
return {
|
||||||
|
'activeTimer' => 1,
|
||||||
|
'apacheAuthnLevel' => 4,
|
||||||
|
'applicationList' => {
|
||||||
|
'default' => {
|
||||||
|
'catname' => 'Default category',
|
||||||
|
'type' => 'category'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'authentication' => 'Demo',
|
||||||
|
'browserIdAuthnLevel' => 1,
|
||||||
|
'captcha_login_enabled' => 0,
|
||||||
|
'captcha_mail_enabled' => 0,
|
||||||
|
'captcha_register_enabled' => 1,
|
||||||
|
'captcha_size' => 6,
|
||||||
|
'captchaStorage' => 'Apache::Session::File',
|
||||||
|
'captchaStorageOptions' => {
|
||||||
|
'Directory' => '/var/lib/lemonldap-ng/captcha/'
|
||||||
|
},
|
||||||
|
'CAS_authnLevel' => 1,
|
||||||
|
'CAS_pgtFile' => '/tmp/pgt.txt',
|
||||||
|
'casAccessControlPolicy' => 'none',
|
||||||
|
'cda' => 0,
|
||||||
|
'cfgNum' => 0,
|
||||||
|
'checkXSS' => 1,
|
||||||
|
'confirmFormMethod' => 'post',
|
||||||
|
'cookieName' => 'lemonldap',
|
||||||
|
'dbiAuthnLevel' => 2,
|
||||||
|
'dbiExportedVars' => {},
|
||||||
|
'demoExportedVars' => {
|
||||||
|
'cn' => 'cn',
|
||||||
|
'mail' => 'mail',
|
||||||
|
'uid' => 'uid'
|
||||||
|
},
|
||||||
|
'domain' => 'example.com',
|
||||||
|
'exportedVars' => {
|
||||||
|
'UA' => 'HTTP_USER_AGENT'
|
||||||
|
},
|
||||||
|
'facebookAuthnLevel' => 1,
|
||||||
|
'facebookExportedVars' => {},
|
||||||
|
'failedLoginNumber' => 5,
|
||||||
|
'globalStorage' => 'Apache::Session::File',
|
||||||
|
'globalStorageOptions' => {
|
||||||
|
'Directory' => '/var/lib/lemonldap-ng/sessions/',
|
||||||
|
'generateModule' =>
|
||||||
|
'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
|
||||||
|
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/'
|
||||||
|
},
|
||||||
|
'googleAuthnLevel' => 1,
|
||||||
|
'googleExportedVars' => {},
|
||||||
|
'groups' => {},
|
||||||
|
'hiddenAttributes' => '_password',
|
||||||
|
'hideOldPassword' => 0,
|
||||||
|
'httpOnly' => 1,
|
||||||
|
'https' => 0,
|
||||||
|
'infoFormMethod' => 'get',
|
||||||
|
'issuerDBCASActivation' => 0,
|
||||||
|
'issuerDBCASPath' => '^/cas/',
|
||||||
|
'issuerDBCASRule' => 1,
|
||||||
|
'issuerDBOpenIDActivation' => 0,
|
||||||
|
'issuerDBOpenIDConnectActivation' => '0',
|
||||||
|
'issuerDBOpenIDConnectPath' => '^/oauth2/',
|
||||||
|
'issuerDBOpenIDConnectRule' => 1,
|
||||||
|
'issuerDBOpenIDPath' => '^/openidserver/',
|
||||||
|
'issuerDBOpenIDRule' => 1,
|
||||||
|
'issuerDBSAMLActivation' => 0,
|
||||||
|
'issuerDBSAMLPath' => '^/saml/',
|
||||||
|
'issuerDBSAMLRule' => 1,
|
||||||
|
'jsRedirect' => 0,
|
||||||
|
'ldapAuthnLevel' => 2,
|
||||||
|
'ldapBase' => 'dc=example,dc=com',
|
||||||
|
'ldapChangePasswordAsUser' => 0,
|
||||||
|
'ldapExportedVars' => {
|
||||||
|
'cn' => 'cn',
|
||||||
|
'mail' => 'mail',
|
||||||
|
'uid' => 'uid'
|
||||||
|
},
|
||||||
|
'ldapGroupAttributeName' => 'member',
|
||||||
|
'ldapGroupAttributeNameGroup' => 'dn',
|
||||||
|
'ldapGroupAttributeNameSearch' => 'cn',
|
||||||
|
'ldapGroupAttributeNameUser' => 'dn',
|
||||||
|
'ldapGroupObjectClass' => 'groupOfNames',
|
||||||
|
'ldapGroupRecursive' => 0,
|
||||||
|
'ldapPasswordResetAttribute' => 'pwdReset',
|
||||||
|
'ldapPasswordResetAttributeValue' => 'TRUE',
|
||||||
|
'ldapPort' => 389,
|
||||||
|
'ldapPpolicyControl' => 0,
|
||||||
|
'ldapPwdEnc' => 'utf-8',
|
||||||
|
'ldapServer' => 'ldap://localhost',
|
||||||
|
'ldapSetPassword' => 0,
|
||||||
|
'ldapTimeout' => 120,
|
||||||
|
'ldapUsePasswordResetAttribute' => 1,
|
||||||
|
'ldapVersion' => 3,
|
||||||
|
'localSessionStorage' => 'Cache::FileCache',
|
||||||
|
'localSessionStorageOptions' => {
|
||||||
|
'cache_depth' => 3,
|
||||||
|
'cache_root' => '/tmp',
|
||||||
|
'default_expires_in' => 600,
|
||||||
|
'directory_umask' => '007',
|
||||||
|
'namespace' => 'lemonldap-ng-sessions'
|
||||||
|
},
|
||||||
|
'locationRules' => {
|
||||||
|
'default' => 'deny'
|
||||||
|
},
|
||||||
|
'loginHistoryEnabled' => 1,
|
||||||
|
'logoutServices' => {},
|
||||||
|
'macros' => {},
|
||||||
|
'mailCharset' => 'utf-8',
|
||||||
|
'mailConfirmSubject' => '[LemonLDAP::NG] Password reset confirmation',
|
||||||
|
'mailFrom' => 'noreply@example.com',
|
||||||
|
'mailOnPasswordChange' => 0,
|
||||||
|
'mailSessionKey' => 'mail',
|
||||||
|
'mailSubject' => '[LemonLDAP::NG] Your new password',
|
||||||
|
'mailTimeout' => 0,
|
||||||
|
'mailUrl' => 'http://auth.example.com/mail.pl',
|
||||||
|
'maintenance' => 0,
|
||||||
|
'managerDn' => '',
|
||||||
|
'managerPassword' => '',
|
||||||
|
'multiValuesSeparator' => '; ',
|
||||||
|
'notification' => 0,
|
||||||
|
'notificationStorage' => 'File',
|
||||||
|
'notificationStorageOptions' => {
|
||||||
|
'dirName' => '/var/lib/lemonldap-ng/notifications'
|
||||||
|
},
|
||||||
|
'notificationWildcard' => 'allusers',
|
||||||
|
'notifyDeleted' => 1,
|
||||||
|
'notifyOther' => 0,
|
||||||
|
'nullAuthnLevel' => 2,
|
||||||
|
'oidcAuthnLevel' => 1,
|
||||||
|
'oidcRPCallbackGetParam' => 'openidconnectcallback',
|
||||||
|
'oidcRPStateTimeout' => 600,
|
||||||
|
'oidcServiceMetaDataAuthnContext' => {
|
||||||
|
'loa-1' => 1,
|
||||||
|
'loa-2' => 2,
|
||||||
|
'loa-3' => 3,
|
||||||
|
'loa-4' => 4,
|
||||||
|
'loa-5' => 5
|
||||||
|
},
|
||||||
|
'oidcServiceMetaDataAuthorizeURI' => 'authorize',
|
||||||
|
'oidcServiceMetaDataEndSessionURI' => 'logout',
|
||||||
|
'oidcServiceMetaDataJWKSURI' => 'jwks',
|
||||||
|
'oidcServiceMetaDataRegistrationURI' => 'register',
|
||||||
|
'oidcServiceMetaDataTokenURI' => 'token',
|
||||||
|
'oidcServiceMetaDataUserInfoURI' => 'userinfo',
|
||||||
|
'openIdAuthnLevel' => 1,
|
||||||
|
'openIdExportedVars' => {},
|
||||||
|
'openIdIDPList' => '0;',
|
||||||
|
'openIdSPList' => '0;',
|
||||||
|
'openIdSreg_email' => 'mail',
|
||||||
|
'openIdSreg_fullname' => 'cn',
|
||||||
|
'openIdSreg_nickname' => 'uid',
|
||||||
|
'openIdSreg_timezone' => '_timezone',
|
||||||
|
'passwordDB' => 'Demo',
|
||||||
|
'portal' => 'http://auth.example.com/',
|
||||||
|
'portalAntiFrame' => 1,
|
||||||
|
'portalAutocomplete' => 0,
|
||||||
|
'portalCheckLogins' => 1,
|
||||||
|
'portalDisplayAppslist' => 1,
|
||||||
|
'portalDisplayChangePassword' => '$_auth =~ /^(LDAP|DBI|Demo)$/',
|
||||||
|
'portalDisplayLoginHistory' => 1,
|
||||||
|
'portalDisplayLogout' => 1,
|
||||||
|
'portalDisplayRegister' => 1,
|
||||||
|
'portalDisplayResetPassword' => 1,
|
||||||
|
'portalForceAuthn' => 0,
|
||||||
|
'portalForceAuthnInterval' => 0,
|
||||||
|
'portalOpenLinkInNewWindow' => 0,
|
||||||
|
'portalPingInterval' => 60000,
|
||||||
|
'portalRequireOldPassword' => 1,
|
||||||
|
'portalSkin' => 'bootstrap',
|
||||||
|
'portalUserAttr' => '_user',
|
||||||
|
'protection' => 'none',
|
||||||
|
'radiusAuthnLevel' => 3,
|
||||||
|
'randomPasswordRegexp' => '[A-Z]{3}[a-z]{5}.\\d{2}',
|
||||||
|
'redirectFormMethod' => 'get',
|
||||||
|
'registerConfirmSubject' =>
|
||||||
|
'[LemonLDAP::NG] Account register confirmation',
|
||||||
|
'registerDB' => 'Demo',
|
||||||
|
'registerDoneSubject' => '[LemonLDAP::NG] Your new account',
|
||||||
|
'registerTimeout' => 0,
|
||||||
|
'registerUrl' => 'http://auth.example.com/register.pl',
|
||||||
|
'remoteGlobalStorage' => 'Lemonldap::NG::Common::Apache::Session::SOAP',
|
||||||
|
'remoteGlobalStorageOptions' => {
|
||||||
|
'ns' =>
|
||||||
|
'http://auth.example.com/Lemonldap/NG/Common/CGI/SOAPService',
|
||||||
|
'proxy' => 'http://auth.example.com/index.pl/sessions'
|
||||||
|
},
|
||||||
|
'samlAttributeAuthorityDescriptorAttributeServiceSOAP' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/AA/SOAP;',
|
||||||
|
'samlAuthnContextMapKerberos' => 4,
|
||||||
|
'samlAuthnContextMapPassword' => 2,
|
||||||
|
'samlAuthnContextMapPasswordProtectedTransport' => 3,
|
||||||
|
'samlAuthnContextMapTLSClient' => 5,
|
||||||
|
'samlCommonDomainCookieActivation' => 0,
|
||||||
|
'samlEntityID' => '#PORTAL#/saml/metadata',
|
||||||
|
'samlIDPMetaDataExportedAttributes' => ';;;',
|
||||||
|
'samlIDPMetaDataOptionsAdaptSessionUtime' => 0,
|
||||||
|
'samlIDPMetaDataOptionsAllowLoginFromIDP' => 0,
|
||||||
|
'samlIDPMetaDataOptionsAllowProxiedAuthn' => 0,
|
||||||
|
'samlIDPMetaDataOptionsCheckConditions' => 0,
|
||||||
|
'samlIDPMetaDataOptionsCheckSLOMessageSignature' => 0,
|
||||||
|
'samlIDPMetaDataOptionsCheckSSOMessageSignature' => 0,
|
||||||
|
'samlIDPMetaDataOptionsEncryptionMode' => 'none',
|
||||||
|
'samlIDPMetaDataOptionsForceAuthn' => 0,
|
||||||
|
'samlIDPMetaDataOptionsForceUTF8' => 0,
|
||||||
|
'samlIDPMetaDataOptionsIsPassive' => 0,
|
||||||
|
'samlIDPMetaDataOptionsNameIDFormat' => '',
|
||||||
|
'samlIDPMetaDataOptionsRequestedAuthnContext' => '',
|
||||||
|
'samlIDPMetaDataOptionsSignSLOMessage' => -1,
|
||||||
|
'samlIDPMetaDataOptionsSignSSOMessage' => -1,
|
||||||
|
'samlIDPMetaDataOptionsSSOBinding' => '',
|
||||||
|
'samlIdPResolveCookie' => 'lemonldapidp',
|
||||||
|
'samlIDPSSODescriptorArtifactResolutionServiceArtifact' =>
|
||||||
|
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
|
||||||
|
'samlIDPSSODescriptorSingleLogoutServiceHTTPPost' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
|
||||||
|
'samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
|
||||||
|
'samlIDPSSODescriptorSingleLogoutServiceSOAP' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/singleLogoutSOAP;',
|
||||||
|
'samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/singleSignOnArtifact;',
|
||||||
|
'samlIDPSSODescriptorSingleSignOnServiceHTTPPost' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleSignOn;',
|
||||||
|
'samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleSignOn;',
|
||||||
|
'samlIDPSSODescriptorSingleSignOnServiceSOAP' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/singleSignOnSOAP;',
|
||||||
|
'samlIDPSSODescriptorWantAuthnRequestsSigned' => 1,
|
||||||
|
'samlMetadataForceUTF8' => 1,
|
||||||
|
'samlNameIDFormatMapEmail' => 'mail',
|
||||||
|
'samlNameIDFormatMapKerberos' => 'uid',
|
||||||
|
'samlNameIDFormatMapWindows' => 'uid',
|
||||||
|
'samlNameIDFormatMapX509' => 'mail',
|
||||||
|
'samlOrganizationDisplayName' => 'Example',
|
||||||
|
'samlOrganizationName' => 'Example',
|
||||||
|
'samlOrganizationURL' => 'http://www.example.com',
|
||||||
|
'samlRelayStateTimeout' => 600,
|
||||||
|
'samlServicePrivateKeyEnc' => '',
|
||||||
|
'samlServicePrivateKeySig' => '',
|
||||||
|
'samlServicePrivateKeySigPwd' => '',
|
||||||
|
'samlServicePublicKeyEnc' => '',
|
||||||
|
'samlServicePublicKeySig' => '',
|
||||||
|
'samlSPMetaDataExportedAttributes' => ';;;',
|
||||||
|
'samlSPMetaDataOptionsCheckSLOMessageSignature' => 0,
|
||||||
|
'samlSPMetaDataOptionsCheckSSOMessageSignature' => 0,
|
||||||
|
'samlSPMetaDataOptionsEnableIDPInitiatedURL' => 0,
|
||||||
|
'samlSPMetaDataOptionsEncryptionMode' => 'none',
|
||||||
|
'samlSPMetaDataOptionsNameIDFormat' => '',
|
||||||
|
'samlSPMetaDataOptionsNotOnOrAfterTimeout' => 72000,
|
||||||
|
'samlSPMetaDataOptionsOneTimeUse' => 0,
|
||||||
|
'samlSPMetaDataOptionsSessionNotOnOrAfterTimeout' => 72000,
|
||||||
|
'samlSPMetaDataOptionsSignSLOMessage' => -1,
|
||||||
|
'samlSPMetaDataOptionsSignSSOMessage' => -1,
|
||||||
|
'samlSPSSODescriptorArtifactResolutionServiceArtifact' =>
|
||||||
|
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
|
||||||
|
'samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact' =>
|
||||||
|
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/proxySingleSignOnArtifact',
|
||||||
|
'samlSPSSODescriptorAssertionConsumerServiceHTTPPost' =>
|
||||||
|
'0;1;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleSignOnPost',
|
||||||
|
'samlSPSSODescriptorAuthnRequestsSigned' => 1,
|
||||||
|
'samlSPSSODescriptorSingleLogoutServiceHTTPPost' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
|
||||||
|
'samlSPSSODescriptorSingleLogoutServiceHTTPRedirect' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
|
||||||
|
'samlSPSSODescriptorSingleLogoutServiceSOAP' =>
|
||||||
|
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/proxySingleLogoutSOAP;',
|
||||||
|
'samlSPSSODescriptorWantAssertionsSigned' => 1,
|
||||||
|
'samlUseQueryStringSpecific' => 0,
|
||||||
|
'securedCookie' => 0,
|
||||||
|
'secureTokenAllowOnError' => 1,
|
||||||
|
'secureTokenAttribute' => 'uid',
|
||||||
|
'secureTokenExpiration' => 60,
|
||||||
|
'secureTokenHeader' => 'Auth-Token',
|
||||||
|
'secureTokenMemcachedServers' => '127.0.0.1:11211',
|
||||||
|
'secureTokenUrls' => '.*',
|
||||||
|
'singleIP' => 0,
|
||||||
|
'singleSession' => 0,
|
||||||
|
'singleSessionUserByIP' => 0,
|
||||||
|
'singleUserByIP' => 0,
|
||||||
|
'slaveAuthnLevel' => 2,
|
||||||
|
'slaveExportedVars' => {},
|
||||||
|
'SMTPServer' => '',
|
||||||
|
'Soap' => 0,
|
||||||
|
'SSLAuthnLevel' => 5,
|
||||||
|
'storePassword' => 0,
|
||||||
|
'successLoginNumber' => 5,
|
||||||
|
'syslog' => '',
|
||||||
|
'timeout' => 72000,
|
||||||
|
'timeoutActivity' => 0,
|
||||||
|
'trustedProxies' => '',
|
||||||
|
'twitterAuthnLevel' => 1,
|
||||||
|
'userControl' => '^[\\w\\.\\-@]+$',
|
||||||
|
'userDB' => 'Demo',
|
||||||
|
'useRedirectOnError' => 1,
|
||||||
|
'useRedirectOnForbidden' => 0,
|
||||||
|
'useSafeJail' => 1,
|
||||||
|
'vhostHttps' => -1,
|
||||||
|
'vhostMaintenance' => 0,
|
||||||
|
'vhostPort' => -1,
|
||||||
|
'webIDAuthnLevel' => 1,
|
||||||
|
'webIDExportedVars' => {},
|
||||||
|
'whatToTrace' => 'uid',
|
||||||
|
'yubikeyAuthnLevel' => 3,
|
||||||
|
'yubikeyPublicIDSize' => 12,
|
||||||
|
'zimbraBy' => ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -2,12 +2,30 @@ package Lemonldap::NG::Common::Conf::File;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Lemonldap::NG::Common::Conf::Constants; #inherits
|
use Lemonldap::NG::Common::Conf::Constants; #inherits
|
||||||
use Lemonldap::NG::Common::Conf::Serializer;
|
|
||||||
|
|
||||||
our $VERSION = '1.4.0';
|
our $VERSION = '1.4.0';
|
||||||
|
our $initDone;
|
||||||
|
|
||||||
|
sub Lemonldap::NG::Common::Conf::_lock {
|
||||||
|
my ( $self, $cfgNum ) = splice @_;
|
||||||
|
return "$self->{dirName}/lmConf.lock";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub Lemonldap::NG::Common::Conf::_file {
|
||||||
|
my ( $self, $cfgNum ) = splice @_;
|
||||||
|
return "$self->{dirName}/lmConf-$cfgNum.js";
|
||||||
|
}
|
||||||
|
|
||||||
sub prereq {
|
sub prereq {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
unless ($initDone) {
|
||||||
|
eval "use JSON";
|
||||||
|
if ($@) {
|
||||||
|
$Lemonldap::NG::Common::Conf::msg .= "Unable to load JSON: $@\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
$initDone++;
|
||||||
|
}
|
||||||
unless ( $self->{dirName} ) {
|
unless ( $self->{dirName} ) {
|
||||||
$Lemonldap::NG::Common::Conf::msg .=
|
$Lemonldap::NG::Common::Conf::msg .=
|
||||||
'"dirName" is required in "File" configuration type ! \n';
|
'"dirName" is required in "File" configuration type ! \n';
|
||||||
|
@ -26,7 +44,9 @@ sub available {
|
||||||
opendir D, $self->{dirName};
|
opendir D, $self->{dirName};
|
||||||
my @conf = readdir(D);
|
my @conf = readdir(D);
|
||||||
closedir D;
|
closedir D;
|
||||||
@conf = sort { $a <=> $b } map { /lmConf-(\d+)/ ? $1 : () } @conf;
|
@conf =
|
||||||
|
sort { $a <=> $b }
|
||||||
|
map { /lmConf-(\d+)(?:\.js)?/ ? ( $1 + 0 ) : () } @conf;
|
||||||
return @conf;
|
return @conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,9 +62,9 @@ sub lock {
|
||||||
sleep 2;
|
sleep 2;
|
||||||
return 0 if ( $self->isLocked );
|
return 0 if ( $self->isLocked );
|
||||||
}
|
}
|
||||||
unless ( open F, ">" . $self->{dirName} . "/lmConf.lock" ) {
|
unless ( open F, ">" . $self->_lock ) {
|
||||||
$Lemonldap::NG::Common::Conf::msg .=
|
$Lemonldap::NG::Common::Conf::msg .=
|
||||||
"Unable to lock (" . $self->{dirName} . "/lmConf.lock) \n";
|
"Unable to lock (" . $self->_lock . ") \n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
print F $$;
|
print F $$;
|
||||||
|
@ -54,30 +74,25 @@ sub lock {
|
||||||
|
|
||||||
sub isLocked {
|
sub isLocked {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
-e $self->{dirName} . "/lmConf.lock";
|
-e $self->_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub unlock {
|
sub unlock {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
unlink $self->{dirName} . "/lmConf.lock";
|
unlink $self->_lock;
|
||||||
1;
|
1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub store {
|
sub store {
|
||||||
my ( $self, $fields ) = @_;
|
my ( $self, $fields ) = @_;
|
||||||
$fields = $self->serialize($fields);
|
|
||||||
my $mask = umask;
|
my $mask = umask;
|
||||||
umask( oct('0027') );
|
umask( oct('0027') );
|
||||||
unless ( open FILE,
|
unless ( open FILE, ">" . $self->_file( $fields->{cfgNum} ) ) {
|
||||||
'>' . $self->{dirName} . "/lmConf-" . $fields->{cfgNum} )
|
|
||||||
{
|
|
||||||
$Lemonldap::NG::Common::Conf::msg .= "Open file failed: $! \n";
|
$Lemonldap::NG::Common::Conf::msg .= "Open file failed: $! \n";
|
||||||
$self->unlock;
|
$self->unlock;
|
||||||
return UNKNOWN_ERROR;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
foreach my $k ( sort keys %$fields ) {
|
print FILE JSON->new->canonical(1)->encode($fields);
|
||||||
print FILE "$k\n\t$fields->{$k}\n\n";
|
|
||||||
}
|
|
||||||
close FILE;
|
close FILE;
|
||||||
umask($mask);
|
umask($mask);
|
||||||
return $fields->{cfgNum};
|
return $fields->{cfgNum};
|
||||||
|
@ -86,29 +101,59 @@ sub store {
|
||||||
sub load {
|
sub load {
|
||||||
my ( $self, $cfgNum, $fields ) = @_;
|
my ( $self, $cfgNum, $fields ) = @_;
|
||||||
my $f;
|
my $f;
|
||||||
local $/ = "";
|
if ( -e $self->_file($cfgNum) ) {
|
||||||
unless ( open FILE, $self->{dirName} . "/lmConf-$cfgNum" ) {
|
local $/ = '';
|
||||||
$Lemonldap::NG::Common::Conf::msg .= "Open file failed: $! \n";
|
open FILE, $self->_file($cfgNum) or die "$!$@";
|
||||||
|
$f = join( '', <FILE> );
|
||||||
|
close FILE;
|
||||||
|
my $ret = eval { decode_json($f); };
|
||||||
|
die "Unable to load conf: $@\n" if ($@);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Old format
|
||||||
|
elsif ( -e "$self->{dirName}/lmConf-$cfgNum" ) {
|
||||||
|
open FILE, "$self->{dirName}/lmConf-$cfgNum" or die "$!$@";
|
||||||
|
local $/ = "";
|
||||||
|
unless ( open FILE, $self->{dirName} . "/lmConf-$cfgNum" ) {
|
||||||
|
$Lemonldap::NG::Common::Conf::msg .= "Open file failed: $! \n";
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
while (<FILE>) {
|
||||||
|
my ( $k, $v ) = split /\n\s+/;
|
||||||
|
chomp $k;
|
||||||
|
$v =~ s/\n*$//;
|
||||||
|
if ($fields) {
|
||||||
|
$f->{$k} = $v if ( grep { $_ eq $k } @$fields );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$f->{$k} = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close FILE;
|
||||||
|
require Lemonldap::NG::Common::Conf::Serializer;
|
||||||
|
return $self->unserialize($f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$Lemonldap::NG::Common::Conf::msg .=
|
||||||
|
"Unable to find configuration file";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
while (<FILE>) {
|
|
||||||
my ( $k, $v ) = split /\n\s+/;
|
|
||||||
chomp $k;
|
|
||||||
$v =~ s/\n*$//;
|
|
||||||
if ($fields) {
|
|
||||||
$f->{$k} = $v if ( grep { $_ eq $k } @$fields );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$f->{$k} = $v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close FILE;
|
|
||||||
return $self->unserialize($f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub delete {
|
sub delete {
|
||||||
my ( $self, $cfgNum ) = @_;
|
my ( $self, $cfgNum ) = @_;
|
||||||
unlink( $self->{dirName} . "/lmConf-$cfgNum" );
|
my $file = $self->_file($cfgNum);
|
||||||
|
if ( -e $file ) {
|
||||||
|
my $res = unlink($file);
|
||||||
|
$Lemonldap::NG::Common::Conf::msg .= $! unless ($res);
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$Lemonldap::NG::Common::Conf::msg .=
|
||||||
|
"Unable to delete conf $cfgNum, no such file";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -1,110 +1,9 @@
|
||||||
|
# Now, File.pm is a mix of the old File.pm and JSONFile.pm. So this file is
|
||||||
|
# just set for compatibility
|
||||||
package Lemonldap::NG::Common::Conf::JSONFile;
|
package Lemonldap::NG::Common::Conf::JSONFile;
|
||||||
|
|
||||||
use strict;
|
use Lemonldap::NG::Common::Conf::File;
|
||||||
use Lemonldap::NG::Common::Conf::Constants; #inherits
|
our @ISA = qw(Lemonldap::NG::Common::Conf::File);
|
||||||
|
|
||||||
our $VERSION = '1.4.0';
|
|
||||||
our $initDone;
|
|
||||||
|
|
||||||
sub prereq {
|
|
||||||
my $self = shift;
|
|
||||||
unless ($initDone) {
|
|
||||||
eval "use JSON::Any";
|
|
||||||
if ($@) {
|
|
||||||
$Lemonldap::NG::Common::Conf::msg .=
|
|
||||||
"Unable to load JSON::Any: $@\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
$initDone++;
|
|
||||||
}
|
|
||||||
unless ( $self->{dirName} ) {
|
|
||||||
$Lemonldap::NG::Common::Conf::msg .=
|
|
||||||
'"dirName" is required in "JSONFile" configuration type ! \n';
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
unless ( -d $self->{dirName} ) {
|
|
||||||
$Lemonldap::NG::Common::Conf::msg .=
|
|
||||||
"Directory \"$self->{dirName}\" does not exist ! \n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub available {
|
|
||||||
my $self = shift;
|
|
||||||
opendir D, $self->{dirName};
|
|
||||||
my @conf = readdir(D);
|
|
||||||
closedir D;
|
|
||||||
@conf = sort { $a <=> $b } map { /lmConf-(\d+)\.js/ ? $1 : () } @conf;
|
|
||||||
return @conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub lastCfg {
|
|
||||||
my $self = shift;
|
|
||||||
my @avail = $self->available;
|
|
||||||
return $avail[$#avail];
|
|
||||||
}
|
|
||||||
|
|
||||||
sub lock {
|
|
||||||
my $self = shift;
|
|
||||||
if ( $self->isLocked ) {
|
|
||||||
sleep 2;
|
|
||||||
return 0 if ( $self->isLocked );
|
|
||||||
}
|
|
||||||
unless ( open F, ">" . $self->{dirName} . "/lmConf.lock" ) {
|
|
||||||
$Lemonldap::NG::Common::Conf::msg .=
|
|
||||||
"Unable to lock (" . $self->{dirName} . "/lmConf.lock) \n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
print F $$;
|
|
||||||
close F;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub isLocked {
|
|
||||||
my $self = shift;
|
|
||||||
-e $self->{dirName} . "/lmConf.lock";
|
|
||||||
}
|
|
||||||
|
|
||||||
sub unlock {
|
|
||||||
my $self = shift;
|
|
||||||
unlink $self->{dirName} . "/lmConf.lock";
|
|
||||||
1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub store {
|
|
||||||
my ( $self, $fields ) = @_;
|
|
||||||
my $mask = umask;
|
|
||||||
umask( oct('0027') );
|
|
||||||
unless ( open FILE, ">$self->{dirName}/lmConf-$fields->{cfgNum}.js" ) {
|
|
||||||
$Lemonldap::NG::Common::Conf::msg .= "Open file failed: $! \n";
|
|
||||||
$self->unlock;
|
|
||||||
return UNKNOWN_ERROR;
|
|
||||||
}
|
|
||||||
print FILE JSON::Any->objToJson($fields);
|
|
||||||
close FILE;
|
|
||||||
umask($mask);
|
|
||||||
return $fields->{cfgNum};
|
|
||||||
}
|
|
||||||
|
|
||||||
sub load {
|
|
||||||
my ( $self, $cfgNum, $fields ) = @_;
|
|
||||||
my $f = '';
|
|
||||||
open FILE, "$self->{dirName}/lmConf-$cfgNum.js" or die "$!$@";
|
|
||||||
while (<FILE>) {
|
|
||||||
$f .= $_;
|
|
||||||
}
|
|
||||||
close FILE;
|
|
||||||
my $ret;
|
|
||||||
eval { $ret = JSON::Any->jsonToObj($f); };
|
|
||||||
die "Unable to load conf: $@\n" if ($@);
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub delete {
|
|
||||||
my ( $self, $cfgNum ) = @_;
|
|
||||||
unlink( $self->{dirName} . "/lmConf-$cfgNum.js" );
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
__END__
|
|
||||||
|
|
151
lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI.pm
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
package Lemonldap::NG::Common::PSGI;
|
||||||
|
|
||||||
|
use 5.10.0;
|
||||||
|
use Mouse;
|
||||||
|
use JSON;
|
||||||
|
use Lemonldap::NG::Common::PSGI::Constants;
|
||||||
|
use Lemonldap::NG::Common::PSGI::Request;
|
||||||
|
|
||||||
|
our $VERSION = '1.5.99';
|
||||||
|
|
||||||
|
our $_json = JSON->new->allow_nonref;
|
||||||
|
|
||||||
|
has error => ( is => 'rw', default => '' );
|
||||||
|
has languages => ( is => 'rw', isa => 'Str', default => 'en' );
|
||||||
|
has logLevel => ( is => 'rw', isa => 'Str' );
|
||||||
|
has staticPrefix => ( is => 'rw', isa => 'Str' );
|
||||||
|
has templateDir => ( is => 'rw', isa => 'Str' );
|
||||||
|
has links => ( is => 'rw', isa => 'ArrayRef' );
|
||||||
|
|
||||||
|
sub lmLog {
|
||||||
|
my ( $self, $msg, $level ) = splice @_;
|
||||||
|
my $levels = {
|
||||||
|
emerg => 7,
|
||||||
|
alert => 6,
|
||||||
|
crit => 5,
|
||||||
|
error => 4,
|
||||||
|
warn => 3,
|
||||||
|
notice => 2,
|
||||||
|
info => 1,
|
||||||
|
debug => 0
|
||||||
|
};
|
||||||
|
my $l = $levels->{$level} || 1;
|
||||||
|
return if ( ref($self) and $l < $levels->{ $self->{logLevel} } );
|
||||||
|
print STDERR "[$level] " . ( $l ? '' : (caller)[0] . ': ' ) . " $msg\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Responses methods
|
||||||
|
sub sendJSONresponse {
|
||||||
|
my ( $self, $req, $j, %args ) = splice @_;
|
||||||
|
$args{code} ||= 200;
|
||||||
|
my $type = 'text/json';
|
||||||
|
if ( ref $j ) {
|
||||||
|
if ( $args{forceJSON} or $req->accept =~ m|application/json| ) {
|
||||||
|
$j = $_json->encode($j);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
# TODO: escape keys in hash values
|
||||||
|
eval {
|
||||||
|
require XML::Simple;
|
||||||
|
$j = XML::Simple::XMLout($j);
|
||||||
|
$type = 'text/xml';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [ $args{code}, [ 'Content-Type', $type ], [$j] ];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub sendError {
|
||||||
|
my ( $self, $req, $err, $code ) = splice @_;
|
||||||
|
$err ||= $req->error;
|
||||||
|
$code ||= 500;
|
||||||
|
return $self->sendJSONresponse( $req, { error => $err }, code => $code );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub abort {
|
||||||
|
my ( $self, $err ) = splice @_;
|
||||||
|
$self->lmLog( $err, 'error' );
|
||||||
|
return sub {
|
||||||
|
$self->sendError( Lemonldap::NG::Common::PSGI::Request->new( $_[0] ),
|
||||||
|
$err, 500 );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _mustBeDefined {
|
||||||
|
my $name = ( caller(1) )[3];
|
||||||
|
$name =~ s/^.*:://;
|
||||||
|
my $call = ( caller(1) )[0];
|
||||||
|
my $ref = ref( $_[0] ) || $call;
|
||||||
|
die "$name() method must be implemented (probably in $ref)";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub init { 1 }
|
||||||
|
|
||||||
|
sub router { _mustBeDefined(@_) }
|
||||||
|
|
||||||
|
sub sendHtml {
|
||||||
|
my ( $self, $req, $template ) = splice @_;
|
||||||
|
my $htpl;
|
||||||
|
$template = $self->templateDir . "$template.tpl";
|
||||||
|
return $self->sendError( $req, "Unable to read $template", 500 )
|
||||||
|
unless ( -r $template and -f $template );
|
||||||
|
eval {
|
||||||
|
$self->lmLog( "Starting HTML generation using $template", 'debug' );
|
||||||
|
require HTML::Template;
|
||||||
|
$htpl = HTML::Template->new(
|
||||||
|
filehandle => IO::File->new($template),
|
||||||
|
path => $self->templateDir,
|
||||||
|
die_on_bad_params => 1,
|
||||||
|
die_on_missing_include => 1,
|
||||||
|
cache => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
# TODO: replace app
|
||||||
|
# TODO: warn if STATICPREFIX does not end with '/'
|
||||||
|
my $sp = $self->staticPrefix;
|
||||||
|
$sp =~ s/\/*$/\//;
|
||||||
|
$htpl->param(
|
||||||
|
SCRIPT_NAME => $req->scriptname,
|
||||||
|
STATIC_PREFIX => $sp,
|
||||||
|
AVAILABLE_LANGUAGES => $self->languages,
|
||||||
|
LINKS => $self->links ? encode_json( $self->links ) : '""',
|
||||||
|
);
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
return $self->sendError( $req, "Unable to load template: $@", 500 );
|
||||||
|
}
|
||||||
|
$self->lmLog(
|
||||||
|
'For more performance, store the result of this as static file',
|
||||||
|
'info' );
|
||||||
|
|
||||||
|
# Set headers
|
||||||
|
my $hdrs = [ 'Content-Type' => 'text/html' ];
|
||||||
|
unless ( $self->logLevel eq 'debug' ) {
|
||||||
|
push @$hdrs,
|
||||||
|
ETag => "LMNG-manager-$VERSION",
|
||||||
|
'Cache-Control' => 'private, max-age=2592000';
|
||||||
|
}
|
||||||
|
$self->lmLog( "Sending $template", 'debug' );
|
||||||
|
return [ 200, $hdrs, [ $htpl->output() ] ];
|
||||||
|
}
|
||||||
|
|
||||||
|
###############
|
||||||
|
# Main method #
|
||||||
|
###############
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my ( $self, $args ) = splice @_;
|
||||||
|
$self = $self->new($args) unless ref($self);
|
||||||
|
return $self->abort( $self->error ) unless ( $self->init($args) );
|
||||||
|
return $self->_run;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _run {
|
||||||
|
my $self = shift;
|
||||||
|
return sub {
|
||||||
|
$self->router( Lemonldap::NG::Common::PSGI::Request->new( $_[0] ) );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -0,0 +1,25 @@
|
||||||
|
package Lemonldap::NG::Common::PSGI::Constants;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use Exporter 'import';
|
||||||
|
|
||||||
|
use base qw(Exporter);
|
||||||
|
our $VERSION = '1.5.99';
|
||||||
|
|
||||||
|
# CONSTANTS
|
||||||
|
|
||||||
|
use constant {
|
||||||
|
DEBUG => 4,
|
||||||
|
INFO => 3,
|
||||||
|
WARN => 2,
|
||||||
|
NOTICE => 1,
|
||||||
|
ERROR => 0,
|
||||||
|
};
|
||||||
|
our $no = qr/^(?:off|no|0)?$/i;
|
||||||
|
|
||||||
|
our %EXPORT_TAGS = ( 'all' => [qw(DEBUG INFO WARN ERROR $no)] );
|
||||||
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||||
|
our @EXPORT = ( @{ $EXPORT_TAGS{'all'} } );
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
140
lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
package Lemonldap::NG::Common::PSGI::Request;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use Mouse;
|
||||||
|
use JSON;
|
||||||
|
use URI::Escape;
|
||||||
|
|
||||||
|
our $VERSION = '1.5.99';
|
||||||
|
|
||||||
|
# http :// server / path ? query # fragment
|
||||||
|
# m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;
|
||||||
|
|
||||||
|
has HTTP_ACCEPT => ( is => 'ro', reader => 'accept' );
|
||||||
|
has HTTP_ACCEPT_ENCODING => ( is => 'ro', reader => 'encodings' );
|
||||||
|
has HTTP_ACCEPT_LANGUAGE => ( is => 'ro', reader => 'languages' );
|
||||||
|
has HTTP_COOKIE => ( is => 'ro', reader => 'cookies' );
|
||||||
|
has HTTP_HOST => ( is => 'ro', reader => 'hostname' );
|
||||||
|
has REMOTE_ADDR => ( is => 'ro', isa => 'Str', reader => 'remote_ip' );
|
||||||
|
has REMOTE_PORT => ( is => 'ro', isa => 'Int', reader => 'port' );
|
||||||
|
has REQUEST_METHOD => ( is => 'ro', isa => 'Str', reader => 'method' );
|
||||||
|
has SCRIPT_NAME => ( is => 'ro', isa => 'Str', reader => 'scriptname' );
|
||||||
|
has SERVER_PORT => ( is => 'ro', isa => 'Int', reader => 'get_server_port' );
|
||||||
|
has PATH_INFO => (
|
||||||
|
is => 'ro',
|
||||||
|
reader => 'path',
|
||||||
|
lazy => 1,
|
||||||
|
default => '',
|
||||||
|
trigger => sub {
|
||||||
|
$_[0]->{REQUEST_URI} = uri_unescape( $_[0]->{REQUEST_URI} );
|
||||||
|
$_[0]->{REQUEST_URI} =~ s|//+|/|;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
has REQUEST_URI => (
|
||||||
|
is => 'ro',
|
||||||
|
reader => 'uri',
|
||||||
|
trigger => sub {
|
||||||
|
$_[0]->{unparsed_uri} = $_[0]->{REQUEST_URI};
|
||||||
|
$_[0]->{REQUEST_URI} = uri_unescape( $_[0]->{REQUEST_URI} );
|
||||||
|
},
|
||||||
|
);
|
||||||
|
has unparsed_uri => ( is => 'rw', isa => 'Str' );
|
||||||
|
|
||||||
|
has 'psgi.errors' => ( is => 'rw', reader => 'stderr' );
|
||||||
|
|
||||||
|
# Authentication
|
||||||
|
|
||||||
|
has REMOTE_USER => (
|
||||||
|
is => 'ro',
|
||||||
|
isa => 'Int',
|
||||||
|
reader => 'user',
|
||||||
|
trigger => sub {
|
||||||
|
$_[0]->{userData} = { _whatToTrace => $_[0]->{REMOTE_USER}, };
|
||||||
|
},
|
||||||
|
);
|
||||||
|
has userData => ( is => 'rw', isa => 'HashRef', default => sub { {} } );
|
||||||
|
|
||||||
|
# Query parameters
|
||||||
|
has _params => ( is => 'rw', isa => 'HashRef', default => sub { {} } );
|
||||||
|
has QUERY_STRING => (
|
||||||
|
is => 'ro',
|
||||||
|
reader => 'query',
|
||||||
|
trigger => sub {
|
||||||
|
my $self = shift;
|
||||||
|
$self->{QUERY_STRING} = uri_unescape( $self->{QUERY_STRING} );
|
||||||
|
my @tmp =
|
||||||
|
$self->{QUERY_STRING}
|
||||||
|
? split /&/, $self->{QUERY_STRING}
|
||||||
|
: ();
|
||||||
|
foreach my $s (@tmp) {
|
||||||
|
if ( $s =~ /^(.+?)=(.+)$/ ) { $self->{_params}->{$1} = $2; }
|
||||||
|
else { $self->{_params}->{$s} = 1; }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
sub params {
|
||||||
|
my ( $self, $key, $value ) = splice @_;
|
||||||
|
return $self->_params unless ($key);
|
||||||
|
$self->_params->{$key} = $value if ($value);
|
||||||
|
return $self->_params->{$key};
|
||||||
|
}
|
||||||
|
|
||||||
|
# POST management
|
||||||
|
#
|
||||||
|
# When CONTENT_LENGTH is set, store body in memory in `body` key
|
||||||
|
has 'psgix.input.buffered' => ( is => 'ro', reader => '_psgixBuffered', );
|
||||||
|
has 'psgi.input' => ( is => 'ro', reader => '_psgiInput', );
|
||||||
|
has body => ( is => 'rw', isa => 'Str', default => '' );
|
||||||
|
has CONTENT_TYPE => ( is => 'ro', isa => 'Str', reader => 'contentType', );
|
||||||
|
has CONTENT_LENGTH => (
|
||||||
|
is => 'ro',
|
||||||
|
isa => 'Int',
|
||||||
|
reader => 'contentLength',
|
||||||
|
lazy => 1,
|
||||||
|
default => 0,
|
||||||
|
trigger => sub {
|
||||||
|
my $self = shift;
|
||||||
|
if ( $self->method eq 'GET' ) { $self->{body} = undef; }
|
||||||
|
elsif ( $self->method =~ /^(?:POST|PUT)$/ ) {
|
||||||
|
$self->{body} = '';
|
||||||
|
if ( $self->_psgixBuffered ) {
|
||||||
|
my $length = $self->{CONTENT_LENGTH};
|
||||||
|
while ( $length > 0 ) {
|
||||||
|
my $buffer;
|
||||||
|
$self->_psgiInput->read( $buffer,
|
||||||
|
( $length < 8192 ) ? $length : 8192 );
|
||||||
|
$length -= length($buffer);
|
||||||
|
$self->{body} .= $buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->_psgiInput->read( $self->{body},
|
||||||
|
$self->{CONTENT_LENGTH}, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
has error => ( is => 'rw', isa => 'Str', default => '' );
|
||||||
|
|
||||||
|
# JSON parser
|
||||||
|
sub jsonBodyToObj {
|
||||||
|
my $self = shift;
|
||||||
|
unless ( $self->contentType =~ /application\/json/ ) {
|
||||||
|
$self->error('Data is not JSON');
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
unless ( $self->body ) {
|
||||||
|
$self->error('No data');
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
return $self->body if ( ref( $self->body ) );
|
||||||
|
my $j = eval { decode_json( $self->body ) };
|
||||||
|
if ( $@ or $! ) {
|
||||||
|
$self->error("$@$!");
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
return $self->{body} = $j;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
152
lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Router.pm
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
package Lemonldap::NG::Common::PSGI::Router;
|
||||||
|
|
||||||
|
use Mouse;
|
||||||
|
use Lemonldap::NG::Common::PSGI;
|
||||||
|
use Lemonldap::NG::Common::PSGI::Constants;
|
||||||
|
|
||||||
|
our $VERSION = '1.5.99';
|
||||||
|
|
||||||
|
extends 'Lemonldap::NG::Common::PSGI';
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
has 'routes' => (
|
||||||
|
is => 'rw',
|
||||||
|
isa => 'HashRef',
|
||||||
|
default => sub { { GET => {}, POST => {}, PUT => {}, DELETE => {} } }
|
||||||
|
);
|
||||||
|
has 'defaultRoute' => ( is => 'rw', default => 'index.html' );
|
||||||
|
|
||||||
|
# Routes initialization
|
||||||
|
|
||||||
|
sub addRoute {
|
||||||
|
my ( $self, $word, $dest, $methods ) = splice(@_);
|
||||||
|
$methods ||= [qw(GET POST PUT DELETE)];
|
||||||
|
foreach my $method (@$methods) {
|
||||||
|
$self->genRoute( $self->routes->{$method}, $word, $dest );
|
||||||
|
}
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub genRoute {
|
||||||
|
my ( $self, $routes, $word, $dest ) = splice @_;
|
||||||
|
if ( ref $word eq 'ARRAY' ) {
|
||||||
|
foreach my $w (@$word) {
|
||||||
|
$self->genRoute( $routes, $w, $dest );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( $word =~ /^:(.*)$/ ) {
|
||||||
|
$routes->{'#'} = $1;
|
||||||
|
die "Target required for $word" unless ($dest);
|
||||||
|
$word = ':';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$dest ||= $word;
|
||||||
|
}
|
||||||
|
if ( my $t = ref $dest ) {
|
||||||
|
if ( $t eq 'CODE' ) {
|
||||||
|
$routes->{$word} = $dest;
|
||||||
|
}
|
||||||
|
elsif ( $t eq 'HASH' ) {
|
||||||
|
$routes->{$word} ||= {};
|
||||||
|
foreach my $w ( keys %$dest ) {
|
||||||
|
$self->genRoute( $routes->{$word}, $w, $dest->{$w} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $t eq 'ARRAY' ) {
|
||||||
|
$routes->{$word} ||= {};
|
||||||
|
foreach my $w ( @{$dest} ) {
|
||||||
|
$self->genRoute( $routes->{$word}, $w );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die "Type $t unauthorizated in routes";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $dest =~ /^(.+)\.html$/ ) {
|
||||||
|
my $tpl = $1 or die;
|
||||||
|
$routes->{$word} = sub { $self->sendHtml( $_[1], $tpl ) };
|
||||||
|
}
|
||||||
|
elsif ( $self->can($dest) ) {
|
||||||
|
$routes->{$word} = sub { shift; $self->$dest(@_) };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die "$dest() isn't a method";
|
||||||
|
}
|
||||||
|
$self->lmLog( "route $word added", 'debug' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub abort {
|
||||||
|
my ( $self, $path, $msg ) = splice @_;
|
||||||
|
delete $self->routes->{$path};
|
||||||
|
$self->addRoute(
|
||||||
|
$path => sub {
|
||||||
|
my ( $self, $req ) = splice @_;
|
||||||
|
return $self->sendError( $req, $msg, 500 );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Methods that dispatch requests
|
||||||
|
|
||||||
|
sub router {
|
||||||
|
my ( $self, $req ) = splice @_;
|
||||||
|
|
||||||
|
#print STDERR Dumper($self->routes);use Data::Dumper;
|
||||||
|
|
||||||
|
# Reinitialize configuration message
|
||||||
|
$Lemonldap::NG::Common::Conf::msg = '';
|
||||||
|
|
||||||
|
# Launch reqInit() if exists
|
||||||
|
if ( $self->can('reqInit') ) {
|
||||||
|
$self->reqInit($req);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Only words are taken in path
|
||||||
|
my @path = grep { $_ =~ /^[\.\w]+/ } split /\//, $req->path();
|
||||||
|
$self->lmLog( "Start routing " . ( $path[0] // 'default route' ), 'debug' );
|
||||||
|
|
||||||
|
unless (@path) {
|
||||||
|
push @path, $self->defaultRoute;
|
||||||
|
|
||||||
|
# TODO: E-Tag, Expires,...
|
||||||
|
#
|
||||||
|
## NB: this is not HTTP compliant: host and protocol are required !
|
||||||
|
#my $url = '/' . $self->defaultRoute;
|
||||||
|
#return [
|
||||||
|
# 302,
|
||||||
|
# [ 'Content-Type' => 'text/plain', 'Location' => $url ],
|
||||||
|
# ['Document has moved here: $url']
|
||||||
|
#];
|
||||||
|
}
|
||||||
|
return $self->followPath( $req, $self->routes->{ $req->method }, \@path );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub followPath {
|
||||||
|
my ( $self, $req, $routes, $path ) = splice @_;
|
||||||
|
if ( $path->[0] and defined $routes->{ $path->[0] } ) {
|
||||||
|
my $w = shift @$path;
|
||||||
|
if ( ref( $routes->{$w} ) eq 'CODE' ) {
|
||||||
|
return $routes->{$w}->( $self, $req, @$path );
|
||||||
|
}
|
||||||
|
return $self->followPath( $req, $routes->{$w}, $path );
|
||||||
|
}
|
||||||
|
elsif ( $routes->{':'} ) {
|
||||||
|
my $v = shift @$path;
|
||||||
|
$req->params->{ $routes->{'#'} } = $v;
|
||||||
|
if ( ref( $routes->{':'} ) eq 'CODE' ) {
|
||||||
|
return $routes->{':'}->( $self, $req, @$path );
|
||||||
|
}
|
||||||
|
return $self->followPath( $req, $routes->{':'}, $path );
|
||||||
|
}
|
||||||
|
elsif ( my $sub = $routes->{'*'} ) {
|
||||||
|
return $self->$sub( $req, @$path );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->lmLog( 'Bad request received (' . $req->path . ')', 'warn' );
|
||||||
|
return $self->sendError( $req, 'Bad request', 400 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -40,9 +40,10 @@ my $mp = $ENV{MOD_PERL_API_VERSION};
|
||||||
my $mode =
|
my $mode =
|
||||||
$gi && $gi =~ /^CGI/ ? "CGI"
|
$gi && $gi =~ /^CGI/ ? "CGI"
|
||||||
: $mp && $mp >= 2 ? "ApacheMP2"
|
: $mp && $mp >= 2 ? "ApacheMP2"
|
||||||
: $mp ? "ApacheMP1"
|
: $mp ? "ApacheMP1"
|
||||||
: $main::{'nginx::'} ? "Nginx"
|
: $main::{'nginx::'} ? "Nginx"
|
||||||
: "CGI";
|
: ( caller(6) )[0] eq 'Lemonldap::NG::Handler::PSGI' ? "PSGI"
|
||||||
|
: "CGI";
|
||||||
|
|
||||||
# Load API functions and constants
|
# Load API functions and constants
|
||||||
eval "use Lemonldap::NG::Handler::API::$mode (':httpCodes', ':functions');
|
eval "use Lemonldap::NG::Handler::API::$mode (':httpCodes', ':functions');
|
||||||
|
|
186
lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI.pm
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
package Lemonldap::NG::Handler::API::PSGI;
|
||||||
|
|
||||||
|
use Exporter 'import';
|
||||||
|
|
||||||
|
our $VERSION = '1.4.0';
|
||||||
|
our ( %EXPORT_TAGS, @EXPORT_OK, @EXPORT );
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
%EXPORT_TAGS = (
|
||||||
|
httpCodes => [
|
||||||
|
qw( OK REDIRECT FORBIDDEN DONE DECLINED SERVER_ERROR AUTH_REQUIRED MAINTENANCE $logLevel )
|
||||||
|
],
|
||||||
|
functions => [
|
||||||
|
qw( &hostname &remote_ip &uri &uri_with_args
|
||||||
|
&unparsed_uri &args &method &header_in )
|
||||||
|
]
|
||||||
|
);
|
||||||
|
push( @EXPORT_OK, @{ $EXPORT_TAGS{$_} } ) foreach ( keys %EXPORT_TAGS );
|
||||||
|
$EXPORT_TAGS{all} = \@EXPORT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Specific modules and constants for Test or CGI
|
||||||
|
use constant FORBIDDEN => 403;
|
||||||
|
use constant REDIRECT => 302;
|
||||||
|
use constant OK => 0;
|
||||||
|
use constant DECLINED => 0;
|
||||||
|
use constant DONE => 0;
|
||||||
|
use constant SERVER_ERROR => 500;
|
||||||
|
use constant AUTH_REQUIRED => 401;
|
||||||
|
use constant MAINTENANCE => 503;
|
||||||
|
|
||||||
|
my $request;
|
||||||
|
|
||||||
|
## @method void thread_share(string $variable)
|
||||||
|
# share or not the variable (if authorized by specific module)
|
||||||
|
# @param $variable the name of the variable to share
|
||||||
|
sub thread_share {
|
||||||
|
|
||||||
|
# nothing to do in PSGI
|
||||||
|
}
|
||||||
|
|
||||||
|
sub newRequest {
|
||||||
|
my ( $class, $r ) = @_;
|
||||||
|
$request = $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void lmLog(string $msg, string $level)
|
||||||
|
# logs message $msg to STDERR with level $level
|
||||||
|
# set Env Var lmLogLevel to set loglevel; set to "info" by default
|
||||||
|
# @param $msg string message to log
|
||||||
|
# @param $level string loglevel
|
||||||
|
*lmLog = *Lemonldap::NG::Common::PSGI::lmLog;
|
||||||
|
|
||||||
|
## @method void set_user(string user)
|
||||||
|
# sets remote_user
|
||||||
|
# @param user string username
|
||||||
|
sub set_user {
|
||||||
|
my ( $class, $user ) = splice @_;
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string header_in(string header)
|
||||||
|
# returns request header value
|
||||||
|
# @param header string request header
|
||||||
|
# @return request header value
|
||||||
|
sub header_in {
|
||||||
|
my ( $class, $header ) = @_;
|
||||||
|
$header ||= $class; # to use header_in as a method or as a function
|
||||||
|
return $request->{ cgiName($header) };
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void set_header_in(hash headers)
|
||||||
|
# sets or modifies request headers
|
||||||
|
# @param headers hash containing header names => header value
|
||||||
|
sub set_header_in {
|
||||||
|
my ( $class, %headers ) = @_;
|
||||||
|
while ( my ( $h, $v ) = each %headers ) {
|
||||||
|
$request->{ cgiName($h) } = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void unset_header_in(array headers)
|
||||||
|
# removes request headers
|
||||||
|
# @param headers array with header names to remove
|
||||||
|
sub unset_header_in {
|
||||||
|
my ( $class, @headers ) = @_;
|
||||||
|
foreach my $h (@headers) {
|
||||||
|
delete $request->{ cgiName($h) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void set_header_out(hash headers)
|
||||||
|
# sets response headers
|
||||||
|
# @param headers hash containing header names => header value
|
||||||
|
sub set_header_out {
|
||||||
|
my ( $class, %headers ) = @_;
|
||||||
|
while ( my ( $h, $v ) = each %headers ) {
|
||||||
|
$request->{respHeaders}->{$h} = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string hostname
|
||||||
|
# returns host, as set by full URI or Host header
|
||||||
|
# @return host string Host value
|
||||||
|
sub hostname {
|
||||||
|
my $h = $request->hostname;
|
||||||
|
$h =~ s/:\d+//;
|
||||||
|
return $h;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string remote_ip
|
||||||
|
# returns client IP address
|
||||||
|
# @return IP_Addr string client IP
|
||||||
|
sub remote_ip {
|
||||||
|
return $request->remote_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method boolean is_initial_req
|
||||||
|
# always returns true
|
||||||
|
# @return is_initial_req boolean
|
||||||
|
sub is_initial_req {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string args(string args)
|
||||||
|
# gets the query string
|
||||||
|
# @return args string Query string
|
||||||
|
sub args {
|
||||||
|
return $request->query;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string uri
|
||||||
|
# returns the path portion of the URI, normalized, i.e. :
|
||||||
|
# * URL decoded (characters encoded as %XX are decoded,
|
||||||
|
# except ? in order not to merge path and query string)
|
||||||
|
# * references to relative path components "." and ".." are resolved
|
||||||
|
# * two or more adjacent slashes are merged into a single slash
|
||||||
|
# @return path portion of the URI, normalized
|
||||||
|
sub uri {
|
||||||
|
return $request->uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string uri_with_args
|
||||||
|
# returns the URI, with arguments and with path portion normalized
|
||||||
|
# @return URI with normalized path portion
|
||||||
|
sub uri_with_args {
|
||||||
|
return $request->uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string unparsed_uri
|
||||||
|
# returns the full original request URI, with arguments
|
||||||
|
# @return full original request URI, with arguments
|
||||||
|
sub unparsed_uri {
|
||||||
|
return $request->unparsed_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string get_server_port
|
||||||
|
# returns the port the server is receiving the current request on
|
||||||
|
# @return port string server port
|
||||||
|
sub get_server_port {
|
||||||
|
return $request->get_server_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string method
|
||||||
|
# returns the request method
|
||||||
|
# @return port string server port
|
||||||
|
sub method {
|
||||||
|
return $request->method;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void print(string data)
|
||||||
|
# write data in HTTP response body
|
||||||
|
# @param data Text to add in response body
|
||||||
|
sub print {
|
||||||
|
my ( $class, $data ) = @_;
|
||||||
|
$request->{respBody} .= $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cgiName {
|
||||||
|
my $h = uc(shift);
|
||||||
|
$h =~ s/-/_/g;
|
||||||
|
return "HTTP_$h";
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -26,7 +26,7 @@ BEGIN {
|
||||||
sub logLevelInit {
|
sub logLevelInit {
|
||||||
my ( $class, $level ) = @_;
|
my ( $class, $level ) = @_;
|
||||||
$logLevel = $level || $Lemonldap::NG::Handler::API::logLevel || "debug";
|
$logLevel = $level || $Lemonldap::NG::Handler::API::logLevel || "debug";
|
||||||
$logLevel = $logLevels->{$logLevel};
|
$logLevel = $logLevels->{$logLevel} || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
## @rmethod void lmLog(string msg, string level)
|
## @rmethod void lmLog(string msg, string level)
|
||||||
|
|
71
lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI.pm
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
package Lemonldap::NG::Handler::PSGI;
|
||||||
|
|
||||||
|
use 5.10.0;
|
||||||
|
use Mouse;
|
||||||
|
use Lemonldap::NG::Handler::SharedConf qw(:tsv :variables);
|
||||||
|
extends 'Lemonldap::NG::Common::PSGI::Router';
|
||||||
|
|
||||||
|
our $VERSION = 1.5.99;
|
||||||
|
|
||||||
|
around init => sub {
|
||||||
|
my ( $method, $self, $args ) = splice @_;
|
||||||
|
Lemonldap::NG::Handler::SharedConf->init( $self );
|
||||||
|
return $self->$method($args);
|
||||||
|
};
|
||||||
|
|
||||||
|
sub _run {
|
||||||
|
my $self = shift;
|
||||||
|
my $rule = $self->{protection} || $localConfig->{protection};
|
||||||
|
if ( $rule ne 'none' ) {
|
||||||
|
$rule =
|
||||||
|
$rule eq "authenticate" ? "accept" : $rule eq "manager" ? "" : $rule;
|
||||||
|
return sub {
|
||||||
|
my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] );
|
||||||
|
Lemonldap::NG::Handler::API->newRequest($req);
|
||||||
|
my $res = Lemonldap::NG::Handler::SharedConf->run($rule);
|
||||||
|
|
||||||
|
# TODO: Userdata
|
||||||
|
#print STDERR Dumper( \@_, $res ); use Data::Dumper;
|
||||||
|
if ( $res == 403 ) {
|
||||||
|
return [
|
||||||
|
403,
|
||||||
|
[ 'Content-Type' => 'text/plain' ],
|
||||||
|
["You don't have rights to access this page"]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ajax hook: Ajax requests can not understand 30x responses. This
|
||||||
|
# is not really HTTP compliant but nothing in this
|
||||||
|
# protocol can do this. Our javascript understand that
|
||||||
|
# it has to prompt user with the URL
|
||||||
|
elsif (
|
||||||
|
( $res == 302 or $res == 303 )
|
||||||
|
and ( $req->accept =~ m|application/json|
|
||||||
|
or $req->contentType =~ m|application/json| )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
401, [ Authorization => $req->{respHeaders}->{Location} ],
|
||||||
|
['']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
elsif ($res) {
|
||||||
|
return [ $res, [ %{ $req->{respHeaders} } ], [''] ];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $self->router($req);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eval { Lemonldap::NG::Handler::SharedConf->checkConf() } unless (%$tsv);
|
||||||
|
$self->lmLog( $@, 'error' ) if ($@);
|
||||||
|
return sub {
|
||||||
|
|
||||||
|
#print STDERR Dumper(\@_);use Data::Dumper;
|
||||||
|
$self->router( Lemonldap::NG::Common::PSGI::Request->new( $_[0] ) );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
31
lemonldap-ng-manager/KINEMATIC.md
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# Lemonldap::NG::Manager kinematic
|
||||||
|
|
||||||
|
## Initialization
|
||||||
|
|
||||||
|
PSGI file
|
||||||
|
|
|
||||||
|
+-> Common::PSGI::run() (Manager inheritance)
|
||||||
|
|
|
||||||
|
+-> Common::PSGI::new() unless(defined $self)
|
||||||
|
|
|
||||||
|
+-> Manager::init()
|
||||||
|
|
|
||||||
|
+-> Manager::<modules>::addRoutes()
|
||||||
|
(module can be one of `Conf`, `Sessions`, `Notifications`
|
||||||
|
|
|
||||||
|
+-> Common::PSGI::Router::addRoute()
|
||||||
|
|
||||||
|
_Common::PSGI::run()_ returns a subroutine
|
||||||
|
|
||||||
|
## HTTP responses
|
||||||
|
|
||||||
|
PSGI system launch the previous sub
|
||||||
|
|
||||||
|
sub
|
||||||
|
|
|
||||||
|
+-> Common::PSGI::Router::router ( Lemonldap::NG::Common::PSGI::Request->new() )
|
||||||
|
|
|
||||||
|
+-> Common::PSGI::Router::followPath()
|
||||||
|
|
|
||||||
|
+-> Launch the corresponding Manager::<module> subroutine declared with addRoutes()
|
||||||
|
|
42
lemonldap-ng-manager/README.md
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# angular-lemonldap-ng-manager
|
||||||
|
|
||||||
|
This is just a POC to build an angular based manager for
|
||||||
|
Lemonldap::NG.
|
||||||
|
|
||||||
|
See [LemonLDAP::NG website](http://lemonldap-ng.org/).
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
git clone https://github.com/guimard/angular-lemonldap-ng-manager.git
|
||||||
|
cd angular-lemonldap-ng-manager
|
||||||
|
npm install
|
||||||
|
|
||||||
|
## Start servers
|
||||||
|
|
||||||
|
npm run perlserver
|
||||||
|
npm start
|
||||||
|
|
||||||
|
## MVC
|
||||||
|
|
||||||
|
* The view is managed by :
|
||||||
|
* `index.html` for HTML building
|
||||||
|
* _some other html files for forms ?_
|
||||||
|
* `struct.json` who gives the tree position for each configuration element and
|
||||||
|
requests to do
|
||||||
|
* translate.json (which will be delivered by a CGI to choose current language)
|
||||||
|
* The controller is splitted in 2 pieces :
|
||||||
|
* client side in `js/manager.js`, based on ANgularJS, it provides the link
|
||||||
|
between the DOM and the CGI. It manages:
|
||||||
|
* downloads of JSON datas
|
||||||
|
* translations
|
||||||
|
* form display depending on data types
|
||||||
|
* server side, based on PSGI, it provides the link between network and
|
||||||
|
configuration. It will be able to respond to 3 types of _rest_ queries:
|
||||||
|
* key values
|
||||||
|
* hash keys for this type of nodes
|
||||||
|
* hash content
|
||||||
|
* The model (datas) is:
|
||||||
|
* the current configuration
|
||||||
|
* the modified datas _(client side only or both to be able to notify changes
|
||||||
|
to other administrators ?)_
|
||||||
|
|
65
lemonldap-ng-manager/REST-API.md
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# Lemonldap::NG::Manager REST API
|
||||||
|
|
||||||
|
## Configurations
|
||||||
|
|
||||||
|
* List of available configuration: `/confs`
|
||||||
|
* Last configuration number: `/confs/latest/cfgNum`
|
||||||
|
* Configuration metadatas: `/confs/<cfgNum|latest>`
|
||||||
|
* Key value: `/confs/<cfgNum|latest>/<key>`
|
||||||
|
* Full configuration (for saving): `/confs/<cfgNum|latest>?full`
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* `/confs/latest/portal`
|
||||||
|
* `/confs/184/portal`
|
||||||
|
* `/confs/184/virtualHosts/test1.example.com/locationRules`
|
||||||
|
|
||||||
|
### Available verbs:
|
||||||
|
|
||||||
|
* `GET`: see above
|
||||||
|
* `POST /confs`: push a new configuration (or a saved one)
|
||||||
|
`POST /confs?force=yes`: push a new configuration even if another has been
|
||||||
|
posted before
|
||||||
|
* _`DELETE /confs/<cfgNum>`: not allowed_, administrator has to push an older
|
||||||
|
with `?force=yes`
|
||||||
|
|
||||||
|
**And perhaps:**
|
||||||
|
|
||||||
|
* `PUT /confs/prepared/<key>`: modify a value in the future configuration
|
||||||
|
* `DELETE /confs/prepared/<path>/<key>`: delete a hash entry (virtual host for
|
||||||
|
example)
|
||||||
|
* `GET /confs/prepared/<key>`: get value from prepared configuration if exists,
|
||||||
|
get current value otherwise
|
||||||
|
|
||||||
|
## Sessions
|
||||||
|
|
||||||
|
* Sessions list: `/sessions`
|
||||||
|
* Session: `/sessions/<hash>`
|
||||||
|
* **TODO**: Session key: `/sessions/<hash>/<key>`
|
||||||
|
* Delete session: `DELETE /sessions/<hash>`
|
||||||
|
* Filters:
|
||||||
|
* All connected users which username start by a letter:
|
||||||
|
`/sessions?_whatToTrace=<letter>*&groupBy=_whatToTrace`
|
||||||
|
* User's sessions: `/sessions?_whatToTrace=foo.bar`
|
||||||
|
* IP's sessions: `/sessions?ip=1.2.3.4`
|
||||||
|
* Double sessions by IP: `/sessions?doubleIP`
|
||||||
|
* Group by:
|
||||||
|
* First letter of Connected users: `/sessions?groupBy=substr(_whatToTrace,1)`
|
||||||
|
* Order:
|
||||||
|
* Sessions sorted by user: `/sessions?orderBy=_whatToTrace`
|
||||||
|
|
||||||
|
Note that sessions are grouped automaticaly.
|
||||||
|
|
||||||
|
## Notifications
|
||||||
|
|
||||||
|
* Notifications list: `/notifications/actives`
|
||||||
|
* Notification: `/notifications/actives/<notif_id>`
|
||||||
|
* Notified elements list: `/notifications/done`
|
||||||
|
* Notified element: `/notifications/done/<notif_id>`
|
||||||
|
* New session: `POST /notifications`
|
||||||
|
* Filters:
|
||||||
|
* All notifications for users which name starts by a letter:
|
||||||
|
`/notifications?_whatToTrace=<letter>*&groupBy=_whatToTrace`
|
||||||
|
* User's notifications: `/notifications/(actives|done)?_whatToTrace=foo.bar`
|
||||||
|
* Mark as notified: `PUT /notifications/actives/<notif_id> done=1`
|
||||||
|
* Delete notofication: `DELETE /notifications/done/<notif_id>`
|
58
lemonldap-ng-manager/TODO.md
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# Lemonldap::NG::Manager TODO list
|
||||||
|
|
||||||
|
* Check for eval with SAML
|
||||||
|
* userInfo && userWarn
|
||||||
|
* Help interface
|
||||||
|
|
||||||
|
## Configuration management
|
||||||
|
|
||||||
|
* `currentConf` => `$req` instead of `$self`
|
||||||
|
* PSGI: improve log system (syslog,...)
|
||||||
|
* Forms:
|
||||||
|
* issuers resume
|
||||||
|
|
||||||
|
### Struct & datas
|
||||||
|
|
||||||
|
* Tests for new confs
|
||||||
|
* default values: TODO, deliver a "0" conf when no conf is available
|
||||||
|
* Forms:
|
||||||
|
* file: load from URL + download
|
||||||
|
* Grant session rule
|
||||||
|
* OpenID white/black list
|
||||||
|
* oidcOpMetadata ?
|
||||||
|
|
||||||
|
* import from JSON
|
||||||
|
|
||||||
|
### REST API:
|
||||||
|
|
||||||
|
### PSGI authentication
|
||||||
|
|
||||||
|
* JQuery module to add `$._llngAjax`
|
||||||
|
* Angular module to add $llngHttp
|
||||||
|
|
||||||
|
### Help system
|
||||||
|
|
||||||
|
## Sessions explorer
|
||||||
|
|
||||||
|
## Optimization
|
||||||
|
|
||||||
|
* Create modules to get needed values for a new conf without using
|
||||||
|
`Common::Conf::Attributes`
|
||||||
|
* Then delete essential default values in running modules: they have to be
|
||||||
|
provided by any configuration
|
||||||
|
* Use JSON to store datas:
|
||||||
|
* configuration: the new `File` will look at the first character. If not `{`,
|
||||||
|
it will call old `File` functions
|
||||||
|
* sessions: new Apache::Session::Serialize::JSON module
|
||||||
|
|
||||||
|
## Doc
|
||||||
|
|
||||||
|
* Wiki doc
|
||||||
|
* Developer corner:
|
||||||
|
* adding a configurationkey
|
||||||
|
* adding a data type
|
||||||
|
|
||||||
|
## Question more
|
||||||
|
|
||||||
|
* Phonegap
|
||||||
|
* Ionic
|
15
lemonldap-ng-manager/bower.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "angular-lemonldap-ng-manager",
|
||||||
|
"description": "Lemonldap::NG manager with AngularJS",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"homepage": "https://github.com/guimard/angular-lemonldap-ng-manager",
|
||||||
|
"license": "GPL2",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"angular": "1.3.x",
|
||||||
|
"angular-route": "1.x",
|
||||||
|
"angular-ui-tree": "2.1.5",
|
||||||
|
"bootstrap": "~3.1.1",
|
||||||
|
"jquery": "~2.1.1"
|
||||||
|
}
|
||||||
|
}
|
5
lemonldap-ng-manager/eg/manager-server.psgi
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env plackup -I pl/lib
|
||||||
|
|
||||||
|
use Lemonldap::NG::Manager;
|
||||||
|
|
||||||
|
Lemonldap::NG::Manager->run({});
|
|
@ -1,54 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Lemonldap::NG::Manager;
|
|
||||||
use HTML::Template;
|
|
||||||
|
|
||||||
my $manager = new Lemonldap::NG::Manager(
|
|
||||||
{
|
|
||||||
|
|
||||||
# ACCESS TO CONFIGURATION
|
|
||||||
|
|
||||||
# By default, Lemonldap::NG uses the default storage.conf file to know
|
|
||||||
# where to find is configuration
|
|
||||||
# (generaly /etc/lemonldap-ng/storage.conf)
|
|
||||||
# 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',
|
|
||||||
# directory => '/usr/local/lemonldap-ng/conf/'
|
|
||||||
#},
|
|
||||||
|
|
||||||
}
|
|
||||||
) or Lemonldap::NG::Common::CGI->abort('Unable to start manager');
|
|
||||||
|
|
||||||
our $skin = $manager->{managerSkin};
|
|
||||||
our $skin_dir = 'skins';
|
|
||||||
our $main_dir = $manager->getApacheHtdocsPath;
|
|
||||||
|
|
||||||
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( SCRIPT_NAME => $ENV{SCRIPT_NAME} );
|
|
||||||
$template->param( MENU => $manager->menu() );
|
|
||||||
$template->param( DIR => "$skin_dir/$skin" );
|
|
||||||
$template->param( CFGNUM => $manager->{cfgNum} );
|
|
||||||
$template->param( TREE_AUTOCLOSE => $manager->{managerTreeAutoClose} );
|
|
||||||
$template->param( TREE_JQUERYCSS => $manager->{managerTreeJqueryCss} );
|
|
||||||
$template->param( CSS => $manager->{managerCss} );
|
|
||||||
$template->param( CSS_THEME => $manager->{managerCssTheme} );
|
|
||||||
$template->param( VERSION => $Lemonldap::NG::Manager::VERSION );
|
|
||||||
$template->param( LANG => shift @{ $manager->{lang} } );
|
|
||||||
$template->param( PORTAL_URL => $manager->{portal} );
|
|
||||||
$template->param( LI_CLASS_CONFIGURATION => "active" );
|
|
||||||
$template->param( LI_CLASS_SESSION => "" );
|
|
||||||
$template->param( LI_CLASS_NOTIFICATION => "" );
|
|
||||||
print $manager->header('text/html; charset=utf-8');
|
|
||||||
print $template->output;
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use LWP::UserAgent;
|
|
||||||
|
|
||||||
my($host, $url, $type1, $type2) = @ARGV;
|
|
||||||
|
|
||||||
die("Usage: $0 host url data-type")unless($host and $url and $type1);
|
|
||||||
|
|
||||||
my $ua = LWP::UserAgent->new();
|
|
||||||
$ua->timeout(10);
|
|
||||||
|
|
||||||
my ( $method, $vhost, $uri ) = ( $url =~ /^(https?):\/\/([^\/]+)(.*)$/ );
|
|
||||||
unless ($vhost) {
|
|
||||||
$vhost = $host;
|
|
||||||
$uri = $url;
|
|
||||||
}
|
|
||||||
my $r = HTTP::Request->new( 'GET', "$method://$host$uri", HTTP::Headers->new( Host => $vhost ) );
|
|
||||||
my $response = $ua->request($r);
|
|
||||||
if ( $response->code != 200 ) {
|
|
||||||
print STDERR "$host: ".join( ' ', &txt_error, ":", $response->code, $response->message, "</li>");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $tot=0;
|
|
||||||
my $res;
|
|
||||||
foreach (split(/\n/s, $response->content)) {
|
|
||||||
$tot++ if(/<div id="total">/);
|
|
||||||
$tot=0 if(/<\/div>/);
|
|
||||||
if($tot) {
|
|
||||||
/^(\w+)\s*:\s*(\d+)/ or next;
|
|
||||||
$res->{$1} = $2;
|
|
||||||
}
|
|
||||||
$res->{localCache} = $1 if(/^Local Cache\s*:\s*(\d+)/i);
|
|
||||||
$res->{up} = $1 if(/^Server up for\s*:\s*(\d+d\s+\d+h\s+\d+mn)/);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach(keys %$res) {
|
|
||||||
print "$res->{$_}\n" if(/^$type1$/i);
|
|
||||||
}
|
|
||||||
if($type2) {
|
|
||||||
foreach(keys %$res) {
|
|
||||||
print "$res->{$_}\n" if(/^$type2$/i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print "$res->{up}\n$host";
|
|
|
@ -1,30 +0,0 @@
|
||||||
######################################################################
|
|
||||||
# Multi Router Traffic Grapher -- Sample Configuration File
|
|
||||||
######################################################################
|
|
||||||
# This file is for use with mrtg-2.5.4c
|
|
||||||
|
|
||||||
# Global configuration
|
|
||||||
WorkDir: /var/www/mrtg
|
|
||||||
WriteExpires: Yes
|
|
||||||
|
|
||||||
Title[^]: Traffic Analysis for
|
|
||||||
|
|
||||||
# 128K leased line
|
|
||||||
# ----------------
|
|
||||||
#Title[leased]: a 128K leased line
|
|
||||||
#PageTop[leased]: <H1>Our 128K link to the outside world</H1>
|
|
||||||
#Target[leased]: 1:public@router.localnet
|
|
||||||
#MaxBytes[leased]: 16000
|
|
||||||
Target[test.example.com]: `/etc/mrtg/lmng-mrtg 172.16.1.2 https://test.example.com/status OK OK`
|
|
||||||
Options[test.example.com]: nopercent, growright, nobanner, perminute
|
|
||||||
PageTop[test.example.com]: <h1>Requests OK from test.example.com</h1>
|
|
||||||
MaxBytes[test.example.com]: 1000000
|
|
||||||
YLegend[test.example.com]: hits/minute
|
|
||||||
ShortLegend[test.example.com]: hits/mn
|
|
||||||
LegendO[test.example.com]: Hits:
|
|
||||||
LegendI[test.example.com]: Hits:
|
|
||||||
Legend2[test.example.com]: Hits per minute
|
|
||||||
Legend4[test.example.com]: Hits max per minute
|
|
||||||
Title[test.example.com]: Hits per minute
|
|
||||||
WithPeak[test.example.com]: wmy
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Page not found</title>
|
|
||||||
</head>
|
|
||||||
<body style="background:#FFF;text-align:center;">
|
|
||||||
<h1>Page not found</h1>
|
|
||||||
<h2>Please install documentation package to get offline doc</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Page non trouvée</title>
|
|
||||||
</head>
|
|
||||||
<body style="background:#FFF;text-align:center;">
|
|
||||||
<h1>Page non trouvée</h1>
|
|
||||||
<h2>Merci d'installer le paquet contenant la documentation française</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,58 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Lemonldap::NG::Manager;
|
|
||||||
use Lemonldap::NG::Manager::Notifications;
|
|
||||||
use HTML::Template;
|
|
||||||
|
|
||||||
my $cgi = Lemonldap::NG::Manager::Notifications->new(
|
|
||||||
{
|
|
||||||
|
|
||||||
# SESSION EXPLORER CUSTOMIZATION
|
|
||||||
#managerSkin => 'default',
|
|
||||||
|
|
||||||
# ACCESS TO CONFIGURATION
|
|
||||||
|
|
||||||
# By default, Lemonldap::NG uses the default storage.conf file to know
|
|
||||||
# where to find is configuration
|
|
||||||
# (generaly /etc/lemonldap-ng/storage.conf)
|
|
||||||
# You can specify by yourself this 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',
|
|
||||||
# directory => '/usr/local/lemonlda-ng/conf/'
|
|
||||||
#},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
or
|
|
||||||
Lemonldap::NG::Common::CGI->abort('Unable to start notifications explorer');
|
|
||||||
|
|
||||||
my $skin = $cgi->{managerSkin} or $cgi->abort('managerSkin is not defined');
|
|
||||||
my $css = 'tree.css';
|
|
||||||
my $css_theme = 'ui-lightness';
|
|
||||||
my $skin_dir = 'skins';
|
|
||||||
my $main_dir = $cgi->getApacheHtdocsPath;
|
|
||||||
|
|
||||||
my $template = HTML::Template->new(
|
|
||||||
filename => "$main_dir/$skin_dir/$skin/notifications.tpl",
|
|
||||||
die_on_bad_params => 0,
|
|
||||||
cache => 0,
|
|
||||||
filter => sub { $cgi->translate_template(@_) },
|
|
||||||
);
|
|
||||||
$template->param( SCRIPT_NAME => $ENV{SCRIPT_NAME} );
|
|
||||||
$template->param( TREE => $cgi->tree() );
|
|
||||||
$template->param( DIR => "$skin_dir/$skin" );
|
|
||||||
$template->param( CSS => $css );
|
|
||||||
$template->param( CSS_THEME => $css_theme );
|
|
||||||
$template->param( VERSION => $Lemonldap::NG::Manager::VERSION );
|
|
||||||
$template->param( LANG => shift @{ $cgi->{lang} } );
|
|
||||||
$template->param( PORTAL_URL => $cgi->{portal} );
|
|
||||||
$template->param( LI_CLASS_CONFIGURATION => "" );
|
|
||||||
$template->param( LI_CLASS_SESSION => "" );
|
|
||||||
$template->param( LI_CLASS_NOTIFICATION => "active" );
|
|
||||||
print $cgi->header('text/html; charset=utf-8');
|
|
||||||
print $template->output;
|
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
use Lemonldap::NG::Manager::Cli;
|
|
||||||
use POSIX qw(setuid setgid);
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
sub giveUpPrivileges {
|
|
||||||
my ( $user, $group ) = @_;
|
|
||||||
|
|
||||||
$user = "nobody" unless defined($user);
|
|
||||||
$group = "nobody" unless defined($group);
|
|
||||||
|
|
||||||
# become $user:$group and give up root privileges
|
|
||||||
setgid( ( getgrnam($group) )[2] );
|
|
||||||
setuid( ( getpwnam($user) )[2] );
|
|
||||||
|
|
||||||
# if we are still root
|
|
||||||
if ( $> == 0 ) {
|
|
||||||
print STDERR
|
|
||||||
"$0 must not be launched as root since local cache can be corrupted.\n";
|
|
||||||
print STDERR "Continue (y/N)? ";
|
|
||||||
my $res = <STDIN>;
|
|
||||||
exit 1 unless ( $res =~ /^y/i );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## main program
|
|
||||||
|
|
||||||
if ( !@ARGV ) {
|
|
||||||
print STDERR "Usage: $0 <action> <params>\n";
|
|
||||||
print STDERR "- help: list available actions\n";
|
|
||||||
print STDERR "- info: view current configuration information\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
giveUpPrivileges( "__APACHEUSER__", "__APACHEGROUP__" );
|
|
||||||
|
|
||||||
my ( $cli, $action, $method, $ret );
|
|
||||||
|
|
||||||
$cli = new Lemonldap::NG::Manager::Cli;
|
|
||||||
|
|
||||||
# Do not increment configuration by default
|
|
||||||
$cli->{confAccess}->{cfgNumFixed} = 1;
|
|
||||||
|
|
||||||
$action = shift(@ARGV);
|
|
||||||
$method = $cli->determineMethod($action);
|
|
||||||
|
|
||||||
unless ( $cli->can($method) ) {
|
|
||||||
print STDERR "Action $action unknown\n";
|
|
||||||
print STDERR "Enter $0 help to get more information\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# The config is stored in ASCII
|
|
||||||
foreach(@ARGV){ utf8::decode $_; }
|
|
||||||
binmode(STDOUT, ':utf8');
|
|
||||||
|
|
||||||
@ARGV ? $cli->run( $method, @ARGV ) : $cli->run($method);
|
|
||||||
|
|
||||||
# Display error if any
|
|
||||||
if ( $cli->getError() ) {
|
|
||||||
print $cli->getError() . "\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Save configuration if modified
|
|
||||||
if ( $cli->{confModified} ) {
|
|
||||||
$ret = $cli->saveConf();
|
|
||||||
print "Configuration $ret saved\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
exit 0;
|
|
||||||
|
|
||||||
__END__
|
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
=encoding utf8
|
|
||||||
|
|
||||||
lemonldap-ng-cli - Command Line Interface to edit LemonLDAP::NG configuration.
|
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
|
||||||
|
|
||||||
Do lemonldap-ng-cli help to get list of all commands
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
lemonldap-ng-cli allow user to edit the configuration of LemonLDAP::NG via the
|
|
||||||
command line.
|
|
||||||
|
|
||||||
=head1 SEE ALSO
|
|
||||||
|
|
||||||
L<Lemonldap::NG::Manager::Cli>, L<http://lemonldap-ng.org/>
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
|
||||||
|
|
||||||
David Delassus E<lt>david.jose.delassus@gmail.comE<gt>
|
|
||||||
Sandro Cazzaniga E<lt>cazzaniga.sandro@gmail.comE<gt>
|
|
||||||
Clement Oudot E<lt>clem.oudot@gmail.comE<gt>
|
|
||||||
|
|
||||||
=head1 COPYRIGHT AND LICENSE
|
|
||||||
|
|
||||||
Copyright (C) 2012, by David Delassus
|
|
||||||
Copyright (C) 2013, by Sandro Cazzaniga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or modify
|
|
||||||
it under the same terms as Perl itself, either Perl version 5.10.0 or,
|
|
||||||
at your option, any later version of Perl 5 you may have available.
|
|
||||||
|
|
||||||
=cut
|
|
|
@ -1,92 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
|
|
||||||
use Lemonldap::NG::Common::Conf;
|
|
||||||
use Lemonldap::NG::Common::Conf::Constants;
|
|
||||||
use Data::Dumper;
|
|
||||||
use English qw(-no_match_vars);
|
|
||||||
use File::Temp;
|
|
||||||
use POSIX qw(setuid setgid);
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
eval {
|
|
||||||
setgid( ( getgrnam('__APACHEGROUP__') )[2] );
|
|
||||||
setuid( ( getpwnam('__APACHEUSER__') )[2] );
|
|
||||||
print STDERR "Running as uid $EUID and gid $EGID\n";
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( $EUID == 0 ) {
|
|
||||||
print STDERR
|
|
||||||
"$0 must not be launched as root since local cache can be corrupted\n"
|
|
||||||
. "Continue (y/N)? ";
|
|
||||||
my $res = <STDIN>;
|
|
||||||
exit 1 unless ( $res =~ /^y/i );
|
|
||||||
}
|
|
||||||
|
|
||||||
my $conf = Lemonldap::NG::Common::Conf->new();
|
|
||||||
|
|
||||||
unless ($conf) {
|
|
||||||
print STDERR $Lemonldap::NG::Common::Conf::msg;
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $tmp = $conf->getConf();
|
|
||||||
delete $tmp->{reVHosts};
|
|
||||||
delete $tmp->{cipher};
|
|
||||||
delete $tmp->{cfgAuthor};
|
|
||||||
delete $tmp->{cfgAuthorIP};
|
|
||||||
delete $tmp->{cfgDate};
|
|
||||||
$tmp = Dumper($tmp);
|
|
||||||
my $refFile = File::Temp->new( UNLINK => 1 );
|
|
||||||
my $editFile = File::Temp->new( UNLINK => 1 );
|
|
||||||
print $refFile $tmp;
|
|
||||||
print $editFile $tmp;
|
|
||||||
close $refFile;
|
|
||||||
close $editFile;
|
|
||||||
|
|
||||||
system "editor $editFile";
|
|
||||||
|
|
||||||
if (`diff $refFile $editFile`) {
|
|
||||||
my $VAR1;
|
|
||||||
my $buf;
|
|
||||||
|
|
||||||
# Check if the new configuration hash is valid
|
|
||||||
open F1, $editFile->filename();
|
|
||||||
while (<F1>) {
|
|
||||||
$buf .= $_;
|
|
||||||
}
|
|
||||||
eval $buf;
|
|
||||||
die $EVAL_ERROR if $EVAL_ERROR;
|
|
||||||
|
|
||||||
# Update author and date
|
|
||||||
$VAR1->{cfgAuthor} = "lmConfigEditor";
|
|
||||||
$VAR1->{cfgAuthorIP} = "localhost";
|
|
||||||
$VAR1->{cfgDate} = time();
|
|
||||||
|
|
||||||
# Store new configuration
|
|
||||||
my $res = $conf->saveConf($VAR1);
|
|
||||||
if ( $res > 0 ) {
|
|
||||||
print STDERR "Configuration $res saved\n";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
print STDERR "Configuration was not saved:\n ";
|
|
||||||
if ( $res == CONFIG_WAS_CHANGED ) {
|
|
||||||
print STDERR "Configuration has changed\n";
|
|
||||||
}
|
|
||||||
elsif ( $res == DATABASE_LOCKED ) {
|
|
||||||
print STDERR "Configuration database is or can nor be locked\n";
|
|
||||||
}
|
|
||||||
elsif ( $res == UPLOAD_DENIED ) {
|
|
||||||
print STDERR "You're not authorized to save this configuration\n";
|
|
||||||
}
|
|
||||||
elsif ( $res == SYNTAX_ERROR ) {
|
|
||||||
print STDERR "Syntax error in your configuration\n";
|
|
||||||
}
|
|
||||||
elsif ( $res == UNKNOWN_ERROR ) {
|
|
||||||
print STDERR "Unknown error\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
print STDERR "Configuration not changed\n";
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Lemonldap::NG::Manager;
|
|
||||||
use Lemonldap::NG::Manager::Sessions;
|
|
||||||
use HTML::Template;
|
|
||||||
|
|
||||||
my $cgi = Lemonldap::NG::Manager::Sessions->new(
|
|
||||||
{
|
|
||||||
|
|
||||||
# SESSION EXPLORER CUSTOMIZATION
|
|
||||||
#managerSkin => 'default',
|
|
||||||
|
|
||||||
# ACCESS TO CONFIGURATION
|
|
||||||
|
|
||||||
# By default, Lemonldap::NG uses the default storage.conf file to know
|
|
||||||
# where to find is configuration
|
|
||||||
# (generaly /etc/lemonldap-ng/storage.conf)
|
|
||||||
# You can specify by yourself this 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',
|
|
||||||
# directory => '/usr/local/lemonlda-ng/conf/'
|
|
||||||
#},
|
|
||||||
}
|
|
||||||
) or Lemonldap::NG::Common::CGI->abort('Unable to start sessions explorer');
|
|
||||||
|
|
||||||
my $skin = $cgi->{managerSkin} or $cgi->abort('managerSkin is not defined');
|
|
||||||
my $css = 'tree.css';
|
|
||||||
my $css_theme = 'ui-lightness';
|
|
||||||
my $skin_dir = 'skins';
|
|
||||||
my $main_dir = $cgi->getApacheHtdocsPath;
|
|
||||||
|
|
||||||
my $template = HTML::Template->new(
|
|
||||||
filename => "$main_dir/$skin_dir/$skin/sessions.tpl",
|
|
||||||
die_on_bad_params => 0,
|
|
||||||
cache => 0,
|
|
||||||
filter => sub { $cgi->translate_template(@_) },
|
|
||||||
);
|
|
||||||
$template->param( SCRIPT_NAME => $ENV{SCRIPT_NAME} );
|
|
||||||
$template->param( TREE => $cgi->tree() );
|
|
||||||
$template->param( DIR => "$skin_dir/$skin" );
|
|
||||||
$template->param( CSS => $css );
|
|
||||||
$template->param( CSS_THEME => $css_theme );
|
|
||||||
$template->param( VERSION => $Lemonldap::NG::Manager::VERSION );
|
|
||||||
$template->param( LANG => shift @{ $cgi->{lang} } );
|
|
||||||
$template->param( PORTAL_URL => $cgi->{portal} );
|
|
||||||
$template->param( LI_CLASS_CONFIGURATION => "" );
|
|
||||||
$template->param( LI_CLASS_SESSION => "active" );
|
|
||||||
$template->param( LI_CLASS_NOTIFICATION => "" );
|
|
||||||
print $cgi->header('text/html; charset=utf-8');
|
|
||||||
print $template->output;
|
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* Lemonldap::NG styles
|
|
||||||
* Lightness theme for Manager
|
|
||||||
*/
|
|
||||||
|
|
||||||
@import url(manager.css);
|
|
||||||
|
|
||||||
/* jQuery Simple Tree */
|
|
||||||
.simpleTree
|
|
||||||
{
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree ul
|
|
||||||
{
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree li
|
|
||||||
{
|
|
||||||
list-style:none;
|
|
||||||
margin:0;
|
|
||||||
padding:0 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree li span
|
|
||||||
{
|
|
||||||
display:block;
|
|
||||||
padding:5px 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree li.doc span, .simpleTree li.doc-last span
|
|
||||||
{
|
|
||||||
color:#444;
|
|
||||||
padding:5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree ul
|
|
||||||
{
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree .root
|
|
||||||
{
|
|
||||||
cursor:pointer;
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree .line
|
|
||||||
{
|
|
||||||
line-height:3px;
|
|
||||||
height:3px;
|
|
||||||
font-size:3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree .ajax
|
|
||||||
{
|
|
||||||
background: url(../images/spinner.gif) no-repeat center 10px;
|
|
||||||
height:30px;
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree .ajax li
|
|
||||||
{
|
|
||||||
display:none;
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simpleTree .trigger {
|
|
||||||
position:relative;
|
|
||||||
top:6px;
|
|
||||||
left:8px;
|
|
||||||
}
|
|
|
@ -1,442 +0,0 @@
|
||||||
/*!
|
|
||||||
* Bootstrap v3.2.0 (http://getbootstrap.com)
|
|
||||||
* Copyright 2011-2014 Twitter, Inc.
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
||||||
*/
|
|
||||||
|
|
||||||
.btn-default,
|
|
||||||
.btn-primary,
|
|
||||||
.btn-success,
|
|
||||||
.btn-info,
|
|
||||||
.btn-warning,
|
|
||||||
.btn-danger {
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
|
||||||
}
|
|
||||||
.btn-default:active,
|
|
||||||
.btn-primary:active,
|
|
||||||
.btn-success:active,
|
|
||||||
.btn-info:active,
|
|
||||||
.btn-warning:active,
|
|
||||||
.btn-danger:active,
|
|
||||||
.btn-default.active,
|
|
||||||
.btn-primary.active,
|
|
||||||
.btn-success.active,
|
|
||||||
.btn-info.active,
|
|
||||||
.btn-warning.active,
|
|
||||||
.btn-danger.active {
|
|
||||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
|
||||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
|
||||||
}
|
|
||||||
.btn:active,
|
|
||||||
.btn.active {
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-default {
|
|
||||||
text-shadow: 0 1px 0 #fff;
|
|
||||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
|
|
||||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #dbdbdb;
|
|
||||||
border-color: #ccc;
|
|
||||||
}
|
|
||||||
.btn-default:hover,
|
|
||||||
.btn-default:focus {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-default:active,
|
|
||||||
.btn-default.active {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
border-color: #dbdbdb;
|
|
||||||
}
|
|
||||||
.btn-default:disabled,
|
|
||||||
.btn-default[disabled] {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-primary {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#2d6ca2));
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #2b669a;
|
|
||||||
}
|
|
||||||
.btn-primary:hover,
|
|
||||||
.btn-primary:focus {
|
|
||||||
background-color: #2d6ca2;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-primary:active,
|
|
||||||
.btn-primary.active {
|
|
||||||
background-color: #2d6ca2;
|
|
||||||
border-color: #2b669a;
|
|
||||||
}
|
|
||||||
.btn-primary:disabled,
|
|
||||||
.btn-primary[disabled] {
|
|
||||||
background-color: #2d6ca2;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
|
|
||||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #3e8f3e;
|
|
||||||
}
|
|
||||||
.btn-success:hover,
|
|
||||||
.btn-success:focus {
|
|
||||||
background-color: #419641;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-success:active,
|
|
||||||
.btn-success.active {
|
|
||||||
background-color: #419641;
|
|
||||||
border-color: #3e8f3e;
|
|
||||||
}
|
|
||||||
.btn-success:disabled,
|
|
||||||
.btn-success[disabled] {
|
|
||||||
background-color: #419641;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
|
|
||||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #28a4c9;
|
|
||||||
}
|
|
||||||
.btn-info:hover,
|
|
||||||
.btn-info:focus {
|
|
||||||
background-color: #2aabd2;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-info:active,
|
|
||||||
.btn-info.active {
|
|
||||||
background-color: #2aabd2;
|
|
||||||
border-color: #28a4c9;
|
|
||||||
}
|
|
||||||
.btn-info:disabled,
|
|
||||||
.btn-info[disabled] {
|
|
||||||
background-color: #2aabd2;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
|
|
||||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #e38d13;
|
|
||||||
}
|
|
||||||
.btn-warning:hover,
|
|
||||||
.btn-warning:focus {
|
|
||||||
background-color: #eb9316;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-warning:active,
|
|
||||||
.btn-warning.active {
|
|
||||||
background-color: #eb9316;
|
|
||||||
border-color: #e38d13;
|
|
||||||
}
|
|
||||||
.btn-warning:disabled,
|
|
||||||
.btn-warning[disabled] {
|
|
||||||
background-color: #eb9316;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.btn-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
|
|
||||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #b92c28;
|
|
||||||
}
|
|
||||||
.btn-danger:hover,
|
|
||||||
.btn-danger:focus {
|
|
||||||
background-color: #c12e2a;
|
|
||||||
background-position: 0 -15px;
|
|
||||||
}
|
|
||||||
.btn-danger:active,
|
|
||||||
.btn-danger.active {
|
|
||||||
background-color: #c12e2a;
|
|
||||||
border-color: #b92c28;
|
|
||||||
}
|
|
||||||
.btn-danger:disabled,
|
|
||||||
.btn-danger[disabled] {
|
|
||||||
background-color: #c12e2a;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.thumbnail,
|
|
||||||
.img-thumbnail {
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
|
||||||
}
|
|
||||||
.dropdown-menu > li > a:hover,
|
|
||||||
.dropdown-menu > li > a:focus {
|
|
||||||
background-color: #e8e8e8;
|
|
||||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
|
||||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.dropdown-menu > .active > a,
|
|
||||||
.dropdown-menu > .active > a:hover,
|
|
||||||
.dropdown-menu > .active > a:focus {
|
|
||||||
background-color: #357ebd;
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd));
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.navbar-default {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
|
|
||||||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-radius: 4px;
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
|
||||||
}
|
|
||||||
.navbar-default .navbar-nav > .active > a {
|
|
||||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f3f3f3));
|
|
||||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
|
||||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
|
||||||
}
|
|
||||||
.navbar-brand,
|
|
||||||
.navbar-nav > li > a {
|
|
||||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
|
|
||||||
}
|
|
||||||
.navbar-inverse {
|
|
||||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
|
|
||||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.navbar-inverse .navbar-nav > .active > a {
|
|
||||||
background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #222 0%, #282828 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#222), to(#282828));
|
|
||||||
background-image: linear-gradient(to bottom, #222 0%, #282828 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
|
||||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
|
||||||
}
|
|
||||||
.navbar-inverse .navbar-brand,
|
|
||||||
.navbar-inverse .navbar-nav > li > a {
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
|
|
||||||
}
|
|
||||||
.navbar-static-top,
|
|
||||||
.navbar-fixed-top,
|
|
||||||
.navbar-fixed-bottom {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.alert {
|
|
||||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
|
||||||
}
|
|
||||||
.alert-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
|
|
||||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #b2dba1;
|
|
||||||
}
|
|
||||||
.alert-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
|
|
||||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #9acfea;
|
|
||||||
}
|
|
||||||
.alert-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
|
|
||||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #f5e79e;
|
|
||||||
}
|
|
||||||
.alert-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
|
|
||||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #dca7a7;
|
|
||||||
}
|
|
||||||
.progress {
|
|
||||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
|
|
||||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #428bca 0%, #3071a9 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3071a9));
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-success {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
|
|
||||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-info {
|
|
||||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
|
|
||||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-warning {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
|
|
||||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-danger {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
|
|
||||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.progress-bar-striped {
|
|
||||||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
|
||||||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
|
||||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
|
||||||
}
|
|
||||||
.list-group {
|
|
||||||
border-radius: 4px;
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
|
||||||
}
|
|
||||||
.list-group-item.active,
|
|
||||||
.list-group-item.active:hover,
|
|
||||||
.list-group-item.active:focus {
|
|
||||||
text-shadow: 0 -1px 0 #3071a9;
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #428bca 0%, #3278b3 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3278b3));
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #3278b3;
|
|
||||||
}
|
|
||||||
.panel {
|
|
||||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
|
||||||
}
|
|
||||||
.panel-default > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
|
||||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-primary > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd));
|
|
||||||
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-success > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
|
|
||||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-info > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
|
|
||||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-warning > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
|
|
||||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.panel-danger > .panel-heading {
|
|
||||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
|
|
||||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
.well {
|
|
||||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
|
||||||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
|
|
||||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
border-color: #dcdcdc;
|
|
||||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
|
||||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
|
||||||
}
|
|
||||||
/*# sourceMappingURL=bootstrap-theme.css.map */
|
|
|
@ -1,170 +0,0 @@
|
||||||
/*
|
|
||||||
* Lemonldap::NG styles
|
|
||||||
* Commin styles for Manager
|
|
||||||
*
|
|
||||||
* Coding rules:
|
|
||||||
* selector
|
|
||||||
* {
|
|
||||||
* property:value;
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Main */
|
|
||||||
html,body
|
|
||||||
{
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
height:100%;
|
|
||||||
min-height:100%;
|
|
||||||
background: rgb(0,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
body
|
|
||||||
{
|
|
||||||
padding-top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.brand
|
|
||||||
{
|
|
||||||
height:25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul
|
|
||||||
{
|
|
||||||
text-align: left;
|
|
||||||
list-style-position:inside;
|
|
||||||
list-style-image:url("../images/bullet_orange.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Buttons, Inputs*/
|
|
||||||
.buttons
|
|
||||||
{
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input, select, textarea
|
|
||||||
{
|
|
||||||
font-weight:bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea.elastic {
|
|
||||||
max-height: 8em;
|
|
||||||
font:bold 9pt sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea#filearea
|
|
||||||
{
|
|
||||||
font-size:8pt;
|
|
||||||
font-family:monospace;
|
|
||||||
background-color:#ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
input#text, input#int, input#password, select
|
|
||||||
{
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.int
|
|
||||||
{
|
|
||||||
width: 200px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
input#applicationListApplicationLogo
|
|
||||||
{
|
|
||||||
height: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input#skinText
|
|
||||||
{
|
|
||||||
height: 153px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input#authOptions
|
|
||||||
{
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
option
|
|
||||||
{
|
|
||||||
margin:5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Divs */
|
|
||||||
#menu, #data
|
|
||||||
{
|
|
||||||
overflow-x:hidden;
|
|
||||||
overflow-y:auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#buttons, #edition, #help
|
|
||||||
{
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#help_content
|
|
||||||
{
|
|
||||||
padding:5px;
|
|
||||||
overflow:hidden;
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#help_content iframe
|
|
||||||
{
|
|
||||||
width:100%;
|
|
||||||
height:100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#query-switch
|
|
||||||
{
|
|
||||||
padding:0;
|
|
||||||
margin:10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Popup */
|
|
||||||
#popup h3
|
|
||||||
{
|
|
||||||
text-align:center;
|
|
||||||
letter-spacing:2px;
|
|
||||||
border-bottom:1px solid #aaa;
|
|
||||||
padding:5px;
|
|
||||||
margin:5px 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#popup ul
|
|
||||||
{
|
|
||||||
list-style-position:inside;
|
|
||||||
list-style-image:url("../images/bullet_green.png");
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#popup ul.warning {
|
|
||||||
list-style-image:url("../images/bullet_orange.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
#popup ul.error {
|
|
||||||
list-style-image:url("../images/bullet_red.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui-dialog {
|
|
||||||
border:1px solid #000;
|
|
||||||
box-shadow:1px 1px 15px #555;
|
|
||||||
-moz-box-shadow:1px 1px 15px #555;
|
|
||||||
-webkit-box-shadow:1px 1px 15px #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skin selection */
|
|
||||||
input#skinText {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content_skin img, #skinImagePicker img, #content_applicationListApplication img, #appsLogoPicker img {
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#skinImagePicker, #appsLogoPicker, #css-switch {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,200 +0,0 @@
|
||||||
/*
|
|
||||||
* Lemonldap::NG styles
|
|
||||||
* Default theme for Manager
|
|
||||||
*/
|
|
||||||
|
|
||||||
@import url(manager.css);
|
|
||||||
|
|
||||||
.simpleTree
|
|
||||||
{
|
|
||||||
overflow:auto;
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
.simpleTree li
|
|
||||||
{
|
|
||||||
list-style: none;
|
|
||||||
margin:0;
|
|
||||||
padding:0 0 0 34px;
|
|
||||||
line-height: 14px;
|
|
||||||
}
|
|
||||||
.simpleTree li span
|
|
||||||
{
|
|
||||||
display:inline;
|
|
||||||
clear: left;
|
|
||||||
white-space: nowrap;
|
|
||||||
cursor:pointer;
|
|
||||||
}
|
|
||||||
.simpleTree ul
|
|
||||||
{
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
.simpleTree .root
|
|
||||||
{
|
|
||||||
margin-left:-16px;
|
|
||||||
background: url(../images/tree/root.gif) no-repeat 16px 0 transparent;
|
|
||||||
/*background-position: -84px -1646px;width:16px*/
|
|
||||||
}
|
|
||||||
.simpleTree .line
|
|
||||||
{
|
|
||||||
margin:0 0 0 -16px;
|
|
||||||
padding:0;
|
|
||||||
line-height: 3px;
|
|
||||||
height:3px;
|
|
||||||
font-size:3px;
|
|
||||||
background: url(../images/tree/tree.png) 0 0 no-repeat transparent;
|
|
||||||
background-position: -84px -1322px;
|
|
||||||
}
|
|
||||||
.simpleTree .line-last
|
|
||||||
{
|
|
||||||
margin:0 0 0 -16px;
|
|
||||||
padding:0;
|
|
||||||
line-height: 3px;
|
|
||||||
height:3px;
|
|
||||||
font-size:3px;
|
|
||||||
background: url(../images/tree/tree.png) 0 0 no-repeat transparent;
|
|
||||||
background-position: -84px -1712px;
|
|
||||||
}
|
|
||||||
.simpleTree .line-over
|
|
||||||
{
|
|
||||||
margin:0 0 0 -16px;
|
|
||||||
padding:0;
|
|
||||||
line-height: 3px;
|
|
||||||
height:3px;
|
|
||||||
font-size:3px;
|
|
||||||
background: url(../images/tree/tree.png) 0 0 no-repeat transparent;
|
|
||||||
background-position: -84px -1392px;
|
|
||||||
}
|
|
||||||
.simpleTree .line-over-last
|
|
||||||
{
|
|
||||||
margin:0 0 0 -16px;
|
|
||||||
padding:0;
|
|
||||||
line-height: 3px;
|
|
||||||
height:3px;
|
|
||||||
font-size:3px;
|
|
||||||
background: url(../images/tree/tree.png) 0 0 no-repeat transparent;
|
|
||||||
background-position: -84px -1462px;
|
|
||||||
}
|
|
||||||
.simpleTree .folder-open
|
|
||||||
{
|
|
||||||
margin-left:-16px;
|
|
||||||
background: url(../images/tree/tree.png) 0 -2px no-repeat transparent;
|
|
||||||
background-position: 0 -72px;width: 34px;
|
|
||||||
}
|
|
||||||
.simpleTree .folder-open-last
|
|
||||||
{
|
|
||||||
margin-left:-16px;
|
|
||||||
background: url(../images/tree/tree.png) 0 -2px no-repeat transparent;
|
|
||||||
background-position: 0 -72px; width: 34px;
|
|
||||||
}
|
|
||||||
.simpleTree .folder-close
|
|
||||||
{
|
|
||||||
margin-left:-16px;
|
|
||||||
background: url(../images/tree/tree.png) 0 -2px no-repeat transparent;
|
|
||||||
background-position: 0 -1394px; width: 34px;height:14px;
|
|
||||||
}
|
|
||||||
.simpleTree .folder-close-last
|
|
||||||
{
|
|
||||||
margin-left:-16px;
|
|
||||||
background: url(../images/tree/tree.png) 0 -2px no-repeat transparent;
|
|
||||||
background-position: 0 -1322px; width: 34px;height:16px;
|
|
||||||
}
|
|
||||||
.simpleTree .folder-hidden, .simpleTree .folder-hidden-last
|
|
||||||
{
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
.simpleTree .doc
|
|
||||||
{
|
|
||||||
margin-left:-16px;
|
|
||||||
background: url(../images/tree/tree.png) 0 -1px no-repeat transparent;
|
|
||||||
background-position: -84px -72px; width: 32px;height:16px;
|
|
||||||
}
|
|
||||||
.simpleTree .doc-last
|
|
||||||
{
|
|
||||||
margin-left:-16px;
|
|
||||||
background: url(../images/tree/tree.png) 0 -1px no-repeat transparent;
|
|
||||||
background-position: -84px 0; width: 32px;height:16px;
|
|
||||||
}
|
|
||||||
.simpleTree .ajax
|
|
||||||
{
|
|
||||||
background: url(../images/spinner.gif) no-repeat 0 0 transparent;
|
|
||||||
height: 16px;
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
.simpleTree .ajax li
|
|
||||||
{
|
|
||||||
display:none;
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
.simpleTree .trigger
|
|
||||||
{
|
|
||||||
display:inline;
|
|
||||||
margin-left:-32px;
|
|
||||||
width: 28px;
|
|
||||||
height: 11px;
|
|
||||||
cursor:pointer;
|
|
||||||
}
|
|
||||||
.simpleTree .text
|
|
||||||
{
|
|
||||||
}
|
|
||||||
.simpleTree .active
|
|
||||||
{
|
|
||||||
background-color:#F7BE77;
|
|
||||||
padding:0px 2px;
|
|
||||||
border: 1px dashed #444;
|
|
||||||
}
|
|
||||||
#drag_container
|
|
||||||
{
|
|
||||||
background:transparent;
|
|
||||||
color:#000;
|
|
||||||
font: normal 11px arial, tahoma, helvetica, sans-serif;
|
|
||||||
border: 1px dashed #767676;
|
|
||||||
}
|
|
||||||
#drag_container ul
|
|
||||||
{
|
|
||||||
list-style: none;
|
|
||||||
padding:0;
|
|
||||||
margin:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#drag_container li
|
|
||||||
{
|
|
||||||
list-style: none;
|
|
||||||
background-color:transparent;
|
|
||||||
line-height:18px;
|
|
||||||
white-space: nowrap;
|
|
||||||
padding:1px 1px 0px 16px;
|
|
||||||
margin:0;
|
|
||||||
}
|
|
||||||
#drag_container li span
|
|
||||||
{
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#drag_container li.doc, #drag_container li.doc-last
|
|
||||||
{
|
|
||||||
background: url(../images/tree/tree.png) no-repeat -17px 0 transparent;
|
|
||||||
background-position: -84px -72px;width:32px;
|
|
||||||
}
|
|
||||||
#drag_container .folder-close, #drag_container .folder-close-last
|
|
||||||
{
|
|
||||||
background: url(../images/tree/tree.png) no-repeat -17px 0 transparent;
|
|
||||||
background-position: 0 -1394px; width: 34px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#drag_container .folder-open, #drag_container .folder-open-last
|
|
||||||
{
|
|
||||||
background: url(../images/tree/tree.png) no-repeat -17px 0 transparent;
|
|
||||||
background-position: 0 -72px; width: 34px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content
|
|
||||||
{
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.hidden
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
Before Width: | Height: | Size: 657 B |
Before Width: | Height: | Size: 675 B |
|
@ -1,13 +0,0 @@
|
||||||
/* LemonLDAP::NG project */
|
|
||||||
|
|
||||||
Icons of this folder are taken from Crystal project:
|
|
||||||
|
|
||||||
TITLE: Crystal Project Icons
|
|
||||||
AUTHOR: Everaldo Coelho
|
|
||||||
SITE: http://www.everaldo.com
|
|
||||||
CONTACT: everaldo@everaldo.com
|
|
||||||
|
|
||||||
Copyright (c) 2006-2007 Everaldo Coelho.
|
|
||||||
|
|
||||||
They are released under GPL license
|
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.2 KiB |
|
@ -1 +0,0 @@
|
||||||
folder.png
|
|
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.6 KiB |
|
@ -1 +0,0 @@
|
||||||
configure.png
|
|
Before Width: | Height: | Size: 2.4 KiB |
|
@ -1 +0,0 @@
|
||||||
network.png
|
|
|
@ -1 +0,0 @@
|
||||||
gear.png
|
|
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 287 B |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 996 B |
Before Width: | Height: | Size: 43 B |
Before Width: | Height: | Size: 11 KiB |
|
@ -1,173 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Open source library released under licence used by JQuery.
|
|
||||||
* http://plugins.jquery.com/project/ajaxFileUpload
|
|
||||||
*/
|
|
||||||
|
|
||||||
jQuery.extend({
|
|
||||||
createUploadIframe:function(id,uri){
|
|
||||||
var frameId='jUploadFrame' + id;
|
|
||||||
if(window.ActiveXObject){
|
|
||||||
var io=document.createElement('<iframe id="'+frameId+'" name="'+frameId+'" />');
|
|
||||||
if(typeof uri=='boolean'){
|
|
||||||
io.src='javascript:false';
|
|
||||||
}else if(typeof uri=='string'){
|
|
||||||
io.src=uri;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
var io=document.createElement('iframe');
|
|
||||||
io.id=frameId;
|
|
||||||
io.name=frameId;
|
|
||||||
}
|
|
||||||
io.style.position='absolute';
|
|
||||||
io.style.top='-1000px';
|
|
||||||
io.style.left='-1000px';
|
|
||||||
document.body.appendChild(io);
|
|
||||||
return io;
|
|
||||||
},
|
|
||||||
createUploadForm:function(id,fileElementId){
|
|
||||||
// Create form
|
|
||||||
var formId = 'jUploadForm' + id;
|
|
||||||
var fileId = 'jUploadFile' + id;
|
|
||||||
var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
|
|
||||||
var oldElement = $('#' + fileElementId);
|
|
||||||
var newElement = $(oldElement).clone();
|
|
||||||
$(oldElement).attr('id', fileId);
|
|
||||||
$(oldElement).before(newElement);
|
|
||||||
$(oldElement).appendTo(form);
|
|
||||||
// Set CSS attributes
|
|
||||||
$(form).css('position', 'absolute');
|
|
||||||
$(form).css('top', '-1200px');
|
|
||||||
$(form).css('left', '-1200px');
|
|
||||||
$(form).appendTo('body');
|
|
||||||
return form;
|
|
||||||
},
|
|
||||||
ajaxFileUpload:function(s){
|
|
||||||
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
|
|
||||||
s = jQuery.extend({}, jQuery.ajaxSettings, s);
|
|
||||||
var id = new Date().getTime();
|
|
||||||
var form = jQuery.createUploadForm(id,s.fileElementId);
|
|
||||||
var io = jQuery.createUploadIframe(id,s.secureuri);
|
|
||||||
var frameId = 'jUploadFrame' + id;
|
|
||||||
var formId = 'jUploadForm' + id;
|
|
||||||
// Watch for a new set of requests
|
|
||||||
if(s.global && !jQuery.active++){
|
|
||||||
jQuery.event.trigger( "ajaxStart" );
|
|
||||||
}
|
|
||||||
var requestDone = false;
|
|
||||||
// Create the request object
|
|
||||||
var xml = {}
|
|
||||||
if(s.global){
|
|
||||||
jQuery.event.trigger("ajaxSend", [xml, s]);
|
|
||||||
}
|
|
||||||
// Wait for a response to come back
|
|
||||||
var uploadCallback = function(isTimeout){
|
|
||||||
var io = document.getElementById(frameId);
|
|
||||||
try{
|
|
||||||
if(io.contentWindow){
|
|
||||||
xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
|
|
||||||
xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
|
|
||||||
}else if(io.contentDocument){
|
|
||||||
xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
|
|
||||||
xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
|
|
||||||
}
|
|
||||||
}catch(e){
|
|
||||||
jQuery.handleError(s,xml,null,e);
|
|
||||||
}
|
|
||||||
if(xml || isTimeout=="timeout"){
|
|
||||||
requestDone = true;
|
|
||||||
var status;
|
|
||||||
try{
|
|
||||||
status = isTimeout != "timeout" ? "success" : "error";
|
|
||||||
// Make sure that the request was successful or notmodified
|
|
||||||
if(status != "error"){
|
|
||||||
// process the data (runs the xml through httpData regardless of callback)
|
|
||||||
var data = jQuery.uploadHttpData(xml,s.dataType);
|
|
||||||
// If a local callback was specified, fire it and pass it the data
|
|
||||||
if(s.success){
|
|
||||||
s.success( data, status );
|
|
||||||
}
|
|
||||||
// Fire the global callback
|
|
||||||
if(s.global){
|
|
||||||
jQuery.event.trigger("ajaxSuccess",[xml,s]);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
jQuery.handleError(s,xml,status);
|
|
||||||
}
|
|
||||||
}catch(e){
|
|
||||||
status = "error";
|
|
||||||
jQuery.handleError(s,xml,status,e);
|
|
||||||
}
|
|
||||||
// The request was completed
|
|
||||||
if(s.global){
|
|
||||||
jQuery.event.trigger("ajaxComplete",[xml,s]);
|
|
||||||
}
|
|
||||||
// Handle the global AJAX counter
|
|
||||||
if(s.global && !--jQuery.active){
|
|
||||||
jQuery.event.trigger("ajaxStop");
|
|
||||||
}
|
|
||||||
// Process result
|
|
||||||
if(s.complete){
|
|
||||||
s.complete(xml, status);
|
|
||||||
}
|
|
||||||
jQuery(io).unbind();
|
|
||||||
setTimeout(function(){
|
|
||||||
try{
|
|
||||||
$(io).remove();
|
|
||||||
$(form).remove();
|
|
||||||
}catch(e){
|
|
||||||
jQuery.handleError(s, xml, null, e);
|
|
||||||
}
|
|
||||||
},100);
|
|
||||||
xml = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Timeout checker
|
|
||||||
if(s.timeout>0){
|
|
||||||
setTimeout(function(){
|
|
||||||
// Check to see if the request is still happening
|
|
||||||
if(!requestDone) uploadCallback("timeout");
|
|
||||||
},s.timeout);
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
// var io = $('#' + frameId);
|
|
||||||
var form = $('#' + formId);
|
|
||||||
$(form).attr('action', s.url);
|
|
||||||
$(form).attr('method', 'POST');
|
|
||||||
$(form).attr('target', frameId);
|
|
||||||
if(form.encoding){
|
|
||||||
form.encoding = 'multipart/form-data';
|
|
||||||
}else{
|
|
||||||
form.enctype = 'multipart/form-data';
|
|
||||||
}
|
|
||||||
$(form).submit();
|
|
||||||
}catch(e){
|
|
||||||
jQuery.handleError(s,xml,null,e);
|
|
||||||
}
|
|
||||||
if(window.attachEvent){
|
|
||||||
document.getElementById(frameId).attachEvent('onload', uploadCallback);
|
|
||||||
}else{
|
|
||||||
document.getElementById(frameId).addEventListener('load', uploadCallback, false);
|
|
||||||
}
|
|
||||||
return {abort:function(){}};
|
|
||||||
},
|
|
||||||
uploadHttpData:function(r,type){
|
|
||||||
var data = !type;
|
|
||||||
data = type == "xml" || data ? r.responseXML : r.responseText;
|
|
||||||
// If the type is "script", eval it in global context
|
|
||||||
if(type=="script"){
|
|
||||||
jQuery.globalEval(data);
|
|
||||||
}
|
|
||||||
// Get the JavaScript object, if JSON is used.
|
|
||||||
if(type=="json"){
|
|
||||||
eval("data = "+data);
|
|
||||||
}
|
|
||||||
// evaluate scripts within html
|
|
||||||
if(type=="html"){
|
|
||||||
jQuery("<div>").html(data).evalScripts();
|
|
||||||
}
|
|
||||||
//alert($('param', data).each(function(){alert($(this).attr('value'));}));
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
/**
|
|
||||||
* Cookie plugin
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
|
|
||||||
* Dual licensed under the MIT and GPL licenses:
|
|
||||||
* http://www.opensource.org/licenses/mit-license.php
|
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a cookie with the given name and value and other optional parameters.
|
|
||||||
*
|
|
||||||
* @example $.cookie('the_cookie', 'the_value');
|
|
||||||
* @desc Set the value of a cookie.
|
|
||||||
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
|
|
||||||
* @desc Create a cookie with all available options.
|
|
||||||
* @example $.cookie('the_cookie', 'the_value');
|
|
||||||
* @desc Create a session cookie.
|
|
||||||
* @example $.cookie('the_cookie', null);
|
|
||||||
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
|
|
||||||
* used when the cookie was set.
|
|
||||||
*
|
|
||||||
* @param String name The name of the cookie.
|
|
||||||
* @param String value The value of the cookie.
|
|
||||||
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
|
|
||||||
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
|
|
||||||
* If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
|
|
||||||
* If set to null or omitted, the cookie will be a session cookie and will not be retained
|
|
||||||
* when the the browser exits.
|
|
||||||
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
|
|
||||||
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
|
|
||||||
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
|
|
||||||
* require a secure protocol (like HTTPS).
|
|
||||||
* @type undefined
|
|
||||||
*
|
|
||||||
* @name $.cookie
|
|
||||||
* @cat Plugins/Cookie
|
|
||||||
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of a cookie with the given name.
|
|
||||||
*
|
|
||||||
* @example $.cookie('the_cookie');
|
|
||||||
* @desc Get the value of a cookie.
|
|
||||||
*
|
|
||||||
* @param String name The name of the cookie.
|
|
||||||
* @return The value of the cookie.
|
|
||||||
* @type String
|
|
||||||
*
|
|
||||||
* @name $.cookie
|
|
||||||
* @cat Plugins/Cookie
|
|
||||||
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
|
||||||
*/
|
|
||||||
jQuery.cookie = function(name, value, options) {
|
|
||||||
if (typeof value != 'undefined') { // name and value given, set cookie
|
|
||||||
options = options || {};
|
|
||||||
if (value === null) {
|
|
||||||
value = '';
|
|
||||||
options.expires = -1;
|
|
||||||
}
|
|
||||||
var expires = '';
|
|
||||||
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
|
|
||||||
var date;
|
|
||||||
if (typeof options.expires == 'number') {
|
|
||||||
date = new Date();
|
|
||||||
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
|
|
||||||
} else {
|
|
||||||
date = options.expires;
|
|
||||||
}
|
|
||||||
expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
|
|
||||||
}
|
|
||||||
// CAUTION: Needed to parenthesize options.path and options.domain
|
|
||||||
// in the following expressions, otherwise they evaluate to undefined
|
|
||||||
// in the packed version for some reason...
|
|
||||||
var path = options.path ? '; path=' + (options.path) : '';
|
|
||||||
var domain = options.domain ? '; domain=' + (options.domain) : '';
|
|
||||||
var secure = options.secure ? '; secure' : '';
|
|
||||||
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
|
|
||||||
} else { // only name given, get cookie
|
|
||||||
var cookieValue = null;
|
|
||||||
if (document.cookie && document.cookie != '') {
|
|
||||||
var cookies = document.cookie.split(';');
|
|
||||||
for (var i = 0; i < cookies.length; i++) {
|
|
||||||
var cookie = jQuery.trim(cookies[i]);
|
|
||||||
// Does this cookie string begin with the name we want?
|
|
||||||
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
|
||||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cookieValue;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,164 +0,0 @@
|
||||||
/**
|
|
||||||
* @name Elastic
|
|
||||||
* @descripton Elastic is jQuery plugin that grow and shrink your textareas automatically
|
|
||||||
* @version 1.6.11 customized
|
|
||||||
* @requires jQuery 1.2.6+
|
|
||||||
*
|
|
||||||
* @author Jan Jarfalk - customized by FX Deltombe
|
|
||||||
* @author-email jan.jarfalk@unwrongest.com
|
|
||||||
* @author-website http://www.unwrongest.com
|
|
||||||
*
|
|
||||||
* @licence MIT License - http://www.opensource.org/licenses/mit-license.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function($){
|
|
||||||
jQuery.fn.extend({
|
|
||||||
elastic: function() {
|
|
||||||
|
|
||||||
// We will create a div clone of the textarea
|
|
||||||
// by copying these attributes from the textarea to the div.
|
|
||||||
var mimics = [
|
|
||||||
'paddingTop',
|
|
||||||
'paddingRight',
|
|
||||||
'paddingBottom',
|
|
||||||
'paddingLeft',
|
|
||||||
'fontSize',
|
|
||||||
'lineHeight',
|
|
||||||
'fontFamily',
|
|
||||||
'width',
|
|
||||||
'fontWeight',
|
|
||||||
'border-top-width',
|
|
||||||
'border-right-width',
|
|
||||||
'border-bottom-width',
|
|
||||||
'border-left-width',
|
|
||||||
'borderTopStyle',
|
|
||||||
'borderTopColor',
|
|
||||||
'borderRightStyle',
|
|
||||||
'borderRightColor',
|
|
||||||
'borderBottomStyle',
|
|
||||||
'borderBottomColor',
|
|
||||||
'borderLeftStyle',
|
|
||||||
'borderLeftColor'
|
|
||||||
];
|
|
||||||
|
|
||||||
return this.each( function() {
|
|
||||||
|
|
||||||
// Elastic only works on textareas
|
|
||||||
if ( this.type !== 'textarea' ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $textarea = jQuery(this),
|
|
||||||
$twin = jQuery('<div />').css({
|
|
||||||
'position' : 'absolute',
|
|
||||||
'display' : 'none',
|
|
||||||
'word-wrap' : 'break-word',
|
|
||||||
'white-space' :'pre-wrap'
|
|
||||||
}),
|
|
||||||
lineHeight = parseInt($textarea.css('line-height'),10) || parseInt($textarea.css('font-size'),'10'),
|
|
||||||
// modified by FX Deltombe: try to set minheight from textarea rows instead of textarea css height,
|
|
||||||
minheight = lineHeight * parseInt($textarea.attr('rows'), 10) || parseInt($textarea.css('height'),10) || lineHeight*3,
|
|
||||||
maxheight = parseInt($textarea.css('max-height'),10) || Number.MAX_VALUE,
|
|
||||||
goalheight = 0;
|
|
||||||
|
|
||||||
// Opera returns max-height of -1 if not set
|
|
||||||
if (maxheight < 0) { maxheight = Number.MAX_VALUE; }
|
|
||||||
|
|
||||||
// Append the twin to the DOM
|
|
||||||
// We are going to meassure the height of this, not the textarea.
|
|
||||||
$twin.appendTo($textarea.parent());
|
|
||||||
|
|
||||||
// Copy the essential styles (mimics) from the textarea to the twin
|
|
||||||
var i = mimics.length;
|
|
||||||
while(i--){
|
|
||||||
$twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates the width of the twin. (solution for textareas with widths in percent)
|
|
||||||
function setTwinWidth(){
|
|
||||||
var curatedWidth = Math.floor(parseInt($textarea.width(),10));
|
|
||||||
if($twin.width() !== curatedWidth){
|
|
||||||
$twin.css({'width': curatedWidth + 'px'});
|
|
||||||
|
|
||||||
// Update height of textarea
|
|
||||||
update(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets a given height and overflow state on the textarea
|
|
||||||
function setHeightAndOverflow(height, overflow){
|
|
||||||
|
|
||||||
var curratedHeight = Math.floor(parseInt(height,10));
|
|
||||||
if($textarea.height() !== curratedHeight){
|
|
||||||
$textarea.css({'height': curratedHeight + 'px','overflow':overflow});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function will update the height of the textarea if necessary
|
|
||||||
function update(forced) {
|
|
||||||
|
|
||||||
// Get curated content from the textarea.
|
|
||||||
var textareaContent = $textarea.val().replace(/&/g,'&').replace(/ {2}/g, ' ').replace(/<|>/g, '>').replace(/\n/g, '<br />');
|
|
||||||
|
|
||||||
// Compare curated content with curated twin.
|
|
||||||
var twinContent = $twin.html().replace(/<br>/ig,'<br />');
|
|
||||||
|
|
||||||
if(forced || textareaContent+' ' !== twinContent){
|
|
||||||
|
|
||||||
// Add an extra white space so new rows are added when you are at the end of a row.
|
|
||||||
$twin.html(textareaContent+' ');
|
|
||||||
|
|
||||||
// modified by FX Deltombe:consider twin height instead of twin height plus the height of one line
|
|
||||||
// Change textarea height if twin height differs more than 3 pixel from textarea height
|
|
||||||
if(Math.abs($twin.height() - $textarea.height()) > 3){
|
|
||||||
|
|
||||||
var goalheight = $twin.height();
|
|
||||||
if(goalheight >= maxheight) {
|
|
||||||
setHeightAndOverflow(maxheight,'auto');
|
|
||||||
} else if(goalheight <= minheight) {
|
|
||||||
setHeightAndOverflow(minheight,'hidden');
|
|
||||||
} else {
|
|
||||||
setHeightAndOverflow(goalheight,'hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide scrollbars
|
|
||||||
$textarea.css({'overflow':'hidden'});
|
|
||||||
|
|
||||||
// Update textarea size on keyup, change, cut and paste
|
|
||||||
$textarea.bind('keyup change cut paste', function(){
|
|
||||||
update();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update width of twin if browser or textarea is resized (solution for textareas with widths in percent)
|
|
||||||
$(window).bind('resize', setTwinWidth);
|
|
||||||
$textarea.bind('resize', setTwinWidth);
|
|
||||||
$textarea.bind('update', update);
|
|
||||||
|
|
||||||
// Compact textarea on blur
|
|
||||||
$textarea.bind('blur',function(){
|
|
||||||
if($twin.height() < maxheight){
|
|
||||||
if($twin.height() > minheight) {
|
|
||||||
$textarea.height($twin.height());
|
|
||||||
} else {
|
|
||||||
$textarea.height(minheight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// And this line is to catch the browser paste event
|
|
||||||
$textarea.bind('input paste',function(e){ setTimeout( update, 250); });
|
|
||||||
|
|
||||||
// Run update once when elastic is initialized
|
|
||||||
update();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,159 +0,0 @@
|
||||||
/* function displayNotification(string id)
|
|
||||||
* Send an AJAX request to display an active notification
|
|
||||||
* @param id concatenation of uid + '_' + ref
|
|
||||||
* @return HTML code
|
|
||||||
*/
|
|
||||||
function displayNotification(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: scriptname,
|
|
||||||
data: {
|
|
||||||
'notification': id
|
|
||||||
},
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
$('#data').html(data);
|
|
||||||
},
|
|
||||||
error: function(xhr, ajaxOptions, thrownError) {
|
|
||||||
$('#data').html('<h3>Request failed</h3> Error code: ' + xhr.status + ', ' + thrownError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* function displayNotificationDone(string id)
|
|
||||||
* Send an AJAX request to display a done notification
|
|
||||||
* @param id internal notification reference
|
|
||||||
* @return HTML code
|
|
||||||
*/
|
|
||||||
function displayNotificationDone(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: scriptname,
|
|
||||||
data: {
|
|
||||||
'notificationDone': id
|
|
||||||
},
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
$('#data').html(data);
|
|
||||||
},
|
|
||||||
error: function(xhr, ajaxOptions, thrownError) {
|
|
||||||
$('#data').html('<h3>Request failed</h3> Error code: ' + xhr.status + ', ' + thrownError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* function del(string id)
|
|
||||||
* Send an AJAX request to delete a notification (mark as done)
|
|
||||||
* @param id concatenation of uid + '_' + ref
|
|
||||||
* @return HTML code
|
|
||||||
*/
|
|
||||||
function del(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: scriptname,
|
|
||||||
data: {
|
|
||||||
'delete': id
|
|
||||||
},
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
$('#data').html(data);
|
|
||||||
$('#uid_' + safeSelector(id)).remove();
|
|
||||||
},
|
|
||||||
error: function(xhr, ajaxOptions, thrownError) {
|
|
||||||
$('#data').html('<h3>Request failed</h3> Error code: ' + xhr.status + ', ' + thrownError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* function purge(string id)
|
|
||||||
* Send an AJAX request to purge a notification (remove definitely)
|
|
||||||
* @param id internal notification reference
|
|
||||||
* @return HTML code
|
|
||||||
*/
|
|
||||||
function purge(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: scriptname,
|
|
||||||
data: {
|
|
||||||
'purge': id
|
|
||||||
},
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
$('#data').html(data);
|
|
||||||
$('#uid_' + safeSelector(id)).remove();
|
|
||||||
},
|
|
||||||
error: function(xhr, ajaxOptions, thrownError) {
|
|
||||||
$('#data').html('<h3>Request failed</h3> Error code: ' + xhr.status + ', ' + thrownError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/* function newNotif()
|
|
||||||
* Display notification creation form
|
|
||||||
*/
|
|
||||||
function newNotif() {
|
|
||||||
var data = $("#newNotif").html();
|
|
||||||
$('#data').html(data);
|
|
||||||
$("#data input#date").datepicker({
|
|
||||||
'dateFormat': 'yy-mm-dd'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* function sendNewNotif()
|
|
||||||
* Send an AJAX request to create a notification
|
|
||||||
* @return HTML code
|
|
||||||
*/
|
|
||||||
function sendNewNotif() {
|
|
||||||
// Get data
|
|
||||||
var uid = $("input#uid").val();
|
|
||||||
var date = $("input#date").val();
|
|
||||||
var ref = $("input#ref").val();
|
|
||||||
var condition = $("input#condition").val();
|
|
||||||
var xml = $("textarea#xml").val();
|
|
||||||
|
|
||||||
// Reset CSS
|
|
||||||
$("input#uid").css('border-width', '0');
|
|
||||||
$("input#date").css('border-width', '0');
|
|
||||||
$("input#ref").css('border-width', '0');
|
|
||||||
$("textarea#xml").css('border-width', '0');
|
|
||||||
|
|
||||||
// Check data
|
|
||||||
if (!uid) {
|
|
||||||
$("input#uid").css('border-color', 'red').css('border-width', '2px').focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!date) {
|
|
||||||
$("input#date").css('border-color', 'red').css('border-width', '2px').focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ref) {
|
|
||||||
$("input#ref").css('border-color', 'red').css('border-width', '2px').focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!xml) {
|
|
||||||
$("textarea#xml").css('border-color', 'red').css('border-width', '2px').focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send AJAX request
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: scriptname,
|
|
||||||
data: {
|
|
||||||
'newNotif': {
|
|
||||||
'uid': uid,
|
|
||||||
'date': date,
|
|
||||||
'ref': ref,
|
|
||||||
'condition': condition,
|
|
||||||
'xml': xml
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
$('#data').html(data);
|
|
||||||
},
|
|
||||||
error: function(xhr, ajaxOptions, thrownError) {
|
|
||||||
$('#data').html('<h3>Request failed</h3> Error code: ' + xhr.status + ', ' + thrownError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
function displaySession(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: scriptname,
|
|
||||||
data: {
|
|
||||||
'session': id
|
|
||||||
},
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
$('#data').html(data);
|
|
||||||
},
|
|
||||||
error: function(xhr, ajaxOptions, thrownError) {
|
|
||||||
$('#data').html('<h3>Request failed</h3> Error code: ' + xhr.status + ', ' + thrownError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function del(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: scriptname,
|
|
||||||
data: {
|
|
||||||
'delete': id
|
|
||||||
},
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
$('#data').html(data);
|
|
||||||
// Delete session from tree
|
|
||||||
$('#uid' + id).remove();
|
|
||||||
$('#ip' + id).remove();
|
|
||||||
},
|
|
||||||
error: function(xhr, ajaxOptions, thrownError) {
|
|
||||||
$('#data').html('<h3>Request failed</h3> Error code: ' + xhr.status + ', ' + thrownError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,545 +0,0 @@
|
||||||
/*
|
|
||||||
* jQuery SimpleTree Drag&Drop plugin
|
|
||||||
* Update on 22th May 2008
|
|
||||||
* Version 0.3
|
|
||||||
*
|
|
||||||
* Licensed under BSD <http://en.wikipedia.org/wiki/BSD_License>
|
|
||||||
* Copyright (c) 2008, Peter Panov <panov\@elcat.kg>, IKEEN Group http://www.ikeen.com
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Modified by Xavier Guimard <x.guimard@free.fr> for Lemonldap::NG:
|
|
||||||
* * Manage Ajax errors
|
|
||||||
* Modified by Clement Oudot <clem.oudot@gmail.com> for Lemonldap::NG:
|
|
||||||
* * Add useClickToToggle option
|
|
||||||
* * Add afterCloseNearby trigger
|
|
||||||
* * Add afterNewNode trigger
|
|
||||||
* * Add and remove 'active' class instead of erasing all class values
|
|
||||||
* * Add afterSetTrigger trigger
|
|
||||||
* * Correct a bug if ajax call return no data
|
|
||||||
* * Automatically open the node if a subnode is added
|
|
||||||
*
|
|
||||||
* 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,
|
|
||||||
useClickToToggle: false,
|
|
||||||
afterCloseNearby: false,
|
|
||||||
afterNewNode: false,
|
|
||||||
afterSetTrigger: 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();
|
|
||||||
}
|
|
||||||
if (typeof TREE.option.afterCloseNearby == 'function') {
|
|
||||||
TREE.option.afterCloseNearby($(this).parent());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
TREE.nodeToggle = function(obj) {
|
|
||||||
var childUl = $('>ul', obj);
|
|
||||||
if (obj.className.match('open')) {
|
|
||||||
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 = '';
|
|
||||||
var call = '';
|
|
||||||
if (url.indexOf(',js:')) {
|
|
||||||
call = url.match(/.*,call:(.*)/i);
|
|
||||||
if (call == null) {
|
|
||||||
call = '';
|
|
||||||
} else {
|
|
||||||
call = call[1].replace(/,call.*$/, '');
|
|
||||||
}
|
|
||||||
js = url.match(/.*,js:(.*)/i);
|
|
||||||
if (js == null) {
|
|
||||||
js = '';
|
|
||||||
} else {
|
|
||||||
js = js[1].replace(/,call.*$/, '');
|
|
||||||
}
|
|
||||||
url = $.trim(url.replace(/,(?:js|call):.*/i, ''));
|
|
||||||
}
|
|
||||||
$.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: url,
|
|
||||||
contentType: 'html',
|
|
||||||
cache: false,
|
|
||||||
success: function(response) {
|
|
||||||
node.removeAttr('class');
|
|
||||||
if (response.length > 0) {
|
|
||||||
node.html(response);
|
|
||||||
$.extend(node, {
|
|
||||||
url: url
|
|
||||||
});
|
|
||||||
TREE.setTreeNodes(node, true);
|
|
||||||
} else {
|
|
||||||
$("li.line", node).remove();
|
|
||||||
$("li.doc-last", node).remove();
|
|
||||||
}
|
|
||||||
if (typeof TREE.option.afterAjax == 'function') {
|
|
||||||
TREE.option.afterAjax(node);
|
|
||||||
}
|
|
||||||
if (typeof callback == 'function') {
|
|
||||||
callback(node);
|
|
||||||
}
|
|
||||||
if (js.length) {
|
|
||||||
if (!js.match(/\(/)) js += '()';
|
|
||||||
$('>span', node.parent()).click(function() {
|
|
||||||
eval(js)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (call.length) {
|
|
||||||
if (!call.match(/\(/)) call += '()';
|
|
||||||
eval(call);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(xhr, ajaxOptions, thrownError) {
|
|
||||||
TREE.closeNearby(node);
|
|
||||||
alert('Failed to get remote datas. Error code: ' + xhr.status + ', ' + thrownError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
TREE.setTreeNodes = function(obj, useParent) {
|
|
||||||
obj = useParent ? obj.parent() : obj;
|
|
||||||
$('li>span', obj).addClass('text').bind('selectstart', function() {
|
|
||||||
return false;
|
|
||||||
}).click(function() {
|
|
||||||
// Remove all active classes and add the text class
|
|
||||||
$('.active', TREE).toggleClass('active').addClass('text');
|
|
||||||
if (this.className.match('text')) {
|
|
||||||
this.className = this.className.replace('text', 'active');
|
|
||||||
}
|
|
||||||
if (TREE.option.useClickToToggle) {
|
|
||||||
TREE.nodeToggle($(this).parent().get(0));
|
|
||||||
}
|
|
||||||
if (typeof TREE.option.afterClick == 'function') {
|
|
||||||
TREE.option.afterClick($(this).parent());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}).dblclick(function() {
|
|
||||||
mousePressed = false;
|
|
||||||
if (!TREE.option.useClickToToggle) {
|
|
||||||
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).toggleClass('active').addClass('text');
|
|
||||||
if (this.className.match('text')) {
|
|
||||||
this.className = this.className.replace('text', '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('<div id="drag_container"><ul></ul></div>');
|
|
||||||
$('#drag_container').hide().css({
|
|
||||||
opacity: '0.8'
|
|
||||||
});
|
|
||||||
$('#drag_container >ul').append(cloneNode);
|
|
||||||
$("<img>").attr({
|
|
||||||
id: "tree_plus",
|
|
||||||
src: imagepath + "tree/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('hidden') >= 0) {
|
|
||||||
setClassName = setClassName + 'hidden';
|
|
||||||
} else 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('<li class="line"> </li>').filter(':last-child').after('<li class="line-last"></li>');
|
|
||||||
TREE.setEventLine($('.line, .line-last', obj));
|
|
||||||
};
|
|
||||||
TREE.setTrigger = function(node) {
|
|
||||||
$('>span', node).before('<img class="trigger" src="' + imagepath + 'tree/spacer.gif" border=0>');
|
|
||||||
var trigger = $('>.trigger', node);
|
|
||||||
trigger.click(function(event) {
|
|
||||||
TREE.nodeToggle(node);
|
|
||||||
});
|
|
||||||
trigger.css('float', 'left');
|
|
||||||
if (typeof TREE.option.afterSetTrigger == 'function') {
|
|
||||||
TREE.option.afterSetTrigger(node);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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', imagepath + 'tree/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', imagepath + 'tree/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', imagepath + 'tree/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', imagepath + 'tree/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('<ul><li class="line-last"></li></ul>');
|
|
||||||
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) {
|
|
||||||
// Open node if it's closed
|
|
||||||
if (node[0].className.match('close')) {
|
|
||||||
TREE.nodeToggle(node[0]);
|
|
||||||
}
|
|
||||||
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).toggleClass('active').addClass('text');
|
|
||||||
$('span:first', dragNode_source).toggleClass('text').addClass('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) {
|
|
||||||
TREE.newNodeIn(TREE.getSelected(), id, text, callback);
|
|
||||||
};
|
|
||||||
TREE.newNodeIn = function(node, id, text, callback) {
|
|
||||||
var temp_node = $('<li><ul><li id="' + id + '"><span>' + text + '</span></li></ul></li>');
|
|
||||||
TREE.setTreeNodes(temp_node, false);
|
|
||||||
destination = node;
|
|
||||||
dragNode_source = $('.doc-last', temp_node);
|
|
||||||
TREE.moveNodeToFolder(destination);
|
|
||||||
temp_node.remove();
|
|
||||||
if (typeof TREE.option.afterNewNode == 'function') {
|
|
||||||
TREE.option.afterNewNode(node);
|
|
||||||
}
|
|
||||||
if (typeof(callback) == 'function') {
|
|
||||||
callback(dragNode_destination, dragNode_source);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
TREE.newNodeAfter = function(id, text, callback) {
|
|
||||||
TREE.newNodeIn(TREE.getSelected().parent().parent(), id, text, callback);
|
|
||||||
};
|
|
||||||
TREE.newAjaxNodeIn = function(node, id, text, url, callback) {
|
|
||||||
var temp_node = $('<li><ul><li id="' + id + '"><span>' + text + '</span><ul class="ajax"><li id="new">.{url:' + url + '}</li></ul></li></ul></li>');
|
|
||||||
TREE.setTreeNodes(temp_node, false);
|
|
||||||
destination = node;
|
|
||||||
dragNode_source = $('.folder-close-last', temp_node);
|
|
||||||
TREE.moveNodeToFolder(destination);
|
|
||||||
temp_node.remove();
|
|
||||||
if (typeof TREE.option.afterNewNode == 'function') {
|
|
||||||
TREE.option.afterNewNode(node);
|
|
||||||
}
|
|
||||||
if (typeof(callback) == 'function') {
|
|
||||||
callback(dragNode_destination, dragNode_source);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
Before Width: | Height: | Size: 1.4 KiB |
|
@ -1,895 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
|
||||||
<head>
|
|
||||||
<title>LemonLDAP::NG Manager</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
|
||||||
<meta http-equiv="cache-control" content="no-cache" />
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/lemonldap-ng.ico" rel="icon" type="image/x-icon" />
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/lemonldap-ng.ico" rel="shortcut icon" />
|
|
||||||
<!-- Offline doc CSS -->
|
|
||||||
<link rel="stylesheet" type="text/css" href="/doc/css/screen.css" />
|
|
||||||
<!-- jQuery UI CSS -->
|
|
||||||
<link rel="stylesheet" type="text/css" id="csstheme" href="<TMPL_VAR NAME="DIR">/<TMPL_VAR NAME="CSS_THEME">/jquery-ui-1.10.3.custom.min.css" />
|
|
||||||
<!-- Bootstrap CSS -->
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/css/bootstrap.css" rel="stylesheet">
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/css/bootstrap-theme.css" rel="stylesheet">
|
|
||||||
<!-- Manager CSS -->
|
|
||||||
<link rel="stylesheet" type="text/css" id="cssmenu" href="<TMPL_VAR NAME="DIR">/css/<TMPL_VAR NAME="CSS">" />
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery-1.10.2.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/bootstrap.js"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery-ui-1.10.3.custom.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery.cookie.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery.ajaxfileupload.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery.elastic.source.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/tree.js" type="text/JavaScript"></script>
|
|
||||||
<script type="text/JavaScript">//<![CDATA[
|
|
||||||
var scriptname='<TMPL_VAR NAME="SCRIPT_NAME">';
|
|
||||||
var imagepath='<TMPL_VAR NAME="DIR">/images/';
|
|
||||||
var csspath='<TMPL_VAR NAME="DIR">/css/';
|
|
||||||
var jqueryuiversion='1.10.3';
|
|
||||||
var css_menu='<TMPL_VAR NAME="CSS">';
|
|
||||||
var css_theme='<TMPL_VAR NAME="CSS_THEME">';
|
|
||||||
var themepath='<TMPL_VAR NAME="DIR">/';
|
|
||||||
var treeautoclose='<TMPL_VAR NAME="TREE_AUTOCLOSE">';
|
|
||||||
var treejquerycss='<TMPL_VAR NAME="TREE_JQUERYCSS">';
|
|
||||||
var text4newKey='<lang en="Key" fr="Clé" />';
|
|
||||||
var value4newKey='<lang en="Value" fr="Valeur" />';
|
|
||||||
var value4newSamlAttribute='<lang en="Value" fr="Valeur" />';
|
|
||||||
var text4newVhost='<lang en="Virtual host name" fr="Nom de l\'hôte virtuel" />';
|
|
||||||
var text4newSamlMetaData='<lang en="SAML Metadatas name" fr="Nom des métadatas SAML" />';
|
|
||||||
var text4newSamlAttribute='<lang en="Attribute name" fr="Nom de l\'attribut" />';
|
|
||||||
var text4newFilename='<lang en="Filename" fr="Nom du fichier" />';
|
|
||||||
var text4securedCookie0='<lang en="Non secured cookie" fr="Cookie non sécurisé"/>';
|
|
||||||
var text4securedCookie1='<lang en="Secured cookie (HTTPS)" fr="Cookie sécurisé (HTTPS)"/>';
|
|
||||||
var text4securedCookie2='<lang en="Double cookie (HTTP and HTTPS)" fr="Double cookie (HTTP et HTTPS)"/>';
|
|
||||||
var text4securedCookie3='<lang en="Double cookie for single session" fr="Double cookie pour une seule session"/>';
|
|
||||||
var text4newGeneratedFile='<lang en="Password (optional)" fr="Mot de passe (optionnel)" />';
|
|
||||||
var text4edit='<lang en="Edit" fr="Éditer" />';
|
|
||||||
var text4protect='<lang en="Protect" fr="Protéger" />';
|
|
||||||
var text4newCategory='<lang en="Category identifier" fr="Identifiant de la catégorie" />';
|
|
||||||
var text4newApplication='<lang en="Application identifier" fr="Identifiant de l\'application" />';
|
|
||||||
var text4newCondition='<lang en="New Condition" fr="Nouvelle Condition" />';
|
|
||||||
var lang='<TMPL_VAR NAME="LANG">';
|
|
||||||
var text4newOidcOp='<lang en="Provider name" fr="Nom du fournisseur" />';
|
|
||||||
var text4newOidcRp='<lang en="Relying party name" fr="Nom du relai" />';
|
|
||||||
//]]></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/manager.js" type="text/JavaScript"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<!-- Popup -->
|
|
||||||
<div id="popup" title="<lang en="Command result" fr="Résultat de la commande" />">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Skin picker-->
|
|
||||||
<div id="skinImagePicker" title="<lang en="Choose a skin" fr="Choisir un thème" />">
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/portal-skins/bootstrap.png" alt="Bootstrap" title="bootstrap" width="200px" height="129px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/portal-skins/pastel.png" alt="Pastel" title="pastel" width="200px" height="129px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/portal-skins/impact.png" alt="Impact" title="impact" width="200px" height="129px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/portal-skins/dark.png" alt="Dark" title="dark" width="200px" height="129px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/portal-skins/custom.png" alt="Custom" title="custom" width="200px" height="129px" /></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- logo picker-->
|
|
||||||
<div id="appsLogoPicker" title="<lang en="Choose a logo" fr="Choisir un logo" />">
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/attach.png" title="attach" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/bell.png" title="bell" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/bookmark.png" title="bookmark" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/configure.png" title="configure" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/database.png" title="database" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/demo.png" title="demo" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/folder.png" title="folder" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/gear.png" title="gear" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/help.png" title="help" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/mailappt.png" title="mailappt" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/money.png" title="money" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/network.png" title="network" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/terminal.png" title="terminal" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/thumbnail.png" title="thumbnail" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/tux.png" title="tux" width="32px" height="32px" /></button>
|
|
||||||
<button><img src="<TMPL_VAR NAME="DIR">/images/apps-logos/custom.png" title="custom" width="32px" height="32px" /></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<TMPL_INCLUDE NAME="top.tpl">
|
|
||||||
|
|
||||||
<!-- Container -->
|
|
||||||
<div class="container-fluid">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
|
|
||||||
<!-- Menu (tree) -->
|
|
||||||
<div id="menu" class="panel panel-default panel-body">
|
|
||||||
<TMPL_VAR NAME="MENU">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
|
|
||||||
<!-- Buttons -->
|
|
||||||
<div id="buttons" class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h1 class="panel-title">
|
|
||||||
<lang en="Available actions" fr="Actions disponibles" />
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="buttons_content" class="panel-body">
|
|
||||||
<button id="bsave" onclick="uploadConf()" class="btn btn-info">
|
|
||||||
<i class=" glyphicon glyphicon-floppy-disk"></i>
|
|
||||||
<lang en="Save" fr="Sauver" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="bnewvh" style="display:none;" onclick="newVh();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New virtual host" fr="Nouvel hôte virtuel" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="bdelvh" style="display:none;" onclick="delvh(currentId);" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete virtual host" fr="Supprimer l'hôte virtuel" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newkbr" style="display:none;" onclick="newKeyR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New key" fr="Nouvelle clef" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newrbr" style="display:none;" onclick="newRuleR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New rule" fr="Nouvelle règle" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newgsrbr" style="display:none;" onclick="newGrantSessionRuleR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New condition" fr="Nouvelle condition" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newkb" style="display:none;" onclick="newKey();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New key" fr="Nouvelle clef" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newrb" style="display:none;" onclick="newRule();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New rule" fr="Nouvelle règle" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newgsrb" style="display:none;" onclick="newGrantSessionRule();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New condition" fr="Nouvelle condition" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delkb" style="display:none;" onclick="delKey();return false;" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete key" fr="Effacer la clef" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newidpsamlmetadatab" style="display:none;" onclick="newIdpSamlMetaData();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New identity provider" fr="Nouveau fournisseur d'identité" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delidpsamlmetadatab" style="display:none;" onclick="delIdpSamlMetaData(currentId);" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete identity provider" fr="Supprimer le fournisseur d'identité" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newspsamlmetadatab" style="display:none;" onclick="newSpSamlMetaData();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New service provider" fr="Nouveau fournisseur de service" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delspsamlmetadatab" style="display:none;" onclick="delSpSamlMetaData(currentId);" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete service provider" fr="Supprimer le fournisseur de service" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newsamlattributeb" style="display:none;" onclick="newSamlAttribute();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New attribute" fr="Nouvel attribut" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newsamlattributebr" style="display:none;" onclick="newSamlAttributeR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New attribute" fr="Nouvel attribut" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delsamlattributeb" style="display:none;" onclick="delSamlAttribute();return false;" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete attribute" fr="Supprimer l'attribut" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newchoice" style="display:none;" onclick="newChoice();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New choice" fr="Nouveau choix" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newchoicer" style="display:none;" onclick="newChoiceR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New choice" fr="Nouveau choix" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delchoice" style="display:none;" onclick="delChoice();return false;" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete choice" fr="Supprimer le choix" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newcategoryr" style="display:none;" onclick="newCategoryR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New category" fr="Nouvelle catégorie" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delcategory" style="display:none;" onclick="delCategory();return false;" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete category" fr="Supprimer la catégorie" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newapplicationr" style="display:none;" onclick="newApplicationR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New application" fr="Nouvelle application" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delapplication" style="display:none;" onclick="delApplication();return false;" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete application" fr="Supprimer l'application" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newpostr" style="display:none;" onclick="newPostR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New form" fr="Nouveau formulaire" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delpost" style="display:none;" onclick="delPost();return false;" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete form" fr="Supprimer le formulaire" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newpostdatar" style="display:none;" onclick="newPostDataR();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New POST data" fr="Nouvelle donnée POST" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="delpostdata" style="display:none;" onclick="delPostData();return false;" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete POST data" fr="Supprimer la donnée POST" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newoidcopb" style="display:none;" onclick="newOidcOp();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New provider" fr="Nouveau fournisseur" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="deloidcopb" style="display:none;" onclick="delOidcOp(currentId);" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete provider" fr="Supprimer le fournisseur" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="newoidcrpb" style="display:none;" onclick="newOidcRp();return false;" class="btn btn-success">
|
|
||||||
<i class=" glyphicon glyphicon-plus-sign"></i>
|
|
||||||
<lang en="New relying party" fr="Nouveau relai" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="deloidcrpb" style="display:none;" onclick="delOidcRp(currentId);" class="btn btn-danger">
|
|
||||||
<i class=" glyphicon glyphicon-minus-sign"></i>
|
|
||||||
<lang en="Delete relying party" fr="Supprimer le relai" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Buttons -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Edition -->
|
|
||||||
<div id="edition" class="panel panel-default">
|
|
||||||
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h1 class="panel-title">
|
|
||||||
<lang en="Edit key " fr="Édition de la clé " /><span id="content_title"> </span>
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form action="#" onsubmit="return false"i role="form">
|
|
||||||
|
|
||||||
<!-- Edition content -->
|
|
||||||
<div id="content" class="panel-body">
|
|
||||||
|
|
||||||
<!-- Default text -->
|
|
||||||
<div id="content_default" class="content">
|
|
||||||
<lang en="No value" fr="Pas de valeur" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Configuration datas -->
|
|
||||||
<div id="content_cfgDatas" class="hidden">
|
|
||||||
<ul>
|
|
||||||
<li><strong><lang en="Configuration number" fr="Numéro de configuration "/></strong>: <span id="cfgNum"><TMPL_VAR NAME="CFGNUM"></span></li>
|
|
||||||
<li><strong><lang en="Author" fr="Auteur "/></strong>: <span id="cfgAuthor"></span></li>
|
|
||||||
<li><strong><lang en="IP Address" fr="Adresse IP "/></strong>: <span id="cfgAuthorIP"></span></li>
|
|
||||||
<li><strong><lang en="Date" fr="Date "/></strong>: <span id="cfgDate"></span></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Simple text -->
|
|
||||||
<div id="content_text" class="hidden">
|
|
||||||
<input type="text" id="text" class="form-control" />
|
|
||||||
<br />
|
|
||||||
<button onclick="setlminputdata(currentId,text);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Password -->
|
|
||||||
<div id="content_password" class="hidden">
|
|
||||||
<input type="password" id="password" class="form-control" />
|
|
||||||
<br />
|
|
||||||
<button onclick="setlminputdata(currentId,password);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Simple textarea -->
|
|
||||||
<div id="content_textarea" class="hidden">
|
|
||||||
<textarea id="textarea" cols="80" rows="10" class="form-control"></textarea>
|
|
||||||
<br />
|
|
||||||
<button onclick="setlminputdata(currentId,textarea);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- File textarea -->
|
|
||||||
<div id="content_filearea" class="hidden">
|
|
||||||
<textarea readonly="readonly" id="filearea" cols="80" rows="10" class="form-control"></textarea>
|
|
||||||
<div class="buttons">
|
|
||||||
<button id="downloadfile" onclick="downloadFile(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-floppy-save"></i>
|
|
||||||
<lang en="Download this file" fr="Télécharger ce fichier" />
|
|
||||||
</button>
|
|
||||||
<button id="generatefile" onclick="generateFile(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-flash"></i>
|
|
||||||
<lang en="Generate" fr="Générer" />
|
|
||||||
</button>
|
|
||||||
<button id="switchreadonly" onclick="switchReadonly('#filearea');return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-lock"></i>
|
|
||||||
<span></span>
|
|
||||||
</button>
|
|
||||||
<button onclick="setlminputdata(currentId,filearea);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
<span class="loadimg"><img class="hidden" id="button-loadimg" src="<TMPL_VAR NAME="DIR">/images/spinner.gif" width="16px" height="16px" /></span>
|
|
||||||
</div>
|
|
||||||
<table class="table">
|
|
||||||
<tr id="fileinput">
|
|
||||||
<th><lang en="Load from a file" fr="Charger depuis un fichier" /> :</th>
|
|
||||||
<td>
|
|
||||||
<input type="file" name="file" id="file" size="30" />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button onclick="setlmfile(currentId,file);return false;" class="btn btn-info"><i class="glyphicon glyphicon-floppy-open"></i> <lang en="Load" fr="Charger" /></button>
|
|
||||||
<span class="loadimg"><img class="hidden" id="file-loadimg" src="<TMPL_VAR NAME="DIR">/images/spinner.gif" width="16px" height="16px" /></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr id="urlinput">
|
|
||||||
<th><lang en="Load from a URL" fr="Charger depuis une URL" /> :</th>
|
|
||||||
<td>
|
|
||||||
<input type="text" name="url" id="url" size="40" class="form-control"/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button onclick="setlmfile(currentId,url);return false;" class="btn btn-info"><i class="glyphicon glyphicon-cloud-upload"></i> <lang en="Load" fr="Charger" /></button>
|
|
||||||
<span class="loadimg"><img class="hidden" id="url-loadimg" src="<TMPL_VAR NAME="DIR">/images/spinner.gif" width="16px" height="16px" /></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Select -->
|
|
||||||
<div id="content_select" class="hidden">
|
|
||||||
<select id="select" onchange="setlmdata(currentId,this.value);return false;" class="form-control"></select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Integer -->
|
|
||||||
<div id="content_int" class="hidden">
|
|
||||||
<div class="input-group int">
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button onclick="decrease();return false;" class="btn btn-warning"><i class="glyphicon glyphicon-minus"></i></button>
|
|
||||||
</span>
|
|
||||||
<input type="text" id="int" class="form-control" />
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button onclick="increase();return false;" class="btn btn-warning"><i class="glyphicon glyphicon-plus"></i></button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlminputdata(currentId,int);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Boolean -->
|
|
||||||
<div id="content_bool" class="hidden">
|
|
||||||
<div class="btn-group" data-toggle="buttons">
|
|
||||||
<label id="On" class="btn btn-info" onclick="setlmdata(currentId,1)">
|
|
||||||
<input type="radio" name="boolean" autocomplete="off" /><lang en="On" fr="Activé"/>
|
|
||||||
</label>
|
|
||||||
<label id="Off" class="btn btn-info" onclick="setlmdata(currentId,0)">
|
|
||||||
<input type="radio" name="boolean" autocomplete="off" /><lang en="Off" fr="Désactivé"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Troolean -->
|
|
||||||
<div id="content_trool" class="hidden">
|
|
||||||
<div class="btn-group" data-toggle="buttons">
|
|
||||||
<label id="TrOn" class="btn btn-info" onclick="setlmdata(currentId,1)">
|
|
||||||
<input type="radio" name="troolean" autocomplete="off" /><lang en="On" fr="Activé"/>
|
|
||||||
</label>
|
|
||||||
<label id="TrOff" class="btn btn-info" onclick="setlmdata(currentId,0)">
|
|
||||||
<input type="radio" name="troolean" autocomplete="off" /><lang en="Off" fr="Désactivé"/>
|
|
||||||
</label>
|
|
||||||
<label id="TrDefault" class="btn btn-info" onclick="setlmdata(currentId,-1)">
|
|
||||||
<input type="radio" name="troolean" autocomplete="off" /><lang en="Default" fr="Par défaut"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Boolean or Perl Expr -->
|
|
||||||
<div id="content_boolOrPerlExpr" class="hidden">
|
|
||||||
<div class="btn-group buttons" data-toggle="buttons">
|
|
||||||
<label id="bopeOn" class="btn btn-info" onclick="setlmdata(currentId,1);$('#bopeValue').hide();">
|
|
||||||
<input type="radio" name="bope" autocomplete="off" /><lang en="On" fr="Activé"/>
|
|
||||||
</label>
|
|
||||||
<label id="bopeOff" class="btn btn-info" onclick="setlmdata(currentId,0);$('#bopeValue').hide();">
|
|
||||||
<input type="radio" name="bope" autocomplete="off" /><lang en="Off" fr="Désactivé"/>
|
|
||||||
</label>
|
|
||||||
<label id="bopeExpr" class="btn btn-info" onclick="$('#bopeValue').show();">
|
|
||||||
<input type="radio" name="bope" autocomplete="off" /><lang en="Specific rule" fr="Règle spécifique"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<textarea id="bopeValue" cols="30" rows="2" class="form-control"></textarea>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlmbope(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="content_btext" class="hidden">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<textarea class="elastic form-control" id="btextKey" rows="1" cols="25"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<textarea class="elastic form-control" id="btextValue" rows="1" cols="40"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlminputtext(currentId,btextKey);setlminputdata(currentId,btextValue);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Rule -->
|
|
||||||
<div id="content_rules" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Comment" fr="Commentaire" /></th>
|
|
||||||
<td><textarea class="elastic form-control" id="rulComment" rows="1" cols="30"></textarea></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Expression" fr="Expression" /></th>
|
|
||||||
<td><textarea class="elastic form-control" id="rulKey" rows="1" cols="30"></textarea></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Rule" fr="Règle" /></th>
|
|
||||||
<td><textarea class="elastic form-control" id="rulValue" rows="3" cols="50"></textarea></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlmrule(currentId,rulComment,rulKey,rulValue);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Grant session rule -->
|
|
||||||
<div id="content_grantSessionRules" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Comment" fr="Commentaire" /></th>
|
|
||||||
<td><textarea class="elastic form-control" id="grantSessionRulComment" rows="1" cols="30"></textarea></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Condition" fr="Condition" /></th>
|
|
||||||
<td><textarea class="elastic form-control" id="grantSessionRulKey" cols="30" rows="1"></textarea></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Message" fr="Message" /></th>
|
|
||||||
<td><textarea class="elastic form-control" id="grantSessionRulValue" cols="50" rows="1"></textarea></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlmgrantsessionrule(currentId,grantSessionRulComment,grantSessionRulKey,grantSessionRulValue);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- authParams -->
|
|
||||||
<div id="content_authParams" class="hidden">
|
|
||||||
<select id="authText" class="form-control"></select>
|
|
||||||
<input type="text" id="authOptions" class="form-control" size="30" />
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="reloadAuthParams();return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Skin -->
|
|
||||||
<div id="content_skin" class="hidden">
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="current btn btn-default" role="button"><img src="" alt="" class="current" /></button>
|
|
||||||
</span>
|
|
||||||
<input id="skinText" type="text" readonly="readonly" class="form-control"/>
|
|
||||||
</div>
|
|
||||||
<div class="buttons">
|
|
||||||
<button onclick="setlminputdata(currentId,skinText);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Vhost -->
|
|
||||||
<div id="content_vhost" class="hidden">
|
|
||||||
<input type="text" id="vhost" size="30" class="form-control"/>
|
|
||||||
<div class="buttons">
|
|
||||||
<button onclick="setlminputtext(currentId,vhost);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- samlIdpMetaData -->
|
|
||||||
<div id="content_samlIdpMetaData" class="hidden">
|
|
||||||
<input type="text" id="samlIdpMetaData" size="30" class="form-control"/>
|
|
||||||
<div class="buttons">
|
|
||||||
<button onclick="setlminputtext(currentId,samlIdpMetaData);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- samlSpMetaData -->
|
|
||||||
<div id="content_samlSpMetaData" class="hidden">
|
|
||||||
<input type="text" id="samlSpMetaData" size="30" class="form-control"/>
|
|
||||||
<div class="buttons">
|
|
||||||
<button onclick="setlminputtext(currentId,samlSpMetaData);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- samlAttribute -->
|
|
||||||
<div id="content_samlAttribute" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Key name" fr="Nom de la clef"/></th>
|
|
||||||
<td><input type="text" id="samlAttributeKey" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Name" fr="Nom"/></th>
|
|
||||||
<td><input type="text" id="samlAttributeName" class="form-control"/></td>
|
|
||||||
<th><lang en="Mandatory" fr="Obligatoire"/></th>
|
|
||||||
<td>
|
|
||||||
<div class="btn-group" data-toggle="buttons">
|
|
||||||
<label id="samlAttributeMandatoryOn" class="btn btn-info" name="samlAttributeMandatoryBoolean">
|
|
||||||
<input type="radio" value="1" /><lang en="On" fr="Activé"/>
|
|
||||||
</label>
|
|
||||||
<label id="samlAttributeMandatoryOff" class="btn btn-info" name="samlAttributeMandatoryBoolean">
|
|
||||||
<input type="radio" value="0" /><lang en="Off" fr="Désactivé"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Friendly name" fr="Nom alternatif"/></th>
|
|
||||||
<td><input type="text" id="samlAttributeFriendlyName" class="form-control"/></td>
|
|
||||||
<th><lang en="Format" fr="Format"/></th>
|
|
||||||
<td><select id="samlAttributeFormat" class="form-control"></select></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons">
|
|
||||||
<button onclick="setlmsamlattribute(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- samlAssertion -->
|
|
||||||
<div id="content_samlAssertion" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Default" fr="Par défaut"/></th>
|
|
||||||
<td>
|
|
||||||
<div class="btn-group" data-toggle="buttons">
|
|
||||||
<label id="samlAssertionDefaultOn" class="btn btn-info" name="samlAssertionDefaultBoolean">
|
|
||||||
<input type="radio" value="1" /><lang en="On" fr="Activé"/>
|
|
||||||
</label>
|
|
||||||
<label id="samlAssertionDefaultOff" class="btn btn-info" name="samlAssertionDefaultBoolean">
|
|
||||||
<input type="radio" value="0" /><lang en="Off" fr="Désactivé"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="hidden">
|
|
||||||
<th><lang en="Index" fr="Index"/></th>
|
|
||||||
<td><input type="text" size="50" id="samlAssertionIndex" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Binding" fr="Binding"/></th>
|
|
||||||
<td><select disabled="disabled" id="samlAssertionBinding" class="form-control"></select></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Location" fr="URL"/></th>
|
|
||||||
<td><input type="text" size="50" id="samlAssertionLocation" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons">
|
|
||||||
<button onclick="setlmsamlassertion(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- samlService -->
|
|
||||||
<div id="content_samlService" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Binding" fr="Binding"/></th>
|
|
||||||
<td><select disabled="disabled" id="samlServiceBinding" class="form-control"></select></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Location" fr="URL"/></th>
|
|
||||||
<td><input type="text" size="50" id="samlServiceLocation" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Response Location" fr="URL de retour"/></th>
|
|
||||||
<td><input type="text" size="50" id="samlServiceResponseLocation" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons">
|
|
||||||
<button onclick="setlmsamlservice(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- OpenID black/white lists -->
|
|
||||||
<div id="content_openid_serverlist" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="List type" fr="Type de liste"/></th>
|
|
||||||
<td>
|
|
||||||
<div class="btn-group" data-toggle="buttons">
|
|
||||||
<label id="openid_serverlist_black" class="btn btn-info" name="openIdServerlistBoolean">
|
|
||||||
<input type="radio" autocomplete="off" value="0" /><lang en="Black list" fr="Liste noire"/>
|
|
||||||
</label>
|
|
||||||
<label id="openid_serverlist_white" class="btn btn-info" name="openIdServerlistBoolean">
|
|
||||||
<input type="radio" autocomplete="off" value="1" /><lang en="White list" fr="Liste blanche"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="List" fr="Liste"/></th>
|
|
||||||
<td><input type="text" size="50" id="openid_serverlist_text" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setopenididplist(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- authChoice -->
|
|
||||||
<div id="content_authChoice" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Key name" fr="Nom de la clef"/></th>
|
|
||||||
<td><input type="text" id="authChoiceKey" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Authentication module" fr="Module d'authentification"/></th>
|
|
||||||
<td><select id="authChoiceAuth" class="form-control"></select></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="User module" fr="Module d'utilisateurs"/></th>
|
|
||||||
<td><select id="authChoiceUser" class="form-control"></select></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Password module" fr="Module de mots de passe"/></th>
|
|
||||||
<td><select id="authChoicePassword" class="form-control"></select></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="URL" fr="URL"/></th>
|
|
||||||
<td><input type="text" id="authChoiceURL" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlmauthchoice(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- applicationList Category-->
|
|
||||||
<div id="content_applicationListCategory" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Key" fr="Nom de la clef"/></th>
|
|
||||||
<td><input type="text" id="applicationListCategoryKey" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Display name" fr="Nom à afficher"/></th>
|
|
||||||
<td><input type="text" id="applicationListCategoryName" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlminputtext(currentId,'#applicationListCategoryKey');setlminputdata(currentId,'#applicationListCategoryName');return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- applicationList Application-->
|
|
||||||
<div id="content_applicationListApplication" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Key" fr="Nom de la clef"/></th>
|
|
||||||
<td><input type="text" id="applicationListApplicationKey" class="form-control"/></td>
|
|
||||||
<th><lang en="Display name" fr="Nom à afficher"/></th>
|
|
||||||
<td><input type="text" id="applicationListApplicationName" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Address" fr="Adresse"/></th>
|
|
||||||
<td><input type="text" id="applicationListApplicationURL" class="form-control"/></td>
|
|
||||||
<th><lang en="Display mode" fr="Mode d'affichage"/></th>
|
|
||||||
<td><select id="applicationListApplicationDisplay" class="form-control"></select></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Description" fr="Description"/></th>
|
|
||||||
<td><textarea id="applicationListApplicationDescription" class="form-control"/></textarea></td>
|
|
||||||
<th><lang en="Logo" fr="Logo"/></th>
|
|
||||||
<td>
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="current btn btn-default" role="button"><img src="" alt="" class="current" /></button>
|
|
||||||
</span>
|
|
||||||
<input type="text" id="applicationListApplicationLogo" readonly="readonly" class="form-control"/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlmapplication(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Post -->
|
|
||||||
<div id="content_post" class="hidden">
|
|
||||||
<table class="table">
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Form URL" fr="URL du formulaire"/></th>
|
|
||||||
<td><input type="text" id="postKey" size="20" class="form-control"/></td>
|
|
||||||
<th><lang en="jQuery form selector (optional)" fr="Sélecteur jQuery du formulaire (optionnel)"/></th>
|
|
||||||
<td><input type="text" id="formSelector" size="20" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="Target URL (optional)" fr="URL cible (optionnelle)"/></th>
|
|
||||||
<td><input type="text" id="postUrl" size="20" class="form-control"/></td>
|
|
||||||
<th><lang en="jQuery button selector (optional)" fr="Sélecteur jQuery du bouton (optionnel)"/></th>
|
|
||||||
<td><input type="text" id="buttonSelector" size="20" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><lang en="jQuery URL (optional)" fr="URL de jQuery (optionnelle)"/></th>
|
|
||||||
<td colspan="3"><input type="text" id="jqueryUrl" size="60" class="form-control"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlminputtext(currentId,postKey);setlmpostform(currentId);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="content_postdata" class="hidden">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<input type="text" id="postDataKey" class="form-control"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="text" id="postDataValue" class="form-control"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="buttons text-center">
|
|
||||||
<button onclick="setlminputtext(currentId,postDataKey,'postdata:');setlminputdata(currentId,postDataValue);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- oidcOPMetaData -->
|
|
||||||
<div id="content_oidcOPMetaData" class="hidden">
|
|
||||||
<input type="text" id="oidcOPMetaData" size="30" class="form-control"/>
|
|
||||||
<div class="buttons">
|
|
||||||
<button onclick="setlminputtext(currentId,oidcOPMetaData);return false;" class="btn btn-info">
|
|
||||||
<i class="glyphicon glyphicon-ok"></i>
|
|
||||||
<lang en="Apply" fr="Appliquer" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- Edition -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Help -->
|
|
||||||
<div id="help" class="panel panel-default">
|
|
||||||
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h1 class="panel-title">
|
|
||||||
<lang en="Help" fr="Aide"/>
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="help_content" class="panel-body">
|
|
||||||
<!-- AJAX content -->
|
|
||||||
<lang en="Click on the configuration tree to edit parameters" fr="Cliquer sur l'arbre de configuration pour éditer les paramètres" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Help -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Container -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,117 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
|
|
||||||
<head>
|
|
||||||
<title><lang en="LemonLDAP::NG notification explorer" fr="Explorateur de notifications LemonLDAP::NG"/></title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
|
||||||
<meta http-equiv="cache-control" content="no-cache" />
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/lemonldap-ng.ico" rel="icon" type="image/x-icon" />
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/lemonldap-ng.ico" rel="shortcut icon" />
|
|
||||||
<!-- jQuery UI CSS -->
|
|
||||||
<link rel="stylesheet" type="text/css" id="csstheme" href="<TMPL_VAR NAME="DIR">/<TMPL_VAR NAME="CSS_THEME">/jquery-ui-1.10.3.custom.min.css" />
|
|
||||||
<!-- Bootstrap CSS -->
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/css/bootstrap.css" rel="stylesheet">
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/css/bootstrap-theme.css" rel="stylesheet">
|
|
||||||
<!-- Manager CSS -->
|
|
||||||
<link rel="stylesheet" type="text/css" id="cssmenu" href="<TMPL_VAR NAME="DIR">/css/<TMPL_VAR NAME="CSS">" />
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery-1.10.2.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/bootstrap.js"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery-ui-1.10.3.custom.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery.cookie.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/tree.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/notifications.js" type="text/JavaScript"></script>
|
|
||||||
<script type="text/JavaScript">//<![CDATA[
|
|
||||||
var scriptname='<TMPL_VAR NAME="SCRIPT_NAME">';
|
|
||||||
var imagepath='<TMPL_VAR NAME="DIR">/images/';
|
|
||||||
var csspath='<TMPL_VAR NAME="DIR">/css/';
|
|
||||||
var jqueryuiversion='1.10.3';
|
|
||||||
var css_menu='<TMPL_VAR NAME="CSS">';
|
|
||||||
var css_theme='<TMPL_VAR NAME="CSS_THEME">';
|
|
||||||
var themepath='<TMPL_VAR NAME="DIR">/';
|
|
||||||
var treejquerycss='false';
|
|
||||||
var treeautoclose='false';
|
|
||||||
var lang='<TMPL_VAR NAME="LANG">';
|
|
||||||
//]]></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/manager.js" type="text/JavaScript"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<TMPL_INCLUDE NAME="top.tpl">
|
|
||||||
|
|
||||||
<!-- Container -->
|
|
||||||
<div class="container-fluid">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
|
|
||||||
<!-- Menu (tree) -->
|
|
||||||
<div id="menu" class="panel panel-default panel-body text-center">
|
|
||||||
|
|
||||||
<!-- Query choice -->
|
|
||||||
<div id="query-switch" class="btn-group btn-group-justified" role="group">
|
|
||||||
<a href="<TMPL_VAR NAME="SCRIPT_NAME">" alt="list" class="btn btn-info"><i class="glyphicon glyphicon-eye-open"></i> <lang en="Active" fr="Actives" /></a>
|
|
||||||
<a href="<TMPL_VAR NAME="SCRIPT_NAME">?listDone=1" alt="listDone" class="btn btn-info"><i class="glyphicon glyphicon-eye-close"></i> <lang en="Done" fr="Validées" /></a>
|
|
||||||
<a alt="newNotif" onclick="newNotif()" class="btn btn-info"><i class="glyphicon glyphicon-plus-sign"></i> <lang en="Create" fr="Créer" /></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
<TMPL_VAR NAME="TREE">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
|
|
||||||
<!-- Data -->
|
|
||||||
<div id="data" class="panel panel-default">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Form to create a new notification -->
|
|
||||||
<div id="newNotif" style="display: none">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h1 class="panel-title text-center"><lang en="New notification" fr="Nouvelle notification" /></h1>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<table style="width:70%;margin: 10px auto;">
|
|
||||||
<tr>
|
|
||||||
<th style="text-align:right;"><label for="uid"><lang en="User login:" fr="Identifiant de l'utilisateur :" /></label></th>
|
|
||||||
<td><input id="uid" type="text" /></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th style="text-align:right;"><label for="date"><lang en="Date:" fr="Date :" /></label></th>
|
|
||||||
<td><input id="date" type="text" /></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th style="text-align:right;"><label for="ref"><lang en="Reference:" fr="Référence :" /></label></th>
|
|
||||||
<td><input id="ref" type="text" /></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th style="text-align:right;"><label for="condition">Condition <lang en="(optional):" fr="(optionnelle) :" /></label></th>
|
|
||||||
<td><input id="condition" type="text" /></td>
|
|
||||||
</tr>
|
|
||||||
<tr><td colspan="2">
|
|
||||||
<div id="newNotifHelp" class="alert alert-info">
|
|
||||||
<lang en="Set XML content here. You can use the following markups:" fr="Insérer le contenu XML ici. Vous pouvez utiliser les balises suivantes :" />
|
|
||||||
<ul>
|
|
||||||
<li><tt><title></tt><lang en="a title" fr="un titre" /><tt></title></li>
|
|
||||||
<li><tt><subtitle></tt><lang en="a subtitle" fr="un sous-titre" /><tt></subtitle></li>
|
|
||||||
<li><tt><text></tt><lang en="some text" fr="du texte" /><tt></text></li>
|
|
||||||
<li><tt><check></tt><lang en="a checkbox" fr="une case à cocher" /><tt></check></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td></tr>
|
|
||||||
<tr><td colspan="2">
|
|
||||||
<textarea rows="10" cols="80" id="xml"></textarea><br />
|
|
||||||
</td></tr>
|
|
||||||
</table>
|
|
||||||
<div class="text-center">
|
|
||||||
<a id="sendNewNotif" onclick=sendNewNotif() class="btn btn-success"><i class="glyphicon glyphicon-plus-sign"></i> <lang en="Create" fr="Créer" /></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,74 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
|
|
||||||
<head>
|
|
||||||
<title><lang en="LemonLDAP::NG session explorer" fr="Explorateur de sessions LemonLDAP::NG"/></title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
|
||||||
<meta http-equiv="cache-control" content="no-cache" />
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/lemonldap-ng.ico" rel="icon" type="image/x-icon" />
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/lemonldap-ng.ico" rel="shortcut icon" />
|
|
||||||
<!-- jQuery UI CSS -->
|
|
||||||
<link rel="stylesheet" type="text/css" id="csstheme" href="<TMPL_VAR NAME="DIR">/<TMPL_VAR NAME="CSS_THEME">/jquery-ui-1.10.3.custom.min.css" />
|
|
||||||
<!-- Bootstrap CSS -->
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/css/bootstrap.css" rel="stylesheet">
|
|
||||||
<link href="<TMPL_VAR NAME="DIR">/css/bootstrap-theme.css" rel="stylesheet">
|
|
||||||
<!-- Manager CSS -->
|
|
||||||
<link rel="stylesheet" type="text/css" id="cssmenu" href="<TMPL_VAR NAME="DIR">/css/<TMPL_VAR NAME="CSS">" />
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery-1.10.2.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/bootstrap.js"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery-ui-1.10.3.custom.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/jquery.cookie.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/tree.js" type="text/JavaScript"></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/sessions.js" type="text/JavaScript"></script>
|
|
||||||
<script type="text/JavaScript">//<![CDATA[
|
|
||||||
var scriptname='<TMPL_VAR NAME="SCRIPT_NAME">';
|
|
||||||
var imagepath='<TMPL_VAR NAME="DIR">/images/';
|
|
||||||
var csspath='<TMPL_VAR NAME="DIR">/css/';
|
|
||||||
var jqueryuiversion='1.10.3';
|
|
||||||
var css_menu='<TMPL_VAR NAME="CSS">';
|
|
||||||
var css_theme='<TMPL_VAR NAME="CSS_THEME">';
|
|
||||||
var themepath='<TMPL_VAR NAME="DIR">/';
|
|
||||||
var treejquerycss='false';
|
|
||||||
var treeautoclose='false';
|
|
||||||
var lang='<TMPL_VAR NAME="LANG">';
|
|
||||||
//]]></script>
|
|
||||||
<script src="<TMPL_VAR NAME="DIR">/js/manager.js" type="text/JavaScript"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<TMPL_INCLUDE NAME="top.tpl">
|
|
||||||
|
|
||||||
<!-- Container -->
|
|
||||||
<div class="container-fluid">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
|
|
||||||
<!-- Menu (tree) -->
|
|
||||||
<div id="menu" class="panel panel-default panel-body text-center">
|
|
||||||
|
|
||||||
<!-- Query choice -->
|
|
||||||
<div id="query-switch" class="btn-group btn-group-justified" role="group">
|
|
||||||
<a href="<TMPL_VAR NAME="SCRIPT_NAME">" alt="user" class="btn btn-info"><i class="glyphicon glyphicon-user"></i> <lang en="User" fr="Utilisateur" /></a>
|
|
||||||
<a href="<TMPL_VAR NAME="SCRIPT_NAME">?ipclasses=1" alt="ip" class="btn btn-info"><i class="glyphicon glyphicon-tag"></i> <lang en="IP" fr="IP" /></a>
|
|
||||||
<a href="<TMPL_VAR NAME="SCRIPT_NAME">?doubleIp=1" alt="2ip" class="btn btn-info"><i class="glyphicon glyphicon-tags"></i> <lang en="Multi IP" fr="Multi IP" /></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
<TMPL_VAR NAME="TREE">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
|
|
||||||
<!-- Data -->
|
|
||||||
<div id="data" class="panel panel-default">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,39 +0,0 @@
|
||||||
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#manager-menu">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a class="navbar-brand" href="<TMPL_VAR NAME="SCRIPT_NAME">">
|
|
||||||
<img src="<TMPL_VAR NAME="DIR">/images/logo_lemonldap-ng.png" alt="LemonLDAP::NG" class="brand"/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="collapse navbar-collapse" id="manager-menu">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li class="<TMPL_VAR NAME="LI_CLASS_CONFIGURATION">"><a href="index.pl"><i class="glyphicon glyphicon-cog"></i> <lang en="Configuration" fr="Configuration"/></a></li>
|
|
||||||
<li class="<TMPL_VAR NAME="LI_CLASS_SESSION">"><a href="sessions.pl"><i class="glyphicon glyphicon-user"></i> <lang en="Sessions" fr="Sessions"/></a></li>
|
|
||||||
<li class="<TMPL_VAR NAME="LI_CLASS_NOTIFICATION">"><a href="notifications.pl"><i class="glyphicon glyphicon-bell"></i> <lang en="Notifications" fr="Notifications"/></a></li>
|
|
||||||
</ul>
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Menu <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li role="presentation" class="dropdown-header"><lang en="Organization" fr="Organisation" /></li>
|
|
||||||
<li><a href="#"><span class="css-switch" alt="tree"><i class="glyphicon glyphicon-list"></i> <lang en="Tree" fr="Arbre" /></span></a></li>
|
|
||||||
<li><a href="#"><span class="css-switch" alt="accordion"><i class="glyphicon glyphicon-align-justify"></i> <lang en="Accordion" fr="Accordéon" /></span></a></li>
|
|
||||||
<li role="presentation" class="divider"></li>
|
|
||||||
<li><a href="<TMPL_VAR NAME="PORTAL_URL">"><i class="glyphicon glyphicon-home"></i> <lang en="Portal" fr="Portail" /></a></li>
|
|
||||||
<li><a href="<TMPL_VAR NAME="PORTAL_URL">?logout=1"><i class="glyphicon glyphicon-off"></i> <lang en="Logout" fr="Déconnexion" /></a></li>
|
|
||||||
<TMPL_IF NAME="VERSION">
|
|
||||||
<li role="presentation" class="divider"></li>
|
|
||||||
<li role="presentation" class="dropdown-header"><i class="glyphicon glyphicon-info-sign"></i> Version <TMPL_VAR NAME="VERSION"></li>
|
|
||||||
</TMPL_IF>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 230 B |
Before Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 276 B |
Before Width: | Height: | Size: 275 B |
Before Width: | Height: | Size: 340 B |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 418 B |
Before Width: | Height: | Size: 312 B |