Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1926081 - Add modification_time datetime column to profiles table denoting when the profile was last updated #2345

Merged
merged 3 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions Bugzilla/Install/DB.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4447,25 +4447,59 @@ sub _migrate_profiles_modification_ts {

$dbh->bz_add_column('profiles', 'modification_ts', {TYPE => 'DATETIME'});

# A fresh DB will not have this column yet as it is added later by an extension
# so we will need to ignore it later in this case.
my $has_creation_ts = $dbh->bz_column_info('profiles', 'creation_ts');

my $sth = $dbh->prepare(
'UPDATE profiles SET modification_ts = FROM_UNIXTIME(?) WHERE userid = ?');

# Todays timestamp
my $now_when
= $dbh->selectrow_array('SELECT UNIX_TIMESTAMP(LOCALTIMESTAMP(0))');

my $user_ids
= $dbh->selectall_arrayref('SELECT userid FROM profiles ORDER BY userid');
= $dbh->selectcol_arrayref('SELECT userid FROM profiles ORDER BY userid');

my $count = 1;
my $total = scalar @{$user_ids};

foreach my $user_id (@{$user_ids}) {
my ($audit_log_when) = $dbh->selectrow_array(
indicate_progress({total => $total, current => $count++, every => 25});

my $audit_log_when = $dbh->selectrow_array(
'SELECT UNIX_TIMESTAMP(at_time) FROM audit_log
WHERE class = \'Bugzilla::User\' AND object_id = ? ORDER BY at_time DESC '
. $dbh->sql_limit(1), undef, $user_id
);
my ($profiles_act_when) = $dbh->selectrow_array(
my $profiles_act_when = $dbh->selectrow_array(
'SELECT UNIX_TIMESTAMP(profiles_when) FROM profiles_activity
WHERE userid = ? ORDER BY profiles_when DESC '
. $dbh->sql_limit(1), undef, $user_id
);

# We use unix timestamps to make value comparison easier
my $modification_ts = max($audit_log_when, $profiles_act_when);
$audit_log_when ||= 0;
$profiles_act_when ||= 0;

my $creation_when = 0;
if ($has_creation_ts) {
$creation_when
= $dbh->selectrow_array(
'SELECT UNIX_TIMESTAMP(creation_ts) FROM profiles WHERE userid = ?',
undef, $user_id);
$creation_when ||= 0;
}

my $modification_ts = 0;
# IF we could not find anything then use todays date
if (!$audit_log_when && !$profiles_act_when && !$creation_when) {
$modification_ts = $now_when;
}
# We used unix timestamps to make value comparison easier without using DateTime instance of each.
else {
$modification_ts = max($audit_log_when, $profiles_act_when, $creation_when);
}

$sth->execute($modification_ts, $user_id);
}

Expand Down
15 changes: 14 additions & 1 deletion Bugzilla/User.pm
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ sub DB_COLUMNS {
'profiles.mfa',
'profiles.mfa_required_date',
'profiles.nickname',
'profiles.bounce_count'
'profiles.bounce_count',
$dbh->sql_date_format('modification_ts', '%Y-%m-%d %H:%i:%s') . ' AS modification_ts',
),
;
}
Expand All @@ -107,6 +108,7 @@ use constant VALIDATORS => {
password_change_reason => \&_check_password_change_reason,
mfa => \&_check_mfa,
bounce_count => \&_check_numeric,
modification_ts => \&_check_timestamp,
};

sub UPDATE_COLUMNS {
Expand All @@ -124,6 +126,7 @@ sub UPDATE_COLUMNS {
mfa_required_date
nickname
bounce_count
modification_ts
);
push(@cols, 'cryptpassword') if exists $self->{cryptpassword};
return @cols;
Expand Down Expand Up @@ -337,6 +340,11 @@ sub update {
|| exists $changes->{cryptpassword})
);

# Update modification_ts if any changes were made
if (keys %{$changes}) {
$dbh->do('UPDATE profiles set modification_ts = NOW() WHERE userid = ?', undef, $self->id)
}

# XXX Can update profiles_activity here as soon as it understands
# field names like login_name.

Expand Down Expand Up @@ -448,6 +456,10 @@ sub _check_numeric {
return $value;
}

sub _check_timestamp {
return Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
dklawren marked this conversation as resolved.
Show resolved Hide resolved
}

################################################################################
# Mutators
################################################################################
Expand Down Expand Up @@ -669,6 +681,7 @@ sub showmybugslink { $_[0]->{showmybugslink}; }
sub email_disabled { $_[0]->{disable_mail} || !$_[0]->{is_enabled}; }
sub email_enabled { !$_[0]->email_disabled; }
sub last_seen_date { $_[0]->{last_seen_date}; }
sub modification_ts { $_[0]->{modification_ts}; }
sub password_change_required { $_[0]->{password_change_required}; }
sub password_change_reason { $_[0]->{password_change_reason}; }

Expand Down
78 changes: 78 additions & 0 deletions scripts/bug1926081.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env perl
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.

use 5.10.1;
use strict;
use warnings;
use lib qw(. lib local/lib/perl5);

use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Install::Util qw(indicate_progress);

use List::Util qw(max);

Bugzilla->usage_mode(USAGE_MODE_CMDLINE);

my $dbh = Bugzilla->dbh;

my $sth = $dbh->prepare(
'UPDATE profiles SET modification_ts = FROM_UNIXTIME(?) WHERE userid = ?');

# Todays timestamp
my $now_when
= $dbh->selectrow_array('SELECT UNIX_TIMESTAMP(LOCALTIMESTAMP(0))');

my $user_ids
= $dbh->selectcol_arrayref('SELECT userid FROM profiles ORDER BY userid');

my $count = 1;
my $total = scalar @{$user_ids};

foreach my $user_id (@{$user_ids}) {
indicate_progress({total => $total, current => $count++, every => 25});

my $audit_log_when = $dbh->selectrow_array(
'SELECT UNIX_TIMESTAMP(at_time) FROM audit_log
WHERE class = \'Bugzilla::User\' AND object_id = ? ORDER BY at_time DESC '
. $dbh->sql_limit(1), undef, $user_id
);
my $profiles_act_when = $dbh->selectrow_array(
'SELECT UNIX_TIMESTAMP(profiles_when) FROM profiles_activity
WHERE userid = ? ORDER BY profiles_when DESC '
. $dbh->sql_limit(1), undef, $user_id
);

my $creation_when
= $dbh->selectrow_array(
'SELECT UNIX_TIMESTAMP(creation_ts) FROM profiles WHERE userid = ?',
undef, $user_id);

$creation_when ||= 0;
$audit_log_when ||= 0;
$profiles_act_when ||= 0;

my $modification_ts = 0;

# IF we could not find anything then use todays date
if (!$audit_log_when && !$profiles_act_when && !$creation_when) {
$modification_ts = $now_when;
}

# We used unix timestamps to make value comparison easier without using DateTime instance of each.
else {
$modification_ts = max($audit_log_when, $profiles_act_when, $creation_when);
}

$sth->execute($modification_ts, $user_id);
}

$dbh->bz_alter_column('profiles', 'modification_ts',
{TYPE => 'DATETIME', NOTNULL => 1});

1;
7 changes: 6 additions & 1 deletion template/en/default/admin/users/edit.html.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,12 @@ $(function() {
</td>
</tr>
[% END %]

<tr>
<th>Last Modified:</th>
<td>
[% otheruser.modification_ts FILTER html %]
</td>
</tr>
<tr>
<th>Last Login:</th>
<td>
Expand Down
Loading