cased-ruby 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +20 -15
  3. data/README.md +14 -41
  4. data/bin/cli +14 -0
  5. data/cased-ruby.gemspec +2 -0
  6. data/lib/cased.rb +1 -0
  7. data/lib/cased/cli.rb +13 -0
  8. data/lib/cased/cli/asciinema/file.rb +108 -0
  9. data/lib/cased/cli/asciinema/writer.rb +67 -0
  10. data/lib/cased/cli/authentication.rb +31 -0
  11. data/lib/cased/cli/identity.rb +38 -0
  12. data/lib/cased/cli/interactive_session.rb +84 -0
  13. data/lib/cased/cli/log.rb +25 -0
  14. data/lib/cased/cli/recorder.rb +57 -0
  15. data/lib/cased/cli/session.rb +278 -0
  16. data/lib/cased/clients.rb +7 -3
  17. data/lib/cased/config.rb +40 -0
  18. data/lib/cased/http/client.rb +13 -6
  19. data/lib/cased/http/error.rb +5 -2
  20. data/lib/cased/query.rb +6 -3
  21. data/lib/cased/version.rb +1 -1
  22. data/vendor/cache/activesupport-6.1.3.gem +0 -0
  23. data/vendor/cache/concurrent-ruby-1.1.8.gem +0 -0
  24. data/vendor/cache/faraday-1.3.0.gem +0 -0
  25. data/vendor/cache/faraday-net_http-1.0.1.gem +0 -0
  26. data/vendor/cache/i18n-1.8.9.gem +0 -0
  27. data/vendor/cache/json-2.5.1.gem +0 -0
  28. data/vendor/cache/jwt-2.2.2.gem +0 -0
  29. data/vendor/cache/ruby2_keywords-0.0.4.gem +0 -0
  30. data/vendor/cache/subprocess-1.5.4.gem +0 -0
  31. data/vendor/cache/tzinfo-2.0.4.gem +0 -0
  32. data/vendor/cache/zeitwerk-2.4.2.gem +0 -0
  33. metadata +51 -11
  34. data/vendor/cache/activesupport-6.0.3.4.gem +0 -0
  35. data/vendor/cache/concurrent-ruby-1.1.7.gem +0 -0
  36. data/vendor/cache/faraday-1.1.0.gem +0 -0
  37. data/vendor/cache/i18n-1.8.5.gem +0 -0
  38. data/vendor/cache/json-2.3.1.gem +0 -0
  39. data/vendor/cache/ruby2_keywords-0.0.2.gem +0 -0
  40. data/vendor/cache/thread_safe-0.3.6.gem +0 -0
  41. data/vendor/cache/tzinfo-1.2.7.gem +0 -0
  42. data/vendor/cache/zeitwerk-2.4.0.gem +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 45c422e1920ea510d16c5c8a5b91016ac2a4eedb9a2b880ff29018dc18580a13
4
- data.tar.gz: 83e14abb44637e8d61a3fff592d8b434cbf8373cd8a4c8afede513cf89852f8a
3
+ metadata.gz: e22f14bbfac74d8d6ed2565ab7d4dd2607b03178a8534e15681ebad08aadd047
4
+ data.tar.gz: aeec32fc2d39829a6e4c24b4b8024b416dad08d84528d13eaa2d310c4a3c2c59
5
5
  SHA512:
6
- metadata.gz: 5beffb4be2a539b74e6145c4d4b7b96ae6aea94c2bb5cdf9a79dfb90bfaeac615c80b537db0249702d807acb7f69727ff7b81cfc62896d03ad6e2c44124c1360
7
- data.tar.gz: 8ae4ac844f566981de31a5d51ecfe28d4e665f9cebd5c6f5327a596b052e43e92ab0d7db9bb07029211f0786db5baf00035db8022a376b5ea3ba30ac512dbbda
6
+ metadata.gz: ba38566776a824c05f9750a72ca0e0b878279a07e5134fac83d54e9f10d462a8a940bf01f5d0968c1654adfb9a196f3d7ad6398614c987e41168bdf81d40cd93
7
+ data.tar.gz: f5bde94bab92b5cfc4dce4a146ca5a1d02d7946f14e5003386b3b82c920c656b92665b801b5ae5ef116316b0d33e7c3d727a730bda46426e30d08380b7bac798
data/Gemfile.lock CHANGED
@@ -1,43 +1,48 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cased-ruby (0.3.3)
4
+ cased-ruby (0.4.0)
5
5
  activesupport (~> 6)
6
6
  dotpath (= 0.1.0)
7
7
  faraday (~> 1.0)
8
8
  faraday_middleware (~> 1.0)
9
9
  json (~> 2)
10
+ jwt (~> 2)
10
11
  net-http-persistent (~> 3.0)
12
+ subprocess (~> 1.5.0)
11
13
 
12
14
  GEM
13
15
  remote: https://rubygems.org/
14
16
  specs:
15
- activesupport (6.0.3.4)
17
+ activesupport (6.1.3)
16
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
17
- i18n (>= 0.7, < 2)
18
- minitest (~> 5.1)
19
- tzinfo (~> 1.1)
20
- zeitwerk (~> 2.2, >= 2.2.2)
19
+ i18n (>= 1.6, < 2)
20
+ minitest (>= 5.1)
21
+ tzinfo (~> 2.0)
22
+ zeitwerk (~> 2.3)
21
23
  addressable (2.7.0)
22
24
  public_suffix (>= 2.0.2, < 5.0)
23
25
  ast (2.4.0)
24
26
  byebug (11.0.1)
25
- concurrent-ruby (1.1.7)
27
+ concurrent-ruby (1.1.8)
26
28
  connection_pool (2.2.2)
27
29
  crack (0.4.3)
28
30
  safe_yaml (~> 1.0.0)
29
31
  docile (1.3.2)
30
32
  dotpath (0.1.0)
31
- faraday (1.1.0)
33
+ faraday (1.3.0)
34
+ faraday-net_http (~> 1.0)
32
35
  multipart-post (>= 1.2, < 3)
33
36
  ruby2_keywords
37
+ faraday-net_http (1.0.1)
34
38
  faraday_middleware (1.0.0)
35
39
  faraday (~> 1.0)
36
40
  hashdiff (1.0.1)
37
- i18n (1.8.5)
41
+ i18n (1.8.9)
38
42
  concurrent-ruby (~> 1.0)
39
43
  jaro_winkler (1.5.4)
40
- json (2.3.1)
44
+ json (2.5.1)
45
+ jwt (2.2.2)
41
46
  minitest (5.13.0)
42
47
  mocha (1.11.2)
43
48
  multipart-post (2.1.1)
@@ -63,7 +68,7 @@ GEM
63
68
  rubocop-performance (1.5.2)
64
69
  rubocop (>= 0.71.0)
65
70
  ruby-progressbar (1.10.1)
66
- ruby2_keywords (0.0.2)
71
+ ruby2_keywords (0.0.4)
67
72
  safe_yaml (1.0.5)
68
73
  sidekiq (6.0.7)
69
74
  connection_pool (>= 2.2.2)
@@ -74,16 +79,16 @@ GEM
74
79
  docile (~> 1.1)
75
80
  simplecov-html (~> 0.11)
76
81
  simplecov-html (0.12.2)
77
- thread_safe (0.3.6)
78
- tzinfo (1.2.7)
79
- thread_safe (~> 0.1)
82
+ subprocess (1.5.4)
83
+ tzinfo (2.0.4)
84
+ concurrent-ruby (~> 1.0)
80
85
  unicode-display_width (1.6.1)
81
86
  webmock (3.8.3)
82
87
  addressable (>= 2.3.6)
83
88
  crack (>= 0.3.2)
84
89
  hashdiff (>= 0.4.0, < 2.0.0)
85
90
  yard (0.9.24)
86
- zeitwerk (2.4.0)
91
+ zeitwerk (2.4.2)
87
92
 
88
93
  PLATFORMS
89
94
  ruby
data/README.md CHANGED
@@ -8,15 +8,15 @@ A Cased client for Ruby applications in your organization to control and monitor
8
8
  - [Configuration](#configuration)
9
9
  - [Usage](#usage)
10
10
  - [Publishing events to Cased](#publishing-events-to-cased)
11
- - [Retrieving events from a Cased Policy](#retrieving-events-from-a-cased-policy)
12
- - [Retrieving events from a Cased Policy containing variables](#retrieving-events-from-a-cased-policy-containing-variables)
13
- - [Retrieving events from multiple Cased Policies](#retrieving-events-from-multiple-cased-policies)
11
+ - [Retrieving events from a Cased audit trail](#retrieving-events-from-a-cased-audit-trail)
12
+ - [Retrieving events from multiple Cased audit trails](#retrieving-events-from-multiple-cased-audit-trails)
14
13
  - [Exporting events](#exporting-events)
15
- - [Masking & filtering sensitive information](#masking-and-filtering-sensitive-information)
14
+ - [Masking & filtering sensitive information](#masking--filtering-sensitive-information)
16
15
  - [Disable publishing events](#disable-publishing-events)
17
16
  - [Context](#context)
18
17
  - [Testing](#testing)
19
18
  - [Customizing cased-ruby](#customizing-cased-ruby)
19
+ - [Contributing](#contributing)
20
20
 
21
21
  ## Installation
22
22
 
@@ -100,7 +100,7 @@ Cased.publish(
100
100
 
101
101
  **Cased::Model**
102
102
 
103
- cased-ruby provides a class mixin that gives you a framework to publish events.
103
+ `cased-ruby` provides a class mixin that gives you a framework to publish events.
104
104
 
105
105
  ```ruby
106
106
  require 'cased-ruby'
@@ -170,9 +170,9 @@ Both examples above are equivelent in that they publish the following `credit_ca
170
170
  }
171
171
  ```
172
172
 
173
- ### Retrieving events from a Cased Policy
173
+ ### Retrieving events from a Cased audit trail
174
174
 
175
- If you plan on retrieving events from your audit trails you must use an Cased Policy token.
175
+ If you plan on retrieving audit events from your Cased audit trail you must use a Cased API key.
176
176
 
177
177
  ```ruby
178
178
  require 'cased-ruby'
@@ -193,31 +193,9 @@ query.success? # => true
193
193
  query.error? # => false
194
194
  ```
195
195
 
196
- ### Retrieving events from a Cased Policy containing variables
196
+ ### Retrieving events from multiple Cased audit trails
197
197
 
198
- Cased policies allow you to filter events by providing variables to your Cased Policy events query. One example of a Cased Policy is to have a single Cased Policy that you can use to query events for any user in your database without having to create a Cased Policy for each user.
199
-
200
- ```ruby
201
- require 'cased-ruby'
202
-
203
- Cased.configure do |config|
204
- config.policy_key = 'policy_live_1dQpY5JliYgHSkEntAbMVzuOROh'
205
- end
206
-
207
- variables = {
208
- user_id: 'user_1dSHQSNtAH90KA8zGTooMnmMdiD',
209
- }
210
- query = Cased.policy(variables: variables).events.limit(25).page(1)
211
- results = query.results
212
- results.each do |event|
213
- puts event['action'] # => credit_card.charge
214
- puts event['timestamp'] # => 2020-06-23T02:02:39.932759Z
215
- end
216
- ```
217
-
218
- ### Retrieving events from multiple Cased Policies
219
-
220
- To retrieve events from one or more Cased Policies you can configure multiple Cased Policy API keys and retrieve events for each one.
198
+ To retrieve audit events from one or more Cased audit trails you can configure multiple Cased Policy API keys and retrieve events for each one.
221
199
 
222
200
  ```ruby
223
201
  require 'cased-ruby'
@@ -229,14 +207,14 @@ Cased.configure do |config|
229
207
  }
230
208
  end
231
209
 
232
- query = Cased.policy[:users].events.limit(25).page(1)
210
+ query = Cased.policies[:users].events.limit(25).page(1)
233
211
  results = query.results
234
212
  results.each do |event|
235
213
  puts event['action'] # => user.login
236
214
  puts event['timestamp'] # => 2020-06-23T02:02:39.932759Z
237
215
  end
238
216
 
239
- query = Cased.policy[:organizations].events.limit(25).page(1)
217
+ query = Cased.policies[:organizations].events.limit(25).page(1)
240
218
  results = query.results
241
219
  results.each do |event|
242
220
  puts event['action'] # => organization.create
@@ -246,7 +224,7 @@ end
246
224
 
247
225
  ### Exporting events
248
226
 
249
- Exporting events from a Cased Policy allows you to provide users with exports of their own data or to respond to data requests.
227
+ Exporting events from Cased allows you to provide users with exports of their own data or to respond to data requests.
250
228
 
251
229
  ```ruby
252
230
  require 'cased-ruby'
@@ -281,14 +259,9 @@ Cased.publish(
281
259
 
282
260
  ### Console Usage
283
261
 
284
- Most Cased events will be created by users from actions on the website from
285
- custom defined events or lifecycle callbacks. The exception is any console
286
- session where models may generate Cased events as you start to modify records.
262
+ Most Cased events will be created by users from actions on the website from custom defined events or lifecycle callbacks. The exception is any console session where models may generate Cased events as you start to modify records.
287
263
 
288
- By default any console session will include the hostname of where the console
289
- session takes place. Since every event must have an actor, you must set the
290
- actor at the beginning of your console session. If you don't know the user,
291
- it's recommended you create a system/robot user.
264
+ By default any console session will include the hostname of where the console session takes place. Since every event must have an actor, you must set the actor at the beginning of your console session. If you don't know the user, it's recommended you create a system/robot user.
292
265
 
293
266
  ```ruby
294
267
  # OTHER CONSOLE INITIALIZATION HERE
data/bin/cli ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'cased-ruby'
6
+
7
+ Cased.configure do |config|
8
+ config.guard_application_key = 'guard_application_1oFqltbMqSEtJQKRCAYQNrQoXsS'
9
+ config.guard_deny_if_unreachable = true
10
+ end
11
+
12
+ Cased::CLI::InteractiveSession.start
13
+
14
+ puts 'Something destructive'
data/cased-ruby.gemspec CHANGED
@@ -33,7 +33,9 @@ Gem::Specification.new do |spec|
33
33
  spec.add_dependency 'faraday', '~> 1.0'
34
34
  spec.add_dependency 'faraday_middleware', '~> 1.0'
35
35
  spec.add_dependency 'json', '~> 2'
36
+ spec.add_dependency 'jwt', '~> 2'
36
37
  spec.add_dependency 'net-http-persistent', '~> 3.0'
38
+ spec.add_dependency 'subprocess', '~> 1.5.0'
37
39
  spec.add_development_dependency 'bundler', '2.1.4'
38
40
  spec.add_development_dependency 'byebug', '11.0.1'
39
41
  spec.add_development_dependency 'minitest', '5.13.0'
data/lib/cased.rb CHANGED
@@ -15,6 +15,7 @@ require 'cased/sensitive'
15
15
  require 'cased/publishers'
16
16
  require 'cased/test_helper'
17
17
  require 'cased/instrumentation/log_subscriber'
18
+ require 'cased/cli'
18
19
 
19
20
  # Integrations
20
21
  begin
data/lib/cased/cli.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cased
4
+ module CLI
5
+ end
6
+ end
7
+
8
+ require 'cased/cli/asciinema/writer'
9
+ require 'cased/cli/asciinema/file'
10
+ require 'cased/cli/recorder'
11
+ require 'cased/cli/log'
12
+ require 'cased/cli/session'
13
+ require 'cased/cli/interactive_session'
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Cased
6
+ module CLI
7
+ # Spec: https://github.com/asciinema/asciinema/blob/develop/doc/asciicast-v2.md
8
+ module Asciinema
9
+ class File
10
+ OUT = 'o'
11
+ IN = 'i'
12
+
13
+ def self.from_writer(writer)
14
+ new(writer.header, writer.stream)
15
+ end
16
+
17
+ def self.from_cast(cast)
18
+ stream = cast.split("\n").collect do |data|
19
+ JSON.parse(data)
20
+ end
21
+ header = stream.shift
22
+
23
+ new(header, stream)
24
+ end
25
+
26
+ # Required
27
+ attr_reader :header
28
+ attr_reader :version
29
+ attr_reader :width
30
+ attr_reader :height
31
+ attr_reader :stream
32
+
33
+ # Optional
34
+ attr_reader :timestamp
35
+ attr_reader :duration
36
+ attr_reader :idle_time_limit
37
+ attr_reader :command
38
+ attr_reader :title
39
+ attr_reader :env
40
+ attr_reader :theme
41
+
42
+ def initialize(header, stream)
43
+ @header = header
44
+ @version = header.fetch('version')
45
+ @width = header.fetch('width')
46
+ @height = header.fetch('height')
47
+ self.timestamp = header['timestamp']
48
+ self.duration = header['duration']
49
+ self.idle_time_limit = header['idle_time_limit']
50
+ @command = header['command']
51
+ @title = header['title']
52
+ @env = header.fetch('env', {})
53
+ @theme = header['theme']
54
+ @stream = stream
55
+ end
56
+
57
+ def timestamp=(new_timestamp)
58
+ @timestamp = case new_timestamp
59
+ when Integer
60
+ Time.at(new_timestamp)
61
+ when Time, NilClass
62
+ new_timestamp
63
+ else
64
+ raise ArgumentError, "unexpected timestamp format #{new_timestamp.class}, expected Integer, Time, or nil"
65
+ end
66
+ end
67
+
68
+ def duration=(new_duration)
69
+ @duration = case new_duration
70
+ when Float, NilClass
71
+ new_duration
72
+ else
73
+ raise ArgumentError, "unexpected duration format #{new_duration.class}, expected Float or nil"
74
+ end
75
+ end
76
+
77
+ def idle_time_limit=(new_idle_time_limit)
78
+ @idle_time_limit = case new_idle_time_limit
79
+ when Numeric, NilClass
80
+ new_idle_time_limit
81
+ else
82
+ raise ArgumentError, "unexpected idle_time_limit format #{new_idle_time_limit.class}, expected Integer, Float, or nil"
83
+ end
84
+ end
85
+
86
+ def to_cast
87
+ builder = []
88
+ builder << JSON.dump(header)
89
+ stream.each do |duration, type, data|
90
+ builder << JSON.dump([duration, type, data])
91
+ end
92
+ builder.join("\n")
93
+ end
94
+
95
+ def to_s
96
+ str = []
97
+ stream.each do |_timestamp, type, data|
98
+ next unless type == OUT
99
+
100
+ str << data
101
+ end
102
+
103
+ str.join
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Cased
6
+ module CLI
7
+ # Spec: https://github.com/asciinema/asciinema/blob/develop/doc/asciicast-v2.md
8
+ module Asciinema
9
+ class Writer
10
+ VERSION = 2
11
+
12
+ attr_accessor :width
13
+ attr_accessor :height
14
+ attr_reader :stream
15
+ attr_reader :started_at
16
+ attr_reader :finished_at
17
+
18
+ def initialize(command: [], width: 80, height: 24)
19
+ @command = command
20
+ @width = width
21
+ @height = height
22
+ @stream = []
23
+ @started_at = Time.now
24
+ end
25
+
26
+ def <<(output)
27
+ stream << [Time.now - started_at, 'o', output]
28
+ end
29
+
30
+ def time
31
+ @started_at = Time.now
32
+ ret = yield
33
+ @finished_at = Time.now
34
+ ret
35
+ end
36
+
37
+ def to_cast
38
+ # In the event we didn't run the writer in a #time block, we should
39
+ # set the finished time if it isn't set.
40
+ @finished_at ||= Time.now
41
+
42
+ File.new(header, stream).to_cast
43
+ end
44
+
45
+ def header
46
+ {
47
+ 'version' => VERSION,
48
+ 'env' => {
49
+ 'SHELL' => ENV['SHELL'],
50
+ 'TERM' => ENV['TERM'],
51
+ },
52
+ 'width' => width,
53
+ 'height' => height,
54
+ }.tap do |h|
55
+ if started_at
56
+ h['timestamp'] = started_at.to_i
57
+ end
58
+
59
+ if started_at && finished_at
60
+ h['duration'] = finished_at - started_at
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module Cased
6
+ module CLI
7
+ class Authentication
8
+ attr_reader :directory
9
+ attr_reader :credentials_path
10
+ attr_writer :token
11
+
12
+ def initialize
13
+ @token = Cased.config.guard_user_token
14
+ @directory = Pathname.new(File.expand_path('~/.cguard'))
15
+ @credentials_path = @directory.join('credentials')
16
+ end
17
+
18
+ def exists?
19
+ !token.nil?
20
+ end
21
+
22
+ def token
23
+ @token ||= begin
24
+ credentials_path.read
25
+ rescue Errno::ENOENT
26
+ nil
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end