summaryrefslogtreecommitdiffstats
path: root/userprefs.cgi
diff options
context:
space:
mode:
Diffstat (limited to 'userprefs.cgi')
-rwxr-xr-xuserprefs.cgi1611
1 files changed, 820 insertions, 791 deletions
diff --git a/userprefs.cgi b/userprefs.cgi
index 830c49eed..45a1c5194 100755
--- a/userprefs.cgi
+++ b/userprefs.cgi
@@ -30,7 +30,7 @@ use DateTime;
use constant SESSION_MAX => 20;
local our $template = Bugzilla->template;
-local our $vars = {};
+local our $vars = {};
###############################################################################
# Each panel has two functions - panel Foo has a DoFoo, to get the data
@@ -39,898 +39,922 @@ local our $vars = {};
# SaveFoo may be called before DoFoo.
###############################################################################
sub DoAccount {
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
-
- ($vars->{'realname'}) = $dbh->selectrow_array(
- "SELECT realname FROM profiles WHERE userid = ?", undef, $user->id);
-
- if(Bugzilla->params->{'allowemailchange'}
- && Bugzilla->user->authorizer->can_change_email) {
- # First delete old tokens.
- Bugzilla::Token::CleanTokenTable();
-
- my @token = $dbh->selectrow_array(
- "SELECT tokentype, " .
- $dbh->sql_date_math('issuedate', '+', MAX_TOKEN_AGE, 'DAY')
- . ", eventdata
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+
+ ($vars->{'realname'})
+ = $dbh->selectrow_array("SELECT realname FROM profiles WHERE userid = ?",
+ undef, $user->id);
+
+ if ( Bugzilla->params->{'allowemailchange'}
+ && Bugzilla->user->authorizer->can_change_email)
+ {
+ # First delete old tokens.
+ Bugzilla::Token::CleanTokenTable();
+
+ my @token = $dbh->selectrow_array(
+ "SELECT tokentype, "
+ . $dbh->sql_date_math('issuedate', '+', MAX_TOKEN_AGE, 'DAY')
+ . ", eventdata
FROM tokens
WHERE userid = ?
AND tokentype LIKE 'email%'
- ORDER BY tokentype ASC " . $dbh->sql_limit(1), undef, $user->id);
- if (scalar(@token) > 0) {
- my ($tokentype, $change_date, $eventdata) = @token;
- $vars->{'login_change_date'} = $change_date;
-
- if($tokentype eq 'emailnew') {
- my ($oldemail,$newemail) = split(/:/,$eventdata);
- $vars->{'new_login_name'} = $newemail;
- }
- }
+ ORDER BY tokentype ASC " . $dbh->sql_limit(1), undef, $user->id
+ );
+ if (scalar(@token) > 0) {
+ my ($tokentype, $change_date, $eventdata) = @token;
+ $vars->{'login_change_date'} = $change_date;
+
+ if ($tokentype eq 'emailnew') {
+ my ($oldemail, $newemail) = split(/:/, $eventdata);
+ $vars->{'new_login_name'} = $newemail;
+ }
}
+ }
}
sub SaveAccount {
- my $cgi = Bugzilla->cgi;
- my $dbh = Bugzilla->dbh;
+ my $cgi = Bugzilla->cgi;
+ my $dbh = Bugzilla->dbh;
- $dbh->bz_start_transaction;
+ $dbh->bz_start_transaction;
- my $user = Bugzilla->user;
+ my $user = Bugzilla->user;
- my $oldpassword = $cgi->param('old_password');
- my $pwd1 = $cgi->param('new_password1');
- my $pwd2 = $cgi->param('new_password2');
- my $new_login_name = trim($cgi->param('new_login_name'));
- my @mfa_events;
+ my $oldpassword = $cgi->param('old_password');
+ my $pwd1 = $cgi->param('new_password1');
+ my $pwd2 = $cgi->param('new_password2');
+ my $new_login_name = trim($cgi->param('new_login_name'));
+ my @mfa_events;
- if ($user->authorizer->can_change_password
- && ($oldpassword ne "" || $pwd1 ne "" || $pwd2 ne ""))
- {
- my $oldcryptedpwd = $user->cryptpassword;
- $oldcryptedpwd || ThrowCodeError("unable_to_retrieve_password");
+ if ($user->authorizer->can_change_password
+ && ($oldpassword ne "" || $pwd1 ne "" || $pwd2 ne ""))
+ {
+ my $oldcryptedpwd = $user->cryptpassword;
+ $oldcryptedpwd || ThrowCodeError("unable_to_retrieve_password");
- if (bz_crypt($oldpassword, $oldcryptedpwd) ne $oldcryptedpwd) {
- ThrowUserError("old_password_incorrect");
- }
+ if (bz_crypt($oldpassword, $oldcryptedpwd) ne $oldcryptedpwd) {
+ ThrowUserError("old_password_incorrect");
+ }
+
+ if ($pwd1 ne "" || $pwd2 ne "") {
+ ThrowUserError("new_password_missing") unless $pwd1;
+ Bugzilla->assert_password_is_secure($pwd1);
+ Bugzilla->assert_passwords_match($pwd1, $pwd2);
- if ($pwd1 ne "" || $pwd2 ne "") {
- ThrowUserError("new_password_missing") unless $pwd1;
- Bugzilla->assert_password_is_secure($pwd1);
- Bugzilla->assert_passwords_match($pwd1, $pwd2);
-
- if ($oldpassword ne $pwd1) {
- if ($user->mfa) {
- push @mfa_events, {
- type => 'set_password',
- reason => 'changing your password',
- password => $pwd1,
- };
- }
- else {
- $user->set_password($pwd1);
- # Invalidate all logins except for the current one
- Bugzilla->logout(LOGOUT_KEEP_CURRENT);
- }
- }
+ if ($oldpassword ne $pwd1) {
+ if ($user->mfa) {
+ push @mfa_events,
+ {
+ type => 'set_password',
+ reason => 'changing your password',
+ password => $pwd1,
+ };
}
- }
+ else {
+ $user->set_password($pwd1);
- if ($user->authorizer->can_change_email
- && Bugzilla->params->{"allowemailchange"}
- && $new_login_name)
- {
- if ($user->login ne $new_login_name) {
- $oldpassword || ThrowUserError("old_password_required");
-
- # Block multiple email changes for the same user.
- if (Bugzilla::Token::HasEmailChangeToken($user->id)) {
- ThrowUserError("email_change_in_progress");
- }
-
- # Before changing an email address, confirm one does not exist.
- validate_email_syntax($new_login_name)
- || ThrowUserError('illegal_email_address', {addr => $new_login_name});
- is_available_username($new_login_name)
- || ThrowUserError("account_exists", {email => $new_login_name});
-
- if ($user->mfa) {
- push @mfa_events, {
- type => 'set_login',
- reason => 'changing your email address',
- login => $new_login_name,
- };
- }
- else {
- Bugzilla::Token::IssueEmailChangeToken($user, $new_login_name);
- $vars->{email_changes_saved} = 1;
- }
+ # Invalidate all logins except for the current one
+ Bugzilla->logout(LOGOUT_KEEP_CURRENT);
}
+ }
}
+ }
+
+ if ( $user->authorizer->can_change_email
+ && Bugzilla->params->{"allowemailchange"}
+ && $new_login_name)
+ {
+ if ($user->login ne $new_login_name) {
+ $oldpassword || ThrowUserError("old_password_required");
+
+ # Block multiple email changes for the same user.
+ if (Bugzilla::Token::HasEmailChangeToken($user->id)) {
+ ThrowUserError("email_change_in_progress");
+ }
+
+ # Before changing an email address, confirm one does not exist.
+ validate_email_syntax($new_login_name)
+ || ThrowUserError('illegal_email_address', {addr => $new_login_name});
+ is_available_username($new_login_name)
+ || ThrowUserError("account_exists", {email => $new_login_name});
+
+ if ($user->mfa) {
+ push @mfa_events,
+ {
+ type => 'set_login',
+ reason => 'changing your email address',
+ login => $new_login_name,
+ };
+ }
+ else {
+ Bugzilla::Token::IssueEmailChangeToken($user, $new_login_name);
+ $vars->{email_changes_saved} = 1;
+ }
+ }
+ }
- $user->set_name($cgi->param('realname'));
- $user->update({ keep_session => 1, keep_tokens => 1 });
- $dbh->bz_commit_transaction;
+ $user->set_name($cgi->param('realname'));
+ $user->update({keep_session => 1, keep_tokens => 1});
+ $dbh->bz_commit_transaction;
- if (@mfa_events) {
- # build the fields for the postback
- my $mfa_event = {
- postback => {
- action => 'userprefs.cgi',
- fields => {
- tab => 'account',
- },
- },
- reason => ucfirst(join(' and ', map { $_->{reason} } @mfa_events)),
- actions => \@mfa_events,
- };
- # display 2fa verification
- $user->mfa_provider->verify_prompt($mfa_event);
- }
+ if (@mfa_events) {
+
+ # build the fields for the postback
+ my $mfa_event = {
+ postback => {action => 'userprefs.cgi', fields => {tab => 'account',},},
+ reason => ucfirst(join(' and ', map { $_->{reason} } @mfa_events)),
+ actions => \@mfa_events,
+ };
+
+ # display 2fa verification
+ $user->mfa_provider->verify_prompt($mfa_event);
+ }
}
sub MfaAccount {
- my $cgi = Bugzilla->cgi;
- my $user = Bugzilla->user;
- my $dbh = Bugzilla->dbh;
- return unless $user->mfa;
+ my $cgi = Bugzilla->cgi;
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->dbh;
+ return unless $user->mfa;
- my $event = $user->mfa_provider->verify_token($cgi->param('mfa_token'));
+ my $event = $user->mfa_provider->verify_token($cgi->param('mfa_token'));
- foreach my $action (@{ $event->{actions} }) {
- if ($action->{type} eq 'set_login') {
- Bugzilla::Token::IssueEmailChangeToken($user, $action->{login});
- $vars->{email_changes_saved} = 1;
- }
+ foreach my $action (@{$event->{actions}}) {
+ if ($action->{type} eq 'set_login') {
+ Bugzilla::Token::IssueEmailChangeToken($user, $action->{login});
+ $vars->{email_changes_saved} = 1;
+ }
- elsif ($action->{type} eq 'set_password') {
- $dbh->bz_start_transaction;
- $user->set_password($action->{password});
- Bugzilla->logout(LOGOUT_KEEP_CURRENT);
- $user->update({ keep_session => 1, keep_tokens => 1 });
- $dbh->bz_commit_transaction;
- }
+ elsif ($action->{type} eq 'set_password') {
+ $dbh->bz_start_transaction;
+ $user->set_password($action->{password});
+ Bugzilla->logout(LOGOUT_KEEP_CURRENT);
+ $user->update({keep_session => 1, keep_tokens => 1});
+ $dbh->bz_commit_transaction;
}
+ }
}
sub DisableAccount {
- my $user = Bugzilla->user;
+ my $user = Bugzilla->user;
- my $new_login = 'u' . $user->id . '@disabled.tld';
+ my $new_login = 'u' . $user->id . '@disabled.tld';
- Bugzilla->audit(sprintf('<%s> self-disabled %s (now %s)', remote_ip(), $user->login, $new_login));
+ Bugzilla->audit(sprintf(
+ '<%s> self-disabled %s (now %s)',
+ remote_ip(), $user->login, $new_login
+ ));
- $user->set_login($new_login);
- $user->set_name('');
- $user->set_disabledtext('Disabled by account owner.');
- $user->set_disable_mail(1);
- $user->set_password('*');
- $user->update();
+ $user->set_login($new_login);
+ $user->set_name('');
+ $user->set_disabledtext('Disabled by account owner.');
+ $user->set_disable_mail(1);
+ $user->set_password('*');
+ $user->update();
- Bugzilla->logout();
- print Bugzilla->cgi->redirect(Bugzilla->localconfig->{urlbase});
- exit;
+ Bugzilla->logout();
+ print Bugzilla->cgi->redirect(Bugzilla->localconfig->{urlbase});
+ exit;
}
sub DoSettings {
- my $user = Bugzilla->user;
-
- my %settings;
- my $has_settings_enabled = 0;
- foreach my $name (sort keys %{ $user->settings }) {
- my $setting = $user->settings->{$name};
- next if !$setting->{is_enabled};
- my $category = $setting->{category};
- $settings{$category} ||= [];
- push(@{ $settings{$category} }, $setting);
- $has_settings_enabled = 1 if $setting->{is_enabled};
- }
-
- $vars->{settings} = \%settings;
- $vars->{has_settings_enabled} = $has_settings_enabled;
- $vars->{dont_show_button} = !$has_settings_enabled;
+ my $user = Bugzilla->user;
+
+ my %settings;
+ my $has_settings_enabled = 0;
+ foreach my $name (sort keys %{$user->settings}) {
+ my $setting = $user->settings->{$name};
+ next if !$setting->{is_enabled};
+ my $category = $setting->{category};
+ $settings{$category} ||= [];
+ push(@{$settings{$category}}, $setting);
+ $has_settings_enabled = 1 if $setting->{is_enabled};
+ }
+
+ $vars->{settings} = \%settings;
+ $vars->{has_settings_enabled} = $has_settings_enabled;
+ $vars->{dont_show_button} = !$has_settings_enabled;
}
sub SaveSettings {
- my $cgi = Bugzilla->cgi;
- my $user = Bugzilla->user;
-
- my $settings = $user->settings;
- my @setting_list = keys %$settings;
- my $mfa_event = undef;
-
- foreach my $name (@setting_list) {
- next if ! ($settings->{$name}->{'is_enabled'});
- my $value = $cgi->param($name);
- next unless defined $value;
- my $setting = new Bugzilla::User::Setting($name);
-
- if ($name eq 'api_key_only' && $user->mfa
- && ($value eq 'off'
- || ($value eq 'api_key_only-isdefault' && $setting->{default_value} eq 'off'))
- ) {
- $mfa_event = {};
- }
+ my $cgi = Bugzilla->cgi;
+ my $user = Bugzilla->user;
+
+ my $settings = $user->settings;
+ my @setting_list = keys %$settings;
+ my $mfa_event = undef;
+
+ foreach my $name (@setting_list) {
+ next if !($settings->{$name}->{'is_enabled'});
+ my $value = $cgi->param($name);
+ next unless defined $value;
+ my $setting = new Bugzilla::User::Setting($name);
+
+ if (
+ $name eq 'api_key_only'
+ && $user->mfa
+ && ($value eq 'off'
+ || ($value eq 'api_key_only-isdefault' && $setting->{default_value} eq 'off'))
+ )
+ {
+ $mfa_event = {};
+ }
- if ($value eq "${name}-isdefault" ) {
- if (! $settings->{$name}->{'is_default'}) {
- if ($mfa_event) {
- $mfa_event->{reset} = 1;
- }
- else {
- $settings->{$name}->reset_to_default;
- }
- }
+ if ($value eq "${name}-isdefault") {
+ if (!$settings->{$name}->{'is_default'}) {
+ if ($mfa_event) {
+ $mfa_event->{reset} = 1;
}
else {
- $setting->validate_value($value);
- if ($name eq 'api_key_only' && $mfa_event) {
- $mfa_event->{set} = $value;
- }
- else {
- $settings->{$name}->set($value);
- }
+ $settings->{$name}->reset_to_default;
}
+ }
}
+ else {
+ $setting->validate_value($value);
+ if ($name eq 'api_key_only' && $mfa_event) {
+ $mfa_event->{set} = $value;
+ }
+ else {
+ $settings->{$name}->set($value);
+ }
+ }
+ }
- Bugzilla::Hook::process('settings_after_update');
+ Bugzilla::Hook::process('settings_after_update');
- $vars->{'settings'} = $user->settings(1);
- clear_settings_cache($user->id);
+ $vars->{'settings'} = $user->settings(1);
+ clear_settings_cache($user->id);
- if ($mfa_event) {
- $mfa_event->{reason} = 'Disabling API key authentication requirements';
- $mfa_event->{postback} = {
- action => 'userprefs.cgi',
- fields => {
- tab => 'settings',
- },
- };
- $user->mfa_provider->verify_prompt($mfa_event);
- }
+ if ($mfa_event) {
+ $mfa_event->{reason} = 'Disabling API key authentication requirements';
+ $mfa_event->{postback}
+ = {action => 'userprefs.cgi', fields => {tab => 'settings',},};
+ $user->mfa_provider->verify_prompt($mfa_event);
+ }
}
sub MfaSettings {
- my $cgi = Bugzilla->cgi;
- my $user = Bugzilla->user;
- return unless $user->mfa;
-
- my $event = $user->mfa_provider->verify_token($cgi->param('mfa_token'));
-
- my $settings = $user->settings;
- if ($event->{reset}) {
- $settings->{api_key_only}->reset_to_default();
- }
- elsif (my $value = $event->{set}) {
- $settings->{api_key_only}->set($value);
- }
-
- $vars->{settings} = $user->settings(1);
- clear_settings_cache($user->id);
+ my $cgi = Bugzilla->cgi;
+ my $user = Bugzilla->user;
+ return unless $user->mfa;
+
+ my $event = $user->mfa_provider->verify_token($cgi->param('mfa_token'));
+
+ my $settings = $user->settings;
+ if ($event->{reset}) {
+ $settings->{api_key_only}->reset_to_default();
+ }
+ elsif (my $value = $event->{set}) {
+ $settings->{api_key_only}->set($value);
+ }
+
+ $vars->{settings} = $user->settings(1);
+ clear_settings_cache($user->id);
}
sub DoEmail {
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
-
- ###########################################################################
- # User watching
- ###########################################################################
- my $watched_ref = $dbh->selectcol_arrayref(
- "SELECT profiles.login_name FROM watch INNER JOIN profiles" .
- " ON watch.watched = profiles.userid" .
- " WHERE watcher = ?" .
- " ORDER BY profiles.login_name",
- undef, $user->id);
- $vars->{'watchedusers'} = $watched_ref;
-
- my $watcher_ids = $dbh->selectcol_arrayref(
- "SELECT watcher FROM watch WHERE watched = ?",
- undef, $user->id);
-
- my @watchers;
- foreach my $watcher_id (@$watcher_ids) {
- my $watcher = new Bugzilla::User($watcher_id);
- push(@watchers, Bugzilla::User::identity($watcher));
- }
-
- @watchers = sort { lc($a) cmp lc($b) } @watchers;
- $vars->{'watchers'} = \@watchers;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+
+ ###########################################################################
+ # User watching
+ ###########################################################################
+ my $watched_ref = $dbh->selectcol_arrayref(
+ "SELECT profiles.login_name FROM watch INNER JOIN profiles"
+ . " ON watch.watched = profiles.userid"
+ . " WHERE watcher = ?"
+ . " ORDER BY profiles.login_name",
+ undef, $user->id
+ );
+ $vars->{'watchedusers'} = $watched_ref;
+
+ my $watcher_ids
+ = $dbh->selectcol_arrayref("SELECT watcher FROM watch WHERE watched = ?",
+ undef, $user->id);
+
+ my @watchers;
+ foreach my $watcher_id (@$watcher_ids) {
+ my $watcher = new Bugzilla::User($watcher_id);
+ push(@watchers, Bugzilla::User::identity($watcher));
+ }
+
+ @watchers = sort { lc($a) cmp lc($b) } @watchers;
+ $vars->{'watchers'} = \@watchers;
}
sub SaveEmail {
- my $dbh = Bugzilla->dbh;
- my $cgi = Bugzilla->cgi;
- my $user = Bugzilla->user;
-
- Bugzilla::User::match_field({ 'new_watchedusers' => {'type' => 'multi'} });
-
- ###########################################################################
- # Role-based preferences
- ###########################################################################
- $dbh->bz_start_transaction();
-
- my $sth_insert = $dbh->prepare('INSERT INTO email_setting
- (user_id, relationship, event) VALUES (?, ?, ?)');
-
- my $sth_delete = $dbh->prepare('DELETE FROM email_setting
- WHERE user_id = ? AND relationship = ? AND event = ?');
- # Load current email preferences into memory before updating them.
- my $settings = $user->mail_settings;
-
- # Update the table - first, with normal events in the
- # relationship/event matrix.
- my %relationships = Bugzilla::BugMail::relationships();
- foreach my $rel (keys %relationships) {
- next if ($rel == REL_QA && !Bugzilla->params->{'useqacontact'});
- # Positive events: a ticked box means "send me mail."
- foreach my $event (POS_EVENTS) {
- my $is_set = $cgi->param("email-$rel-$event");
- if ($is_set xor $settings->{$rel}{$event}) {
- if ($is_set) {
- $sth_insert->execute($user->id, $rel, $event);
- }
- else {
- $sth_delete->execute($user->id, $rel, $event);
- }
- }
+ my $dbh = Bugzilla->dbh;
+ my $cgi = Bugzilla->cgi;
+ my $user = Bugzilla->user;
+
+ Bugzilla::User::match_field({'new_watchedusers' => {'type' => 'multi'}});
+
+ ###########################################################################
+ # Role-based preferences
+ ###########################################################################
+ $dbh->bz_start_transaction();
+
+ my $sth_insert = $dbh->prepare(
+ 'INSERT INTO email_setting
+ (user_id, relationship, event) VALUES (?, ?, ?)'
+ );
+
+ my $sth_delete = $dbh->prepare(
+ 'DELETE FROM email_setting
+ WHERE user_id = ? AND relationship = ? AND event = ?'
+ );
+
+ # Load current email preferences into memory before updating them.
+ my $settings = $user->mail_settings;
+
+ # Update the table - first, with normal events in the
+ # relationship/event matrix.
+ my %relationships = Bugzilla::BugMail::relationships();
+ foreach my $rel (keys %relationships) {
+ next if ($rel == REL_QA && !Bugzilla->params->{'useqacontact'});
+
+ # Positive events: a ticked box means "send me mail."
+ foreach my $event (POS_EVENTS) {
+ my $is_set = $cgi->param("email-$rel-$event");
+ if ($is_set xor $settings->{$rel}{$event}) {
+ if ($is_set) {
+ $sth_insert->execute($user->id, $rel, $event);
}
-
- # Negative events: a ticked box means "don't send me mail."
- foreach my $event (NEG_EVENTS) {
- my $is_set = $cgi->param("neg-email-$rel-$event");
- if (!$is_set xor $settings->{$rel}{$event}) {
- if (!$is_set) {
- $sth_insert->execute($user->id, $rel, $event);
- }
- else {
- $sth_delete->execute($user->id, $rel, $event);
- }
- }
+ else {
+ $sth_delete->execute($user->id, $rel, $event);
}
+ }
}
- # Global positive events: a ticked box means "send me mail."
- foreach my $event (GLOBAL_EVENTS) {
- my $is_set = $cgi->param("email-" . REL_ANY . "-$event");
- if ($is_set xor $settings->{+REL_ANY}{$event}) {
- if ($is_set) {
- $sth_insert->execute($user->id, REL_ANY, $event);
- }
- else {
- $sth_delete->execute($user->id, REL_ANY, $event);
- }
+ # Negative events: a ticked box means "don't send me mail."
+ foreach my $event (NEG_EVENTS) {
+ my $is_set = $cgi->param("neg-email-$rel-$event");
+ if (!$is_set xor $settings->{$rel}{$event}) {
+ if (!$is_set) {
+ $sth_insert->execute($user->id, $rel, $event);
}
+ else {
+ $sth_delete->execute($user->id, $rel, $event);
+ }
+ }
}
+ }
+
+ # Global positive events: a ticked box means "send me mail."
+ foreach my $event (GLOBAL_EVENTS) {
+ my $is_set = $cgi->param("email-" . REL_ANY . "-$event");
+ if ($is_set xor $settings->{+REL_ANY}{$event}) {
+ if ($is_set) {
+ $sth_insert->execute($user->id, REL_ANY, $event);
+ }
+ else {
+ $sth_delete->execute($user->id, REL_ANY, $event);
+ }
+ }
+ }
- $dbh->bz_commit_transaction();
-
- # We have to clear the cache about email preferences.
- delete $user->{'mail_settings'};
-
- ###########################################################################
- # User watching
- ###########################################################################
- if (defined $cgi->param('new_watchedusers')
- || defined $cgi->param('remove_watched_users'))
- {
- $dbh->bz_start_transaction();
-
- # Use this to protect error messages on duplicate submissions
- my $old_watch_ids =
- $dbh->selectcol_arrayref("SELECT watched FROM watch"
- . " WHERE watcher = ?", undef, $user->id);
+ $dbh->bz_commit_transaction();
- # The new information given to us by the user.
- my $new_watched_users = join(',', $cgi->param('new_watchedusers')) || '';
- my @new_watch_names = split(/[,\s]+/, $new_watched_users);
- my %new_watch_ids;
+ # We have to clear the cache about email preferences.
+ delete $user->{'mail_settings'};
- foreach my $username (@new_watch_names) {
- my $watched_userid = login_to_id(trim($username), THROW_ERROR);
- $new_watch_ids{$watched_userid} = 1;
- }
+ ###########################################################################
+ # User watching
+ ###########################################################################
+ if ( defined $cgi->param('new_watchedusers')
+ || defined $cgi->param('remove_watched_users'))
+ {
+ $dbh->bz_start_transaction();
- # Add people who were added.
- my $insert_sth = $dbh->prepare('INSERT INTO watch (watched, watcher)'
- . ' VALUES (?, ?)');
- foreach my $add_me (keys(%new_watch_ids)) {
- next if grep($_ == $add_me, @$old_watch_ids);
- $insert_sth->execute($add_me, $user->id);
- }
+ # Use this to protect error messages on duplicate submissions
+ my $old_watch_ids
+ = $dbh->selectcol_arrayref("SELECT watched FROM watch" . " WHERE watcher = ?",
+ undef, $user->id);
- if (defined $cgi->param('remove_watched_users')) {
- my @removed = $cgi->param('watched_by_you');
- # Remove people who were removed.
- my $delete_sth = $dbh->prepare('DELETE FROM watch WHERE watched = ?'
- . ' AND watcher = ?');
-
- my %remove_watch_ids;
- foreach my $username (@removed) {
- my $watched_userid = login_to_id(trim($username), THROW_ERROR);
- $remove_watch_ids{$watched_userid} = 1;
- }
- foreach my $remove_me (keys(%remove_watch_ids)) {
- $delete_sth->execute($remove_me, $user->id);
- }
- }
+ # The new information given to us by the user.
+ my $new_watched_users = join(',', $cgi->param('new_watchedusers')) || '';
+ my @new_watch_names = split(/[,\s]+/, $new_watched_users);
+ my %new_watch_ids;
- $dbh->bz_commit_transaction();
+ foreach my $username (@new_watch_names) {
+ my $watched_userid = login_to_id(trim($username), THROW_ERROR);
+ $new_watch_ids{$watched_userid} = 1;
}
- ###########################################################################
- # Ignore Bugs
- ###########################################################################
- my %ignored_bugs = map { $_->{'id'} => 1 } @{$user->bugs_ignored};
-
- # Validate the new bugs to ignore by checking that they exist and also
- # if the user gave an alias
- my @add_ignored = split(/[\s,]+/, $cgi->param('add_ignored_bugs'));
- @add_ignored = map { Bugzilla::Bug->check($_)->id } @add_ignored;
- map { $ignored_bugs{$_} = 1 } @add_ignored;
-
- # Remove any bug ids the user no longer wants to ignore
- foreach my $key (grep(/^remove_ignored_bug_/, $cgi->param)) {
- my ($bug_id) = $key =~ /(\d+)$/;
- delete $ignored_bugs{$bug_id};
+ # Add people who were added.
+ my $insert_sth
+ = $dbh->prepare('INSERT INTO watch (watched, watcher)' . ' VALUES (?, ?)');
+ foreach my $add_me (keys(%new_watch_ids)) {
+ next if grep($_ == $add_me, @$old_watch_ids);
+ $insert_sth->execute($add_me, $user->id);
}
- # Update the database with any changes made
- my ($removed, $added) = diff_arrays([ map { $_->{'id'} } @{$user->bugs_ignored} ],
- [ keys %ignored_bugs ]);
+ if (defined $cgi->param('remove_watched_users')) {
+ my @removed = $cgi->param('watched_by_you');
+
+ # Remove people who were removed.
+ my $delete_sth
+ = $dbh->prepare('DELETE FROM watch WHERE watched = ?' . ' AND watcher = ?');
+
+ my %remove_watch_ids;
+ foreach my $username (@removed) {
+ my $watched_userid = login_to_id(trim($username), THROW_ERROR);
+ $remove_watch_ids{$watched_userid} = 1;
+ }
+ foreach my $remove_me (keys(%remove_watch_ids)) {
+ $delete_sth->execute($remove_me, $user->id);
+ }
+ }
- if (scalar @$removed || scalar @$added) {
- $dbh->bz_start_transaction();
+ $dbh->bz_commit_transaction();
+ }
+
+ ###########################################################################
+ # Ignore Bugs
+ ###########################################################################
+ my %ignored_bugs = map { $_->{'id'} => 1 } @{$user->bugs_ignored};
+
+ # Validate the new bugs to ignore by checking that they exist and also
+ # if the user gave an alias
+ my @add_ignored = split(/[\s,]+/, $cgi->param('add_ignored_bugs'));
+ @add_ignored = map { Bugzilla::Bug->check($_)->id } @add_ignored;
+ map { $ignored_bugs{$_} = 1 } @add_ignored;
+
+ # Remove any bug ids the user no longer wants to ignore
+ foreach my $key (grep(/^remove_ignored_bug_/, $cgi->param)) {
+ my ($bug_id) = $key =~ /(\d+)$/;
+ delete $ignored_bugs{$bug_id};
+ }
+
+ # Update the database with any changes made
+ my ($removed, $added)
+ = diff_arrays([map { $_->{'id'} } @{$user->bugs_ignored}],
+ [keys %ignored_bugs]);
+
+ if (scalar @$removed || scalar @$added) {
+ $dbh->bz_start_transaction();
- if (scalar @$removed) {
- $dbh->do('DELETE FROM email_bug_ignore WHERE user_id = ? AND ' .
- $dbh->sql_in('bug_id', $removed),
- undef, $user->id);
- }
- if (scalar @$added) {
- my $sth = $dbh->prepare('INSERT INTO email_bug_ignore
- (user_id, bug_id) VALUES (?, ?)');
- $sth->execute($user->id, $_) foreach @$added;
- }
+ if (scalar @$removed) {
+ $dbh->do(
+ 'DELETE FROM email_bug_ignore WHERE user_id = ? AND '
+ . $dbh->sql_in('bug_id', $removed),
+ undef, $user->id
+ );
+ }
+ if (scalar @$added) {
+ my $sth = $dbh->prepare(
+ 'INSERT INTO email_bug_ignore
+ (user_id, bug_id) VALUES (?, ?)'
+ );
+ $sth->execute($user->id, $_) foreach @$added;
+ }
- # Reset the cache of ignored bugs if the list changed.
- delete $user->{bugs_ignored};
+ # Reset the cache of ignored bugs if the list changed.
+ delete $user->{bugs_ignored};
- $dbh->bz_commit_transaction();
- }
+ $dbh->bz_commit_transaction();
+ }
}
sub DoPermissions {
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
- my (@has_bits, @set_bits);
-
- my $groups = $dbh->selectall_arrayref(
- "SELECT DISTINCT name, description FROM groups WHERE id IN (" .
- $user->groups_as_string . ") ORDER BY name");
- foreach my $group (@$groups) {
- my ($nam, $desc) = @$group;
- push(@has_bits, {"desc" => $desc, "name" => $nam});
- }
- $groups = $dbh->selectall_arrayref('SELECT DISTINCT id, name, description
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+ my (@has_bits, @set_bits);
+
+ my $groups
+ = $dbh->selectall_arrayref(
+ "SELECT DISTINCT name, description FROM groups WHERE id IN ("
+ . $user->groups_as_string
+ . ") ORDER BY name");
+ foreach my $group (@$groups) {
+ my ($nam, $desc) = @$group;
+ push(@has_bits, {"desc" => $desc, "name" => $nam});
+ }
+ $groups = $dbh->selectall_arrayref(
+ 'SELECT DISTINCT id, name, description
FROM groups
- ORDER BY name');
- foreach my $group (@$groups) {
- my ($group_id, $nam, $desc) = @$group;
- if ($user->can_bless($group_id)) {
- push(@set_bits, {"desc" => $desc, "name" => $nam});
- }
+ ORDER BY name'
+ );
+ foreach my $group (@$groups) {
+ my ($group_id, $nam, $desc) = @$group;
+ if ($user->can_bless($group_id)) {
+ push(@set_bits, {"desc" => $desc, "name" => $nam});
}
+ }
- # If the user has product specific privileges, inform him about that.
- foreach my $privs (PER_PRODUCT_PRIVILEGES) {
- next if $user->in_group($privs);
- $vars->{"local_$privs"} = $user->get_products_by_permission($privs);
- }
+ # If the user has product specific privileges, inform him about that.
+ foreach my $privs (PER_PRODUCT_PRIVILEGES) {
+ next if $user->in_group($privs);
+ $vars->{"local_$privs"} = $user->get_products_by_permission($privs);
+ }
- $vars->{'has_bits'} = \@has_bits;
- $vars->{'set_bits'} = \@set_bits;
+ $vars->{'has_bits'} = \@has_bits;
+ $vars->{'set_bits'} = \@set_bits;
}
# No SavePermissions() because this panel has no changeable fields.
sub DoSavedSearches {
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
-
- if ($user->queryshare_groups_as_string) {
- $vars->{'queryshare_groups'} =
- Bugzilla::Group->new_from_list($user->queryshare_groups);
- }
- $vars->{'bless_group_ids'} = [map { $_->id } @{$user->bless_groups}];
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+
+ if ($user->queryshare_groups_as_string) {
+ $vars->{'queryshare_groups'}
+ = Bugzilla::Group->new_from_list($user->queryshare_groups);
+ }
+ $vars->{'bless_group_ids'} = [map { $_->id } @{$user->bless_groups}];
}
sub SaveSavedSearches {
- my $cgi = Bugzilla->cgi;
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
+ my $cgi = Bugzilla->cgi;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
- # We'll need this in a loop, so do the call once.
- my $user_id = $user->id;
+ # We'll need this in a loop, so do the call once.
+ my $user_id = $user->id;
- my $sth_insert_nl = $dbh->prepare('INSERT INTO namedqueries_link_in_footer
+ my $sth_insert_nl = $dbh->prepare(
+ 'INSERT INTO namedqueries_link_in_footer
(namedquery_id, user_id)
- VALUES (?, ?)');
- my $sth_delete_nl = $dbh->prepare('DELETE FROM namedqueries_link_in_footer
+ VALUES (?, ?)'
+ );
+ my $sth_delete_nl = $dbh->prepare(
+ 'DELETE FROM namedqueries_link_in_footer
WHERE namedquery_id = ?
- AND user_id = ?');
- my $sth_insert_ngm = $dbh->prepare('INSERT INTO namedquery_group_map
+ AND user_id = ?'
+ );
+ my $sth_insert_ngm = $dbh->prepare(
+ 'INSERT INTO namedquery_group_map
(namedquery_id, group_id)
- VALUES (?, ?)');
- my $sth_update_ngm = $dbh->prepare('UPDATE namedquery_group_map
+ VALUES (?, ?)'
+ );
+ my $sth_update_ngm = $dbh->prepare(
+ 'UPDATE namedquery_group_map
SET group_id = ?
- WHERE namedquery_id = ?');
- my $sth_delete_ngm = $dbh->prepare('DELETE FROM namedquery_group_map
- WHERE namedquery_id = ?');
-
- # Update namedqueries_link_in_footer for this user.
- foreach my $q (@{$user->queries}, @{$user->queries_available}) {
- if (defined $cgi->param("link_in_footer_" . $q->id)) {
- $sth_insert_nl->execute($q->id, $user_id) if !$q->link_in_footer;
- }
- else {
- $sth_delete_nl->execute($q->id, $user_id) if $q->link_in_footer;
- }
+ WHERE namedquery_id = ?'
+ );
+ my $sth_delete_ngm = $dbh->prepare(
+ 'DELETE FROM namedquery_group_map
+ WHERE namedquery_id = ?'
+ );
+
+ # Update namedqueries_link_in_footer for this user.
+ foreach my $q (@{$user->queries}, @{$user->queries_available}) {
+ if (defined $cgi->param("link_in_footer_" . $q->id)) {
+ $sth_insert_nl->execute($q->id, $user_id) if !$q->link_in_footer;
}
+ else {
+ $sth_delete_nl->execute($q->id, $user_id) if $q->link_in_footer;
+ }
+ }
- # For user's own queries, update namedquery_group_map.
- foreach my $q (@{$user->queries}) {
- my $group_id;
+ # For user's own queries, update namedquery_group_map.
+ foreach my $q (@{$user->queries}) {
+ my $group_id;
- if ($user->in_group(Bugzilla->params->{'querysharegroup'})) {
- $group_id = $cgi->param("share_" . $q->id) || '';
- }
+ if ($user->in_group(Bugzilla->params->{'querysharegroup'})) {
+ $group_id = $cgi->param("share_" . $q->id) || '';
+ }
- if ($group_id) {
- # Don't allow the user to share queries with groups he's not
- # allowed to.
- next unless grep($_ eq $group_id, @{$user->queryshare_groups});
-
- # $group_id is now definitely a valid ID of a group the
- # user can share queries with, so we can trick_taint.
- detaint_natural($group_id);
- if ($q->shared_with_group) {
- $sth_update_ngm->execute($group_id, $q->id);
- }
- else {
- $sth_insert_ngm->execute($q->id, $group_id);
- }
-
- # If we're sharing our query with a group we can bless, we
- # have the ability to add link to our search to the footer of
- # direct group members automatically.
- if ($user->can_bless($group_id) && $cgi->param('force_' . $q->id)) {
- my $group = new Bugzilla::Group($group_id);
- my $members = $group->members_non_inherited;
- foreach my $member (@$members) {
- next if $member->id == $user->id;
- $sth_insert_nl->execute($q->id, $member->id)
- if !$q->link_in_footer($member);
- }
- }
- }
- else {
- # They have unshared that query.
- if ($q->shared_with_group) {
- $sth_delete_ngm->execute($q->id);
- }
-
- # Don't remove namedqueries_link_in_footer entries for users
- # subscribing to the shared query. The idea is that they will
- # probably want to be subscribers again should the sharing
- # user choose to share the query again.
+ if ($group_id) {
+
+ # Don't allow the user to share queries with groups he's not
+ # allowed to.
+ next unless grep($_ eq $group_id, @{$user->queryshare_groups});
+
+ # $group_id is now definitely a valid ID of a group the
+ # user can share queries with, so we can trick_taint.
+ detaint_natural($group_id);
+ if ($q->shared_with_group) {
+ $sth_update_ngm->execute($group_id, $q->id);
+ }
+ else {
+ $sth_insert_ngm->execute($q->id, $group_id);
+ }
+
+ # If we're sharing our query with a group we can bless, we
+ # have the ability to add link to our search to the footer of
+ # direct group members automatically.
+ if ($user->can_bless($group_id) && $cgi->param('force_' . $q->id)) {
+ my $group = new Bugzilla::Group($group_id);
+ my $members = $group->members_non_inherited;
+ foreach my $member (@$members) {
+ next if $member->id == $user->id;
+ $sth_insert_nl->execute($q->id, $member->id) if !$q->link_in_footer($member);
}
+ }
+ }
+ else {
+ # They have unshared that query.
+ if ($q->shared_with_group) {
+ $sth_delete_ngm->execute($q->id);
+ }
+
+ # Don't remove namedqueries_link_in_footer entries for users
+ # subscribing to the shared query. The idea is that they will
+ # probably want to be subscribers again should the sharing
+ # user choose to share the query again.
}
+ }
- $user->flush_queries_cache;
+ $user->flush_queries_cache;
- # Update profiles.mybugslink.
- my $showmybugslink = defined($cgi->param("showmybugslink")) ? 1 : 0;
- $dbh->do("UPDATE profiles SET mybugslink = ? WHERE userid = ?",
- undef, ($showmybugslink, $user->id));
- $user->{'showmybugslink'} = $showmybugslink;
- Bugzilla->memcached->clear({ table => 'profiles', id => $user->id });
+ # Update profiles.mybugslink.
+ my $showmybugslink = defined($cgi->param("showmybugslink")) ? 1 : 0;
+ $dbh->do("UPDATE profiles SET mybugslink = ? WHERE userid = ?",
+ undef, ($showmybugslink, $user->id));
+ $user->{'showmybugslink'} = $showmybugslink;
+ Bugzilla->memcached->clear({table => 'profiles', id => $user->id});
}
sub SaveMFA {
- my $cgi = Bugzilla->cgi;
- my $user = Bugzilla->user;
- my $action = $cgi->param('mfa_action') // '';
- my $params = Bugzilla->input_params;
-
- my $crypt_password = $user->cryptpassword;
- if (bz_crypt(delete $params->{password}, $crypt_password) ne $crypt_password) {
- ThrowUserError('password_incorrect');
- }
+ my $cgi = Bugzilla->cgi;
+ my $user = Bugzilla->user;
+ my $action = $cgi->param('mfa_action') // '';
+ my $params = Bugzilla->input_params;
+
+ my $crypt_password = $user->cryptpassword;
+ if (bz_crypt(delete $params->{password}, $crypt_password) ne $crypt_password) {
+ ThrowUserError('password_incorrect');
+ }
+
+ my $mfa = $cgi->param('mfa') // $user->mfa;
+ my $provider = Bugzilla::MFA->new_from($user, $mfa) // return;
+
+ my $reason;
+ if ($action eq 'enable') {
+ $provider->enroll(Bugzilla->input_params);
+ $reason = 'Two-factor enrollment';
+ }
+ elsif ($action eq 'recovery') {
+ $reason = 'Recovery code generation';
+ }
+ elsif ($action eq 'disable') {
+ $reason = 'Disabling two-factor authentication';
+ }
+
+ if ($provider->can_verify_inline) {
+ $provider->verify_check($params);
+ SaveMFAupdate($cgi->param('mfa_action'), $mfa);
+ }
+ else {
+ my $mfa_event = {
+ postback =>
+ {action => 'userprefs.cgi', fields => {tab => 'mfa', mfa => $mfa,},},
+ reason => $reason,
+ action => $action,
+ };
+ $provider->verify_prompt($mfa_event);
+ }
+}
- my $mfa = $cgi->param('mfa') // $user->mfa;
- my $provider = Bugzilla::MFA->new_from($user, $mfa) // return;
+sub SaveMFAupdate {
+ my ($action, $mfa) = @_;
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->dbh;
+ $action //= '';
- my $reason;
- if ($action eq 'enable') {
- $provider->enroll(Bugzilla->input_params);
- $reason = 'Two-factor enrollment';
- }
- elsif ($action eq 'recovery') {
- $reason = 'Recovery code generation';
- }
- elsif ($action eq 'disable') {
- $reason = 'Disabling two-factor authentication';
- }
+ if ($action eq 'enable') {
+ $dbh->bz_start_transaction;
- if ($provider->can_verify_inline) {
- $provider->verify_check($params);
- SaveMFAupdate($cgi->param('mfa_action'), $mfa);
- }
- else {
- my $mfa_event = {
- postback => {
- action => 'userprefs.cgi',
- fields => {
- tab => 'mfa',
- mfa => $mfa,
- },
- },
- reason => $reason,
- action => $action,
- };
- $provider->verify_prompt($mfa_event);
- }
-}
+ $user->set_mfa($mfa);
+ $user->mfa_provider->enrolled();
+ Bugzilla->request_cache->{mfa_warning} = 0;
+ my $settings = Bugzilla->user->settings;
+ $settings->{api_key_only}->set('on');
+ clear_settings_cache(Bugzilla->user->id);
-sub SaveMFAupdate {
- my ($action, $mfa) = @_;
- my $user = Bugzilla->user;
- my $dbh = Bugzilla->dbh;
- $action //= '';
-
- if ($action eq 'enable') {
- $dbh->bz_start_transaction;
-
- $user->set_mfa($mfa);
- $user->mfa_provider->enrolled();
- Bugzilla->request_cache->{mfa_warning} = 0;
- my $settings = Bugzilla->user->settings;
- $settings->{api_key_only}->set('on');
- clear_settings_cache(Bugzilla->user->id);
-
- $user->update({ keep_session => 1, keep_tokens => 1 });
- $dbh->bz_commit_transaction;
- }
+ $user->update({keep_session => 1, keep_tokens => 1});
+ $dbh->bz_commit_transaction;
+ }
- elsif ($action eq 'recovery') {
- my $codes = $user->mfa_provider->generate_recovery_codes();
- my $token = issue_short_lived_session_token('mfa-recovery');
- set_token_extra_data($token, $codes);
- $vars->{mfa_recovery_token} = $token;
+ elsif ($action eq 'recovery') {
+ my $codes = $user->mfa_provider->generate_recovery_codes();
+ my $token = issue_short_lived_session_token('mfa-recovery');
+ set_token_extra_data($token, $codes);
+ $vars->{mfa_recovery_token} = $token;
- }
+ }
- elsif ($action eq 'disable') {
- $user->set_mfa('');
- $user->update({ keep_session => 1, keep_tokens => 1 });
+ elsif ($action eq 'disable') {
+ $user->set_mfa('');
+ $user->update({keep_session => 1, keep_tokens => 1});
- }
+ }
}
sub SaveMFAcallback {
- my $cgi = Bugzilla->cgi;
- my $user = Bugzilla->user;
+ my $cgi = Bugzilla->cgi;
+ my $user = Bugzilla->user;
- my $mfa = $cgi->param('mfa');
- my $provider = Bugzilla::MFA->new_from($user, $mfa) // return;
- my $event = $provider->verify_token($cgi->param('mfa_token'));
+ my $mfa = $cgi->param('mfa');
+ my $provider = Bugzilla::MFA->new_from($user, $mfa) // return;
+ my $event = $provider->verify_token($cgi->param('mfa_token'));
- SaveMFAupdate($event->{action}, $mfa);
+ SaveMFAupdate($event->{action}, $mfa);
}
sub DoMFA {
- my $cgi = Bugzilla->cgi;
- return unless my $provider = $cgi->param('frame');
-
- print $cgi->header(
- -Cache_Control => 'no-cache, no-store, must-revalidate',
- -Expires => 'Thu, 01 Dec 1994 16:00:00 GMT',
- -Pragma => 'no-cache',
- );
- if ($provider eq 'recovery') {
- my $token = $cgi->param('t');
- $vars->{codes} = get_token_extra_data($token);
- delete_token($token);
- $template->process("mfa/recovery.html.tmpl", $vars)
- || ThrowTemplateError($template->error());
- }
- elsif ($provider =~ /^[a-z]+$/) {
- trick_taint($provider);
- $template->process("mfa/$provider/enroll.html.tmpl", $vars)
- || ThrowTemplateError($template->error());
- }
- exit;
+ my $cgi = Bugzilla->cgi;
+ return unless my $provider = $cgi->param('frame');
+
+ print $cgi->header(
+ -Cache_Control => 'no-cache, no-store, must-revalidate',
+ -Expires => 'Thu, 01 Dec 1994 16:00:00 GMT',
+ -Pragma => 'no-cache',
+ );
+ if ($provider eq 'recovery') {
+ my $token = $cgi->param('t');
+ $vars->{codes} = get_token_extra_data($token);
+ delete_token($token);
+ $template->process("mfa/recovery.html.tmpl", $vars)
+ || ThrowTemplateError($template->error());
+ }
+ elsif ($provider =~ /^[a-z]+$/) {
+ trick_taint($provider);
+ $template->process("mfa/$provider/enroll.html.tmpl", $vars)
+ || ThrowTemplateError($template->error());
+ }
+ exit;
}
sub SaveSessions {
- my $cgi = Bugzilla->cgi;
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
-
- # Do it in a transaction.
- $dbh->bz_start_transaction;
- if ($cgi->param("session_logout_all")) {
- my $info_getter = $user->authorizer && $user->authorizer->successful_info_getter();
- if ($info_getter->cookie) {
- $dbh->do("DELETE FROM logincookies WHERE userid = ? AND cookie != ?", undef,
- $user->id, $info_getter->cookie);
- }
+ my $cgi = Bugzilla->cgi;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+
+ # Do it in a transaction.
+ $dbh->bz_start_transaction;
+ if ($cgi->param("session_logout_all")) {
+ my $info_getter
+ = $user->authorizer && $user->authorizer->successful_info_getter();
+ if ($info_getter->cookie) {
+ $dbh->do("DELETE FROM logincookies WHERE userid = ? AND cookie != ?",
+ undef, $user->id, $info_getter->cookie);
}
- else {
- my @logout_ids = $cgi->param('session_logout_id');
- my $sessions = Bugzilla::User::Session->new_from_list(\@logout_ids);
- foreach my $session (@$sessions) {
- $session->remove_from_db if $session->userid == $user->id;
- }
+ }
+ else {
+ my @logout_ids = $cgi->param('session_logout_id');
+ my $sessions = Bugzilla::User::Session->new_from_list(\@logout_ids);
+ foreach my $session (@$sessions) {
+ $session->remove_from_db if $session->userid == $user->id;
}
+ }
- $dbh->bz_commit_transaction;
+ $dbh->bz_commit_transaction;
}
sub DoSessions {
- my $user = Bugzilla->user;
- my $dbh = Bugzilla->dbh;
- my $sessions = Bugzilla::User::Session->match({ userid => $user->id, LIMIT => SESSION_MAX + 1 });
- my $info_getter = $user->authorizer && $user->authorizer->successful_info_getter();
-
- if ($info_getter && $info_getter->can('cookie')) {
- foreach my $session (@$sessions) {
- $session->{current} = $info_getter->cookie eq $session->{cookie};
- }
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->dbh;
+ my $sessions = Bugzilla::User::Session->match(
+ {userid => $user->id, LIMIT => SESSION_MAX + 1});
+ my $info_getter
+ = $user->authorizer && $user->authorizer->successful_info_getter();
+
+ if ($info_getter && $info_getter->can('cookie')) {
+ foreach my $session (@$sessions) {
+ $session->{current} = $info_getter->cookie eq $session->{cookie};
}
- my ($count) = $dbh->selectrow_array("SELECT count(*) FROM logincookies WHERE userid = ?", undef,
- $user->id);
-
- $vars->{too_many_sessions} = @$sessions == SESSION_MAX + 1;
- $vars->{sessions} = $sessions;
- $vars->{session_count} = $count;
- $vars->{session_max} = SESSION_MAX;
- pop @$sessions if $vars->{too_many_sessions};
+ }
+ my ($count)
+ = $dbh->selectrow_array("SELECT count(*) FROM logincookies WHERE userid = ?",
+ undef, $user->id);
+
+ $vars->{too_many_sessions} = @$sessions == SESSION_MAX + 1;
+ $vars->{sessions} = $sessions;
+ $vars->{session_count} = $count;
+ $vars->{session_max} = SESSION_MAX;
+ pop @$sessions if $vars->{too_many_sessions};
}
sub DoApiKey {
- my $user = Bugzilla->user;
+ my $user = Bugzilla->user;
- my $api_keys = Bugzilla::User::APIKey->match({ user_id => $user->id });
- $vars->{api_keys} = $api_keys;
- $vars->{any_revoked} = grep { $_->revoked } @$api_keys;
+ my $api_keys = Bugzilla::User::APIKey->match({user_id => $user->id});
+ $vars->{api_keys} = $api_keys;
+ $vars->{any_revoked} = grep { $_->revoked } @$api_keys;
}
sub SaveApiKey {
- my $cgi = Bugzilla->cgi;
- my $dbh = Bugzilla->dbh;
- my $user = Bugzilla->user;
- my @mfa_events;
-
- # Do it in a transaction.
- $dbh->bz_start_transaction;
-
- # Update any existing keys
- my $api_keys = Bugzilla::User::APIKey->match({ user_id => $user->id });
- foreach my $api_key (@$api_keys) {
- my $description = $cgi->param('description_' . $api_key->id);
- my $revoked = !!$cgi->param('revoked_' . $api_key->id);
-
- if ($description ne $api_key->description || $revoked != $api_key->revoked) {
- if ($user->mfa && !$revoked && $api_key->revoked) {
- push @mfa_events, {
- type => 'update',
- reason => 'enabling an API key',
- id => $api_key->id,
- description => $description,
- };
- }
- else {
- $api_key->set_all({
- description => $description,
- revoked => $revoked,
- });
- $api_key->update();
- if ($revoked) {
- Bugzilla->log_user_request(undef, undef, 'api-key-revoke')
- }
- else {
- Bugzilla->log_user_request(undef, undef, 'api-key-unrevoke')
- }
- }
- }
- }
-
- # Create a new API key if requested.
- if ($cgi->param('new_key')) {
- my $description = $cgi->param('new_description');
- if ($user->mfa) {
- push @mfa_events, {
- type => 'create',
- reason => 'creating an API key',
- description => $description,
- };
+ my $cgi = Bugzilla->cgi;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+ my @mfa_events;
+
+ # Do it in a transaction.
+ $dbh->bz_start_transaction;
+
+ # Update any existing keys
+ my $api_keys = Bugzilla::User::APIKey->match({user_id => $user->id});
+ foreach my $api_key (@$api_keys) {
+ my $description = $cgi->param('description_' . $api_key->id);
+ my $revoked = !!$cgi->param('revoked_' . $api_key->id);
+
+ if ($description ne $api_key->description || $revoked != $api_key->revoked) {
+ if ($user->mfa && !$revoked && $api_key->revoked) {
+ push @mfa_events,
+ {
+ type => 'update',
+ reason => 'enabling an API key',
+ id => $api_key->id,
+ description => $description,
+ };
+ }
+ else {
+ $api_key->set_all({description => $description, revoked => $revoked,});
+ $api_key->update();
+ if ($revoked) {
+ Bugzilla->log_user_request(undef, undef, 'api-key-revoke');
}
else {
- $vars->{new_key} = _create_api_key($description);
+ Bugzilla->log_user_request(undef, undef, 'api-key-unrevoke');
}
+ }
}
-
- $dbh->bz_commit_transaction;
-
- if (@mfa_events) {
- # build the fields for the postback
- my $mfa_event = {
- postback => {
- action => 'userprefs.cgi',
- fields => {
- tab => 'apikey',
- },
- },
- reason => ucfirst(join(' and ', map { $_->{reason} } @mfa_events)),
- actions => \@mfa_events,
+ }
+
+ # Create a new API key if requested.
+ if ($cgi->param('new_key')) {
+ my $description = $cgi->param('new_description');
+ if ($user->mfa) {
+ push @mfa_events,
+ {
+ type => 'create',
+ reason => 'creating an API key',
+ description => $description,
};
- # display 2fa verification
- $user->mfa_provider->verify_prompt($mfa_event);
}
+ else {
+ $vars->{new_key} = _create_api_key($description);
+ }
+ }
+
+ $dbh->bz_commit_transaction;
+
+ if (@mfa_events) {
+
+ # build the fields for the postback
+ my $mfa_event = {
+ postback => {action => 'userprefs.cgi', fields => {tab => 'apikey',},},
+ reason => ucfirst(join(' and ', map { $_->{reason} } @mfa_events)),
+ actions => \@mfa_events,
+ };
+
+ # display 2fa verification
+ $user->mfa_provider->verify_prompt($mfa_event);
+ }
}
sub MfaApiKey {
- my $cgi = Bugzilla->cgi;
- my $user = Bugzilla->user;
- my $dbh = Bugzilla->dbh;
- return unless $user->mfa;
+ my $cgi = Bugzilla->cgi;
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->dbh;
+ return unless $user->mfa;
- my $event = $user->mfa_provider->verify_token($cgi->param('mfa_token'));
+ my $event = $user->mfa_provider->verify_token($cgi->param('mfa_token'));
- foreach my $action (@{ $event->{actions} }) {
- if ($action->{type} eq 'create') {
- $vars->{new_key} = _create_api_key($action->{description});
- }
+ foreach my $action (@{$event->{actions}}) {
+ if ($action->{type} eq 'create') {
+ $vars->{new_key} = _create_api_key($action->{description});
+ }
- elsif ($action->{type} eq 'update') {
- $dbh->bz_start_transaction;
- my $api_key = Bugzilla::User::APIKey->check({ id => $action->{id} });
- $api_key->set_all({
- description => $action->{description},
- revoked => 0,
- });
- $api_key->update();
- Bugzilla->log_user_request(undef, undef, 'api-key-unrevoke');
- $dbh->bz_commit_transaction;
- }
+ elsif ($action->{type} eq 'update') {
+ $dbh->bz_start_transaction;
+ my $api_key = Bugzilla::User::APIKey->check({id => $action->{id}});
+ $api_key->set_all({description => $action->{description}, revoked => 0,});
+ $api_key->update();
+ Bugzilla->log_user_request(undef, undef, 'api-key-unrevoke');
+ $dbh->bz_commit_transaction;
}
+ }
}
sub _create_api_key {
- my ($description) = @_;
- my $user = Bugzilla->user;
+ my ($description) = @_;
+ my $user = Bugzilla->user;
- my $key = Bugzilla::User::APIKey->create({
- user_id => $user->id,
- description => $description,
+ my $key
+ = Bugzilla::User::APIKey->create({
+ user_id => $user->id, description => $description,
});
- Bugzilla->log_user_request(undef, undef, 'api-key-create');
+ Bugzilla->log_user_request(undef, undef, 'api-key-create');
- # As a security precaution, we always sent out an e-mail when
- # an API key is created
- my $template = Bugzilla->template_inner($user->setting('lang'));
- my $message;
- $template->process('email/new-api-key.txt.tmpl', $vars, \$message)
- || ThrowTemplateError($template->error());
+ # As a security precaution, we always sent out an e-mail when
+ # an API key is created
+ my $template = Bugzilla->template_inner($user->setting('lang'));
+ my $message;
+ $template->process('email/new-api-key.txt.tmpl', $vars, \$message)
+ || ThrowTemplateError($template->error());
- MessageToMTA($message);
+ MessageToMTA($message);
- return $key;
+ return $key;
}
###############################################################################
@@ -947,15 +971,16 @@ $cgi->delete('GoAheadAndLogIn');
Bugzilla->login(LOGIN_OPTIONAL);
if (!Bugzilla->user->id) {
- # Use credentials given in the form if login cookies are not available.
- $cgi->param('Bugzilla_login', $cgi->param('old_login'));
- $cgi->param('Bugzilla_password', $cgi->param('old_password'));
+
+ # Use credentials given in the form if login cookies are not available.
+ $cgi->param('Bugzilla_login', $cgi->param('old_login'));
+ $cgi->param('Bugzilla_password', $cgi->param('old_password'));
}
Bugzilla->login(LOGIN_REQUIRED);
-my $save_changes = $cgi->param('dosave');
+my $save_changes = $cgi->param('dosave');
my $disable_account = $cgi->param('account_disable');
-my $mfa_token = $cgi->param('mfa_token');
+my $mfa_token = $cgi->param('mfa_token');
$vars->{'changes_saved'} = $save_changes || $mfa_token;
my $current_tab_name = $cgi->param('tab') || "account";
@@ -966,72 +991,76 @@ trick_taint($current_tab_name);
$vars->{'current_tab_name'} = $current_tab_name;
my $token = $cgi->param('token');
-check_token_data($token, 'edit_user_prefs') if $save_changes || $disable_account;
+check_token_data($token, 'edit_user_prefs')
+ if $save_changes || $disable_account;
# Do any saving, and then display the current tab.
SWITCH: for ($current_tab_name) {
- # Extensions must set it to 1 to confirm the tab is valid.
- my $handled = 0;
- Bugzilla::Hook::process('user_preferences',
- { 'vars' => $vars,
- save_changes => $save_changes,
- current_tab => $current_tab_name,
- handled => \$handled });
- last SWITCH if $handled;
-
- /^account$/ && do {
- MfaAccount() if $mfa_token;
- DisableAccount() if $disable_account;
- SaveAccount() if $save_changes;
- DoAccount();
- last SWITCH;
- };
- /^settings$/ && do {
- MfaSettings() if $mfa_token;
- SaveSettings() if $save_changes;
- DoSettings();
- last SWITCH;
- };
- /^email$/ && do {
- SaveEmail() if $save_changes;
- DoEmail();
- last SWITCH;
- };
- /^permissions$/ && do {
- DoPermissions();
- last SWITCH;
- };
- /^saved-searches$/ && do {
- SaveSavedSearches() if $save_changes;
- DoSavedSearches();
- last SWITCH;
- };
- /^apikey$/ && do {
- MfaApiKey() if $mfa_token;
- SaveApiKey() if $save_changes;
- DoApiKey();
- last SWITCH;
- };
- /^sessions$/ && do {
- SaveSessions() if $save_changes;
- DoSessions();
- last SWITCH;
- };
- /^mfa$/ && do {
- SaveMFAcallback() if $mfa_token;
- SaveMFA() if $save_changes;
- DoMFA();
- last SWITCH;
- };
-
- ThrowUserError("unknown_tab",
- { current_tab_name => $current_tab_name });
+ # Extensions must set it to 1 to confirm the tab is valid.
+ my $handled = 0;
+ Bugzilla::Hook::process(
+ 'user_preferences',
+ {
+ 'vars' => $vars,
+ save_changes => $save_changes,
+ current_tab => $current_tab_name,
+ handled => \$handled
+ }
+ );
+ last SWITCH if $handled;
+
+ /^account$/ && do {
+ MfaAccount() if $mfa_token;
+ DisableAccount() if $disable_account;
+ SaveAccount() if $save_changes;
+ DoAccount();
+ last SWITCH;
+ };
+ /^settings$/ && do {
+ MfaSettings() if $mfa_token;
+ SaveSettings() if $save_changes;
+ DoSettings();
+ last SWITCH;
+ };
+ /^email$/ && do {
+ SaveEmail() if $save_changes;
+ DoEmail();
+ last SWITCH;
+ };
+ /^permissions$/ && do {
+ DoPermissions();
+ last SWITCH;
+ };
+ /^saved-searches$/ && do {
+ SaveSavedSearches() if $save_changes;
+ DoSavedSearches();
+ last SWITCH;
+ };
+ /^apikey$/ && do {
+ MfaApiKey() if $mfa_token;
+ SaveApiKey() if $save_changes;
+ DoApiKey();
+ last SWITCH;
+ };
+ /^sessions$/ && do {
+ SaveSessions() if $save_changes;
+ DoSessions();
+ last SWITCH;
+ };
+ /^mfa$/ && do {
+ SaveMFAcallback() if $mfa_token;
+ SaveMFA() if $save_changes;
+ DoMFA();
+ last SWITCH;
+ };
+
+ ThrowUserError("unknown_tab", {current_tab_name => $current_tab_name});
}
delete_token($token) if $save_changes;
if ($current_tab_name ne 'permissions') {
- $vars->{'token'} = issue_session_token('edit_user_prefs');
+ $vars->{'token'} = issue_session_token('edit_user_prefs');
}
# Generate and return the UI (HTML page) from the appropriate template.