Unverified Commit 3028d0fd authored by IKEDA Soji's avatar IKEDA Soji Committed by GitHub
Browse files

Merge pull request #477 from ikedas/issue-309_6.2.36 by ikedas

Issue #309 on 6.2.36
parents 8b112a83 432ef50a
......@@ -4699,6 +4699,7 @@ sub _review_user {
wwslog('info', 'No parameter was edited by user');
} else {
# Validation of the form finished. Start of valid data treatments.
# FIXME: Use commit().
 
# Delete/add users.
my @del_users = map {
......@@ -4739,6 +4740,10 @@ sub _review_user {
#FIXME: Report error
}
}
if ($list->get_family and (@del_users or @{$new_users || []})) {
$list->update_config_changes('param', $role);
}
}
}
 
......@@ -4996,7 +5001,13 @@ sub do_edit {
} else {
# Validation of the form finished. Start of valid data
# treatments.
# FIXME: Use commit().
$list->update_list_admin($email, $role, $new_admin->{$role}->[0]);
# Keep track of changes for family.
if ($list->get_family) {
$list->update_config_changes('param', $role);
}
}
 
$in{'page'} = $role; # For review.
......
......@@ -375,20 +375,7 @@ sub modify_list {
return $return;
}
## get allowed and forbidden list customizing
my $custom = $self->_get_customizing($list);
unless (defined $custom) {
$log->syslog('err', 'Impossible to get list %s customizing',
$list->{'name'});
push @{$return->{'string_error'}},
"Error during updating list $list->{'name'}, the list is set in status error_config.";
$list->set_status_error_config('modify_list_family', $self->{'name'});
return $return;
}
my $config_changes = $custom->{'config_changes'};
my $old_status = $list->{'admin'}{'status'};
## list config family updating
# list config family updating
my $spindle = Sympa::Spindle::ProcessRequest->new(
context => $self,
action => 'update_automatic_list',
......@@ -406,105 +393,6 @@ sub modify_list {
return $return;
}
## set list customizing
foreach my $p (keys %{$custom->{'allowed'}}) {
$list->{'admin'}{$p} = $custom->{'allowed'}{$p};
delete $list->{'admin'}{'defaults'}{$p};
$log->syslog('info', 'Customizing: Keeping values for parameter %s',
$p);
}
## info file
unless ($config_changes->{'file'}{'info'}) {
unless (defined $hash_list->{'config'}{'description'}) {
$hash_list->{'config'}{'description'} = '';
}
$hash_list->{'config'}{'description'} =~ s/\r\n|\r/\n/g;
my $fh;
unless (open $fh, '>', "$list->{'dir'}/info") {
push @{$return->{'string_info'}},
sprintf('Impossible to create new %s/info file: %s',
$list->{'dir'}, $ERRNO);
}
print $fh $hash_list->{'config'}{'description'};
close $fh;
}
foreach my $f (keys %{$config_changes->{'file'}}) {
$log->syslog('info', 'Customizing: This file has been changed: %s',
$f);
}
## rename forbidden files
#foreach my $f (@{$custom->{'forbidden'}{'file'}}) {
# unless (rename "$list->{'dir'}"."/"."info",
# "$list->{'dir'}"."/"."info.orig") {
# ###############
# }
# if ($f eq 'info') {
# $hash_list->{'config'}{'description'} =~ s/\r\n|\r/\n/g;
# unless (open INFO, '>', "$list_dir/info") {
# ###############
# }
# print INFO $hash_list->{'config'}{'description'};
# close INFO;
# }
#}
## notify owner for forbidden customizing
if ( #(scalar $custom->{'forbidden'}{'file'}) ||
(scalar @{$custom->{'forbidden'}{'param'}})
) {
#my $forbidden_files = join(',',@{$custom->{'forbidden'}{'file'}});
my $forbidden_param = join(',', @{$custom->{'forbidden'}{'param'}});
$log->syslog('notice',
"These parameters aren't allowed in the new family definition, they are erased by a new instantiation family : \n $forbidden_param"
);
$list->send_notify_to_owner('erase_customizing',
[$self->{'name'}, $forbidden_param]);
}
## status
my $result = $self->_set_status_changes($list, $old_status);
if ($result->{'aliases'} == 1) {
push @{$return->{'string_info'}},
sprintf('The %s list has been modified.', $list->{'name'});
} elsif ($result->{'install_remove'} eq 'install') {
push @{$return->{'string_info'}},
sprintf('List %s has been modified, required aliases.',
$list->{'name'});
} else {
push @{$return->{'string_info'}},
sprintf('List %s has been modified, aliases need to be removed.',
$list->{'name'});
}
## config_changes
foreach my $p (@{$custom->{'forbidden'}{'param'}}) {
if (defined $config_changes->{'param'}{$p}) {
delete $config_changes->{'param'}{$p};
}
}
unless (open FILE, '>', "$list->{'dir'}/config_changes") {
$list->set_status_error_config('error_copy_file', $self->{'name'});
push @{$return->{'string_info'}},
sprintf
'Impossible to create file %s/config_changes : %s, the list is set in status error_config.',
$list->{'dir'}, $ERRNO;
}
close FILE;
my @kept_param = keys %{$config_changes->{'param'}};
$list->update_config_changes('param', \@kept_param);
my @kept_files = keys %{$config_changes->{'file'}};
$list->update_config_changes('file', \@kept_files);
$list->{'admin'}{'latest_instantiation'}{'email'} =
Sympa::get_address($self, 'listmaster');
$list->{'admin'}{'latest_instantiation'}{'date_epoch'} = time;
......@@ -1935,17 +1823,7 @@ sub _update_existing_list {
my ($self, $list, $hash_list) = @_;
$log->syslog('debug3', '(%s, %s)', $self->{'name'}, $list->{'name'});
## get allowed and forbidden list customizing
my $custom = $self->_get_customizing($list);
unless (defined $custom) {
$log->syslog('err', 'Impossible to get list %s customizing',
$list->{'name'});
return undef;
}
my $config_changes = $custom->{'config_changes'};
my $old_status = $list->{'admin'}{'status'};
## list config family updating
# list config family updating
my $spindle = Sympa::Spindle::ProcessRequest->new(
context => $self,
action => 'update_automatic_list',
......@@ -1960,339 +1838,15 @@ sub _update_existing_list {
return undef;
}
## set list customizing
foreach my $p (keys %{$custom->{'allowed'}}) {
$list->{'admin'}{$p} = $custom->{'allowed'}{$p};
delete $list->{'admin'}{'defaults'}{$p};
$log->syslog('info', 'Customizing: Keeping values for parameter %s',
$p);
}
## info file
unless ($config_changes->{'file'}{'info'}) {
unless (defined $hash_list->{'config'}{'description'}) {
$hash_list->{'config'}{'description'} = '';
}
$hash_list->{'config'}{'description'} =~ s/\r\n|\r/\n/g;
my $fh;
unless (open $fh, '>', $list->{'dir'} . '/info') {
$log->syslog('err', 'Impossible to open %s/info: %m',
$list->{'dir'});
}
print $fh $hash_list->{'config'}{'description'};
close $fh;
}
foreach my $f (keys %{$config_changes->{'file'}}) {
$log->syslog('info', 'Customizing: This file has been changed: %s',
$f);
}
## rename forbidden files
#foreach my $f (@{$custom->{'forbidden'}{'file'}}) {
# unless (rename "$list->{'dir'}"."/"."info",
# "$list->{'dir'}"."/"."info.orig") {
# ###############
# }
# if ($f eq 'info') {
# $hash_list->{'config'}{'description'} =~ s/\r\n|\r/\n/g;
# unless (open INFO, '>', "$list_dir/info") {
# ###############
# }
# print INFO $hash_list->{'config'}{'description'};
# close INFO;
# }
#}
## notify owner for forbidden customizing
if ( #(scalar $custom->{'forbidden'}{'file'}) ||
(scalar @{$custom->{'forbidden'}{'param'}})
) {
#my $forbidden_files = join(',',@{$custom->{'forbidden'}{'file'}});
my $forbidden_param = join(',', @{$custom->{'forbidden'}{'param'}});
$log->syslog('notice',
"These parameters aren't allowed in the new family definition, they are erased by a new instantiation family : \n $forbidden_param"
);
$list->send_notify_to_owner('erase_customizing',
[$self->{'name'}, $forbidden_param]);
}
## status
my $result = $self->_set_status_changes($list, $old_status);
if ($result->{'aliases'} == 1) {
push(@{$self->{'updated_lists'}{'aliases_ok'}}, $list->{'name'});
} elsif ($result->{'install_remove'} eq 'install') {
$self->{'updated_lists'}{'aliases_to_install'}{$list->{'name'}} =
$list->{'name'};
} else {
$self->{'updated_lists'}{'aliases_to_remove'}{$list->{'name'}} =
$list->{'name'};
}
## config_changes
foreach my $p (@{$custom->{'forbidden'}{'param'}}) {
if (defined $config_changes->{'param'}{$p}) {
delete $config_changes->{'param'}{$p};
}
}
unless (open FILE, '>', $list->{'dir'} . '/config_changes') {
$log->syslog('err', 'Impossible to open file %s/config_changes: %m',
$list->{'dir'});
push(@{$self->{'generated_lists'}{'file_error'}}, $list->{'name'});
$list->set_status_error_config('error_copy_file', $self->{'name'});
}
close FILE;
my @kept_param = keys %{$config_changes->{'param'}};
$list->update_config_changes('param', \@kept_param);
my @kept_files = keys %{$config_changes->{'file'}};
$list->update_config_changes('file', \@kept_files);
return $list;
}
=pod
=head2 sub _get_customizing()
Gets list customizations from the config_changes file and keeps on changes allowed by param_constraint.conf
=head3 Arguments
=over
# Moved:
# Use Sympa::Request::Handler::update_automatic_list::_get_customizing().
#sub _get_customizing;
=item * I<$self>, the Sympa::Family object
=item * I<$list>, a List object corresponding to the list we want to check
=back
=head3 Return
=over
=item * I<$result>, a reference to a hash containing:
=over 4
=item * $result->{'config_changes'} : the list config_changes
=item * $result->{'allowed'}, a hash of allowed parameters: ($param,$values)
=item * $result->{'forbidden'}{'param'} = \@
=item * $result->{'forbidden'}{'file'} = \@ (not working)
=back
=back
=cut
#####################################################
# _get_customizing
#####################################################
# gets list customizing from config_changes file and
# keep on changes that are allowed by param_constraint.conf
#
# IN : -$self
# -$list
# OUT :- $result->{'config_changes'} : the list config_changes
# - $result->{'allowed'}
# hash of allowed param : ($param,$values)
# - $result->{'forbidden'}{'param'} = \@
# {'file'} = \@ (no working)
#####################################################
sub _get_customizing {
my ($self, $list) = @_;
$log->syslog('debug3', '(%s, %s)', $self->{'name'}, $list->{'name'});
my $result;
my $config_changes = $list->get_config_changes;
unless (defined $config_changes) {
$log->syslog('err', 'Impossible to get config_changes');
return undef;
}
## FILES
#foreach my $f (keys %{$config_changes->{'file'}}) {
# my $privilege; # =may_edit($f)
#
# unless ($privilege eq 'write') {
# push @{$result->{'forbidden'}{'file'}},$f;
# }
#}
## PARAMETERS
# get customizing values
my $changed_values;
foreach my $p (keys %{$config_changes->{'param'}}) {
$changed_values->{$p} = $list->{'admin'}{$p};
}
# check these values
my $constraint = $self->get_constraints();
unless (defined $constraint) {
$log->syslog('err', 'Unable to get family constraints',
$self->{'name'}, $list->{'name'});
return undef;
}
my $fake_list =
bless {'domain' => $list->{'domain'}, 'admin' => $changed_values} =>
'Sympa::List';
## TODO: update parameter cache
foreach my $param (keys %{$constraint}) {
my $constraint_value = $constraint->{$param};
my $param_value;
my $value_error;
unless (defined $constraint_value) {
$log->syslog(
'err',
'No value constraint on parameter %s in param_constraint.conf',
$param
);
next;
}
$param_value = $fake_list->get_param_value($param, 1);
$value_error = $self->check_values($param_value, $constraint_value);
foreach my $v (@{$value_error}) {
push @{$result->{'forbidden'}{'param'}}, $param;
$log->syslog('err', 'Error constraint on parameter %s, value: %s',
$param, $v);
}
}
# keep allowed values
foreach my $param (@{$result->{'forbidden'}{'param'}}) {
if ($param =~ /^([\w-]+)\.([\w-]+)$/) {
$param = $1;
}
if (defined $changed_values->{$param}) {
delete $changed_values->{$param};
}
}
$result->{'allowed'} = $changed_values;
$result->{'config_changes'} = $config_changes;
return $result;
}
=pod
=head2 sub _set_status_changes()
Sets changes (loads the users, installs or removes the aliases); deals with the new and old_status (for already existing lists).
=head3 Arguments
=over
=item * I<$self>, the Sympa::Family object
=item * I<$list>, a List object corresponding to the list the changes of which we want to set.
=item * I<$old_status>, a character string corresponding to the list status before family instantiation.
=back
=head3 Return
=over
=item * I<$result>, a reference to a hash containing:
=over 4
=item * $result->{'install_remove'} = "install" or "remove"
=item * $result->{'aliases'} = 1 if install or remove is done or a string of aliases needed to be installed or removed
=back
=back
=cut
#####################################################
# _set_status_changes
#####################################################
# set changes (load the users, install or removes the
# aliases) dealing with the new and old_status (for
# already existing lists)
# IN : -$self
# -$list : the new list
# -$old_status : the list status before instantiation
# family
#
# OUT :-$result->{'install_remove'} ='install' or 'remove'
# -$result->{'aliases'} = 1 (if install or remove is done) or
# a string of aliases needed to be installed or removed
#####################################################
sub _set_status_changes {
my ($self, $list, $old_status) = @_;
$log->syslog('debug3', '(%s, %s, %s)', $self->{'name'}, $list);
my $result;
$result->{'aliases'} = 1;
unless (defined $list->{'admin'}{'status'}) {
$list->{'admin'}{'status'} = 'open';
}
# Aliases.
my $aliases = Sympa::Aliases->new(
Conf::get_robot_conf($list->{'domain'}, 'alias_manager'));
if ($list->{'admin'}{'status'} eq 'open') {
unless ($old_status eq 'open') {
$result->{'install_remove'} = 'install';
$result->{'aliases'} = ($aliases and $aliases->add($list));
}
}
if ($list->{'admin'}{'status'} eq 'pending'
and ($old_status eq 'open' or $old_status eq 'error_config')) {
$result->{'install_remove'} = 'remove';
$result->{'aliases'} = ($aliases and $aliases->del($list));
}
### subscribers
#if (($old_status ne 'pending') && ($old_status ne 'open')) {
# if ($list->{'admin'}{'user_data_source'} eq 'file') {
# $list->{'users'} = Sympa::List::_load_list_members_file(
# $list->{'dir'} . '/subscribers.closed.dump');
# } elsif ($list->{'admin'}{'user_data_source'} eq 'database') {
# unless (-f $list->{'dir'} . '/subscribers.closed.dump') {
# $log->syslog('notice', 'No subscribers to restore');
# }
# my @users = Sympa::List::_load_list_members_file(
# $list->{'dir'} . '/subscribers.closed.dump');
#
# ## Insert users in database
# foreach my $user (@users) {
# $list->add_list_member($user);
# }
# }
#}
return $result;
}
# No longer used.
#sub _set_status_changes;
=pod
......
......@@ -51,6 +51,16 @@ sub _twist {
my $param = $request->{parameters};
my $robot_id = $family->{'robot'};
# Get allowed and forbidden list customizing.
my $custom = _get_customizing($family, $list);
unless (defined $custom) {
$log->syslog('err', 'Impossible to get list %s customizing', $list);
$self->add_stash($request, 'intern');
return undef;
}
my $config_changes = $custom->{'config_changes'};
my $old_status = $list->{'admin'}{'status'};
# Check the template supposed to be used exist.
my $template_file = Sympa::search_fullpath($family, 'config.tt2');
unless (defined $template_file) {
......@@ -94,6 +104,9 @@ sub _twist {
my @config = do { local $RS = ''; <$ifh> };
close $ifh;
foreach my $role (qw(owner editor)) {
# No update needed if modification allowed.
next if $custom->{allowed}->{$role};
my $file = $list->{'dir'} . '/' . $role . '.dump';
unlink "$file.old";
rename $file, "$file.old";
......@@ -157,10 +170,39 @@ sub _twist {
return undef;
}
# Store permanent list users.
#XXX$list->restore_users('member');
$list->restore_users('owner');
$list->restore_users('editor');
# Update permanent list users.
# No update needed if modification allowed.
$list->restore_users('owner') unless $custom->{allowed}->{owner};
$list->restore_users('editor') unless $custom->{allowed}->{editor};
# Restore list customizations.
foreach my $p (keys %{$custom->{'allowed'}}) {
$list->{'admin'}{$p} = $custom->{'allowed'}{$p};
delete $list->{'admin'}{'defaults'}{$p};
$log->syslog('info', 'Customizing: Keeping values for parameter %s',
$p);
}
# Update info file.
unless ($config_changes->{'file'}{'info'}) {
my $description =
(defined $param->{description}) ? $param->{description} : '';
$description =~ s/\r\n|\r/\n/g;
if (open my $fh, '>', $list->{'dir'} . '/info') {
print $fh $description;
close $fh;
} else {
$log->syslog('err', 'Impossible to open %s/info: %m',
$list->{'dir'});
}
}
# Changed files
foreach my $f (keys %{$config_changes->{'file'}}) {
$log->syslog('info', 'Customizing: This file has been changed: %s',
$f);
}
#FIXME: would be better to rename forbidden files?
#FIXME: Not saved?
$list->{'admin'}{'creation'}{'date_epoch'} = time;
......@@ -175,9 +217,152 @@ sub _twist {
$list->sync_include();
}
# (Note: Following block corresponds to previous _set_status_changes()).
my $current_status = $list->{'admin'}{'status'} || 'open';
# Update aliases.
if ($current_status eq 'open' and not($old_status eq 'open')) {
my $aliases = Sympa::Aliases->new(
Conf::get_robot_conf($list->{'domain'}, 'alias_manager'));
if ($aliases and $aliases->add($list)) {
$self->add_stash($request, 'notice', 'auto_aliases');
}
} elsif ($current_status eq 'pending'
and ($old_status eq 'open' or $old_status eq 'error_config')) {
my $aliases = Sympa::Aliases->new(
Conf::get_robot_conf($list->{'domain'}, 'alias_manager'));
$aliases and $aliases->del($list);
}