5.7.202. Bugzilla::Extension::RedHat::Util¶
5.7.202.1. NAME¶
Bugzilla::Extension::RedHat::Util - Shared helpers for reversing the
manage_user_access repudiate action.
5.7.202.2. SYNOPSIS¶
use Bugzilla::Extension::RedHat::Util;
my ($removed, $added) = reconstruct_repudiate_restore($bug_id, $system_id);
my ($args, $warnings) = repudiate_restore_args($bug_id, $removed, $added);
my @to_restore = find_restorable_comments($bug, $other_user_id);
Used by both Bugzilla::Extension::RedHat::Job::UndoRepudiate (which is only
loaded inside the job queue worker) and extensions/RedHat/bin/undo_repudiate.pl(an admin script run outside the job queue, including for --dry-run reporting
that must never disagree with what the job actually does).
reconstruct_repudiate_restore¶
Locates the repudiate transaction for a bug and reconstructs the
pre-repudiate field values from bugs_activity.
Returns ($removed, $added) hashrefs keyed by field name, or an empty list
if no matching transaction was found.
reconstruct_dup_id¶
Recovers a bug’s dup_id from the CMT_DUPE_OF comment
Bug::set_dup_id always posts on a bug when it’s marked a duplicate
(Bugzilla/Bug.pm:3405-3409) - not from bugs_activity, which never
logs dup_id changes at all (see repudiate_restore_args). That
comment’s type/extra_data are untouched by DeSpamComments’ text
stubbing (only thetext is rewritten), so it survives a repudiate intact
- the same way a CMT_ATTACHMENT_CREATED comment’s extra_datapreserves an attachment id.
Returns the dup_id, or undef if no such comment exists (e.g. the bug
was marked DUPLICATE some other way that never went through
set_dup_id, such as a direct SQL import).
repudiate_restore_args¶
Turns the ($removed, $added) hashrefs from reconstruct_repudiate_restore
into the hashref shape “set_all” in Bugzilla::Bug expects.
Returns ($args, $warnings): $args is the set_all hashref:
$warnings is an arrayref of human-readable strings describing anything
that could not be fully restored (currently just a bug that used to be a
DUPLICATE with no recoverable dup_id - see the comment below), for the
caller to log/report as it sees fit. Empty when there’s nothing to flag.
restore_with_inactive_values_allowed¶
Bugzilla::Bug’s component/version/target_milestone/target_releasevalidators throw value_inactive when set_all tries to set a bug to a
value that is no longer active for its product - which old-enough
repudiated bugs run into routinely, since products retire old
versions/milestones/releases over time. The value being restored isn’t a
new, questionable choice; it’s simply what the bug legitimately already
had.
This runs $code (typically a set_all/update call) with
is_active forced true for Bugzilla::Version, Bugzilla::Component,
Bugzilla::Milestone, and Bugzilla::Release, via local on each
class’s typeglob - not by writing to the isactive column. Nothing
outside this process’s current call stack is ever affected: no other
request, job, or user can observe it, unlike flipping the column (which
would make the value briefly selectable by anyone else using the same
product, and could interact badly with other systems keyed off that column
- exactly what happened when an earlier version of this activated-then-
updated the value objects and tripped an unrelated, previously-latent bug
in BayotBase’s object_end_of_update hook). The override is removed the
instant $code returns, including if it dies - local restores the
original sub as the call stack unwinds regardless of how it exits.
ensure_admin_can_restore_from_nobody¶
Spam Sinkhole’s nobody group has canedit => 1 with mandatory
control, so only members of nobody may edit a bug that still carries that
group, including the system_user running this restore, and even though
it’s an admin. nobody is intentionally never supposed to have real direct
members, so the fix is a standing group_group_map grant that makes members
of admin inherit membership in nobody (the exact mechanism
“create” in Bugzilla::Group uses to give admin rights over a brand new
group), rather than adding anyone to nobody directly.
This is granted once and never revoked. Multiple admins can run
undo_repudiate.pl concurrently for different users, restores run for a long
time after the enqueuing script has already exited, and jobs run with real
parallelism, so there is no point in the job/script lifecycle where it would be
safe to know “no restore is still in flight” and revoke this. The grant is
idempotent: safe to call every time, cheap no-op once it exists.
find_restorable_comments¶
Finds comments on $bug authored by $other_user_id whose current text is
still the spam stub, paired with the original text recovered from
longdescs_activity.
Returns a list of [$comment, $original_text] pairs.
remove_spam_tag¶
Removes the spam tag DeSpamComments::_insinkerator added to a comment,
via raw SQL mirroring exactly how it was added (in reverse) - including the
matching longdescs_tags_activity row, so the removal is itself audited.
Bugzilla::Comment::remove_tag/update() is not used here: in
production, restoring a comment’s text worked but the tag it added
(_insinkerator writes it via raw SQL) was still left in place afterwards
even though remove_tag/update() ran with no error. Going straight at
longdescs_tags with the same primitives _insinkerator used to add the
tag sidesteps whatever in the Comment object/tag-diffing machinery was
responsible, rather than continuing to rely on a path already shown not to
work for this exact tag.
This documentation undoubtedly has bugs; if you find some, please file them here.