appmap 0.32.0 → 0.34.4

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.
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe AppMap::Open do
6
+ context 'a block of Ruby code' do
7
+ it 'opens in the browser' do
8
+ appmap = AppMap.record do
9
+ File.read __FILE__
10
+ end
11
+
12
+ open = AppMap::Open.new(appmap)
13
+ server = open.run_server
14
+ page = Net::HTTP.get URI.parse("http://localhost:#{open.port}")
15
+ expect(page).to include(%(name="data" value='{"version))
16
+ server.kill
17
+ end
18
+ end
19
+ end
@@ -56,10 +56,12 @@ class CLITest < Minitest::Test
56
56
  Class frequency:
57
57
  ----------------
58
58
  1 Main
59
+ 1 IO
59
60
 
60
61
  Method frequency:
61
62
  ----------------
62
63
  1 Main.say_hello
64
+ 1 IO#write
63
65
  OUTPUT
64
66
  end
65
67
 
@@ -80,12 +82,20 @@ class CLITest < Minitest::Test
80
82
  {
81
83
  "name": "Main",
82
84
  "count": 1
85
+ },
86
+ {
87
+ "name": "IO",
88
+ "count": 1
83
89
  }
84
90
  ],
85
91
  "method_frequency": [
86
92
  {
87
93
  "name": "Main.say_hello",
88
94
  "count": 1
95
+ },
96
+ {
97
+ "name": "IO#write",
98
+ "count": 1
89
99
  }
90
100
  ]
91
101
  }
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'appmap', git: 'applandinc/appmap-ruby', branch: `git rev-parse --abbrev-ref HEAD`.strip
@@ -0,0 +1,3 @@
1
+ name: openssl_recorder
2
+ packages:
3
+ - path: lib
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ # From the manual page https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL.html
4
+
5
+ require 'openssl'
6
+
7
+ module Example
8
+ def Example.sign
9
+ ca_key = OpenSSL::PKey::RSA.new 2048
10
+ pass_phrase = 'my secure pass phrase goes here'
11
+
12
+ cipher = OpenSSL::Cipher.new 'AES-256-CBC'
13
+
14
+ open 'tmp/ca_key.pem', 'w', 0644 do |io|
15
+ io.write ca_key.export(cipher, pass_phrase)
16
+ end
17
+
18
+ ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example'
19
+
20
+ ca_cert = OpenSSL::X509::Certificate.new
21
+ ca_cert.serial = 0
22
+ ca_cert.version = 2
23
+ ca_cert.not_before = Time.now
24
+ ca_cert.not_after = Time.now + 86400
25
+
26
+ ca_cert.public_key = ca_key.public_key
27
+ ca_cert.subject = ca_name
28
+ ca_cert.issuer = ca_name
29
+
30
+ extension_factory = OpenSSL::X509::ExtensionFactory.new
31
+ extension_factory.subject_certificate = ca_cert
32
+ extension_factory.issuer_certificate = ca_cert
33
+
34
+ ca_cert.add_extension extension_factory.create_extension('subjectKeyIdentifier', 'hash')
35
+ ca_cert.add_extension extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
36
+
37
+ ca_cert.add_extension extension_factory.create_extension(
38
+ 'keyUsage', 'cRLSign,keyCertSign', true)
39
+
40
+ ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
41
+
42
+ open 'tmp/ca_cert.pem', 'w' do |io|
43
+ io.write ca_cert.to_pem
44
+ end
45
+
46
+ csr = OpenSSL::X509::Request.new
47
+ csr.version = 0
48
+ csr.subject = OpenSSL::X509::Name.new([ ['CN', 'the name to sign', OpenSSL::ASN1::UTF8STRING] ])
49
+ csr.public_key = ca_key.public_key
50
+ csr.sign ca_key, OpenSSL::Digest::SHA1.new
51
+
52
+ open 'tmp/csr.pem', 'w' do |io|
53
+ io.write csr.to_pem
54
+ end
55
+
56
+ csr = OpenSSL::X509::Request.new File.read 'tmp/csr.pem'
57
+
58
+ raise 'CSR can not be verified' unless csr.verify csr.public_key
59
+
60
+ csr_cert = OpenSSL::X509::Certificate.new
61
+ csr_cert.serial = 0
62
+ csr_cert.version = 2
63
+ csr_cert.not_before = Time.now
64
+ csr_cert.not_after = Time.now + 600
65
+
66
+ csr_cert.subject = csr.subject
67
+ csr_cert.public_key = csr.public_key
68
+ csr_cert.issuer = ca_cert.subject
69
+
70
+ extension_factory = OpenSSL::X509::ExtensionFactory.new
71
+ extension_factory.subject_certificate = csr_cert
72
+ extension_factory.issuer_certificate = ca_cert
73
+
74
+ csr_cert.add_extension extension_factory.create_extension('basicConstraints', 'CA:FALSE')
75
+
76
+ csr_cert.add_extension extension_factory.create_extension(
77
+ 'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
78
+
79
+ csr_cert.add_extension extension_factory.create_extension('subjectKeyIdentifier', 'hash')
80
+
81
+ csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
82
+
83
+ 'tmp/csr_cert.pem'.tap do |fname|
84
+ open fname, 'w' do |io|
85
+ io.write csr_cert.to_pem
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ if __FILE__ == $0
92
+ cert_file = Example.sign
93
+ puts "Wrote cert file #{cert_file}"
94
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # From the manual page https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL.html
4
+
5
+ require 'openssl'
6
+
7
+ module Example
8
+ def Example.encrypt
9
+ cipher = OpenSSL::Cipher.new 'AES-256-CBC'
10
+ cipher.encrypt
11
+ iv = cipher.random_iv
12
+
13
+ pwd = 'some hopefully not to easily guessable password'
14
+ salt = OpenSSL::Random.random_bytes 16
15
+ iter = 20000
16
+ key_len = cipher.key_len
17
+ digest = OpenSSL::Digest::SHA256.new
18
+
19
+ key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
20
+ cipher.key = key
21
+
22
+ document = 'the document'
23
+
24
+ encrypted = cipher.update document
25
+ encrypted << cipher.final
26
+ encrypted
27
+ end
28
+ end
29
+
30
+ if __FILE__ == $0
31
+ ciphertext = Example.encrypt
32
+ require 'base64'
33
+ puts "Computed ciphertext #{Base64.urlsafe_encode64(ciphertext)}"
34
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ # From the manual page https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL.html
4
+
5
+ require 'appmap'
6
+ require 'openssl'
7
+ require 'openssl/digest'
8
+
9
+ module Example
10
+ def Example.sign
11
+ key = OpenSSL::PKey::RSA.new 2048
12
+
13
+ document = 'the document'
14
+
15
+ digest = OpenSSL::Digest::SHA256.new
16
+ key.sign digest, document
17
+ end
18
+ end
19
+
20
+ if __FILE__ == $0
21
+ appmap = AppMap.record do
22
+ Example.sign
23
+ puts 'Computed signature'
24
+ end
25
+ appmap['metadata'] = [ 'recorder' => __FILE__ ]
26
+
27
+ File.write('appmap.json', JSON.generate(appmap))
28
+ end
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'test_helper'
5
+ require 'English'
6
+
7
+ class OpenSSLTest < Minitest::Test
8
+ def perform_test(test_name)
9
+ Bundler.with_clean_env do
10
+ Dir.chdir 'test/fixtures/openssl_recorder' do
11
+ FileUtils.rm_rf 'tmp'
12
+ system 'bundle config --local local.appmap ../../..'
13
+ system 'bundle'
14
+ system({ 'APPMAP' => 'true', 'DEBUG' => 'true' }, %(bundle exec ruby lib/openssl_#{test_name}.rb))
15
+
16
+ yield
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_key_sign
22
+ perform_test 'key_sign' do
23
+ appmap_file = 'appmap.json'
24
+
25
+ assert File.file?(appmap_file), 'appmap output file does not exist'
26
+ appmap = JSON.parse(File.read(appmap_file))
27
+ assert_equal AppMap::APPMAP_FORMAT_VERSION, appmap['version']
28
+ assert_equal [ { 'recorder' => 'lib/openssl_key_sign.rb' } ], appmap['metadata']
29
+ assert_equal JSON.parse(<<~JSON), appmap['classMap']
30
+ [
31
+ {
32
+ "name": "lib",
33
+ "type": "package",
34
+ "children": [
35
+ {
36
+ "name": "Example",
37
+ "type": "class",
38
+ "children": [
39
+ {
40
+ "name": "sign",
41
+ "type": "function",
42
+ "location": "lib/openssl_key_sign.rb:10",
43
+ "static": true
44
+ }
45
+ ]
46
+ }
47
+ ]
48
+ },
49
+ {
50
+ "name": "openssl",
51
+ "type": "package",
52
+ "children": [
53
+ {
54
+ "name": "OpenSSL",
55
+ "type": "class",
56
+ "children": [
57
+ {
58
+ "name": "PKey",
59
+ "type": "class",
60
+ "children": [
61
+ {
62
+ "name": "PKey",
63
+ "type": "class",
64
+ "children": [
65
+ {
66
+ "name": "sign",
67
+ "type": "function",
68
+ "location": "OpenSSL::PKey::PKey#sign",
69
+ "static": false,
70
+ "labels": [
71
+ "security",
72
+ "crypto"
73
+ ]
74
+ }
75
+ ]
76
+ }
77
+ ]
78
+ }
79
+ ]
80
+ }
81
+ ]
82
+ },
83
+ {
84
+ "name": "io",
85
+ "type": "package",
86
+ "children": [
87
+ {
88
+ "name": "IO",
89
+ "type": "class",
90
+ "children": [
91
+ {
92
+ "name": "write",
93
+ "type": "function",
94
+ "location": "IO#write",
95
+ "static": false,
96
+ "labels": [
97
+ "io"
98
+ ]
99
+ }
100
+ ]
101
+ }
102
+ ]
103
+ }
104
+ ]
105
+ JSON
106
+ sanitized_events = appmap['events'].map(&:deep_symbolize_keys).map(&AppMap::Util.method(:sanitize_event)).map do |event|
107
+ delete_value = ->(obj) { (obj || {}).delete(:value) }
108
+ delete_value.call(event[:receiver])
109
+ delete_value.call(event[:return_value])
110
+ event
111
+ end
112
+
113
+ diff = Diffy::Diff.new(<<~JSON.strip, JSON.pretty_generate(sanitized_events).strip)
114
+ [
115
+ {
116
+ "id": 1,
117
+ "event": "call",
118
+ "defined_class": "Example",
119
+ "method_id": "sign",
120
+ "path": "lib/openssl_key_sign.rb",
121
+ "lineno": 10,
122
+ "static": true,
123
+ "parameters": [
124
+
125
+ ],
126
+ "receiver": {
127
+ "class": "Module"
128
+ }
129
+ },
130
+ {
131
+ "id": 2,
132
+ "event": "call",
133
+ "defined_class": "OpenSSL::PKey::PKey",
134
+ "method_id": "sign",
135
+ "path": "OpenSSL::PKey::PKey#sign",
136
+ "static": false,
137
+ "parameters": [
138
+ {
139
+ "name": "arg",
140
+ "class": "OpenSSL::Digest::SHA256",
141
+ "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
142
+ "kind": "req"
143
+ },
144
+ {
145
+ "name": "arg",
146
+ "class": "String",
147
+ "value": "the document",
148
+ "kind": "req"
149
+ }
150
+ ],
151
+ "receiver": {
152
+ "class": "OpenSSL::PKey::RSA"
153
+ }
154
+ },
155
+ {
156
+ "id": 3,
157
+ "event": "return",
158
+ "parent_id": 2,
159
+ "return_value": {
160
+ "class": "String"
161
+ }
162
+ },
163
+ {
164
+ "id": 4,
165
+ "event": "return",
166
+ "parent_id": 1,
167
+ "return_value": {
168
+ "class": "String"
169
+ }
170
+ },
171
+ {
172
+ "id": 5,
173
+ "event": "call",
174
+ "defined_class": "IO",
175
+ "method_id": "write",
176
+ "path": "IO#write",
177
+ "static": false,
178
+ "parameters": [
179
+ {
180
+ "name": "arg",
181
+ "class": "String",
182
+ "value": "Computed signature",
183
+ "kind": "rest"
184
+ }
185
+ ],
186
+ "receiver": {
187
+ "class": "IO"
188
+ }
189
+ },
190
+ {
191
+ "id": 6,
192
+ "event": "return",
193
+ "parent_id": 5,
194
+ "return_value": {
195
+ "class": "Integer"
196
+ }
197
+ }
198
+ ]
199
+ JSON
200
+ assert_equal '', diff.to_s
201
+ end
202
+ end
203
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.0
4
+ version: 0.34.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Gilpin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-05 00:00:00.000000000 Z
11
+ date: 2020-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: bundler
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +164,20 @@ dependencies:
150
164
  - - ">="
151
165
  - !ruby/object:Gem::Version
152
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rake-compiler
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
153
181
  - !ruby/object:Gem::Dependency
154
182
  name: climate_control
155
183
  requirement: !ruby/object:Gem::Requirement
@@ -234,16 +262,46 @@ dependencies:
234
262
  - - "~>"
235
263
  - !ruby/object:Gem::Version
236
264
  version: '4.0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: timecop
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: '0'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - ">="
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
279
+ - !ruby/object:Gem::Dependency
280
+ name: hashie
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ type: :development
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ">="
291
+ - !ruby/object:Gem::Version
292
+ version: '0'
237
293
  description:
238
294
  email:
239
295
  - kgilpin@gmail.com
240
296
  executables:
241
297
  - appmap
242
- extensions: []
298
+ extensions:
299
+ - ext/appmap/extconf.rb
243
300
  extra_rdoc_files: []
244
301
  files:
245
302
  - ".dockerignore"
246
303
  - ".gitignore"
304
+ - ".rbenv-gemsets"
247
305
  - ".rubocop.yml"
248
306
  - ".ruby-version"
249
307
  - ".travis.yml"
@@ -263,6 +321,8 @@ files:
263
321
  - examples/mock_webapp/lib/mock_webapp/request.rb
264
322
  - examples/mock_webapp/lib/mock_webapp/user.rb
265
323
  - exe/appmap
324
+ - ext/appmap/appmap.c
325
+ - ext/appmap/extconf.rb
266
326
  - lib/appmap.rb
267
327
  - lib/appmap/algorithm/prune_class_map.rb
268
328
  - lib/appmap/algorithm/stats.rb
@@ -277,6 +337,7 @@ files:
277
337
  - lib/appmap/metadata.rb
278
338
  - lib/appmap/middleware/remote_recording.rb
279
339
  - lib/appmap/minitest.rb
340
+ - lib/appmap/open.rb
280
341
  - lib/appmap/rails/action_handler.rb
281
342
  - lib/appmap/rails/sql_handler.rb
282
343
  - lib/appmap/railtie.rb
@@ -457,6 +518,7 @@ files:
457
518
  - spec/fixtures/rails_users_app/spec/spec_helper.rb
458
519
  - spec/fixtures/rails_users_app/users_app/.gitignore
459
520
  - spec/hook_spec.rb
521
+ - spec/open_spec.rb
460
522
  - spec/rails_spec_helper.rb
461
523
  - spec/railtie_spec.rb
462
524
  - spec/record_sql_rails4_pg_spec.rb
@@ -487,6 +549,11 @@ files:
487
549
  - test/fixtures/minitest_recorder/appmap.yml
488
550
  - test/fixtures/minitest_recorder/lib/hello.rb
489
551
  - test/fixtures/minitest_recorder/test/hello_test.rb
552
+ - test/fixtures/openssl_recorder/Gemfile
553
+ - test/fixtures/openssl_recorder/appmap.yml
554
+ - test/fixtures/openssl_recorder/lib/openssl_cert_sign.rb
555
+ - test/fixtures/openssl_recorder/lib/openssl_encrypt.rb
556
+ - test/fixtures/openssl_recorder/lib/openssl_key_sign.rb
490
557
  - test/fixtures/process_recorder/appmap.yml
491
558
  - test/fixtures/process_recorder/hello.rb
492
559
  - test/fixtures/rspec_recorder/Gemfile
@@ -496,6 +563,7 @@ files:
496
563
  - test/fixtures/rspec_recorder/spec/labeled_hello_spec.rb
497
564
  - test/fixtures/rspec_recorder/spec/plain_hello_spec.rb
498
565
  - test/minitest_test.rb
566
+ - test/openssl_test.rb
499
567
  - test/record_process_test.rb
500
568
  - test/rspec_test.rb
501
569
  - test/test_helper.rb