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

Merge pull request #511 from ldidry/delete-my-account by ldidry

Fix #300 — Allow to delete your own account
parents 9d8a9da2 cdf63b0e
......@@ -438,6 +438,9 @@
[%~ ELSIF report_entry == 'logout' ~%]
[%|loc%]You have logged out[%END%]
[%~ ELSIF report_entry == 'account_deleted' ~%]
[%|loc%]You have been unsubscribed from all your lists and your account has been deleted[%END%]
[%~ END ~%]
[%################~%]
......@@ -830,6 +833,12 @@ Warning: this message may already have been sent by one of the list's moderators
[%~ ELSIF report_entry == 'owner_domain_min' ~%]
[%|loc(report_param.value,report_param.owner_domain_min,report_param.owner_domain)%]Unable to reduce the number of list owners in required domains to %1. Domains that count toward the minimum requirement of %2: %3[%END%]
[%~ ELSIF report_entry == 'still_owner' ~%]
[%|loc(report_param.lists)%]You are the only owner of the following list(s): %1. Please give ownership to other people before deleting your account. You have been unsubscribed from all your lists though.[%END%]
[%~ ELSIF report_entry == 'no_classic_session' ~%]
[%|loc()%]You are not authorized to delete your account if you are not using the built-in authentication (i.e. you are using a LDAP authentication, a SSO system, etc.).[%END%]
[%~ END ~%]
[%~ END ~%]
<!-- confirm_action.tt2 -->
[%#
# Set h2 title and text of confirmation page
#%]
[% IF confirm_action == 'add' ~%]
[% IF previous_action == 'show_exclude' ~%]
<h2><i class="fa fa-check-circle"></i>
......@@ -91,6 +94,15 @@
<p><strong>
[%|loc%]Do you really want to unsubscribe ALL selected subscribers?[%END%]
</strong></p>
[%~ ELSIF confirm_action == 'delete_account' ~%]
<h2><i class="fa fa-check-circle"></i>
[%|loc%]Delete my account[%END%]
</h2>
<p><strong>
[%|loc%]Do you really want to unsubscribe you from all your lists, remove your ownership of your lists and permanently delete your account?[%END%]
<br />
[%|loc%]Please note that you will not be able to delete your account if you are the only owner of one or more list.[%END%]
</strong></p>
[%~ ELSIF confirm_action == 'auth_add' ~%]
<h2><i class="fa fa-check-circle"></i>
[%|loc%]Add subscribers[%END%]
......@@ -238,6 +250,11 @@
</strong></p>
[%~ END %]
[%#
# Create the form.
# Add hidden fields containing the values of the form you want to confirm
# %]
<form action="[% path_cgi %]" method="POST">
[% IF confirm_action == 'add' ~%]
[% FOREACH e = email ~%]
......@@ -303,6 +320,11 @@
[% IF quiet %]checked="checked"[%END%] />
<label for="quiet">[%|loc%]Quiet (don't send deletion email)[%END%]</label>
</div>
[%~ ELSIF confirm_action == 'delete_account' ~%]
<fieldset>
<input type="hidden" name="passwd" value="x"/>
<input type="hidden" name="i_understand_the_consequences" value="1"/>
</fieldset>
[%~ ELSIF confirm_action == 'distribute' ~%]
[% FOREACH i = id ~%]
<input type="hidden" name="id" value="[% i %]" />
......@@ -366,9 +388,17 @@
value="[% i.value.value.replace('\n', '&#10;') %]" />
[%~ END %]
[%~ END %]
[%#
# Confirmation common hidden fields
#%]
<input type="hidden" name="action" value="[% confirm_action %]" />
<input type="hidden" name="list" value="[% list %]" />
<input type="hidden" name="previous_action" value="[% previous_action %]" />
[%#
# Submit and cancel buttons
#%]
[% IF confirm_action == 'arc' || confirm_action == 'arcsearch_id' ~%]
<div>
<input class="MainMenuLinks" type="submit"
......
......@@ -70,6 +70,24 @@
</form>
[% END %]
[% IF session.auth == 'classic' AND conf.allow_account_deletion %]
<h4>[%|loc%]Deleting your account[%END%]</h4>
<p>
[%|loc%]Deleting your account will unsubscribe you from all your lists, remove your ownership of your lists and permanently delete your account.[%END%]
<br />
[%|loc%]Please note that you will not be able to delete your account if you are the only owner of one or more list.[%END%]
</p>
<form action="[% path_cgi %]" method="post">
<fieldset>
<label for="password_for_account_deletion">[%|loc%]Enter your password:[%END%]</label>
<input type="password" name="passwd" id="password_for_account_deletion" size="25" />
<input type="checkbox" name="i_understand_the_consequences" id="i_understand_the_consequences" required><label for="i_understand_the_consequences">[%|loc%]I understand that I will be unsubscribed from all my lists and that my account will be permanently deleted.[%END%]</label>
<br />
<input class="MainMenuLinks" type="submit" name="action_delete_account" value="[%|loc%]Submit[%END%]" />
</fieldset>
</form>
[% END %]
</div>
<!-- end pref.tt2 -->
......@@ -333,6 +333,7 @@ our %comm = (
'create_automatic_list' => 'do_create_automatic_list',
'create_automatic_list_request' => 'do_create_automatic_list_request',
'auth' => 'do_auth',
'delete_account' => 'do_delete_account',
);
 
my %comm_aliases = (
......@@ -568,6 +569,7 @@ our %required_args = (
'get_pending_lists' => ['param.user.email'],
'decl_del' => ['param.list', 'param.user.email'],
'decl_add' => ['param.list', 'param.user.email'],
'delete_account' => ['passwd', 'i_understand_the_consequences'],
'including_lists' => ['param.list', 'param.user.email'],
'info' => ['param.list'],
'install_pending_list' => ['param.user.email'],
......@@ -729,12 +731,12 @@ our %required_privileges = (
# as possible.
 
our %require_csrftoken = (
'add' => 1,
'del' => 1,
'move_user' => 1,
'savefile' => 1,
'setpasswd' => 1,
'setpref' => 1,
'add' => 1,
'del' => 1,
'move_user' => 1,
'savefile' => 1,
'setpasswd' => 1,
'setpref' => 1,
);
 
# this definition is used to choose the left side menu type (admin ->
......@@ -1167,6 +1169,7 @@ while ($query = CGI::Fast->new) {
'pictures_max_size',
'show_report_abuse',
'quiet_subscription',
'allow_account_deletion',
) {
 
$param->{'conf'}{$p} = Conf::get_robot_conf($robot, $p);
......@@ -17153,6 +17156,159 @@ sub do_auth {
return $default_home;
}
 
sub do_delete_account {
if (Conf::get_robot_conf($robot, 'allow_account_deletion')) {
wwslog(
'info',
sprintf(
'Account deletion: %s asked for its account to be deleted',
$param->{'user'}->{'email'})
);
# Show form if HTTP POST method not used.
return 1 unless $ENV{'REQUEST_METHOD'} eq 'POST';
my $email =
Sympa::Tools::Text::canonic_email($param->{'user'}->{'email'});
my $passwd = delete $in{'passwd'}; # Clear it.
unless ($email) {
Sympa::WWW::Report::reject_report_web('user', 'no_email', {},
$param->{'action'});
wwslog('info', 'No email');
web_db_log(
{ 'parameters' => $email,
'target_email' => $email,
'status' => 'error',
'error_type' => "no_email"
}
);
return 'pref';
}
unless ($session->{auth} eq 'classic') {
Sympa::WWW::Report::reject_report_web('user',
'no_classic_session', {}, $param->{'action'});
wwslog('info', 'No classic session');
web_db_log(
{ 'parameters' => $email,
'target_email' => $email,
'status' => 'error',
'error_type' => "no_classic_session"
}
);
return 'pref';
}
my $next_action =
$session->confirm_action($in{'action'}, $in{'response_action'},
previous_action => 'pref');
unless ($passwd) {
Sympa::WWW::Report::reject_report_web('user', 'missing_arg',
{'argument' => 'passwd'},
$param->{'action'});
wwslog('info', 'Missing parameter passwd');
web_db_log(
{ 'parameters' => $email,
'target_email' => $email,
'status' => 'error',
'error_type' => "missing_parameter"
}
);
return 'pref';
}
my $data;
unless (($next_action eq '1')
|| ($data = Sympa::WWW::Auth::check_auth($robot, $email, $passwd))
) {
$log->syslog('notice', 'Authentication failed');
web_db_log(
{ 'parameters' => $email,
'target_email' => $email,
'status' => 'error',
'error_type' => 'authentication'
}
);
return 'pref';
}
return $next_action unless $next_action eq '1';
$param->{'email'} = $email;
_set_my_lists_info();
my @only_owner;
for my $list (sort keys %{$param->{'which'}}) {
my $l = Sympa::List->new($list, $robot);
# Unsubscribe
$l->delete_list_member('users' => [$email])
if $param->{'which'}->{$list}->{'is_subscriber'};
# Remove from the editors
$l->delete_list_admin('editor', $email)
if $param->{'which'}->{$list}->{'is_editor'};
# Remove from the owners
if ($param->{'which'}->{$list}->{'is_owner'}) {
my @admins = $l->get_admins('owner');
if (scalar(@admins) > 1) {
$l->delete_list_admin('owner', $email);
# Don't let a list without a privileged admin
my @privileged_admins =
$l->get_admins('privileged_owner');
unless (scalar(@privileged_admins)) {
@admins = $l->get_admins('owner');
for my $admin (@admins) {
$l->update_list_admin($admin->{email}, 'owner',
{profile => 'privileged'});
}
}
} else {
wwslog(
'info',
sprintf(
'Account deletion: %s is the only owner of %s. The account will not be deleted.',
$email, $list
)
);
push @only_owner, $list;
}
}
}
if (@only_owner) {
Sympa::WWW::Report::reject_report_web('user', 'still_owner',
{lists => join(', ', @only_owner)},
$param->{'action'});
return 'pref';
}
my $user = Sympa::User->new($email);
$user->expire;
wwslog(
'info',
sprintf('Account deletion: the account of %s has been deleted',
$email)
);
Sympa::WWW::Report::notice_report_web('account_deleted', {},
$param->{'action'});
do_logout();
} else {
wwslog(
'info',
sprintf(
'Account deletion: %s asked for its account to be deleted but allow_account_deletion is not set to 1.',
$param->{'user'}->{'email'})
);
}
}
sub prevent_visibility_bypass {
wwslog('debug2', 'Starting');
if (defined $list and ref $list eq 'Sympa::List') {
......
......@@ -2254,6 +2254,15 @@ our @params = (
'file' => 'sympa.conf',
'optional' => 1,
},
{ 'name' => 'allow_account_deletion',
'gettext_id' =>
'EXPERIMENTAL! Allow users to delete their account. If enabled, shows a "delete my account" form in user\'s preferences page.',
'gettext_comment' =>
'Account deletion usubscribe the users from his/her lists and remove him/her from lists ownership. Only usable by users using internal authentication (i.e. no LDAP, no SSO…). See https://github.com/sympa-community/sympa/issues/300 for details',
'default' => '0',
'file' => 'sympa.conf',
'optional' => 1,
},
## Not implemented yet.
## {
......
......@@ -8161,7 +8161,7 @@ sub _load_list_param {
# Empty value.
unless (defined $value and $value =~ /\S/) {
return undef; #FIXME
return undef; #FIXME
}
# For compatibility to <= 6.2.40: Special name "default" stands for
......
......@@ -265,8 +265,8 @@ sub load_topics {
$list_of_topics{$robot}{$tree[0]}{'order'} =
$topic->{'order'};
} else {
my $subtopic = join('/', @tree[1 .. $#tree]);
my $title = _load_topics_get_title($topic);
my $subtopic = join('/', @tree[1 .. $#tree]);
my $title = _load_topics_get_title($topic);
my $visibility =
$topic->{'visibility'} || $default_topics_visibility;
$list_of_topics{$robot}{$tree[0]}{'sub'}{$subtopic} =
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment