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

New request handler create_automatic_list to be integrated to Sympa::Request framework.

- WWSympa: do_create_automatic_list(), formerly do_automatic_lists().
- sympa.pl --add_list.
parent eb3192e6
......@@ -195,9 +195,6 @@ nobase_default_DATA = \
web_tt2/arcsearch.tt2 \
web_tt2/arc.tt2 \
web_tt2/aside_menu.tt2 \
web_tt2/automatic_lists_management_request.tt2 \
web_tt2/automatic_lists_request.tt2 \
web_tt2/automatic_lists.tt2 \
web_tt2/blacklist.tt2 \
web_tt2/button_footer.tt2 \
web_tt2/button_header.tt2 \
......@@ -210,6 +207,7 @@ nobase_default_DATA = \
web_tt2/confirm_action.tt2 \
web_tt2/copy_template.tt2 \
web_tt2/crash.tt2 \
web_tt2/create_automatic_list_request.tt2 \
web_tt2/create_list_request.tt2 \
web_tt2/create_list.tt2 \
web_tt2/css.tt2 \
......
......@@ -429,6 +429,9 @@
[%~ ELSIF report_entry == 'listname_lowercased' ~%]
[%|loc%]List name has been lowercased[%END%]
[%~ ELSIF report_entry == 'auto_aliases' ~%]
[%|loc%]Aliases have been installed.[%END%]
[%~ ELSIF report_entry == 'user_notified' ~%]
[%|loc(report_param.notified_user)%]User %1 has been notified[%END%]
......
<!-- automatic_lists.tt2 -->
<div>
<h1>[%|loc%]Automatic lists result[% END %]</h1>
<p>The list created would be [% list_name %]</p>
</div>
<!-- End automatic_lists.tt2 -->
<!-- $Id$ -->
<div>
<h1>[%|loc%]Automatic lists management[% END %]</h1>
<p>[%|loc(automatic_lists_description.family_name)%]The automatic lists are based on the %1 family[% END %]</p>
[% FOREACH p = automatic_lists_description.class %]
<p>Found class [% p.name %]</p>
[%END%]
</div>
<!-- End automatic_list_management_request.tt2 -->
<!-- automatic_lists_request.tt2 -->
<div>
<h1>[% family.display %]</h1>
<p>[%|loc%]In this form, you will be able to create and / or access lists created on the basis of parameters you will defined.[% END %]</p>
<form action="[% path_cgi %]" method="post" class="add-request" name="automatic_lists">
[% FOREACH p = family.description.class %]
<h2>[% p.stamp %]</h2>
<p> [% p.description %]</p>
[% FOREACH i = p.instances %]
<input type="radio" id="automatic_list_part_[% p.order %].[% i.value %]" name="automatic_list_part_[% p.order %]" value="[% i.value %]"[% IF i.default %] checked="checked"[% END %]> <label for="automatic_list_part_[% p.order %].[% i.value %]">[% i.tag %]</label><br>
[%END%]
[%END%]
<input class="MainMenuLinks" type="submit" name="action_automatic_lists" value="[%|loc%]Go to list[%END%]" />
<input type="hidden" name="family" value="[% family.name %]" />
</form>
</div>
<!-- End automatic_lists_request.tt2 -->
<!-- create_automatic_list_request.tt2 -->
<div>
<h1>[% family.display %]</h1>
<p>[%|loc%]In this form, you will be able to create and / or access lists created on the basis of parameters you will defined.[% END %]</p>
<form action="[% path_cgi %]" method="post" class="add-request"
name="create_automatic_list">
[% FOREACH p = family.description.class ~%]
<h2>[% p.stamp %]</h2>
<p> [% p.description %]</p>
[% FOREACH i = p.instances %]
<div>
<input type="radio" id="automatic_list_part_[% p.order %].[% i.value %]"
name="automatic_list_part_[% p.order %]"
value="[% i.value %]"
[%~ IF i.default %] checked="checked"[% END %]>
<label for="automatic_list_part_[% p.order %].[% i.value %]">
[%~ i.tag ~%]
</label>
</div>
[%~ END %]
[%~ END %]
<div>
<input class="MainMenuLinks" type="submit" name="action_create_automatic_list"
value="[%|loc%]Go to list[%END%]" />
</div>
<input type="hidden" name="family" value="[% family.name %]" />
</form>
</div>
<!-- End create_automatic_list_request.tt2 -->
......@@ -62,18 +62,18 @@
[% SET family_li = '' %]
[% SET owns_family = 0 %]
[% FOREACH alf IN conf.automatic_list_families.keys %]
[% IF action == 'automatic_lists_request' && family.name == conf.automatic_list_families.$alf.name %][% SET class = 'active' %][% ELSE %][% SET class = '' %][% END %]
[% IF session.is_family_owner.$alf %]
[% IF action == 'create_automatic_list_request' && family.name == conf.automatic_list_families.$alf.name %][% SET class = 'active' %][% ELSE %][% SET class = '' %][% END %]
[% IF may_create_automatic_list.$alf %]
[% display = conf.automatic_list_families.$alf.display %]
[% name = conf.automatic_list_families.$alf.name %]
[% family_li = BLOCK ~%]
[% family_li ~%]
<li class="[% class %]"><a href="[% 'automatic_lists_request' | url_rel([name]) %]" ><i class="fa fa-list-alt"></i> [% display %]</a></li>
<li class="[% class %]"><a href="[% 'create_automatic_list_request' | url_rel([name]) %]" ><i class="fa fa-list-alt"></i> [% display %]</a></li>
[%~ END %]
[% owns_family = 1 %]
[% END %]
[% END %]
[% IF top_menu %][% IF action == 'automatic_lists_request' %][% SET class = 'active' %][% ELSE %][% SET class = '' %][% END %][% END %]
[% IF top_menu %][% IF action == 'create_automatic_list_request' %][% SET class = 'active' %][% ELSE %][% SET class = '' %][% END %][% END %]
[% IF owns_family %]
<li class="has-dropdown [% class %]">
<a href="#"><i class="fa fa-list-alt"></i> [%|loc%]Lists Families[%END%]</a>
......
......@@ -327,25 +327,27 @@ our %comm = (
# 'lca' stands for 'list_custom_action'. I used a short name to make it
# discrete in a URL.
'lca' => 'do_lca',
'automatic_lists_management_request' =>
'do_automatic_lists_management_request',
'automatic_lists_management' => 'do_automatic_lists_management',
'automatic_lists_request' => 'do_automatic_lists_request',
'automatic_lists' => 'do_automatic_lists',
'auth' => 'do_auth',
#XXX'automatic_lists_management_request' =>
#XXX 'do_automatic_lists_management_request',
#XXX'automatic_lists_management' => 'do_automatic_lists_management',
'create_automatic_list' => 'do_create_automatic_list',
'create_automatic_list_request' => 'do_create_automatic_list_request',
'auth' => 'do_auth',
);
 
my %comm_aliases = (
'add_fromsub' => 'auth_add',
'add_request' => 'import',
'change_email' => 'move_user',
'change_email_request' => 'move_user',
'ignoresig' => 'decl_del',
'ignoresub' => 'decl_add',
'del_fromsig' => 'auth_del',
'rename_list' => 'move_list',
'sigrequest' => 'signoff',
'subrequest' => 'subscribe',
'add_fromsub' => 'auth_add',
'add_request' => 'import',
'automatic_lists' => 'create_automatic_list',
'automatic_lists_request' => 'create_automatic_list_request',
'change_email' => 'move_user',
'change_email_request' => 'move_user',
'ignoresig' => 'decl_del',
'ignoresub' => 'decl_add',
'del_fromsig' => 'auth_del',
'rename_list' => 'move_list',
'sigrequest' => 'signoff',
'subrequest' => 'subscribe',
);
 
my %auth_action = (
......@@ -489,10 +491,10 @@ our %action_args = (
'show_exclude' => ['list'],
'ca' => ['custom_action', '@cap'],
'lca' => ['custom_action', 'list', '@cap'],
'automatic_lists_management_request' => [],
'automatic_lists_management' => [],
'automatic_lists_request' => ['family'],
'automatic_lists' => [],
#XXX'automatic_lists_management_request' => [],
#XXX'automatic_lists_management' => [],
'create_automatic_list' => ['family'],
'create_automatic_list_request' => ['family'],
'auth' => ['id', 'heldaction', 'listname'],
'auth_add' => ['list'],
'auth_del' => ['list'],
......@@ -524,8 +526,6 @@ our %required_args = (
'auth_add' => ['param.list', 'param.user.email'],
'auth_del' => ['param.list', 'param.user.email'],
'auto_signoff' => ['param.list', 'email'],
'automatic_lists_request' => ['family'],
'automatic_lists' => ['family'],
'attach' => ['param.list'],
'blacklist' => ['param.list'],
'move_user' => ['param.user.email', 'current_email|old_email', 'email|new_email'],
......@@ -534,8 +534,10 @@ our %required_args = (
'compose_mail' => ['param.user.email', 'param.list'],
'copy_template' => ['webormail'],
## other required parameters are checked in the subroutine
'create_list' => ['param.user.email'],
'create_list_request' => ['param.user.email'],
'create_automatic_list' => ['param.user.email', 'family'],
'create_automatic_list_request' => ['param.user.email', 'family'],
'create_list' => ['param.user.email'],
'create_list_request' => ['param.user.email'],
#XXX'css' => [],
'd_admin' => ['param.list', 'param.user.email'],
'd_change_access' => ['param.list', 'param.user.email'],
......@@ -719,8 +721,8 @@ our %required_privileges = (
'viewbounce' => ['owner', 'editor'],
'viewlogs' => ['owner', 'editor'],
'viewmod' => ['editor', 'owner', 'listmaster'],
'automatic_lists_management_request' => ['listmaster'],
'automatic_lists_management' => ['listmaster'],
#XXX'automatic_lists_management_request' => ['listmaster'],
#XXX'automatic_lists_management' => ['listmaster'],
);
 
# this definition is used to choose the left side menu type (admin ->
......@@ -791,8 +793,8 @@ my %action_type = (
'editfile' => 'serveradmin', #FIXME: admin?
'unset_dumpvars' => 'serveradmin',
'set_dumpvars' => 'serveradmin',
'automatic_lists_management_request' => 'serveradmin',
'automatic_lists_management' => 'serveradmin',
#XXX'automatic_lists_management_request' => 'serveradmin',
#XXX'automatic_lists_management' => 'serveradmin',
);
 
# Actions that are not used in return of login,
......@@ -1296,29 +1298,6 @@ while ($query = CGI::Fast->new) {
$in{'oauth_token'} = delete $session->{'oauth_token'}
if $oauth_token ne '' && $session->{'email'} ne 'nobody';
 
$session->{'is_family_owner'} = undef;
my $automatic_list_families =
Conf::get_robot_conf($robot, 'automatic_list_families');
if (defined $automatic_list_families) {
foreach my $key (keys %{$automatic_list_families}) {
my $family;
if ($family = Sympa::Family->new($key, $robot)) {
if ($family->is_allowed_to_create_automatic_lists(
( 'auth_level' => 'md5',
'sender' => $session->{'email'},
'message' => undef,
'listname' => ''
)
)
) {
$session->{'is_family_owner'}{$key} = 1;
} else {
$session->{'is_family_owner'}{$key} = undef;
}
}
}
}
$param->{'session'} = $session->as_hashref();
 
$log->{level} = $session->{'log_level'} if ($session->{'log_level'});
......@@ -2857,6 +2836,31 @@ sub check_param_in {
undef($param->{'may_create_list'});
}
 
# Check if the current user can create automatic list.
$param->{'may_create_automatic_list'} = {};
my $automatic_list_families =
Conf::get_robot_conf($robot, 'automatic_list_families');
foreach my $key (keys %{$automatic_list_families || {}}) {
my $family = Sympa::Family->new($key, $robot);
next unless $family;
my $result = Sympa::Scenario::request_action(
$family->{'robot'}, 'automatic_list_creation',
$param->{'auth_method'},
{ 'sender' => $param->{'user'}{'email'},
'message' => undef,
'family' => $family,
'automatic_listname' => '',
}
);
my $r_action = $result->{'action'} if ref $result eq 'HASH';
$param->{'may_create_automatic_list'}{$key} = 1
if $r_action and $r_action =~ /do_it/;
}
# Compat. <= 6.2.22.
$param->{'session'}{'is_family_owner'} =
$param->{'may_create_automatic_list'};
return 1;
 
}
......@@ -16940,20 +16944,14 @@ sub do_maintenance {
return 1;
}
 
sub do_automatic_lists_management_request {
wwslog('notice', 'Starting');
$param->{'automatic_lists_description'} =
Conf::load_automatic_lists_description();
return 1;
}
sub do_automatic_lists_management {
wwslog('notice', 'Starting');
# Never used.
#sub do_automatic_lists_management_request;
 
return 1;
}
# Never used.
#sub do_automatic_lists_management;
 
sub do_automatic_lists_request {
# Old name: do_automatic_lists_request().
sub do_create_automatic_list_request {
wwslog('notice', 'Starting');
# check authorization
my $family;
......@@ -16961,24 +16959,9 @@ sub do_automatic_lists_request {
wwslog('err',
'Failed to instantiate family %s. This family does not exist',
$in{'family'});
Sympa::send_notify_to_listmaster(
$robot,
'automatic_list_creation_failed',
[ "Failed to instantiate family $in{'family'}. This family does not exist."
]
);
return undef;
}
unless (
$family->is_allowed_to_create_automatic_lists(
( 'auth_level' => 'md5',
'sender' => $session->{'email'},
'message' => undef,
'listname' => ''
)
)
) {
unless ($param->{'may_create_automatic_list'}{$family->{'name'}}) {
Sympa::Report::reject_report_web('auth',
"You are not allowed to create list in this family",
{}, $param->{'action'});
......@@ -16992,65 +16975,90 @@ sub do_automatic_lists_request {
return 1;
}
 
sub do_automatic_lists {
wwslog('notice', 'Starting');
# Old name: do_automatic_lists().
sub do_create_automatic_list {
wwslog('notice', '(%s)', $in{'family'});
my $family_name = $in{'family'};
# Automatic creation of a mailing list, based on a family.
my $family;
unless ($family = Sympa::Family->new($family_name, $robot)) {
$log->syslog('err',
'Failed to create the dynamic list: Family %s does not exist',
$family_name
);
return undef;
}
$param->{'family'} = $family;
 
my $family_config =
(Conf::get_robot_conf($robot, 'automatic_list_families') || {})
->{$family_name};
my @list_name_parts;
my $families_config =
Conf::get_robot_conf($robot, 'automatic_list_families');
my $family_config = $families_config->{$family_name};
my $listname =
$family_config->{'prefix'} . $family_config->{'prefix_separator'};
foreach my $input (keys %in) {
next unless ($input =~ /automatic_list_part_(\d+)/);
next unless $input =~ /automatic_list_part_(\d+)/;
$list_name_parts[$1] = $in{$input};
}
foreach my $list_name_part (@list_name_parts) {
$listname .= "$list_name_part$family_config->{'classes_separator'}";
}
my $sep = $family_config->{'classes_separator'} . '$';
if ($listname =~ /(.*)($sep)/) {
$listname = $1;
while (@list_name_parts
and not(defined $list_name_parts[$#list_name_parts]
and length $list_name_parts[$#list_name_parts])) {
pop @list_name_parts;
}
my $listname =
$family_config->{'prefix'} . $family_config->{'prefix_separator'} .
join($family_config->{'classes_separator'}, @list_name_parts);
 
$list = Sympa::List->new($listname, $robot);
unless (defined $list) {
## Automatic creation of a mailing list, based on a family
unless ($family = Sympa::Family->new($family_name, $robot)) {
$log->syslog('err',
"Failed to create the dynamic list $listname: family $family_name does not exist."
);
Sympa::send_notify_to_listmaster(
$robot,
'automatic_list_creation_failed',
[ "Failed to create the dynamic list $listname: family $family_name does not exist."
]
);
return undef;
}
my $spindle = Sympa::Spindle::ProcessRequest->new(
context => $family,
action => 'create_automatic_list',
listname => $listname,
parameters => {},
abort_on_error => 1,
sender => $param->{'user'}{'email'},
md5_check => 1,
scenario_context => {
sender => $param->{'user'}{'email'},
message => undef,
family => $family,
automatic_listname => $listname,
},
);
unless ($spindle and $spindle->spin) {
wwslog('err', 'Failed to create the dynamic list %s', $listname);
return 'create_automatic_list_request';
}
 
unless (
$list = $family->create_automatic_list(
( 'listname' => $listname,
'auth_level' => 'md5',
'sender' => $session->{'email'}
)
)
) {
$log->syslog('err', 'Failed to create the dynamic list %s',
$listname);
Sympa::send_notify_to_listmaster(
$robot,
'automatic_list_creation_failed',
["Failed to create the dynamic list $listname."]
);
return undef;
foreach my $report (@{$spindle->{stash} || []}) {
if ($report->[1] eq 'notice') {
Sympa::Report::notice_report_web(@{$report}[2, 3],
$param->{'action'});
} elsif ($report->[1] eq 'user'
and $report->[2] eq 'list_already_exists') {
# Pass the list already exists.
;
} else {
Sympa::Report::reject_report_web(@{$report}[1 .. 3],
$param->{action});
}
}
unless (@{$spindle->{stash} || []}) {
Sympa::Report::notice_report_web('performed', {}, $param->{'action'});
} elsif (grep {$_->[1] eq 'user' and $_->[2] eq 'list_already_exists' }
@{$spindle->{stash} || []}) {
;
} elsif (not $spindle->success) {
$log->syslog('err', 'Failed to create the dynamic list %s',
$listname);
Sympa::send_notify_to_listmaster(
$robot,
'automatic_list_creation_failed',
["Failed to create the dynamic list $listname."]
);
return 'create_automatic_list_request';
}
 
$in{'list'} = $listname;
$list = Sympa::List->new($listname, $robot);
$in{'list'} = $list ? $list->{'name'} : undef;
return 'compose_mail';
}
 
......
......@@ -1435,23 +1435,10 @@ sub load_automatic_lists_description {
},
},
);
# find appropriate automatic_lists_description.tt2 file
my $config;
if (defined $robot) {
$config =
$Conf{'etc'} . '/'
. $robot
. '/families/'
. $family
. '/automatic_lists_description.conf';
} else {
$config =
$Conf{'etc'}
. '/families/'
. $family
. '/automatic_lists_description.conf';
}
return undef unless (-r $config);
# find appropriate automatic_lists_description.conf file
my $config = Sympa::search_fullpath($robot,
'automatic_lists_description.conf', subdir => ('families/' . $family));
return undef unless $config;
my $description =
load_generic_conf_file($config, \%automatic_lists_params);
......
......@@ -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_automatic_list.pm \
Sympa/Request/Handler/create_list.pm \
Sympa/Request/Handler/decl.pm \
Sympa/Request/Handler/del.pm \
......
......@@ -43,15 +43,9 @@ use strict;
use warnings;
use English qw(-no_match_vars);
use Sympa;
use Conf;
use Sympa::Constants;
use Sympa::List;
use Sympa::LockedFile;
use Sympa::Log;
use Sympa::Regexps;
use Sympa::Robot;
use Sympa::Template;
my $log = Sympa::Log->instance;
......@@ -64,382 +58,11 @@ This is the description of the subfunctions contained by admin.pm
# Moved to: Sympa::Request::Handler::create_list::_twist().
#sub create_list_old;
########################################################
# create_list
########################################################
# Create a list : used by sympa.pl--instantiate_family
# with 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
# - $family : the family object
# - $robot : the list's robot ** No longer used.
# - $abort_on_error : won't create the list directory on
# tt2 process error (useful for dynamic lists that
# throw exceptions)
# 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 {
my ($param, $family, $dummy, $abort_on_error) = @_;
$log->syslog('info', '(%s, %s, %s)', $param->{'listname'},
$family->{'name'}, $param->{'subject'});
## mandatory list parameters
foreach my $arg ('listname') {
unless ($param->{$arg}) {
$log->syslog('err', 'Missing list param %s', $arg);
return undef;
}
}
unless ($family) {
$log->syslog('err', 'Missing param "family"');
return undef;
}
#robot
my $robot = $family->{'robot'};
unless ($robot) {
$log->syslog('err', 'Missing param "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;
}
if ($res) {
$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;
}
## template file
my $template_file = Sympa::search_fullpath($family, 'config.tt2');
unless (defined $template_file) {
$log->syslog('err', 'No config template from family %s@%s',
$family->{'name'}, $robot);
return undef;
}
my $family_config =
Conf::get_robot_conf($robot, 'automatic_list_families');
$param->{'family_config'} = $family_config->{$family->{'name'}};
my $conf;