Commit eb3192e6 authored by IKEDA Soji's avatar IKEDA Soji
Browse files

New request handler create_list (formerly Sympa::Admin::create_list_old()) to...

New request handler create_list (formerly Sympa::Admin::create_list_old()) to be integrated to Sympa::Request framework.
- WWSympa: do_create_list().
- sympa.pl --create_list.
- SympaSOAP: createList().
parent 5d1be859
......@@ -627,7 +627,7 @@ Warning: this message may already have been sent by one of the list's editor.[%E
[%~ ELSIF report_entry == 'passwd_validation' ~%]
[%|loc(report_param.reason)%]The password you typed does not match this sites standards of strength: %1. Please pick a stronger password.[%END%]
[%~ ELSIF report_entry == 'wrong_input_path' ~%]
[%~ ELSIF report_entry == 'unknown_template' ~%]
[%|loc(report_param.tpl)%]Provided path is incorrect for template '%1'[%END%]
[%~ ELSIF report_entry == 'cannot_open_file' ~%]
......
......@@ -9701,210 +9701,77 @@ sub do_create_list {
$in{'template'}
);
 
## Check that all the needed arguments are present.
## This is checked here because it requires to return the incomplete form
## to the user
foreach my $arg ('listname', 'subject', 'template', 'info', 'topics') {
unless ($in{$arg}) {
Sympa::Report::reject_report_web('user', 'missing_arg',
{'argument' => $arg},
$param->{'action'});
wwslog('info', 'Missing param %s', $arg);
web_db_log(
{ 'parameters' => $in{'listname'},
'list' => $in{'listname'},
'status' => 'error',
'error_type' => 'missing_parameter'
}
);
return 'create_list_request';
}
}
# Check length.
if (Sympa::Constants::LIST_LEN() < length($in{'listname'})) {
Sympa::Report::reject_report_web('user', 'wrong_value',
{'argument' => 'listname'},
$param->{'action'});
wwslog('info', 'Too long listname');
web_db_log(
{ 'parameters' => $in{'listname'},
'status' => 'error',
'error_type' => 'wrong_value', #FIXME
}
);
return 'create_list_request';
}
## Lowercase listname if required
if ($in{'listname'} =~ /[A-Z]/) {
$in{'listname'} = lc($in{'listname'});
Sympa::Report::notice_report_web('listname_lowercased', {},
$param->{'action'});
}
my $spindle = Sympa::Spindle::ProcessRequest->new(
context => $robot,
action => 'create_list',
listname => $in{'listname'},
parameters => {
owner => [{
email => $param->{'user'}{'email'},
gecos => $param->{'user'}{'gecos'},
}],
subject => $in{'subject'},
creation_email => $param->{'user'}{'email'},
lang => $param->{'lang'},
status => $param->{'status'}, #FIXME
template => $in{'template'},
topics => $in{'topics'},
description => $in{'info'},
custom_input => $in{'custom_input'},
},
sender => $param->{'user'}{'email'},
( $param->{'user'}{'email'}
? (md5_check => 1)
: ()
),
 
my $result = Sympa::Scenario::request_action(
$robot,
'create_list',
$param->{'auth_method'},
{ 'sender' => $param->{'user'}{'email'},
'candidate_listname' => $in{'listname'},
'candidate_subject' => $in{'subject'},
'candidate_template' => $in{'template'},
'candidate_info' => $in{'info'},
'candidate_topics' => $in{'topics'},
'remote_host' => $param->{'remote_host'},
'remote_addr' => $param->{'remote_addr'}
scenario_context => {
sender => $param->{'user'}{'email'},
candidate_listname => $in{'listname'},
candidate_subject => $in{'subject'},
candidate_template => $in{'template'},
candidate_info => $in{'info'},
candidate_topics => $in{'topics'},
remote_host => $param->{'remote_host'},
remote_addr => $param->{'remote_addr'},
}
);
if (ref($result) eq 'HASH') {
$param->{'create_action'} = $result->{'action'};
$param->{'reason'} = $result->{'reason'};
}
wwslog('info', ', get action: %s', $param->{'create_action'});
## If the action is forbidden, stop here.
if ($param->{'create_action'} =~ /reject/) {
Sympa::Report::reject_report_web('auth', $param->{'reason'}, {},
$param->{'action'}, $list);
wwslog('info', 'Not allowed');
web_db_log(
{ 'parameters' => $in{'listname'},
'list' => $in{'listname'},
'status' => 'error',
'error_type' => 'authorization'
}
);
return 'home';
## If the action is reserved to listmaster, note that it will have to
## be moderated
} elsif ($param->{'create_action'} =~ /listmaster/i) {
$param->{'status'} = 'pending';
## If the action is plainly authorized, note that it will be executed.
} elsif ($param->{'create_action'} =~ /do_it/i) {
$param->{'status'} = 'open';
## If the action hasn't an authorization status, stop here.
} else {
Sympa::Report::reject_report_web('intern',
'internal_scenario_error_create_list',
{}, $param->{'action'}, '', $param->{'user'}{'email'}, $robot);
wwslog('info', 'Internal error in scenario create_list');
web_db_log(
{ 'parameters' => $in{'listname'},
'list' => $in{'listname'},
'status' => 'error',
'error_type' => 'internal'
}
);
return 'create_list_request';
}
 
## 'other' topic means no topic
$in{'topics'} = undef if ($in{'topics'} eq 'other');
## Store creation parameters.
my %owner;
$owner{'email'} = $param->{'user'}{'email'};
$owner{'gecos'} = $param->{'user'}{'gecos'};
my $parameters;
push @{$parameters->{'owner'}}, \%owner;
$parameters->{'listname'} = $in{'listname'};
$parameters->{'subject'} = $in{'subject'};
$parameters->{'creation_email'} = $param->{'user'}{'email'};
$parameters->{'lang'} = $param->{'lang'};
$parameters->{'status'} = $param->{'status'};
$parameters->{'topics'} = $in{'topics'};
$parameters->{'description'} = $in{'info'};
$parameters->{'custom_input'} = $in{'custom_input'};
# Create list
if (my $testlist = Sympa::List->new($in{'listname'}, $robot)) {
Sympa::Report::reject_report_web('user', 'list_already_exists',
{'new_listname' => $in{'listname'}},
$param->{'action'}, '', $param->{'user'}{'email'}, $robot);
wwslog('info', 'Requested list %s already exist (from %s)',
$in{'listname'}, $param->{'user'}{'email'});
web_db_log(
{ 'parameters' => $in{'listname'},
'list' => $in{'listname'},
'status' => 'error',
'error_type' => 'user'
}
);
return 'create_list_request';
}
my $resul =
Sympa::Admin::create_list_old($parameters, $in{'template'}, $robot,
'web', $param->{'user'}{'email'});
unless (defined $resul) {
Sympa::Report::reject_report_web('intern', 'create_list', {},
$param->{'action'}, '', $param->{'user'}{'email'}, $robot);
wwslog('info', 'Unable to create list %s for %s',
$in{'listname'}, $param->{'user'}{'email'});
web_db_log(
{ 'parameters' => $in{'listname'},
'list' => $in{'listname'},
'status' => 'error',
'error_type' => 'internal'
}
);
unless ($spindle and $spindle->spin) {
return 'create_list_request';
}
 
## Create list object
$in{'list'} = $in{'listname'};
check_param_in();
if ($param->{'create_action'} =~ /do_it/i) {
if ($resul->{'aliases'} == 1) {
$param->{'auto_aliases'} = 1;
foreach my $report (@{$spindle->{stash} || []}) {
if ($report->[1] eq 'notice') {
Sympa::Report::notice_report_web(@{$report}[2, 3],
$param->{'action'});
} else {
Sympa::Report::reject_report_web(
'intern',
'failed_to_install_aliases',
{'listname' => $in{'listname'}},
$param->{'action'},
$list,
$param->{'user'}{'email'},
$robot
);
wwslog('err', 'Failed to install list aliases');
Sympa::Report::reject_report_web(@{$report}[1 .. 3],
$param->{action});
}
}
unless (@{$spindle->{stash} || []}) {
Sympa::Report::notice_report_web('performed', {}, $param->{'action'});
}
 
## notify listmaster
my $list = Sympa::List->new($in{'listname'}, $robot);
unless (defined $list) {
wwslog('info', 'Failed to create list object for list "%s"',
$in{'listname'});
Sympa::Report::reject_report_web('intern', 'create_list', {},
$param->{'action'}, '', $param->{'user'}{'email'}, $robot);
if (grep { $_->[1] ne 'notice' } @{$spindle->{stash} || []}) {
return 'create_list_request';
}
 
if ($param->{'create_action'} =~ /notify/) {
wwslog('info', 'Notify listmaster');
Sympa::send_notify_to_listmaster($list, 'request_list_creation',
{'email' => $param->{'user'}{'email'}});
# Were aliases installed?
if (grep { $_->[1] eq 'notice' and $_->[2] eq 'auto_aliases' }
@{$spindle->{stash} || []}) {
$param->{'auto_aliases'} = 1;
} else {
$param->{'auto_aliases'} = 0;
}
 
web_db_log(
{ 'parameters' => $in{'listname'},
'list' => $in{'listname'},
'status' => 'success'
}
);
$in{'list'} = $resul->{'list'}{'name'};
check_param_in();
# Switch to new list context.
$list = Sympa::List->new($in{'listname'}, $robot);
$param->{'list'} = $in{'listname'};
$param->{'redirect_to'} =
Sympa::get_url($list, 'admin', nomenu => $param->{'nomenu'});
 
$param->{'listname'} = $resul->{'list'}{'name'};
return 1;
}
 
......
......@@ -83,6 +83,7 @@ nobase_modules_DATA = \
Sympa/Request/Handler/add.pm \
Sympa/Request/Handler/auth.pm \
Sympa/Request/Handler/confirm.pm \
Sympa/Request/Handler/create_list.pm \
Sympa/Request/Handler/decl.pm \
Sympa/Request/Handler/del.pm \
Sympa/Request/Handler/distribute.pm \
......
......@@ -41,13 +41,11 @@ package Sympa::Admin;
use strict;
use warnings;
use Encode qw();
use English qw(-no_match_vars);
use Sympa;
use Conf;
use Sympa::Constants;
use Sympa::Language;
use Sympa::List;
use Sympa::LockedFile;
use Sympa::Log;
......@@ -55,8 +53,7 @@ use Sympa::Regexps;
use Sympa::Robot;
use Sympa::Template;
my $language = Sympa::Language->instance;
my $log = Sympa::Log->instance;
my $log = Sympa::Log->instance;
=head1 SUBFUNCTIONS
......@@ -64,288 +61,8 @@ This is the description of the subfunctions contained by admin.pm
=cut
=pod
=head2 sub create_list_old(HASHRef,STRING,STRING)
Creates a list. Used by the create_list() sub in sympa.pl and the do_create_list() sub in wwsympa.fcgi.
=head3 Arguments
=over
=item * I<$param>, a ref on a hash containing parameters of the config list. The following keys are mandatory:
=over 4
=item - I<$param-E<gt>{'listname'}>,
=item - I<$param-E<gt>{'subject'}>,
=item - I<$param-E<gt>{'owner'}>, (or owner_include): array of hashes, with key email mandatory
=item - I<$param-E<gt>{'owner_include'}>, array of hashes, with key source mandatory
=back
=item * I<$list_tpl>, a string containing the list creation template
=item * I<$robot>, a string containing the name of the robot the list will be hosted by.
=back
=head3 Return
=over
=item * I<undef>, if something prevents the list creation
=item * I<a reference to a hash>, if the list is normally created. This hash contains two keys:
=over 4
=item - I<list>, the list object corresponding to the list just created
=item - I<aliases>, undef if not applicable; 1 (if ok) or $aliases : concatenated string of aliases if they are not installed or 1 (in status open)
=back
=back
=cut
########################################################
# create_list_old
########################################################
# Create a list : used by sympa.pl--create_list and
# wwsympa.fcgi--do_create_list
# without family concept
#
# IN : - $param : ref on parameters of the config list
# with obligatory :
# $param->{'listname'}
# $param->{'subject'}
# $param->{'owner'} (or owner_include):
# array of hash,with key email obligatory
# $param->{'owner_include'} array of hash :
# with key source obligatory
# - $list_tpl : the create list template
# - $robot : the list's robot
# - $origin : the source of the command : web, soap or command_line
# no longer used
# OUT : - hash with keys :
# -list :$list
# -aliases : undef if not applicable; 1 (if ok) or
# $aliases : concated string of alias if they
# are not installed or 1(in status open)
#######################################################
sub create_list_old {
my ($param, $list_tpl, $robot, $origin, $user_mail) = @_;
$log->syslog('debug', '(%s, %s)', $param->{'listname'}, $robot, $origin);
## obligatory list parameters
foreach my $arg ('listname', 'subject') {
unless ($param->{$arg}) {
$log->syslog('err', 'Missing list param %s', $arg);
return undef;
}
}
# owner.email || owner_include.source
unless (check_owner_defined($param->{'owner'}, $param->{'owner_include'}))
{
$log->syslog('err',
'Problem in owner definition in this list creation');
return undef;
}
# template
unless ($list_tpl) {
$log->syslog('err', 'Missing param "template"', $list_tpl);
return undef;
}
# robot
unless ($robot) {
$log->syslog('err', 'Missing param "robot"', $robot);
return undef;
}
## check listname
$param->{'listname'} = lc($param->{'listname'});
my $listname_regexp = Sympa::Regexps::listname();
unless ($param->{'listname'} =~ /^$listname_regexp$/i
and length $param->{'listname'} <= Sympa::Constants::LIST_LEN()) {
$log->syslog('err', 'Incorrect listname %s', $param->{'listname'});
return undef;
}
my $regx = Conf::get_robot_conf($robot, 'list_check_regexp');
if ($regx) {
if ($param->{'listname'} =~ /^(\S+)-($regx)$/) {
$log->syslog('err',
'Incorrect listname %s matches one of service aliases',
$param->{'listname'});
return undef;
}
}
if ( $param->{'listname'} eq Conf::get_robot_conf($robot, 'email')
or $param->{'listname'} eq
Conf::get_robot_conf($robot, 'listmaster_email')) {
$log->syslog('err',
'Incorrect listname %s matches one of service aliases',
$param->{'listname'});
return undef;
}
## Check listname on SMTP server
my $res = list_check_smtp($param->{'listname'}, $robot);
unless (defined $res) {
$log->syslog('err', 'Can\'t check list %.128s on %s',
$param->{'listname'}, $robot);
return undef;
}
## Check this listname doesn't exist already.
if ($res
|| Sympa::List->new($param->{'listname'}, $robot, {'just_try' => 1}))
{
$log->syslog('err',
'Could not create already existing list %s on %s for',
$param->{'listname'}, $robot);
foreach my $o (@{$param->{'owner'}}) {
$log->syslog('err', $o->{'email'});
}
return undef;
}
## Check the template supposed to be used exist.
my $template_file = Sympa::search_fullpath($robot, 'config.tt2',
subdir => 'create_list_templates/' . $list_tpl);
unless (defined $template_file) {
$log->syslog('err', 'No template %s found', $list_tpl);
return undef;
}
## Create the list directory
my $list_dir;
# a virtual robot
if (-d "$Conf::Conf{'home'}/$robot") {
unless (-d $Conf::Conf{'home'} . '/' . $robot) {
unless (mkdir $Conf::Conf{'home'} . '/' . $robot, 0777) {
$log->syslog('err', 'Unable to create %s/%s: %s',
$Conf::Conf{'home'}, $robot, $ERRNO);
return undef;
}
}
$list_dir =
$Conf::Conf{'home'} . '/' . $robot . '/' . $param->{'listname'};
} else {
$list_dir = $Conf::Conf{'home'} . '/' . $param->{'listname'};
}
## Check the privileges on the list directory
unless (mkdir $list_dir, 0777) {
$log->syslog('err', 'Unable to create %s: %s', $list_dir, $ERRNO);
return undef;
}
## Check topics
if ($param->{'topics'}) {
unless (check_topics($param->{'topics'}, $robot)) {
$log->syslog('err', 'Topics param %s not defined in topics.conf',
$param->{'topics'});
}
}
# Creation of the config file.
$param->{'creation'}{'date_epoch'} = time;
$param->{'creation_email'} ||= Sympa::get_address($robot, 'listmaster');
$param->{'status'} ||= 'open';
## Lock config before openning the config file
my $lock_fh = Sympa::LockedFile->new($list_dir . '/config', 5, '>');
unless ($lock_fh) {
$log->syslog('err', 'Impossible to create %s/config: %m', $list_dir);
return undef;
}
my $config = '';
my $template =
Sympa::Template->new($robot,
subdir => 'create_list_templates/' . $list_tpl);
unless ($template->parse($param, 'config.tt2', \$config)) {
$log->syslog(
'err', 'Can\'t parse %s/config.tt2: %s',
$list_tpl, $template->{last_error}
);
return undef;
}
print $lock_fh $config;
## Unlock config file
$lock_fh->close;
## Creation of the info file
# remove DOS linefeeds (^M) that cause problems with Outlook 98, AOL, and
# EIMS:
$param->{'description'} =~ s/\r\n|\r/\n/g;
## info file creation.
unless (open INFO, '>', "$list_dir/info") {
$log->syslog('err', 'Impossible to create %s/info: %m', $list_dir);
}
if (defined $param->{'description'}) {
Encode::from_to($param->{'description'},
'utf8', $Conf::Conf{'filesystem_encoding'});
print INFO $param->{'description'};
}
close INFO;
## Create list object
my $list;
unless ($list = Sympa::List->new($param->{'listname'}, $robot)) {
$log->syslog('err', 'Unable to create list %s', $param->{'listname'});
return undef;
}
## Create shared if required.
#if (defined $list->{'admin'}{'shared_doc'}) {
# $list->create_shared();
#}
#log in stat_table to make statistics
if ($origin eq "web") {
$log->add_stat(
'robot' => $robot,
'list' => $param->{'listname'},
'operation' => 'create_list',
'parameter' => '',
'mail' => $user_mail
);
}
my $return = {};
$return->{'list'} = $list;
if ($list->{'admin'}{'status'} eq 'open') {
$return->{'aliases'} = install_aliases($list);
} else {
$return->{'aliases'} = 1;
}
## Synchronize list members if required
if ($list->has_include_data_sources()) {
$log->syslog('notice', "Synchronizing list members...");
$list->sync_include();
}
$list->save_config($param->{'creation_email'});
return $return;
}
# Moved to: Sympa::Request::Handler::create_list::_twist().
#sub create_list_old;
########################################################
# create_list
......@@ -730,107 +447,8 @@ sub update_list {
# Moved to: (part of) Sympa::Request::Handler::move_list::_copy().
#sub clone_list_as_empty;
########################################################
# check_owner_defined
########################################################
# verify if they are any owner defined : it must exist
# at least one param owner(in $owner) or one param
# owner_include (in $owner_include)
# the owner param must have sub param email
# the owner_include param must have sub param source
#
# IN : - $owner : ref on array of hash
# or
# ref on hash
# - $owner_include : ref on array of hash
# or
# ref on hash
# OUT : - 1 if exists owner(s)
# or
# undef if no owner defined
#########################################################
sub check_owner_defined {
my ($owner, $owner_include) = @_;
$log->syslog('debug2', '');
if (ref($owner) eq "ARRAY") {
if (ref($owner_include) eq "ARRAY") {
if (($#{$owner} < 0) && ($#{$owner_include} < 0)) {
$log->syslog('err',
'Missing list param owner or owner_include');
return undef;
}
} else {
if (($#{$owner}