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 +4 -4
- data/.github/workflows/ruby.yml +0 -16
- data/Gemfile.lock +3 -3
- data/README.md +35 -1
- data/lib/cased/cli/asciinema/file.rb +5 -0
- data/lib/cased/cli/config.rb +21 -0
- data/lib/cased/cli/identity.rb +8 -3
- data/lib/cased/cli/interactive_session.rb +40 -1
- data/lib/cased/cli/log.rb +2 -0
- data/lib/cased/cli/session.rb +20 -4
- data/lib/cased/config.rb +13 -0
- data/lib/cased/http/client.rb +0 -2
- data/lib/cased/version.rb +1 -1
- data/vendor/cache/activesupport-6.1.3.1.gem +0 -0
- data/vendor/cache/i18n-1.8.10.gem +0 -0
- metadata +5 -4
- data/vendor/cache/activesupport-6.1.3.gem +0 -0
- data/vendor/cache/i18n-1.8.9.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4592facfed9641c5f262e1c82905e77b8ba687cf3a32e056688a7521573ea3ca
|
4
|
+
data.tar.gz: bb5c406b6423b618a0ad9c6356fcfe4e67cfce24c80fc97951aea1cbb846f138
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86d308c4698823a52959e7fcd32f62c4d023539162fea109d4c893f524e43bb57a845140a21a8177c2e2c1c0fbde5e58832ec8637383b4ea76db0e6f49605ad5
|
7
|
+
data.tar.gz: fe135b92df5a2987e01f2b8272af7b45479bc59ea9a73c35c246602c4ffe7b0e42bd766049b4867d574c14113b5fb83ff515f9e1ad62027a4a1aa347e0a1eb87
|
data/.github/workflows/ruby.yml
CHANGED
@@ -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.
|
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.
|
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
|
-
|
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
|
data/lib/cased/cli/identity.rb
CHANGED
@@ -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
|
-
|
31
|
-
|
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
|
-
|
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
data/lib/cased/cli/session.rb
CHANGED
@@ -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.
|
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
|
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
|
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.
|
data/lib/cased/http/client.rb
CHANGED
data/lib/cased/version.rb
CHANGED
Binary file
|
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.
|
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-
|
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.
|
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
|
data/vendor/cache/i18n-1.8.9.gem
DELETED
Binary file
|