pwn 0.5.469 → 0.5.470

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3776d69c2f72f9b607ae0b156d28edf85a3db2270c33623db7af2e1c630f7ca
4
- data.tar.gz: d57db357712c6670ca2446bf45bba505ac3ec64785bcd4fded78ce6151dc9849
3
+ metadata.gz: 47e1cc9953717f8cfc9b329cf6693ab82f239785ef4be0cc5f5d13bfa8c84dc6
4
+ data.tar.gz: d2fcbfd91e6e5063ccdbbe23da76daff86840bf42c027603221f94c0d9d5e743
5
5
  SHA512:
6
- metadata.gz: 3e53da8aaf44763a2370452aff6b06601846d69fc41ee91b20115fbba35275af40bfdc95b7d14d39576c19f3e09355bfb4f7e4fd0c3da9309dbb20cf90b2484b
7
- data.tar.gz: f204e8f4de53b59e8738705a973ed186eebb2fdff72aff0358ac3147d123fd0d75bcdef42a040bcb0a697c21670f5e264e90f37e14971270670f30cec3d6f2f3
6
+ metadata.gz: 9be1c54763704034fe92d0190c5bf56d91822e8f8ed8d9824eff2dc18fcc7be0c9d271a339b875e22a718fafd06b4251fd956beae3feb5e73a152008e9a832e8
7
+ data.tar.gz: 37334410cafd2c97f8c84e0562e2e62a16931e25cc7fa670b307e82ac94164cb6f209b7976606775079c4e92dea723ab4d1c55e3110f9dbc0c321321c79e099f
data/README.md CHANGED
@@ -37,7 +37,7 @@ $ cd /opt/pwn
37
37
  $ ./install.sh
38
38
  $ ./install.sh ruby-gem
39
39
  $ pwn
40
- pwn[v0.5.469]:001 >>> PWN.help
40
+ pwn[v0.5.470]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](https://youtu.be/G7iLUY4FzsI)
@@ -52,7 +52,7 @@ $ rvm use ruby-3.4.4@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.5.469]:001 >>> PWN.help
55
+ pwn[v0.5.470]:001 >>> PWN.help
56
56
  ```
57
57
 
58
58
  If you're using a multi-user install of RVM do:
@@ -62,7 +62,7 @@ $ rvm use ruby-3.4.4@pwn
62
62
  $ rvmsudo gem uninstall --all --executables pwn
63
63
  $ rvmsudo gem install --verbose pwn
64
64
  $ pwn
65
- pwn[v0.5.469]:001 >>> PWN.help
65
+ pwn[v0.5.470]:001 >>> PWN.help
66
66
  ```
67
67
 
68
68
  PWN periodically upgrades to the latest version of Ruby which is reflected in `/opt/pwn/.ruby-version`. The easiest way to upgrade to the latest version of Ruby from a previous PWN installation is to run the following script:
@@ -405,12 +405,17 @@ module PWN
405
405
  rest_call: "issue/createmeta/#{project_key}/issuetypes/#{issue_type_id}",
406
406
  params: params
407
407
  )
408
+ max_results = this_resp[:maxResults]
409
+ start_at = this_resp[:startAt]
410
+ total = this_resp[:total]
408
411
  is_last = this_resp[:isLast]
409
- response[:maxResults] = this_resp[:maxResults]
410
- response[:startAt] = this_resp[:startAt]
411
- response[:total] = this_resp[:total]
412
+ values = this_resp[:values]
413
+
414
+ response[:maxResults] = max_results
415
+ response[:startAt] = start_at
416
+ response[:total] = total
412
417
  response[:isLast] = is_last
413
- response[:values].concat(this_resp[:values])
418
+ response[:values].concat(values)
414
419
  break if is_last
415
420
 
416
421
  start_at += max_results
@@ -423,53 +428,63 @@ module PWN
423
428
 
424
429
  # Supported Method Parameters::
425
430
  # issue_resp = PWN::Plugins::JiraDataCenter.clone_issue(
426
- # issue: 'required - issue to clone (e.g. Bug, Issue, Story, or Epic ID)'
431
+ # issue: 'required - issue to clone (e.g. Bug, Issue, Story, or Epic ID)',
432
+ # copy_attachments: 'optional - boolean to indicate whether to copy attachments (Defaults to false)'
427
433
  # )
428
434
 
429
435
  public_class_method def self.clone_issue(opts = {})
430
436
  issue = opts[:issue]
431
437
  raise 'ERROR: issue cannot be nil.' if issue.nil?
432
438
 
439
+ copy_attachments = opts[:copy_attachments] ||= false
440
+
441
+ # Expand editmeta so we have full field set + attachment info
433
442
  issue_data = get_issue(issue: issue, params: { expand: 'editmeta' })
434
443
 
435
444
  project_key = issue_data[:fields][:project][:key]
436
- summary = "CLONE - #{issue_data[:fields][:summary]}"
445
+ original_summary = issue_data[:fields][:summary]
446
+ summary = "CLONE - #{original_summary}"
447
+
448
+ # Determine issue type early
449
+ issue_type = issue_data[:fields][:issuetype][:name].downcase.to_sym
450
+ issue_type_id = issue_data[:fields][:issuetype][:id]
451
+
452
+ # Epic name handling (only if original issue is an epic)
437
453
  epic_name = nil
438
454
  epic_name_field_key = nil
439
455
  if issue_type == :epic
440
456
  all_fields = get_all_fields
441
- epic_name_field_key = all_fields.find { |field| field[:name] == 'Epic Name' }[:id]
442
- epic_name = issue_data[:fields][epic_name_field_key.to_sym]
457
+ epic_field_obj = all_fields.find { |field| field[:name] == 'Epic Name' }
458
+ epic_name_field_key = epic_field_obj[:id] if epic_field_obj
459
+ epic_name = issue_data[:fields][epic_name_field_key.to_sym] if epic_name_field_key
443
460
  end
444
461
 
445
462
  description = issue_data[:fields][:description]
446
463
 
447
- # Determine issue type (was previously missing) and create metadata
448
- issue_type = issue_data[:fields][:issuetype][:name].downcase.to_sym
449
- issue_type_id = issue_data[:fields][:issuetype][:id]
450
-
464
+ # Fetch create metadata to understand which fields can be set
451
465
  meta = get_issue_type_metadata(
452
466
  project_key: project_key,
453
467
  issue_type_id: issue_type_id
454
468
  )
455
469
  candidate_array = meta[:values] ||= []
456
470
 
457
- # Build list of fields we can 'set' on create (per create metadata)
471
+ # Build list of fields we can set on create (operations include 'set' OR empty operations)
458
472
  allowed_fields = []
459
473
  candidate_array.each do |field_obj|
460
474
  next unless field_obj.is_a?(Hash)
461
475
 
462
476
  ops = field_obj[:operations] ||= []
463
- next unless ops.include?('set')
477
+ # Permit if 'set' allowed or operations list empty (often still creatable)
478
+ next unless ops.empty? || ops.include?('set')
464
479
 
465
480
  field_key = field_obj[:key] || field_obj[:id] || field_obj[:fieldId]
466
481
  next if field_key.nil? || field_key.to_s.empty?
467
482
 
468
- allowed_fields.push(field_key.to_s)
483
+ allowed_fields << field_key.to_s
469
484
  end
470
485
 
471
486
  reserved_fields = %i[project summary issuetype description]
472
- reserved_fields.push(epic_name_field_key.to_sym) if epic_name_field_key
487
+ reserved_fields << epic_name_field_key.to_sym if epic_name_field_key
473
488
 
474
489
  filtered_fields = {}
475
490
  issue_data[:fields].each do |k, v|
@@ -482,11 +497,21 @@ module PWN
482
497
 
483
498
  case v
484
499
  when Array
485
- filtered_fields[k] = v.map { |elem| elem.is_a?(Hash) ? elem.slice(*%i[id key name value]) : elem }
500
+ # Preserve minimal identifying attributes for each element; if element is primitive keep as-is
501
+ filtered_fields[k] = v.map do |elem|
502
+ if elem.is_a?(Hash)
503
+ # Retain common identifier keys; if none present keep full hash
504
+ keys_to_keep = %i[id key name value]
505
+ elem.keys.any? { |kk| keys_to_keep.include?(kk) } ? elem.slice(*keys_to_keep) : elem
506
+ else
507
+ elem
508
+ end
509
+ end
486
510
  when Hash
511
+ keys_to_keep = %i[id key name value]
487
512
  filtered_fields[k] =
488
- if v.keys.any? { |kk| %i[id key name value].include?(kk) }
489
- v.slice(*%i[id key name value])
513
+ if v.keys.any? { |kk| keys_to_keep.include?(kk) }
514
+ v.slice(*keys_to_keep)
490
515
  else
491
516
  v
492
517
  end
@@ -497,14 +522,27 @@ module PWN
497
522
 
498
523
  additional_fields = { fields: filtered_fields }
499
524
 
500
- create_issue(
525
+ attachments = []
526
+ if copy_attachments
527
+ attachments_obj = issue_data[:fields][:attachment] ||= []
528
+ attachments_obj.each do |att_obj|
529
+ attachments.push(att_obj[:filename])
530
+ end
531
+ end
532
+
533
+ # Create the cloned issue
534
+ cloned_issue = create_issue(
501
535
  project_key: project_key,
502
536
  summary: summary,
503
537
  issue_type: issue_type,
504
538
  epic_name: epic_name,
505
539
  description: description,
506
- additional_fields: additional_fields
540
+ additional_fields: additional_fields,
541
+ attachments: attachments
507
542
  )
543
+
544
+ # Return the fully fetched cloned issue
545
+ get_issue(issue: cloned_issue[:key])
508
546
  rescue StandardError => e
509
547
  raise e
510
548
  end
@@ -598,7 +636,8 @@ module PWN
598
636
  )
599
637
 
600
638
  issue_resp = #{self}.clone_issue(
601
- issue: 'required - issue to clone (e.g. Bug, Issue, Story, or Epic ID)'
639
+ issue: 'required - issue to clone (e.g. Bug, Issue, Story, or Epic ID)',
640
+ copy_attachments: 'optional - boolean to indicate whether to copy attachments (Defaults to false)'
602
641
  )
603
642
 
604
643
  issue_resp = #{self}.delete_issue(
data/lib/pwn/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.5.469'
4
+ VERSION = '0.5.470'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.469
4
+ version: 0.5.470
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.