Class: Gitlab::BackgroundMigration::FixVulnerabilitiesTransitionedFromDismissedToResolved
- Inherits:
-
BatchedMigrationJob
- Object
- BatchedMigrationJob
- Gitlab::BackgroundMigration::FixVulnerabilitiesTransitionedFromDismissedToResolved
show all
- Defined in:
- lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb
Defined Under Namespace
Classes: Note, Project, StateTransition, User, Vulnerability
Constant Summary
collapse
- FIRST_APPEARANCE_DATE =
The earliest that records could have appeared on .com was when the feature flag was enabled on 2024-12-05: gitlab.com/gitlab-org/gitlab/-/issues/505711
In self-managed, it could have appeared beginning in the 17.7 release on 2024-12-19.
Date.new(2024, 12, 5)
"Status changed to dismissed. Reverts a bug that incorrectly set this vulnerability to resolved." \
"For details, see [issue 523433](https://gitlab.com/gitlab-org/gitlab/-/issues/523433)"
BatchedMigrationJob::DEFAULT_FEATURE_CATEGORY, BatchedMigrationJob::MINIMUM_PAUSE_MS
Database::DynamicModelHelpers::BATCH_SIZE
Instance Method Summary
collapse
#batch_metrics, cursor, cursor?, cursor_columns, feature_category, #filter_batch, generic_instance, health_context_tables, #initialize, job_arguments, job_arguments_count, operation_name, scope_to, tables_to_check_for_vacuum
define_batchable_model, #each_batch, #each_batch_range
Instance Method Details
#affected_transition(vulnerability) ⇒ Object
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 117
def affected_transition(vulnerability)
vulnerability.state_transitions.find do |state_transition|
break if state_transition.created_before_issue_first_appeared?
break if state_transition.author.present? && !state_transition.author.security_policy_bot?
state_transition.transitioned_from_dismissed_to_resolved?
end
end
|
#affected_vulnerability_data(vulnerability_reads) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 99
def affected_vulnerability_data(vulnerability_reads)
Vulnerability
.id_in(vulnerability_reads.pluck(:vulnerability_id))
.transitioned_at_least_once
.with_state_transitions_author_and_project
.filter_map do |vulnerability|
bug_transition = affected_transition(vulnerability)
next if bug_transition.blank?
{
vulnerability: vulnerability,
bug_transition: bug_transition,
original_dismissal_transition: original_dismissal(vulnerability, bug_transition)
}
end
end
|
#connection ⇒ Object
179
180
181
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 179
def connection
::SecApplicationRecord.connection
end
|
#insert_notes(data, timestamp) ⇒ Object
158
159
160
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 158
def insert_notes(data, timestamp)
Note.insert_all(note_attributes(data, timestamp))
end
|
#note_attributes(data, timestamp) ⇒ Object
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 162
def note_attributes(data, timestamp)
data.map do |record|
vulnerability = record[:vulnerability]
{
noteable_type: "Vulnerability",
noteable_id: vulnerability.id,
project_id: vulnerability.project.id,
namespace_id: vulnerability.project.project_namespace_id,
system: true,
note: COMMENT,
author_id: record[:bug_transition].author_id,
created_at: timestamp,
updated_at: timestamp
}
end
end
|
#original_dismissal(vulnerability, bug_transition) ⇒ Object
128
129
130
131
132
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 128
def original_dismissal(vulnerability, bug_transition)
bug_transition_index = vulnerability.state_transitions.index(bug_transition)
prior_transitions = vulnerability.state_transitions[(bug_transition_index + 1)..]
prior_transitions.find { |transition| transition.to_state == Vulnerability.states[:dismissed] }
end
|
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 72
def perform
each_sub_batch do |batch|
vulnerability_reads = scoped_vulnerability_reads(batch)
next if vulnerability_reads.blank?
data = affected_vulnerability_data(vulnerability_reads)
next if data.blank?
batch_timestamp = Time.current
transition_states(data, batch_timestamp)
insert_notes(data, batch_timestamp)
end
end
|
#scoped_vulnerability_reads(vulnerability_reads) ⇒ Object
89
90
91
92
93
94
95
96
97
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 89
def scoped_vulnerability_reads(vulnerability_reads)
relation = vulnerability_reads.where(state: [Vulnerability.states[:detected], Vulnerability.states[:resolved]])
return relation if namespace_id == 'instance'
relation
.where(vulnerability_reads.arel_table[:traversal_ids].gteq([namespace_id]))
.where(vulnerability_reads.arel_table[:traversal_ids].lt([namespace_id.next]))
end
|
#state_transition_attributes(data, timestamp) ⇒ Object
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 143
def state_transition_attributes(data, timestamp)
data.map do |record|
{
author_id: record[:bug_transition].author_id,
from_state: Vulnerability.states[record[:vulnerability].state],
to_state: Vulnerability.states[:dismissed],
dismissal_reason: record[:original_dismissal_transition]&.dismissal_reason || 0,
vulnerability_id: record[:vulnerability].id,
comment: COMMENT,
created_at: timestamp,
updated_at: timestamp
}
end
end
|
#transition_states(data, timestamp) ⇒ Object
134
135
136
137
138
139
140
141
|
# File 'lib/gitlab/background_migration/fix_vulnerabilities_transitioned_from_dismissed_to_resolved.rb', line 134
def transition_states(data, timestamp)
vulnerability_ids = data.map { |record| record[:vulnerability].id }
Vulnerability.transaction do
Vulnerability.id_in(vulnerability_ids).update_all(state: :dismissed, updated_at: timestamp)
StateTransition.insert_all(state_transition_attributes(data, timestamp))
end
end
|