Class: SemgrepWebApp::SastFinding

Inherits:
BaseModel
  • Object
show all
Defined in:
lib/semgrep_web_app/models/sast_finding.rb

Overview

A Code finding that Semgrep has identified in your organization

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BaseModel

#check_for_conflict, #process_additional_properties, #process_array, #process_basic_value, #process_hash, #to_hash, #to_json

Constructor Details

#initialize(assistant: SKIP, categories: SKIP, click_to_fix_failures: SKIP, click_to_fix_prs: SKIP, confidence: SKIP, created_at: SKIP, external_ticket: SKIP, first_seen_scan_id: SKIP, id: SKIP, line_of_code_url: SKIP, location: SKIP, match_based_id: SKIP, ref: SKIP, relevant_since: SKIP, repository: SKIP, review_comments: SKIP, rule: SKIP, rule_message: SKIP, rule_name: SKIP, severity: SKIP, sourcing_policy: SKIP, state: SKIP, state_updated_at: SKIP, status: SKIP, syntactic_id: SKIP, triage_comment: SKIP, triage_reason: SKIP, triage_state: SKIP, triaged_at: SKIP, additional_properties: nil) ⇒ SastFinding

Returns a new instance of SastFinding.



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 221

def initialize(assistant: SKIP, categories: SKIP,
               click_to_fix_failures: SKIP, click_to_fix_prs: SKIP,
               confidence: SKIP, created_at: SKIP, external_ticket: SKIP,
               first_seen_scan_id: SKIP, id: SKIP, line_of_code_url: SKIP,
               location: SKIP, match_based_id: SKIP, ref: SKIP,
               relevant_since: SKIP, repository: SKIP,
               review_comments: SKIP, rule: SKIP, rule_message: SKIP,
               rule_name: SKIP, severity: SKIP, sourcing_policy: SKIP,
               state: SKIP, state_updated_at: SKIP, status: SKIP,
               syntactic_id: SKIP, triage_comment: SKIP,
               triage_reason: SKIP, triage_state: SKIP, triaged_at: SKIP,
               additional_properties: nil)
  # Add additional model properties to the instance
  additional_properties = {} if additional_properties.nil?

  @assistant = assistant unless assistant == SKIP
  @categories = categories unless categories == SKIP
  @click_to_fix_failures = click_to_fix_failures unless click_to_fix_failures == SKIP
  @click_to_fix_prs = click_to_fix_prs unless click_to_fix_prs == SKIP
  @confidence = confidence unless confidence == SKIP
  @created_at = created_at unless created_at == SKIP
  @external_ticket = external_ticket unless external_ticket == SKIP
  @first_seen_scan_id = first_seen_scan_id unless first_seen_scan_id == SKIP
  @id = id unless id == SKIP
  @line_of_code_url = line_of_code_url unless line_of_code_url == SKIP
  @location = location unless location == SKIP
  @match_based_id = match_based_id unless match_based_id == SKIP
  @ref = ref unless ref == SKIP
  @relevant_since = relevant_since unless relevant_since == SKIP
  @repository = repository unless repository == SKIP
  @review_comments = review_comments unless review_comments == SKIP
  @rule = rule unless rule == SKIP
  @rule_message = rule_message unless rule_message == SKIP
  @rule_name = rule_name unless rule_name == SKIP
  @severity = severity unless severity == SKIP
  @sourcing_policy = sourcing_policy unless sourcing_policy == SKIP
  @state = state unless state == SKIP
  @state_updated_at = state_updated_at unless state_updated_at == SKIP
  @status = status unless status == SKIP
  @syntactic_id = syntactic_id unless syntactic_id == SKIP
  @triage_comment = triage_comment unless triage_comment == SKIP
  @triage_reason = triage_reason unless triage_reason == SKIP
  @triage_state = triage_state unless triage_state == SKIP
  @triaged_at = triaged_at unless triaged_at == SKIP
  @additional_properties = additional_properties
end

Instance Attribute Details

#assistantAssistant

Semgrep Assistant data. Only present if Assistant is enabled

Returns:



14
15
16
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 14

def assistant
  @assistant
end

#categoriesArray[String]

The categories of the finding as classified by the associated rule metadata

Returns:

  • (Array[String])


19
20
21
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 19

def categories
  @categories
end

#click_to_fix_failuresArray[ClickToFixFailure]

Failed PR creation attempts by Semgrep's autofix feature (Click to Fix) for this finding

Returns:



24
25
26
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 24

def click_to_fix_failures
  @click_to_fix_failures
end

#click_to_fix_prsArray[ClickToFixPr]

Pull requests created by Semgrep's autofix feature (Click to Fix) for this finding

Returns:



29
30
31
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 29

def click_to_fix_prs
  @click_to_fix_prs
end

#confidenceConfidence1

Confidence of the finding, derived from the rule that triggered it

Returns:



33
34
35
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 33

def confidence
  @confidence
end

#created_atString

The timestamp when this finding was created

Returns:

  • (String)


37
38
39
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 37

def created_at
  @created_at
end

#external_ticketExternalTicket

External ticket associated with finding

Returns:



41
42
43
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 41

def external_ticket
  @external_ticket
end

#first_seen_scan_idInteger

Unique ID of the Semgrep scan that first identified this finding

Returns:

  • (Integer)


45
46
47
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 45

def first_seen_scan_id
  @first_seen_scan_id
end

#idInteger

Unique ID of this finding

Returns:

  • (Integer)


49
50
51
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 49

def id
  @id
end

#line_of_code_urlString

The source URL including file and line number

Returns:

  • (String)


53
54
55
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 53

def line_of_code_url
  @line_of_code_url
end

#locationFindingLocation

Location of the record in a file, as reported by Semgrep. If null, then the information does not exist or lacks integrity (older or broken scans)

Returns:



58
59
60
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 58

def location
  @location
end

#match_based_idString

ID calculated based on a finding's file path, rule identifier and pattern, and index

Returns:

  • (String)


63
64
65
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 63

def match_based_id
  @match_based_id
end

#refString

External reference to the source of this finding (e.g. PR)

Returns:

  • (String)


67
68
69
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 67

def ref
  @ref
end

#relevant_sinceString

The timestamp when this finding was detected by Semgrep (the first time, or when reintroduced)

Returns:

  • (String)


72
73
74
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 72

def relevant_since
  @relevant_since
end

#repositoryFindingRepository

Which repository this finding was identified in

Returns:



76
77
78
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 76

def repository
  @repository
end

#review_commentsArray[ReviewComment]

List of external review comment information associated with a finding

Returns:



80
81
82
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 80

def review_comments
  @review_comments
end

#ruleFindingRule

Rule that applies to this finding

Returns:



84
85
86
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 84

def rule
  @rule
end

#rule_messageString

Deprecated in favor of rule.message. Rule message at the time of finding identification. Older findings may not have a value for this field

Returns:

  • (String)


89
90
91
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 89

def rule_message
  @rule_message
end

#rule_nameString

Deprecated in favor of rule.name

Returns:

  • (String)


93
94
95
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 93

def rule_name
  @rule_name
end

#severitySeverity1

Severity of the finding, derived from the rule that triggered it. Low is equivalent to INFO, Medium to WARNING, and High to ERROR

Returns:



98
99
100
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 98

def severity
  @severity
end

#sourcing_policyPolicyReference

Reference to a policy, with some basic information. If null, then the information does not exist or lacks integrity (older or broken scans)

Returns:



103
104
105
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 103

def sourcing_policy
  @sourcing_policy
end

#stateState

The finding's resolution state. Managed only by changes detected at scan time, the state is combined with triage_state to ultimately determine a final status which is exposed in the UI and API

Returns:



109
110
111
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 109

def state
  @state
end

#state_updated_atString

When this issue's state (resolution state) was last updated, as distinct from when the issue was triaged (triaged_at)

Returns:

  • (String)


114
115
116
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 114

def state_updated_at
  @state_updated_at
end

#statusStatus

The finding's status as exposed in the UI. Status is a derived property combining information from the finding state and triage_state. The triage_state can be used to override the scan state if the finding is still detected

Returns:



121
122
123
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 121

def status
  @status
end

#syntactic_idString

ID calculated based on a finding's file path, rule identifier and matched code, and index. Prefer match_based_id

Returns:

  • (String)


126
127
128
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 126

def syntactic_id
  @syntactic_id
end

#triage_commentString

The detailed comment provided during triage

Returns:

  • (String)


130
131
132
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 130

def triage_comment
  @triage_comment
end

#triage_reasonTriageReason

Reason provided when this issue was triaged

Returns:



134
135
136
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 134

def triage_reason
  @triage_reason
end

#triage_stateTriageState

The finding's triage state. Note: "reviewing" and "fixing" are only in private beta. Set by the user and used along with state to generate the final "status" viewable in the UI

Returns:



140
141
142
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 140

def triage_state
  @triage_state
end

#triaged_atString

When the finding was triaged

Returns:

  • (String)


144
145
146
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 144

def triaged_at
  @triaged_at
end

Class Method Details

.from_hash(hash) ⇒ Object

Creates an instance of the object from a hash.



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 269

def self.from_hash(hash)
  return nil unless hash

  # Extract variables from the hash.
  assistant = Assistant.from_hash(hash['assistant']) if hash['assistant']
  categories = hash.key?('categories') ? hash['categories'] : SKIP
  # Parameter is an array, so we need to iterate through it
  click_to_fix_failures = nil
  unless hash['click_to_fix_failures'].nil?
    click_to_fix_failures = []
    hash['click_to_fix_failures'].each do |structure|
      click_to_fix_failures << (ClickToFixFailure.from_hash(structure) if structure)
    end
  end

  click_to_fix_failures = SKIP unless hash.key?('click_to_fix_failures')
  # Parameter is an array, so we need to iterate through it
  click_to_fix_prs = nil
  unless hash['click_to_fix_prs'].nil?
    click_to_fix_prs = []
    hash['click_to_fix_prs'].each do |structure|
      click_to_fix_prs << (ClickToFixPr.from_hash(structure) if structure)
    end
  end

  click_to_fix_prs = SKIP unless hash.key?('click_to_fix_prs')
  confidence = hash.key?('confidence') ? hash['confidence'] : SKIP
  created_at = hash.key?('created_at') ? hash['created_at'] : SKIP
  external_ticket = ExternalTicket.from_hash(hash['external_ticket']) if
    hash['external_ticket']
  first_seen_scan_id =
    hash.key?('first_seen_scan_id') ? hash['first_seen_scan_id'] : SKIP
  id = hash.key?('id') ? hash['id'] : SKIP
  line_of_code_url =
    hash.key?('line_of_code_url') ? hash['line_of_code_url'] : SKIP
  location = FindingLocation.from_hash(hash['location']) if hash['location']
  match_based_id =
    hash.key?('match_based_id') ? hash['match_based_id'] : SKIP
  ref = hash.key?('ref') ? hash['ref'] : SKIP
  relevant_since =
    hash.key?('relevant_since') ? hash['relevant_since'] : SKIP
  repository = FindingRepository.from_hash(hash['repository']) if hash['repository']
  # Parameter is an array, so we need to iterate through it
  review_comments = nil
  unless hash['review_comments'].nil?
    review_comments = []
    hash['review_comments'].each do |structure|
      review_comments << (ReviewComment.from_hash(structure) if structure)
    end
  end

  review_comments = SKIP unless hash.key?('review_comments')
  rule = FindingRule.from_hash(hash['rule']) if hash['rule']
  rule_message = hash.key?('rule_message') ? hash['rule_message'] : SKIP
  rule_name = hash.key?('rule_name') ? hash['rule_name'] : SKIP
  severity = hash.key?('severity') ? hash['severity'] : SKIP
  sourcing_policy = PolicyReference.from_hash(hash['sourcing_policy']) if
    hash['sourcing_policy']
  state = hash.key?('state') ? hash['state'] : SKIP
  state_updated_at =
    hash.key?('state_updated_at') ? hash['state_updated_at'] : SKIP
  status = hash.key?('status') ? hash['status'] : SKIP
  syntactic_id = hash.key?('syntactic_id') ? hash['syntactic_id'] : SKIP
  triage_comment =
    hash.key?('triage_comment') ? hash['triage_comment'] : SKIP
  triage_reason = hash.key?('triage_reason') ? hash['triage_reason'] : SKIP
  triage_state = hash.key?('triage_state') ? hash['triage_state'] : SKIP
  triaged_at = hash.key?('triaged_at') ? hash['triaged_at'] : SKIP

  # Create a new hash for additional properties, removing known properties.
  new_hash = hash.reject { |k, _| names.value?(k) }

  additional_properties = APIHelper.get_additional_properties(
    new_hash, proc { |value| value }
  )

  # Create object from extracted values.
  SastFinding.new(assistant: assistant,
                  categories: categories,
                  click_to_fix_failures: click_to_fix_failures,
                  click_to_fix_prs: click_to_fix_prs,
                  confidence: confidence,
                  created_at: created_at,
                  external_ticket: external_ticket,
                  first_seen_scan_id: first_seen_scan_id,
                  id: id,
                  line_of_code_url: line_of_code_url,
                  location: location,
                  match_based_id: match_based_id,
                  ref: ref,
                  relevant_since: relevant_since,
                  repository: repository,
                  review_comments: review_comments,
                  rule: rule,
                  rule_message: rule_message,
                  rule_name: rule_name,
                  severity: severity,
                  sourcing_policy: sourcing_policy,
                  state: state,
                  state_updated_at: state_updated_at,
                  status: status,
                  syntactic_id: syntactic_id,
                  triage_comment: triage_comment,
                  triage_reason: triage_reason,
                  triage_state: triage_state,
                  triaged_at: triaged_at,
                  additional_properties: additional_properties)
end

.namesObject

A mapping from model property names to API property names.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 147

def self.names
  @_hash = {} if @_hash.nil?
  @_hash['assistant'] = 'assistant'
  @_hash['categories'] = 'categories'
  @_hash['click_to_fix_failures'] = 'click_to_fix_failures'
  @_hash['click_to_fix_prs'] = 'click_to_fix_prs'
  @_hash['confidence'] = 'confidence'
  @_hash['created_at'] = 'created_at'
  @_hash['external_ticket'] = 'external_ticket'
  @_hash['first_seen_scan_id'] = 'first_seen_scan_id'
  @_hash['id'] = 'id'
  @_hash['line_of_code_url'] = 'line_of_code_url'
  @_hash['location'] = 'location'
  @_hash['match_based_id'] = 'match_based_id'
  @_hash['ref'] = 'ref'
  @_hash['relevant_since'] = 'relevant_since'
  @_hash['repository'] = 'repository'
  @_hash['review_comments'] = 'review_comments'
  @_hash['rule'] = 'rule'
  @_hash['rule_message'] = 'rule_message'
  @_hash['rule_name'] = 'rule_name'
  @_hash['severity'] = 'severity'
  @_hash['sourcing_policy'] = 'sourcing_policy'
  @_hash['state'] = 'state'
  @_hash['state_updated_at'] = 'state_updated_at'
  @_hash['status'] = 'status'
  @_hash['syntactic_id'] = 'syntactic_id'
  @_hash['triage_comment'] = 'triage_comment'
  @_hash['triage_reason'] = 'triage_reason'
  @_hash['triage_state'] = 'triage_state'
  @_hash['triaged_at'] = 'triaged_at'
  @_hash
end

.nullablesObject

An array for nullable fields



217
218
219
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 217

def self.nullables
  []
end

.optionalsObject

An array for optional fields



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 182

def self.optionals
  %w[
    assistant
    categories
    click_to_fix_failures
    click_to_fix_prs
    confidence
    created_at
    external_ticket
    first_seen_scan_id
    id
    line_of_code_url
    location
    match_based_id
    ref
    relevant_since
    repository
    review_comments
    rule
    rule_message
    rule_name
    severity
    sourcing_policy
    state
    state_updated_at
    status
    syntactic_id
    triage_comment
    triage_reason
    triage_state
    triaged_at
  ]
end

.validate(value) ⇒ Object

Validates an instance of the object from a given value.

Parameters:

  • The (SastFinding | Hash)

    value against the validation is performed.



380
381
382
383
384
385
386
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 380

def self.validate(value)
  return true if value.instance_of? self

  return false unless value.instance_of? Hash

  true
end

Instance Method Details

#inspectObject

Provides a debugging-friendly string with detailed object information.



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 406

def inspect
  class_name = self.class.name.split('::').last
  "<#{class_name} assistant: #{@assistant.inspect}, categories: #{@categories.inspect},"\
  " click_to_fix_failures: #{@click_to_fix_failures.inspect}, click_to_fix_prs:"\
  " #{@click_to_fix_prs.inspect}, confidence: #{@confidence.inspect}, created_at:"\
  " #{@created_at.inspect}, external_ticket: #{@external_ticket.inspect}, first_seen_scan_id:"\
  " #{@first_seen_scan_id.inspect}, id: #{@id.inspect}, line_of_code_url:"\
  " #{@line_of_code_url.inspect}, location: #{@location.inspect}, match_based_id:"\
  " #{@match_based_id.inspect}, ref: #{@ref.inspect}, relevant_since:"\
  " #{@relevant_since.inspect}, repository: #{@repository.inspect}, review_comments:"\
  " #{@review_comments.inspect}, rule: #{@rule.inspect}, rule_message:"\
  " #{@rule_message.inspect}, rule_name: #{@rule_name.inspect}, severity:"\
  " #{@severity.inspect}, sourcing_policy: #{@sourcing_policy.inspect}, state:"\
  " #{@state.inspect}, state_updated_at: #{@state_updated_at.inspect}, status:"\
  " #{@status.inspect}, syntactic_id: #{@syntactic_id.inspect}, triage_comment:"\
  " #{@triage_comment.inspect}, triage_reason: #{@triage_reason.inspect}, triage_state:"\
  " #{@triage_state.inspect}, triaged_at: #{@triaged_at.inspect}, additional_properties:"\
  " #{@additional_properties}>"
end

#to_sObject

Provides a human-readable string representation of the object.



389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/semgrep_web_app/models/sast_finding.rb', line 389

def to_s
  class_name = self.class.name.split('::').last
  "<#{class_name} assistant: #{@assistant}, categories: #{@categories},"\
  " click_to_fix_failures: #{@click_to_fix_failures}, click_to_fix_prs: #{@click_to_fix_prs},"\
  " confidence: #{@confidence}, created_at: #{@created_at}, external_ticket:"\
  " #{@external_ticket}, first_seen_scan_id: #{@first_seen_scan_id}, id: #{@id},"\
  " line_of_code_url: #{@line_of_code_url}, location: #{@location}, match_based_id:"\
  " #{@match_based_id}, ref: #{@ref}, relevant_since: #{@relevant_since}, repository:"\
  " #{@repository}, review_comments: #{@review_comments}, rule: #{@rule}, rule_message:"\
  " #{@rule_message}, rule_name: #{@rule_name}, severity: #{@severity}, sourcing_policy:"\
  " #{@sourcing_policy}, state: #{@state}, state_updated_at: #{@state_updated_at}, status:"\
  " #{@status}, syntactic_id: #{@syntactic_id}, triage_comment: #{@triage_comment},"\
  " triage_reason: #{@triage_reason}, triage_state: #{@triage_state}, triaged_at:"\
  " #{@triaged_at}, additional_properties: #{@additional_properties}>"
end