jira_scan 0.0.2 → 0.0.3

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.
Files changed (4) hide show
  1. checksums.yaml +8 -8
  2. data/bin/jira-scan +21 -5
  3. data/lib/jira_scan.rb +86 -8
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YmVmMjdhMTg1NThlZmMzNDBjNzE3Y2Q0MjY3NzQ1MTY5OTRlMjc5Yg==
4
+ N2U3MTgzNjZlMDY0N2Q5MzJiMTJhYjFlZjA3ODg4Njg3YmNmYzVlOA==
5
5
  data.tar.gz: !binary |-
6
- OTk3Mjc4M2FiNDU0MzdlYjU0ZjhiYTA2MzdlNWRjZjk2YWQ5NzQxOA==
6
+ ZTBmYmNhMmQ0MDQ0MTdmY2Q4MWRiYzQ1MzUxMWNmOWJmNmQwZjljOQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDk2MTdhZjM5ZWI3Y2NjYWIwNzI0MzhiZjU1NzNiNDg3NDU2NjViODJlZjQ2
10
- ZDg4YTg3NGQ1YTg4NGMwZTMyMDNlNjVkNzhhOGMxZTEzMGY5ODdiNDgzMzkw
11
- ZGYwM2E1MDJkZjkxZDY2NzdjNGU3NTMzZDEzNmY0Zjk2MzQ1ZDI=
9
+ ZTg1NzllMDk0MWNlNWRjZDEwNTcyMTc0YWJlMmMzYjUzYjk3ZjUzMjkyYWIw
10
+ M2U2YmI5MjllMTEzNTc0NGE4YWVkMzE0Y2I2MzVkOWY3NDAyYjc1MTVkZjQ2
11
+ YTJjMGZiYTcyYWFjMjRmZmI2YzdkMDAwMTVkMTVjYzRlODVmNDE=
12
12
  data.tar.gz: !binary |-
13
- NzA2ODczZTI3YzAxYWFhYmEyMWMyMjJjYjJhYzIyN2I0ZDkzYjllZThiMTZi
14
- MTNhMWNjYmZkZThhZTNkNThmY2UzOWJjMTQ5YTk2M2NjZWY2ZTRmNDQzZjAy
15
- Y2RiMzZhMmQ1YzUzNDg0ZDIxNDA3YjEwOWNkZmQzMjBmMzgzYmE=
13
+ NDc1ODc0MjIzMGY1YzlkMGYzMGY4Y2Q1ZmI3MDkwNjczNzI4ZDE5NDdhYmQ1
14
+ NzgwMTZiOGU3N2Y3MGVkYTQxMGE1ODMxMTVkNTBjNTIwOTQxMjI2OTJkZTg0
15
+ YmExYzZlOWFkNGUyODZkYTA0M2QwYWJhZTI1YmQwZGM5N2UxNmQ=
data/bin/jira-scan CHANGED
@@ -17,7 +17,7 @@ def banner
17
17
  _ | | | '__/ _` |\\___ \\ / __/ _` | '_ \\
18
18
  | |__| | | | | (_| |____) | (_| (_| | | | |
19
19
  \\____/|_|_| \\__,_|_____/ \\___\\__,_|_| |_|
20
- version 0.0.2"
20
+ version 0.0.3"
21
21
  puts
22
22
  puts '-' * 60
23
23
  end
@@ -39,6 +39,10 @@ opts = OptionParser.new do |o|
39
39
  options[:skip] = true
40
40
  end
41
41
 
42
+ o.on('-i', '--insecure', 'Skip SSL/TLS validation') do
43
+ options[:insecure] = true
44
+ end
45
+
42
46
  o.on('-v', '--verbose', 'Enable verbose output') do
43
47
  options[:verbose] = true
44
48
  end
@@ -53,6 +57,7 @@ opts.parse!
53
57
 
54
58
  $VERBOSE = true unless options[:verbose].nil?
55
59
  @check = true unless options[:skip]
60
+ @insecure = false unless options[:insecure]
56
61
 
57
62
  if options[:url].nil?
58
63
  puts opts
@@ -85,7 +90,9 @@ def scan(url)
85
90
 
86
91
  # Check if the URL is Jira
87
92
  if @check
88
- unless JiraScan::isJira(url)
93
+ is_jira = JiraScan::detectJiraDashboard(url)
94
+ is_jira = JiraScan::detectJiraLogin(url) unless is_jira
95
+ unless is_jira
89
96
  puts '- Jira not found'
90
97
  exit(1)
91
98
  end
@@ -93,7 +100,8 @@ def scan(url)
93
100
  end
94
101
 
95
102
  # Get Jira version
96
- version = JiraScan::getVersion(url)
103
+ version = JiraScan::getVersionFromDashboard(url)
104
+ version = JiraScan::getVersionFromLogin(url) unless version
97
105
  puts "+ Version: #{version}" if version
98
106
 
99
107
  # Dev mode enabled
@@ -109,7 +117,7 @@ def scan(url)
109
117
  if user_picker
110
118
  puts '+ User Picker Browser is available'
111
119
  # Retrieve list of first 1,000 users
112
- users = JiraScan::getUsersFromUserPicker(url)
120
+ users = JiraScan::getUsersFromUserPickerBrowser(url)
113
121
  unless users.empty?
114
122
  puts "+ Found users (#{users.length}):"
115
123
  table = Terminal::Table.new :headings => ['Username', 'Full Name', 'Email'], :rows => users
@@ -150,7 +158,15 @@ def scan(url)
150
158
  end
151
159
 
152
160
  # Retrieve list of field names
153
- field_names = JiraScan::getFieldNames(url)
161
+ field_names = JiraScan::getFieldNamesQueryComponentDefault(url)
162
+ unless field_names.empty?
163
+ puts "+ Found field names (#{field_names.length}):"
164
+ table = Terminal::Table.new :headings => ['Name', 'ID', 'Key', 'IsShown', 'Last Viewed'], :rows => field_names
165
+ puts table
166
+ end
167
+
168
+ # Retrieve list of field names
169
+ field_names = JiraScan::getFieldNamesQueryComponentJql(url)
154
170
  unless field_names.empty?
155
171
  puts "+ Found field names (#{field_names.length}):"
156
172
  table = Terminal::Table.new :headings => ['Name', 'ID', 'Key', 'IsShown', 'Last Viewed'], :rows => field_names
data/lib/jira_scan.rb CHANGED
@@ -10,16 +10,33 @@ require 'net/http'
10
10
  require 'openssl'
11
11
 
12
12
  class JiraScan
13
- VERSION = '0.0.2'.freeze
13
+ VERSION = '0.0.3'.freeze
14
14
 
15
15
  #
16
- # Check if Jira
16
+ # Check if URL is running Jira using Login page
17
17
  #
18
18
  # @param [String] URL
19
19
  #
20
20
  # @return [Boolean]
21
21
  #
22
- def self.isJira(url)
22
+ def self.detectJiraLogin(url)
23
+ url += '/' unless url.to_s.end_with? '/'
24
+ res = sendHttpRequest("#{url}login.jsp")
25
+
26
+ return false unless res
27
+ return false unless res.code.to_i == 200
28
+
29
+ res.body.to_s.include?('JIRA')
30
+ end
31
+
32
+ #
33
+ # Check if URL is running Jira using Dashboard page
34
+ #
35
+ # @param [String] URL
36
+ #
37
+ # @return [Boolean]
38
+ #
39
+ def self.detectJiraDashboard(url)
23
40
  url += '/' unless url.to_s.end_with? '/'
24
41
  res = sendHttpRequest("#{url}secure/Dashboard.jspa")
25
42
 
@@ -30,13 +47,13 @@ class JiraScan
30
47
  end
31
48
 
32
49
  #
33
- # Get Jira version
50
+ # Get Jira version from Dashboard page
34
51
  #
35
52
  # @param [String] URL
36
53
  #
37
54
  # @return [String] Jira version
38
55
  #
39
- def self.getVersion(url)
56
+ def self.getVersionFromDashboard(url)
40
57
  url += '/' unless url.to_s.end_with? '/'
41
58
  res = sendHttpRequest("#{url}secure/Dashboard.jspa")
42
59
 
@@ -58,6 +75,35 @@ class JiraScan
58
75
  "#{version}-##{build}"
59
76
  end
60
77
 
78
+ #
79
+ # Get Jira version from Login page
80
+ #
81
+ # @param [String] URL
82
+ #
83
+ # @return [String] Jira version
84
+ #
85
+ def self.getVersionFromLogin(url)
86
+ url += '/' unless url.to_s.end_with? '/'
87
+ res = sendHttpRequest("#{url}login.jsp")
88
+
89
+ return unless res
90
+ return unless res.code.to_i == 200
91
+
92
+ version = res.body.to_s.scan(%r{<meta name="ajs-version-number" content="([\d\.]+)">}).flatten.first
93
+ build = res.body.to_s.scan(%r{<meta name="ajs-build-number" content="(\d+)">}).flatten.first
94
+
95
+ unless version && build
96
+ if res.body.to_s =~ /Version: ([\d\.]+)-#(\d+)/
97
+ version = $1
98
+ build = $2
99
+ else
100
+ return
101
+ end
102
+ end
103
+
104
+ "#{version}-##{build}"
105
+ end
106
+
61
107
  #
62
108
  # Check if dev mode is enabled
63
109
  #
@@ -258,7 +304,7 @@ class JiraScan
258
304
  #
259
305
  # @return [Array] list of field names
260
306
  #
261
- def self.getFieldNames(url)
307
+ def self.getFieldNamesQueryComponentDefault(url)
262
308
  url += '/' unless url.to_s.end_with? '/'
263
309
  res = sendHttpRequest("#{url}secure/QueryComponent!Default.jspa")
264
310
 
@@ -284,6 +330,39 @@ class JiraScan
284
330
  []
285
331
  end
286
332
 
333
+ #
334
+ # Retrieve list of field names from QueryComponent!Jql.jspa (EDB-49924)
335
+ #
336
+ # @param [String] URL
337
+ #
338
+ # @return [Array] list of field names
339
+ #
340
+ def self.getFieldNamesQueryComponentJql(url)
341
+ url += '/' unless url.to_s.end_with? '/'
342
+ res = sendHttpRequest("#{url}secure/QueryComponent!Jql.jspa?jql=")
343
+
344
+ return [] unless res
345
+ return [] unless res.code.to_i == 200
346
+ return [] unless res.body.to_s.start_with?('{"searchers"')
347
+
348
+ searchers = JSON.parse(res.body.to_s)["searchers"]
349
+ return [] if searchers.empty?
350
+
351
+ groups = searchers['groups']
352
+ return [] if groups.empty?
353
+
354
+ field_names = []
355
+ groups.each do |g|
356
+ g['searchers'].each do |s|
357
+ field_names << s
358
+ end
359
+ end
360
+
361
+ JSON.parse(field_names.to_json, symbolize_names: true).map {|f| [f[:name], f[:id], f[:key], f[:isShown].to_s, f[:lastViewed]] }
362
+ rescue
363
+ []
364
+ end
365
+
287
366
  private
288
367
 
289
368
  #
@@ -299,8 +378,7 @@ class JiraScan
299
378
  http = Net::HTTP.new(target.host, target.port)
300
379
  if target.scheme.to_s.eql?('https')
301
380
  http.use_ssl = true
302
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
303
- # http.verify_mode = OpenSSL::SSL::VERIFY_PEER
381
+ http.verify_mode = @insecure ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
304
382
  end
305
383
  http.open_timeout = 20
306
384
  http.read_timeout = 20
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jira_scan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brendan Coles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-23 00:00:00.000000000 Z
11
+ date: 2021-07-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple remote scanner for Atlassian Jira
14
14
  email: bcoles@gmail.com