cased-ruby 0.4.2 → 0.4.7

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: f866d60b9da3d895469686a8510dc93a0bf2ec80b45c8b0d0c2af912233b5849
4
- data.tar.gz: bca2f7aff437b0b739a5784b0d598171c5e61c6491ee4bf408fc3718f4a649a1
3
+ metadata.gz: 4592facfed9641c5f262e1c82905e77b8ba687cf3a32e056688a7521573ea3ca
4
+ data.tar.gz: bb5c406b6423b618a0ad9c6356fcfe4e67cfce24c80fc97951aea1cbb846f138
5
5
  SHA512:
6
- metadata.gz: 6fad8ffa2d18d75001a72cd6a861658e5b8e02c11d6ede6f7df320ec420424db372bbbd06f8e3b57425a96f0d684513144a863b6f5a65d7c0301a3fcc15159fc
7
- data.tar.gz: d51546813623b1a5196dbf7bc393581e75ad347522909a45c09bd9ae3e3e620341f905670c71e206f2b12ba405cdb8e589b2c35e2ec7b0cae34b6cb192183a35
6
+ metadata.gz: 86d308c4698823a52959e7fcd32f62c4d023539162fea109d4c893f524e43bb57a845140a21a8177c2e2c1c0fbde5e58832ec8637383b4ea76db0e6f49605ad5
7
+ data.tar.gz: fe135b92df5a2987e01f2b8272af7b45479bc59ea9a73c35c246602c4ffe7b0e42bd766049b4867d574c14113b5fb83ff515f9e1ad62027a4a1aa347e0a1eb87
@@ -28,19 +28,3 @@ jobs:
28
28
  - name: Run Tests
29
29
  run: |
30
30
  bundle exec rake test
31
-
32
- - name: Generate yard documentation
33
- run: |
34
- bundle exec yard
35
-
36
- - name: Upload test coverage report
37
- uses: actions/upload-artifact@v2
38
- with:
39
- name: coverage
40
- path: coverage/**/*
41
-
42
- - name: Upload generated yard documentation
43
- uses: actions/upload-artifact@v2
44
- with:
45
- name: yard
46
- path: doc/**/*
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cased-ruby (0.4.2)
4
+ cased-ruby (0.4.7)
5
5
  activesupport (~> 6)
6
6
  dotpath (= 0.1.0)
7
7
  faraday (~> 1.0)
@@ -14,7 +14,7 @@ PATH
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- activesupport (6.1.3)
17
+ activesupport (6.1.3.1)
18
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
19
19
  i18n (>= 1.6, < 2)
20
20
  minitest (>= 5.1)
@@ -38,7 +38,7 @@ GEM
38
38
  faraday_middleware (1.0.0)
39
39
  faraday (~> 1.0)
40
40
  hashdiff (1.0.1)
41
- i18n (1.8.9)
41
+ i18n (1.8.10)
42
42
  concurrent-ruby (~> 1.0)
43
43
  jaro_winkler (1.5.4)
44
44
  json (2.5.1)
data/README.md CHANGED
@@ -9,6 +9,7 @@ A Cased client for Ruby applications in your organization to control and monitor
9
9
  - [Usage](#usage)
10
10
  - [Cased CLI](#cased-cli)
11
11
  - [Starting an approval workflow](#starting-an-approval-workflow)
12
+ - [Attaching metadata to all CLI requests](#attaching-metadata-to-all-cli-requests)
12
13
  - [Audit trails](#audit-trails)
13
14
  - [Publishing events to Cased](#publishing-events-to-cased)
14
15
  - [Retrieving events from a Cased audit trail](#retrieving-events-from-a-cased-audit-trail)
@@ -85,6 +86,17 @@ Cased.configure do |config|
85
86
 
86
87
  # CASED_HTTP_READ_TIMEOUT=10
87
88
  config.http_read_timeout = 10
89
+
90
+ # Attach metadata to all CLI requests. This metadata will appear in Cased and
91
+ # any notification source such as email or Slack.
92
+ #
93
+ # You are limited to 20 properties and cannot be a nested dictionary. Metadata
94
+ # specified in the CLI request overrides any configured globally.
95
+ config.cli.metadata = {
96
+ rails_env: ENV['RAILS_ENV'],
97
+ heroku_application: ENV['HEROKU_APP_NAME'],
98
+ git_commit: ENV['GIT_COMMIT'],
99
+ }
88
100
  end
89
101
  ```
90
102
 
@@ -135,7 +147,8 @@ end
135
147
 
136
148
  authentication = Cased::CLI::Authentication.new
137
149
  identity = Cased::CLI::Identity.new
138
- authentication.token = identity.identify
150
+ token, ip_address = identity.identify
151
+ authentication.token = token
139
152
 
140
153
  session = Cased::CLI::Session.new(
141
154
  authentication: authentication,
@@ -180,6 +193,27 @@ You no longer need to handle obtaining the user token or asking for a reason up
180
193
  front, `Cased::CLI::InteractiveSession` will prompt the user for any reason
181
194
  being required as necessary.
182
195
 
196
+ #### Attaching metadata to all CLI requests
197
+
198
+ While you can customize the metadata included for each CLI request, it may prove
199
+ useful to specify metadata globally that will be included with each CLI request.
200
+ Some useful information to include may be the current Rails environment, Heroku
201
+ application, Git commit deployed, and more.
202
+
203
+ Metadata is limited to 20 properties and cannot be a nested dictionary.
204
+
205
+ ```ruby
206
+ Cased.configure do |config|
207
+ config.cli.metadata = {
208
+ rails_env: ENV['RAILS_ENV'],
209
+ heroku_application: ENV['HEROKU_APP_NAME'],
210
+ git_commit: ENV['GIT_COMMIT'],
211
+ }
212
+ end
213
+ ```
214
+
215
+ Note: Metadata specified in the CLI request overrides any configured globally.
216
+
183
217
  ### Audit trails
184
218
 
185
219
  #### Publishing events to Cased
@@ -15,12 +15,17 @@ module Cased
15
15
  end
16
16
 
17
17
  def self.from_cast(cast)
18
+ return if cast.blank?
19
+
18
20
  stream = cast.split("\n").collect do |data|
19
21
  JSON.parse(data)
20
22
  end
21
23
  header = stream.shift
24
+ return unless header.is_a?(Hash)
22
25
 
23
26
  new(header, stream)
27
+ rescue JSON::ParserError
28
+ nil
24
29
  end
25
30
 
26
31
  # Required
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cased
4
+ module CLI
5
+ class Config
6
+ # @example
7
+ # Cased.configure do |config|
8
+ # config.cli.metadata = {
9
+ # rails_env: ENV['RAILS_ENV'],
10
+ # heroku_application: ENV['HEROKU_APP_NAME'],
11
+ # git_commit: ENV['GIT_COMMIT'],
12
+ # }
13
+ # end
14
+ attr_accessor :metadata
15
+
16
+ def initialize
17
+ @metadata = {}
18
+ end
19
+ end
20
+ end
21
+ end
@@ -23,15 +23,20 @@ module Cased
23
23
  def poll(poll_url)
24
24
  count = 0
25
25
  user_id = nil
26
+ ip_address = nil
26
27
 
27
28
  while user_id.nil?
28
29
  count += 1
29
30
  response = Cased.clients.cli.get(poll_url)
30
- user_id = response.body.dig('user', 'id')
31
- sleep 1 if user_id.nil?
31
+ if response.success?
32
+ user_id = response.body.dig('user', 'id')
33
+ ip_address = response.body.fetch('ip_address')
34
+ else
35
+ sleep 1
36
+ end
32
37
  end
33
38
 
34
- user_id
39
+ [user_id, ip_address]
35
40
  end
36
41
  end
37
42
  end
@@ -30,8 +30,31 @@ module Cased
30
30
  end
31
31
 
32
32
  def create
33
+ signal_handler = Signal.trap('SIGINT') do
34
+ if session.requested?
35
+ Cased::CLI::Log.log 'Exiting and canceling request…'
36
+ session.cancel
37
+ exit 0
38
+ elsif signal_handler.respond_to?(:call)
39
+ # We need to call the original handler if we exit this interactive
40
+ # session successfully
41
+ signal_handler.call
42
+ else
43
+ raise Interrupt
44
+ end
45
+ end
46
+
33
47
  if session.create
34
48
  handle_state(session.state)
49
+ elsif session.reauthenticate?
50
+ Cased::CLI::Log.log "You must re-authenticate with Cased due to recent changes to this application's settings."
51
+
52
+ identity = Cased::CLI::Identity.new
53
+ token, ip_address = identity.identify
54
+ session.authentication.token = token
55
+ session.forwarded_ip_address = ip_address
56
+
57
+ create
35
58
  elsif session.unauthorized?
36
59
  if session.authentication.exists?
37
60
  Cased::CLI::Log.log "Existing credentials at #{session.authentication.credentials_path} are not valid."
@@ -40,7 +63,9 @@ module Cased
40
63
  end
41
64
 
42
65
  identity = Cased::CLI::Identity.new
43
- session.authentication.token = identity.identify
66
+ token, ip_address = identity.identify
67
+ session.authentication.token = token
68
+ session.forwarded_ip_address = ip_address
44
69
 
45
70
  create
46
71
  elsif session.reason_required?
@@ -61,22 +86,36 @@ module Cased
61
86
  end
62
87
 
63
88
  def wait_for_approval
89
+ sleep 1
64
90
  session.refresh && handle_state(session.state)
65
91
  end
66
92
 
93
+ def waiting_for_approval_message
94
+ return if defined?(@waiting_for_approval_message_displayed)
95
+
96
+ motd = session.guard_application.dig('settings', 'message_of_the_day')
97
+ waiting_message = motd.blank? ? 'Approval request sent…' : motd
98
+ Cased::CLI::Log.log "#{waiting_message} (id: #{session.id})"
99
+ @waiting_for_approval_message_displayed = true
100
+ end
101
+
67
102
  def handle_state(state)
68
103
  case state
69
104
  when 'approved'
70
105
  Cased::CLI::Log.log 'CLI session has been approved'
71
106
  session.record
72
107
  when 'requested'
108
+ waiting_for_approval_message
73
109
  wait_for_approval
74
110
  when 'denied'
75
111
  Cased::CLI::Log.log 'CLI session has been denied'
112
+ exit 1
76
113
  when 'timed_out'
77
114
  Cased::CLI::Log.log 'CLI session has timed out'
115
+ exit 1
78
116
  when 'canceled'
79
117
  Cased::CLI::Log.log 'CLI session has been canceled'
118
+ exit 0
80
119
  end
81
120
  end
82
121
  end
data/lib/cased/cli/log.rb CHANGED
@@ -13,6 +13,8 @@ module Cased
13
13
 
14
14
  def self.log(text)
15
15
  puts string(text)
16
+ ensure
17
+ STDOUT.flush
16
18
  end
17
19
 
18
20
  def self.color(text, color, bold = false)
@@ -86,9 +86,17 @@ module Cased
86
86
  # @return [String, nil]
87
87
  attr_accessor :reason
88
88
 
89
+ # Public: The forwarded IP V4 or IP V6 address of the user that initiated
90
+ # the CLI session.
91
+ #
92
+ # @example
93
+ # session.forwarded_ip_address #=> "1.1.1.1"
94
+ # @return [String, nil]
95
+ attr_accessor :forwarded_ip_address
96
+
89
97
  # Public: The client's IP V4 or IP V6 address that initiated the CLI session.
90
98
  # @example
91
- # session.reason #=> "1.1.1.1"
99
+ # session.ip_address #=> "1.1.1.1"
92
100
  # @return [String, nil]
93
101
  attr_reader :ip_address
94
102
 
@@ -120,7 +128,7 @@ module Cased
120
128
  @authentication = authentication || Cased::CLI::Authentication.new
121
129
  @reason = reason
122
130
  @command = command || [$PROGRAM_NAME, *ARGV].join(' ')
123
- @metadata = metadata
131
+ @metadata = Cased.config.cli.metadata.merge(metadata)
124
132
  @requester = {}
125
133
  @responder = {}
126
134
  @guard_application = {}
@@ -144,6 +152,7 @@ module Cased
144
152
  @command = session.fetch('command')
145
153
  @metadata = session.fetch('metadata')
146
154
  @reason = session.fetch('reason')
155
+ @forwarded_ip_address = session.fetch('forwarded_ip_address')
147
156
  @ip_address = session.fetch('ip_address')
148
157
  @requester = session.fetch('requester')
149
158
  @responded_at = session['responded_at']
@@ -175,7 +184,7 @@ module Cased
175
184
  return false unless api_url
176
185
 
177
186
  response = Cased.clients.cli.get(api_url, user_token: authentication.token)
178
- self.session = response.body if response.success?
187
+ self.session = response.body
179
188
  end
180
189
 
181
190
  def error?
@@ -194,6 +203,10 @@ module Cased
194
203
  error == :unauthorized
195
204
  end
196
205
 
206
+ def reauthenticate?
207
+ error == :reauthenticate
208
+ end
209
+
197
210
  def record_output?
198
211
  guard_application.dig('settings', 'record_output') || false
199
212
  end
@@ -222,6 +235,7 @@ module Cased
222
235
 
223
236
  response = Cased.clients.cli.post('cli/sessions',
224
237
  user_token: authentication.token,
238
+ forwarded_ip_address: forwarded_ip_address,
225
239
  reason: reason,
226
240
  metadata: metadata,
227
241
  command: command)
@@ -233,6 +247,8 @@ module Cased
233
247
  @error = :reason_required
234
248
  when 'unauthorized'
235
249
  @error = :unauthorized
250
+ when 'reauthenticate'
251
+ @error = :reauthenticate
236
252
  else
237
253
  @error = true
238
254
  return false
@@ -244,7 +260,7 @@ module Cased
244
260
 
245
261
  def cancel
246
262
  response = Cased.clients.cli.post("#{api_url}/cancel", user_token: authentication.token)
247
- self.session = response.body if response.success?
263
+ self.session = response.body
248
264
 
249
265
  canceled?
250
266
  end
data/lib/cased/config.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'cased/cli/config'
4
+
3
5
  module Cased
4
6
  class Config
5
7
  # The amount of time in seconds to allow the HTTP client to open a
@@ -149,6 +151,16 @@ module Cased
149
151
  # end
150
152
  attr_writer :silence
151
153
 
154
+ # @example
155
+ # Cased.configure do |config|
156
+ # config.cli.metadata = {
157
+ # rails_env: ENV['RAILS_ENV'],
158
+ # heroku_application: ENV['HEROKU_APP_NAME'],
159
+ # git_commit: ENV['GIT_COMMIT'],
160
+ # }
161
+ # end
162
+ attr_reader :cli
163
+
152
164
  def initialize
153
165
  @http_read_timeout = ENV.fetch('CASED_HTTP_READ_TIMEOUT', 10).to_i
154
166
  @http_open_timeout = ENV.fetch('CASED_HTTP_OPEN_TIMEOUT', 5).to_i
@@ -172,6 +184,7 @@ module Cased
172
184
  hash[normalized_key] = api_key if api_key
173
185
  end
174
186
  end
187
+ @cli = Cased::CLI::Config.new
175
188
  end
176
189
 
177
190
  # Policy keys are used to query for events from audit trails.
@@ -20,8 +20,6 @@ module Cased
20
20
 
21
21
  conn.options.timeout = Cased.config.http_read_timeout
22
22
  conn.options.open_timeout = Cased.config.http_open_timeout
23
-
24
- conn.adapter :net_http_persistent
25
23
  end
26
24
  end
27
25
 
data/lib/cased/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cased
4
- VERSION = '0.4.2'
4
+ VERSION = '0.4.7'
5
5
  end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cased-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garrett Bjerkhoel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-05 00:00:00.000000000 Z
11
+ date: 2021-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -305,6 +305,7 @@ files:
305
305
  - lib/cased/cli/asciinema/file.rb
306
306
  - lib/cased/cli/asciinema/writer.rb
307
307
  - lib/cased/cli/authentication.rb
308
+ - lib/cased/cli/config.rb
308
309
  - lib/cased/cli/identity.rb
309
310
  - lib/cased/cli/interactive_session.rb
310
311
  - lib/cased/cli/log.rb
@@ -343,7 +344,7 @@ files:
343
344
  - lib/cased/sensitive/string.rb
344
345
  - lib/cased/test_helper.rb
345
346
  - lib/cased/version.rb
346
- - vendor/cache/activesupport-6.1.3.gem
347
+ - vendor/cache/activesupport-6.1.3.1.gem
347
348
  - vendor/cache/addressable-2.7.0.gem
348
349
  - vendor/cache/ast-2.4.0.gem
349
350
  - vendor/cache/byebug-11.0.1.gem
@@ -356,7 +357,7 @@ files:
356
357
  - vendor/cache/faraday-net_http-1.0.1.gem
357
358
  - vendor/cache/faraday_middleware-1.0.0.gem
358
359
  - vendor/cache/hashdiff-1.0.1.gem
359
- - vendor/cache/i18n-1.8.9.gem
360
+ - vendor/cache/i18n-1.8.10.gem
360
361
  - vendor/cache/jaro_winkler-1.5.4.gem
361
362
  - vendor/cache/json-2.5.1.gem
362
363
  - vendor/cache/jwt-2.2.2.gem
Binary file
Binary file