2009-12-17 20:20:17 +01:00
|
|
|
## @file
|
|
|
|
# Test uploaded parameters and store new configuration
|
|
|
|
|
|
|
|
## @class
|
|
|
|
# Test uploaded parameters and store new configuration
|
2009-12-11 19:17:00 +01:00
|
|
|
package Lemonldap::NG::Manager::Uploader;
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use XML::LibXML;
|
|
|
|
use XML::LibXSLT;
|
|
|
|
use MIME::Base64;
|
2010-03-11 17:43:21 +01:00
|
|
|
use JSON;
|
2010-03-12 13:56:14 +01:00
|
|
|
use LWP::Simple;
|
2010-03-22 18:47:59 +01:00
|
|
|
use LWP::UserAgent;
|
2009-12-11 19:17:00 +01:00
|
|
|
|
2010-02-08 13:20:37 +01:00
|
|
|
use URI::Escape;
|
2009-12-17 20:20:17 +01:00
|
|
|
use Lemonldap::NG::Common::Safelib; #link protected safe Safe object
|
|
|
|
use Lemonldap::NG::Manager::Downloader; #inherits
|
2009-12-20 09:49:45 +01:00
|
|
|
use Lemonldap::NG::Manager::_Struct; #link protected struct _Struct object
|
|
|
|
use Lemonldap::NG::Manager::_i18n;
|
|
|
|
use Lemonldap::NG::Common::Conf::Constants; #inherits
|
2009-12-11 19:17:00 +01:00
|
|
|
|
|
|
|
our $VERSION = '0.1';
|
|
|
|
our ( $stylesheet, $parser );
|
|
|
|
|
2009-12-17 20:20:17 +01:00
|
|
|
## @method void confUpload(ref rdata)
|
|
|
|
# Parse rdata to find parameters using XSLT, test them and tries to store the
|
|
|
|
# new configuration
|
|
|
|
# @param $rdata pointer to posted datas
|
2009-12-11 19:17:00 +01:00
|
|
|
sub confUpload {
|
|
|
|
my ( $self, $rdata ) = @_;
|
|
|
|
$$rdata =~ s/<img.*?>//g;
|
|
|
|
$$rdata =~ s/<li class="line".*?<\/li>//g;
|
|
|
|
|
2010-03-14 14:36:20 +01:00
|
|
|
# Variables to store current vhost and IDP name
|
|
|
|
my $vhostname;
|
|
|
|
my $idpname;
|
2010-03-25 15:38:54 +01:00
|
|
|
my $spname;
|
2010-03-14 14:36:20 +01:00
|
|
|
|
2009-12-31 12:10:05 +01:00
|
|
|
# 1. ANALYSE DATAS
|
|
|
|
|
|
|
|
# 1.1 Apply XSLT stylesheet to returned datas
|
2009-12-11 19:17:00 +01:00
|
|
|
my $result =
|
|
|
|
$self->stylesheet->transform(
|
|
|
|
$self->parser->parse_string( '<root>' . $$rdata . '</root>' ) )
|
|
|
|
->documentElement();
|
|
|
|
|
2009-12-31 12:10:05 +01:00
|
|
|
# 1.2 Get configuration number
|
2009-12-11 19:17:00 +01:00
|
|
|
unless ( $self->{cfgNum} =
|
|
|
|
$result->getChildrenByTagName('conf')->[0]->getAttribute('value') )
|
|
|
|
{
|
|
|
|
die "No configuration number found";
|
|
|
|
}
|
|
|
|
my $newConf = { cfgNum => $self->{cfgNum} };
|
2009-12-19 09:57:59 +01:00
|
|
|
my $errors = {};
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# 1.3 Load and test returned parameters
|
|
|
|
# => begin loop
|
2009-12-11 19:17:00 +01:00
|
|
|
foreach ( @{ $result->getChildrenByTagName('element') } ) {
|
|
|
|
my ( $id, $name, $value ) = (
|
|
|
|
$_->getAttribute('id'),
|
|
|
|
$_->getAttribute('name'),
|
|
|
|
$_->getAttribute('value')
|
|
|
|
);
|
2010-02-08 13:20:37 +01:00
|
|
|
|
|
|
|
# Unescape value
|
|
|
|
$value = uri_unescape($value);
|
|
|
|
|
2010-03-04 14:41:59 +01:00
|
|
|
$self->lmLog(
|
|
|
|
"Upload process for attribute $name (id: $id / value: $value)",
|
|
|
|
'debug' );
|
|
|
|
|
2009-12-11 19:17:00 +01:00
|
|
|
my $NK = 0;
|
|
|
|
$id =~
|
|
|
|
s/^text_(NewID_)?li_(\w+)(\d)(?:_\d+)?$/decode_base64($2.'='x $3)/e;
|
|
|
|
$NK = 1 if ($1);
|
2009-12-16 17:49:17 +01:00
|
|
|
$id =~ s/\r//g;
|
2009-12-11 19:17:00 +01:00
|
|
|
$id =~ s/^\///;
|
2010-03-14 14:36:20 +01:00
|
|
|
|
|
|
|
# Get Virtual Host name
|
|
|
|
if ( $id =~ /locationRules\/([^\/]*)?$/ ) {
|
|
|
|
$self->lmLog( "Entering Virtual Host $name", 'debug' );
|
|
|
|
$vhostname = $name;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get SAML IDP name
|
|
|
|
if ( $id =~ /samlIDPMetaDataExportedAttributes\/([^\/]*)?$/ ) {
|
|
|
|
$self->lmLog( "Entering IDP $name", 'debug' );
|
|
|
|
$idpname = $name;
|
|
|
|
}
|
|
|
|
|
2010-03-25 15:38:54 +01:00
|
|
|
# Get SAML SP name
|
|
|
|
if ( $id =~ /samlSPMetaDataExportedAttributes\/([^\/]*)?$/ ) {
|
|
|
|
$self->lmLog( "Entering SP $name", 'debug' );
|
|
|
|
$spname = $name;
|
|
|
|
}
|
|
|
|
|
2010-03-14 14:36:20 +01:00
|
|
|
# Manage new keys
|
2010-03-13 18:39:50 +01:00
|
|
|
if ($NK) {
|
|
|
|
|
|
|
|
# Special case: avoid bug with node created from parent node
|
2010-03-25 15:38:54 +01:00
|
|
|
if ( $id =~
|
|
|
|
/^(virtualHosts|samlIDPMetaDataExportedAttributes|samlSPMetaDataExportedAttributes)/
|
|
|
|
)
|
|
|
|
{
|
2010-03-13 18:39:50 +01:00
|
|
|
$self->lmLog( "Special trigger for $id (attribute $name)",
|
|
|
|
'debug' );
|
|
|
|
|
|
|
|
# A strange '5' appears at the end of value, remove it
|
|
|
|
$id =~ s/5$//;
|
|
|
|
|
|
|
|
# Virtual Host header
|
|
|
|
$id =~
|
|
|
|
s/^virtualHosts\/([^\/]*)?\/header.*/exportedHeaders\/$1\/$name/;
|
|
|
|
|
|
|
|
# Virtual Host rule
|
|
|
|
$id =~
|
|
|
|
s/^virtualHosts\/([^\/]*)?\/rule.*/locationRules\/$1\/$name/;
|
|
|
|
|
|
|
|
# SAML IDP attribute
|
|
|
|
$id =~
|
|
|
|
s/^samlIDPMetaDataExportedAttributes\/([^\/]*)?.*/samlIDPMetaDataExportedAttributes\/$1\/$name/;
|
2010-03-25 15:38:54 +01:00
|
|
|
|
|
|
|
# SAML SP attribute
|
|
|
|
$id =~
|
|
|
|
s/^samlSPMetaDataExportedAttributes\/([^\/]*)?.*/samlSPMetaDataExportedAttributes\/$1\/$name/;
|
|
|
|
|
2010-03-13 18:39:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Normal case
|
|
|
|
else {
|
|
|
|
$id =~ s/(?:\/[^\/]*)?$/\/$name/;
|
|
|
|
}
|
|
|
|
}
|
2010-03-04 14:41:59 +01:00
|
|
|
|
2010-03-14 14:36:20 +01:00
|
|
|
# Set current Virtual Host name
|
|
|
|
$id =~
|
|
|
|
s/^(exportedHeaders|locationRules)\/([^\/]*)?\/(.*)$/$1\/$vhostname\/$3/;
|
|
|
|
|
|
|
|
# Set current SAML IDP name
|
|
|
|
$id =~
|
|
|
|
s/^(samlIDPMetaDataXML|samlIDPMetaDataExportedAttributes|samlIDPMetaDataOptions)\/([^\/]*)?\/(.*)$/$1\/$idpname\/$3/;
|
|
|
|
|
2010-03-25 15:38:54 +01:00
|
|
|
# Set current SAML SP name
|
|
|
|
$id =~
|
|
|
|
s/^(samlSPMetaDataXML|samlSPMetaDataExportedAttributes|samlSPMetaDataOptions)\/([^\/]*)?\/(.*)$/$1\/$spname\/$3/;
|
|
|
|
|
2010-03-04 14:41:59 +01:00
|
|
|
$self->lmLog( "id transformed into $id", 'debug' );
|
|
|
|
|
2010-03-01 21:32:28 +01:00
|
|
|
next
|
2010-03-04 14:41:59 +01:00
|
|
|
if ( $id =~
|
2010-03-25 15:38:54 +01:00
|
|
|
/^(generalParameters|variables|virtualHosts|samlIDPMetaDataNode|samlSPMetaDataNode)/
|
|
|
|
);
|
2009-12-11 19:17:00 +01:00
|
|
|
my ( $confKey, $test ) = $self->getConfTests($id);
|
|
|
|
my ( $res, $m );
|
|
|
|
|
|
|
|
if ( !defined($test) ) {
|
2009-12-19 09:57:59 +01:00
|
|
|
$errors->{errors}->{$name} =
|
2009-12-11 19:17:00 +01:00
|
|
|
"Key $name: Lemonldap::NG::Manager error, see Apache's logs";
|
|
|
|
$self->lmLog(
|
|
|
|
"Unknown configuration key $id (name: $name, value: $value)",
|
|
|
|
'error' );
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $test->{'*'} and $id =~ /\// ) { $test = $test->{'*'} }
|
|
|
|
|
2009-12-31 12:10:05 +01:00
|
|
|
# 1.3.1 Tests:
|
|
|
|
|
|
|
|
# No tests for some keys
|
2009-12-11 19:17:00 +01:00
|
|
|
unless ( $test->{keyTest} and ( $id !~ /\// or $test->{'*'} ) ) {
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# 1.3.1.1 Tests that return an error
|
|
|
|
# (parameter will not be stored in $newConf)
|
2009-12-11 19:17:00 +01:00
|
|
|
if ( $test->{keyTest} ) {
|
|
|
|
( $res, $m ) = $self->applyTest( $test->{keyTest}, $name );
|
|
|
|
unless ($res) {
|
2009-12-19 09:57:59 +01:00
|
|
|
$errors->{errors}->{$name} = $m || $test->{keyMsgFail};
|
2009-12-11 19:17:00 +01:00
|
|
|
next;
|
|
|
|
}
|
2010-02-08 13:20:37 +01:00
|
|
|
$errors->{warnings}->{$name} = $m if ($m);
|
2009-12-11 19:17:00 +01:00
|
|
|
}
|
|
|
|
if ( $test->{test} ) {
|
|
|
|
( $res, $m ) = $self->applyTest( $test->{test}, $value );
|
|
|
|
unless ($res) {
|
2009-12-19 09:57:59 +01:00
|
|
|
$errors->{errors}->{$name} = $m || $test->{msgFail};
|
2009-12-11 19:17:00 +01:00
|
|
|
next;
|
|
|
|
}
|
2010-02-08 13:20:37 +01:00
|
|
|
$errors->{warnings}->{$name} = $m if ($m);
|
2009-12-11 19:17:00 +01:00
|
|
|
}
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# 1.3.1.2 Tests that return a warning
|
2009-12-11 19:17:00 +01:00
|
|
|
if ( $test->{warnKeyTest} ) {
|
|
|
|
( $res, $m ) = $self->applyTest( $test->{warnKeyTest}, $name );
|
|
|
|
unless ($res) {
|
2009-12-19 09:57:59 +01:00
|
|
|
$errors->{warnings}->{$name} = $m || $test->{keyMsgWarn};
|
2009-12-11 19:17:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( $test->{warnTest} ) {
|
|
|
|
( $res, $m ) = $self->applyTest( $test->{warnTest}, $value );
|
|
|
|
unless ($res) {
|
2009-12-19 09:57:59 +01:00
|
|
|
$errors->{warnings}->{$name} = $m || $test->{keyMsgWarn};
|
2009-12-11 19:17:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# 1.3.2 Store accepted parameter in $newConf
|
2010-03-04 14:41:59 +01:00
|
|
|
$self->lmLog( "Tests OK for $name, store $value in $confKey", 'debug' );
|
2009-12-11 19:17:00 +01:00
|
|
|
$self->setKeyToH( $newConf, $confKey,
|
|
|
|
$test->{keyTest}
|
|
|
|
? ( ( $id !~ /\// or $test->{'*'} ) ? {} : ( $name => $value ) )
|
|
|
|
: $value );
|
2009-12-31 12:10:05 +01:00
|
|
|
} # END LOOP
|
2009-12-11 19:17:00 +01:00
|
|
|
|
2009-12-31 12:10:05 +01:00
|
|
|
# 1.4 Loading unchanged parameters (ajax nodes not open)
|
2010-03-11 16:00:59 +01:00
|
|
|
$self->lmLog( "Save unchanged parameters", 'debug' );
|
2009-12-11 19:17:00 +01:00
|
|
|
foreach ( @{ $result->getChildrenByTagName('ignore') } ) {
|
|
|
|
my $node = $_->getAttribute('value');
|
|
|
|
$node =~ s/^.*node=(.*?)(?:&.*)?\}$/$1/;
|
2010-03-11 16:00:59 +01:00
|
|
|
$self->lmLog( "Unchanged node $node", 'debug' );
|
2009-12-30 15:22:24 +01:00
|
|
|
foreach my $k ( $self->findAllConfKeys( $self->corresp($node) ) ) {
|
2010-03-11 16:00:59 +01:00
|
|
|
$self->lmLog( "Unchanged key $k (node $node)", 'debug' );
|
2009-12-11 19:17:00 +01:00
|
|
|
my $v = $self->keyToH( $k, $self->conf );
|
|
|
|
$v = $self->keyToH( $k, $self->defaultConf ) unless ( defined $v );
|
|
|
|
if ( defined $v ) {
|
|
|
|
$self->setKeyToH( $newConf, $k, $v );
|
|
|
|
}
|
|
|
|
else {
|
2009-12-23 10:37:38 +01:00
|
|
|
$self->lmLog( "No default value found for $k", 'info' );
|
2009-12-11 19:17:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-31 12:10:05 +01:00
|
|
|
# 1.5 Author attributes for accounting
|
|
|
|
$newConf->{cfgAuthor} = $ENV{REMOTE_USER} || 'anonymous';
|
2009-12-30 21:00:54 +01:00
|
|
|
$newConf->{cfgAuthorIP} = $ENV{REMOTE_ADDR};
|
|
|
|
$newConf->{cfgDate} = time();
|
|
|
|
|
2009-12-31 12:10:05 +01:00
|
|
|
# 2. SAVE CONFIGURATION
|
|
|
|
|
|
|
|
$errors->{result}->{other} = '';
|
|
|
|
|
|
|
|
# 2.1 Don't store configuration if a syntax error was detected
|
2009-12-19 22:40:53 +01:00
|
|
|
if ( $errors->{errors} ) {
|
|
|
|
$errors->{result}->{cfgNum} = 0;
|
2009-12-20 09:49:45 +01:00
|
|
|
$errors->{result}->{msg} = $self->translate('syntaxError');
|
2009-12-31 12:10:05 +01:00
|
|
|
$self->_sub( 'userInfo',
|
|
|
|
"Configuration rejected for $newConf->{cfgAuthor}: syntax error" );
|
2009-12-19 22:40:53 +01:00
|
|
|
}
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# 2.2 Try to save configuration
|
2009-12-19 22:40:53 +01:00
|
|
|
else {
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# if "force" is set, Lemonldap::NG::Common::Conf accept it even if
|
|
|
|
# conf database is locked or conf number isn't current number (used to
|
|
|
|
# restore an old configuration)
|
2009-12-30 16:40:37 +01:00
|
|
|
$self->confObj->{force} = 1 if ( $self->param('force') );
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# Call saveConf()
|
2009-12-19 22:40:53 +01:00
|
|
|
$errors->{result}->{cfgNum} = $self->confObj->saveConf($newConf);
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# 2.2.1 Prepare response
|
|
|
|
my $msg;
|
|
|
|
|
|
|
|
# case "success"
|
|
|
|
if ( $errors->{result}->{cfgNum} > 0 ) {
|
|
|
|
|
|
|
|
# Store accounting datas to the response
|
2010-01-01 13:04:26 +01:00
|
|
|
$errors->{cfgDatas} = {
|
|
|
|
cfgAuthor => $newConf->{cfgAuthor},
|
|
|
|
cfgAuthorIP => $newConf->{cfgAuthorIP},
|
|
|
|
cfgDate => $newConf->{cfgDate}
|
|
|
|
};
|
2009-12-31 12:10:05 +01:00
|
|
|
$msg = 'confSaved';
|
|
|
|
|
|
|
|
# Log success using Lemonldap::NG::Common::CGI::userNotice():
|
|
|
|
# * in system logs if "syslog" is set
|
|
|
|
# * in apache errors file otherwise
|
|
|
|
$self->_sub( 'userNotice',
|
|
|
|
"Conf $errors->{result}->{cfgNum} saved by $newConf->{cfgAuthor}"
|
|
|
|
);
|
2010-03-22 17:09:07 +01:00
|
|
|
|
|
|
|
# Reload Handlers listed in apply section
|
|
|
|
$errors->{applyStatus} = $self->applyConf();
|
|
|
|
|
2009-12-31 12:10:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# other cases
|
|
|
|
else {
|
|
|
|
$msg = {
|
|
|
|
CONFIG_WAS_CHANGED, 'confWasChanged',
|
|
|
|
UNKNOWN_ERROR, 'unknownError',
|
|
|
|
DATABASE_LOCKED, 'databaseLocked',
|
|
|
|
UPLOAD_DENIED, 'uploadDenied',
|
|
|
|
SYNTAX_ERROR, 'syntaxError',
|
2010-01-01 13:04:26 +01:00
|
|
|
DEPRECATED, 'confModuledeprecated',
|
2009-12-31 12:10:05 +01:00
|
|
|
}->{ $errors->{result}->{cfgNum} };
|
|
|
|
|
|
|
|
# Log failure using Lemonldap::NG::Common::CGI::userError()
|
|
|
|
$self->_sub( 'userError',
|
|
|
|
"Configuration rejected for $newConf->{cfgAuthor}: $msg" );
|
|
|
|
}
|
|
|
|
|
|
|
|
# Translate msg returned
|
|
|
|
$errors->{result}->{msg} = $self->translate($msg);
|
2009-12-30 16:40:37 +01:00
|
|
|
if ( $errors->{result}->{cfgNum} == CONFIG_WAS_CHANGED
|
|
|
|
or $errors->{result}->{cfgNum} == DATABASE_LOCKED )
|
|
|
|
{
|
|
|
|
$errors->{result}->{other} = '<a href="javascript:uploadConf(1)">'
|
|
|
|
. $self->translate('clickHereToForce') . '</a>';
|
|
|
|
}
|
2010-01-01 13:04:26 +01:00
|
|
|
elsif ( $errors->{result}->{cfgNum} == DEPRECATED ) {
|
|
|
|
$errors->{result}->{other} = 'Module : ' . $self->confObj->{type};
|
|
|
|
}
|
2009-12-19 22:40:53 +01:00
|
|
|
}
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# 3. PREPARE JSON RESPONSE
|
2009-12-11 19:17:00 +01:00
|
|
|
my $buf = '{';
|
2009-12-17 20:20:17 +01:00
|
|
|
my $i = 0;
|
2009-12-19 09:57:59 +01:00
|
|
|
while ( my ( $type, $h ) = each %$errors ) {
|
2009-12-17 20:20:17 +01:00
|
|
|
$buf .= ',' if ($i);
|
2010-03-13 15:31:22 +01:00
|
|
|
$buf .= "\"$type\":{";
|
2009-12-19 22:40:53 +01:00
|
|
|
$buf .= join(
|
|
|
|
',',
|
|
|
|
map {
|
2010-03-13 15:31:22 +01:00
|
|
|
$h->{$_} =~ s/"/\\"/g;
|
2009-12-19 22:40:53 +01:00
|
|
|
$h->{$_} =~ s/\n/ /g;
|
2010-03-13 15:31:22 +01:00
|
|
|
"\"$_\":\"$h->{$_}\""
|
2009-12-19 22:40:53 +01:00
|
|
|
} keys %$h
|
|
|
|
);
|
2009-12-11 19:17:00 +01:00
|
|
|
$buf .= '}';
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
$buf .= '}';
|
2009-12-31 12:10:05 +01:00
|
|
|
|
|
|
|
# 4. SEND JSON RESPONSE
|
2009-12-17 20:20:17 +01:00
|
|
|
print $self->header(
|
2010-03-13 15:31:22 +01:00
|
|
|
-type => 'application/json; charset=utf-8',
|
2009-12-17 20:20:17 +01:00
|
|
|
-Content_Length => length($buf)
|
2010-03-13 15:31:22 +01:00
|
|
|
);
|
|
|
|
print $buf;
|
2009-12-11 19:17:00 +01:00
|
|
|
$self->quit();
|
|
|
|
}
|
|
|
|
|
2010-03-11 17:43:21 +01:00
|
|
|
## @method public void fileUpload (fieldname)
|
|
|
|
# Retrieve a file from an HTTP request, and return it. This function is for
|
|
|
|
# some functionnalities into the SAML2 modules of the manager, accessing
|
|
|
|
# to data through Ajax requests.
|
|
|
|
# @param $fieldname The name of the html input field.
|
|
|
|
sub fileUpload {
|
2010-03-13 18:39:50 +01:00
|
|
|
my $self = shift;
|
2010-03-11 17:43:21 +01:00
|
|
|
my $fieldname = shift;
|
2010-03-15 12:21:12 +01:00
|
|
|
my $filename = shift;
|
|
|
|
my $content = '';
|
|
|
|
|
|
|
|
# Direct download
|
2010-03-20 18:14:28 +01:00
|
|
|
if ($filename) {
|
|
|
|
$content = ${ $self->rparam($fieldname) };
|
|
|
|
print $self->header(
|
|
|
|
-type => 'application/force-download; charset=utf-8',
|
|
|
|
-attachment => $filename,
|
|
|
|
-Content_Length => length $content
|
2010-03-15 12:21:12 +01:00
|
|
|
) . $content;
|
|
|
|
}
|
2010-03-11 17:43:21 +01:00
|
|
|
|
2010-03-15 12:21:12 +01:00
|
|
|
# JSON request
|
2010-03-20 18:14:28 +01:00
|
|
|
else {
|
|
|
|
my $UPLOAD_FH = $self->upload($fieldname);
|
|
|
|
while (<$UPLOAD_FH>) {
|
|
|
|
$content .= "$_";
|
|
|
|
}
|
|
|
|
$content =~ s!<!<!g;
|
|
|
|
$content =~ s!>!>!g;
|
|
|
|
|
2010-04-13 18:43:32 +02:00
|
|
|
# Red Hat / Debian compatibilities
|
2010-04-14 17:37:57 +02:00
|
|
|
my $json = new JSON();
|
2010-04-13 18:43:32 +02:00
|
|
|
my $json_content = '';
|
2010-04-14 17:37:57 +02:00
|
|
|
if ( $JSON::VERSION lt 2 ) {
|
2010-04-13 18:43:32 +02:00
|
|
|
local $JSON::UTF8 = 1;
|
2010-04-14 17:37:57 +02:00
|
|
|
$json_content = $json->objToJson( [$content] );
|
2010-04-13 18:43:32 +02:00
|
|
|
$json_content =~ s/^\[//;
|
|
|
|
$json_content =~ s/\]$//;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$json = $json->allow_nonref( ['1'] );
|
|
|
|
$json = $json->utf8( ['1'] );
|
|
|
|
$json_content = $json->encode($content);
|
|
|
|
}
|
2010-03-20 18:14:28 +01:00
|
|
|
|
2010-04-14 17:37:57 +02:00
|
|
|
my $content = '{"status":"OK", "content":' . $json_content . '}';
|
2010-03-20 18:14:28 +01:00
|
|
|
print $self->header(
|
|
|
|
-type => 'text/html; charset=utf-8',
|
|
|
|
-Content_Length => length $content
|
2010-03-15 12:21:12 +01:00
|
|
|
) . $content;
|
|
|
|
}
|
2010-03-11 17:43:21 +01:00
|
|
|
|
2010-03-15 12:21:12 +01:00
|
|
|
$self->quit();
|
2010-03-11 17:43:21 +01:00
|
|
|
}
|
|
|
|
|
2010-03-12 13:56:14 +01:00
|
|
|
## @method public void fileUpload (fieldname)
|
|
|
|
# Retrieve a file from an URL, and return it. This function is for
|
|
|
|
# some functionnalities into the SAML2 modules of the manager, accessing
|
|
|
|
# to data through Ajax requests.
|
|
|
|
# @param $fieldname The name of the html input field that contains the URL.
|
|
|
|
sub urlUpload {
|
2010-03-13 18:39:50 +01:00
|
|
|
my $self = shift;
|
2010-03-12 13:56:14 +01:00
|
|
|
my $fieldname = shift;
|
2010-03-15 12:21:12 +01:00
|
|
|
my $content = '';
|
2010-03-12 13:56:14 +01:00
|
|
|
|
|
|
|
# Get the URL
|
2010-03-13 18:39:50 +01:00
|
|
|
my $url = ${ $self->rparam($fieldname) };
|
2010-03-12 13:56:14 +01:00
|
|
|
|
|
|
|
# Get contents from URL
|
|
|
|
my $content = get $url;
|
2010-03-13 18:39:50 +01:00
|
|
|
$content = '' unless ( defined $content );
|
2010-03-12 13:56:14 +01:00
|
|
|
$content =~ s!<!<!g;
|
|
|
|
$content =~ s!>!>!g;
|
|
|
|
|
|
|
|
# Build JSON reponse
|
2010-04-13 18:43:32 +02:00
|
|
|
# Require Red Hat and Debian compatibilites
|
2010-04-14 17:37:57 +02:00
|
|
|
my $json = new JSON();
|
2010-04-13 18:43:32 +02:00
|
|
|
my $json_content = '';
|
2010-04-14 17:37:57 +02:00
|
|
|
if ( $JSON::VERSION lt 2 ) {
|
2010-04-13 18:43:32 +02:00
|
|
|
local $JSON::UTF8 = 1;
|
2010-04-14 17:37:57 +02:00
|
|
|
$json_content = $json->objToJson( [$content] );
|
2010-04-13 18:43:32 +02:00
|
|
|
$json_content =~ s/^\[//;
|
|
|
|
$json_content =~ s/\]$//;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$json = $json->allow_nonref( ['1'] );
|
|
|
|
$json = $json->utf8( ['1'] );
|
|
|
|
$json_content = $json->encode($content);
|
|
|
|
}
|
2010-03-12 13:56:14 +01:00
|
|
|
|
2010-04-13 18:43:32 +02:00
|
|
|
$content = '{"status":"OK", "content":' . $json_content . '}';
|
2010-03-15 12:21:12 +01:00
|
|
|
print $self->header(
|
|
|
|
-type => 'text/html; charset=utf-8',
|
|
|
|
-Content_Length => length $content
|
2010-03-20 18:14:28 +01:00
|
|
|
) . $content;
|
2010-03-12 13:56:14 +01:00
|
|
|
}
|
|
|
|
|
2009-12-17 20:20:17 +01:00
|
|
|
## @method protected array applyTest(void* test,string value)
|
|
|
|
# Apply the test to the value and return the result and an optional message
|
|
|
|
# returned by the test if the sub ref.
|
|
|
|
# @param $test Ref to a regexp or a sub
|
|
|
|
# @param $value Value to test
|
|
|
|
# @return Array containing:
|
|
|
|
# - the test result
|
|
|
|
# - an optional message
|
2009-12-11 19:17:00 +01:00
|
|
|
sub applyTest {
|
|
|
|
my ( $self, $test, $value ) = @_;
|
|
|
|
my ( $res, $msg );
|
|
|
|
if ( ref($test) eq 'CODE' ) {
|
|
|
|
( $res, $msg ) = &$test($value);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$res = ( $value =~ $test ? 1 : 0 );
|
|
|
|
}
|
|
|
|
return ( $res, $msg );
|
|
|
|
}
|
|
|
|
|
2009-12-17 20:20:17 +01:00
|
|
|
## @method protected array getConfTests(string id)
|
|
|
|
# Call Lemonldap::NG::Manager::_Struct::testStruct().
|
2009-12-11 19:17:00 +01:00
|
|
|
sub getConfTests {
|
|
|
|
my ( $self, $id ) = @_;
|
|
|
|
my ( $confKey, $tmp ) = ( $id =~ /^(.*?)(?:\/(.*))?$/ );
|
|
|
|
my $h = $self->testStruct()->{$confKey};
|
|
|
|
if ( $h and $h->{'*'} and my ( $k, $v ) = ( $tmp =~ /^(.*?)\/(.*)$/ ) ) {
|
|
|
|
return ( "$confKey/$k", $h->{'*'} );
|
|
|
|
}
|
|
|
|
return ( $confKey, $h );
|
|
|
|
}
|
|
|
|
|
2009-12-17 20:20:17 +01:00
|
|
|
## @method protected array findAllConfKeys(hashref h)
|
|
|
|
# Parse a tree structure to find all nodes corresponding to a configuration
|
|
|
|
# value.
|
|
|
|
# @param $h Tree structure
|
|
|
|
# @return Array of configuration parameter names
|
2009-12-11 19:17:00 +01:00
|
|
|
sub findAllConfKeys {
|
|
|
|
my ( $self, $h ) = @_;
|
|
|
|
my @res = ();
|
2009-12-23 10:37:38 +01:00
|
|
|
|
|
|
|
# expand _nodes
|
|
|
|
if ( ref( $h->{_nodes} ) eq 'CODE' ) {
|
|
|
|
$h->{_nodes} = $h->{_nodes}->($self);
|
|
|
|
}
|
2009-12-11 19:17:00 +01:00
|
|
|
foreach my $n ( @{ $h->{_nodes} } ) {
|
|
|
|
$n =~ s/^.*?:(.*?)(?:\:.*)?$/$1/;
|
2010-03-11 16:00:59 +01:00
|
|
|
$self->lmLog( "findAllConfKey: got node $n", 'debug' );
|
2009-12-11 19:17:00 +01:00
|
|
|
if ( ref( $h->{$n} ) ) {
|
|
|
|
push @res, $self->findAllConfKeys( $h->{$n} );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
my $m = $h->{$n} || $n;
|
|
|
|
push @res, ( $m =~ /^(?:.*?:)?(.*?)(?:\:.*)?$/ ? $1 : () );
|
|
|
|
}
|
|
|
|
}
|
2009-12-17 20:20:17 +01:00
|
|
|
push @res, @{ $h->{_upload} } if ( $h->{_upload} );
|
2009-12-11 19:17:00 +01:00
|
|
|
return @res;
|
|
|
|
}
|
|
|
|
|
2010-02-24 17:24:17 +01:00
|
|
|
## @method protected String formatValue(string key, string value)
|
|
|
|
# Format a value.
|
|
|
|
# @param $key String "/path/key"
|
|
|
|
# @param $value String
|
|
|
|
# @return A formated value.
|
|
|
|
sub formatValue {
|
|
|
|
my ( $self, $key, $value ) = @_;
|
2010-06-25 15:51:09 +02:00
|
|
|
|
|
|
|
# Not used now
|
|
|
|
return $value;
|
2010-02-24 17:24:17 +01:00
|
|
|
}
|
|
|
|
|
2009-12-17 20:20:17 +01:00
|
|
|
## @method protected void setKeyToH(hashref h,string key,string k2,string value)
|
|
|
|
# Insert key=>$value in $h at the position declared with $key. If $k2 is set,
|
|
|
|
# insert key=>{$k2=>$value}. Note that $key is splited with "/". The last part
|
|
|
|
# is used as key.
|
|
|
|
# @param $h New Lemonldap::NG configuration
|
|
|
|
# @param $key String "/path/key"
|
|
|
|
# @param $k2 Optional subkey
|
2009-12-11 19:17:00 +01:00
|
|
|
sub setKeyToH {
|
|
|
|
my $value = pop;
|
2009-12-30 15:22:24 +01:00
|
|
|
return unless ( ref($value) or length($value) );
|
2009-12-11 19:17:00 +01:00
|
|
|
my ( $self, $h, $key, $k2 ) = @_;
|
|
|
|
my $tmp = $h;
|
|
|
|
$key =~ s/^\///;
|
2010-03-01 21:32:28 +01:00
|
|
|
$value = $self->formatValue( $key, $value );
|
2009-12-11 19:17:00 +01:00
|
|
|
while (1) {
|
|
|
|
if ( $key =~ /\// ) {
|
|
|
|
my $k = $`;
|
|
|
|
$key = $';
|
|
|
|
$tmp = $tmp->{$k} ||= {};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ($k2) {
|
|
|
|
$tmp->{$key} = {} unless ( ref( $tmp->{$key} ) );
|
|
|
|
$tmp->{$key}->{$k2} = $value;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$tmp->{$key} = $value;
|
|
|
|
}
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-17 20:20:17 +01:00
|
|
|
## @method private XML::LibXML parser()
|
|
|
|
# @return XML::LibXML object (cached in global $parser variable)
|
2009-12-11 19:17:00 +01:00
|
|
|
sub parser {
|
|
|
|
my $self = shift;
|
|
|
|
return $parser if ($parser);
|
|
|
|
$parser = XML::LibXML->new();
|
|
|
|
}
|
|
|
|
|
2009-12-17 20:20:17 +01:00
|
|
|
## @method private XML::LibXSLT stylesheet()
|
|
|
|
# Returns XML::LibXSLT parser (cached in global $stylesheet variable). Use
|
|
|
|
# datas stored at the end of this file to initialize the object.
|
|
|
|
# @return XML::LibXSLT object
|
2009-12-11 19:17:00 +01:00
|
|
|
sub stylesheet {
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
return $stylesheet if ($stylesheet);
|
|
|
|
my $xslt = XML::LibXSLT->new();
|
|
|
|
my $style_doc = $self->parser->parse_string( join( '', <DATA> ) );
|
|
|
|
close DATA;
|
|
|
|
$stylesheet = $xslt->parse_stylesheet($style_doc);
|
|
|
|
}
|
|
|
|
|
2010-03-22 17:09:07 +01:00
|
|
|
## @method private applyConf()
|
|
|
|
# Try to apply configuration by reloading Handlers
|
|
|
|
# @return reload status
|
|
|
|
sub applyConf {
|
|
|
|
my $self = shift;
|
|
|
|
my $status;
|
|
|
|
|
|
|
|
# Get apply section values
|
|
|
|
my $localConf = $self->confObj->getLocalConf( APPLYSECTION, undef, 0 );
|
|
|
|
|
|
|
|
# Create user agent
|
|
|
|
my $ua = new LWP::UserAgent( requests_redirectable => [] );
|
|
|
|
$ua->timeout(10);
|
|
|
|
|
|
|
|
# Parse apply values
|
|
|
|
foreach ( keys %$localConf ) {
|
|
|
|
my ( $host, $request ) = ( $_, $localConf->{$_} );
|
|
|
|
my ( $method, $vhost, $uri ) =
|
|
|
|
( $request =~ /^(https?):\/\/([^\/]+)(.*)$/ );
|
|
|
|
unless ($vhost) {
|
|
|
|
$vhost = $host;
|
|
|
|
$uri = $request;
|
|
|
|
}
|
|
|
|
my $r =
|
|
|
|
HTTP::Request->new( 'GET', "$method://$host$uri",
|
|
|
|
HTTP::Headers->new( Host => $vhost ) );
|
|
|
|
my $response = $ua->request($r);
|
|
|
|
if ( $response->code != 200 ) {
|
|
|
|
$status->{$host} =
|
|
|
|
"Error " . $response->code . " (" . $response->message . ")";
|
|
|
|
$self->_sub( 'userError',
|
|
|
|
"Apply configuration for $host: error "
|
|
|
|
. $response->code . " ("
|
|
|
|
. $response->message
|
|
|
|
. ")" );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$status->{$host} = "OK";
|
|
|
|
$self->_sub( 'userNotice', "Apply configuration for $host: ok" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $status;
|
|
|
|
}
|
|
|
|
|
2009-12-11 19:17:00 +01:00
|
|
|
1;
|
|
|
|
__DATA__
|
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
<xsl:stylesheet version="1.0"
|
|
|
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
|
|
|
<xsl:output method="xml"
|
|
|
|
encoding="UTF-8"/>
|
|
|
|
<xsl:template match="/">
|
|
|
|
<root>
|
|
|
|
<xsl:apply-templates/>
|
|
|
|
</root>
|
|
|
|
</xsl:template>
|
|
|
|
<xsl:template match="li">
|
|
|
|
<xsl:choose>
|
|
|
|
<xsl:when test="starts-with(.,'.')">
|
|
|
|
<ignore><xsl:attribute name="value"><xsl:value-of select="."/></xsl:attribute></ignore>
|
|
|
|
</xsl:when>
|
|
|
|
<xsl:otherwise>
|
|
|
|
<xsl:apply-templates/>
|
|
|
|
</xsl:otherwise>
|
|
|
|
</xsl:choose>
|
|
|
|
</xsl:template>
|
|
|
|
<xsl:template match="span">
|
|
|
|
<xsl:choose>
|
|
|
|
<xsl:when test="@id='text_li_cm9vdA2'">
|
|
|
|
<conf><xsl:attribute name="value"><xsl:value-of select="@value"/></xsl:attribute></conf>
|
|
|
|
</xsl:when>
|
|
|
|
<xsl:otherwise>
|
|
|
|
<element>
|
|
|
|
<xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
|
|
|
|
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
|
|
|
|
<xsl:attribute name="value"><xsl:value-of select="@value"/></xsl:attribute>
|
|
|
|
</element>
|
|
|
|
</xsl:otherwise>
|
|
|
|
</xsl:choose>
|
|
|
|
</xsl:template>
|
|
|
|
</xsl:stylesheet>
|