jira_scan 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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