Import and adapt https://github.com/guimard/angular-lemonldap-ng-manager.git
@ -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; |
@ -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; |
||||
|
||||
use strict; |
||||
use Lemonldap::NG::Common::Conf::Constants; #inherits |
||||
|
||||
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" ); |
||||
} |
||||
use Lemonldap::NG::Common::Conf::File; |
||||
our @ISA = qw(Lemonldap::NG::Common::Conf::File); |
||||
|
||||
1; |
||||
__END__ |
||||
|
||||
|
@ -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; |
||||
|
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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() |
||||
|
@ -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 ?)_ |
||||
|
@ -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>` |
@ -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 |
@ -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" |
||||
} |
||||
} |
@ -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,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 |