class Cased::CLI::InteractiveSession
InteractiveSession
is responsible for initiating a Cased
CLI
session and responding to all its possible states.
InteractiveSession
is intended to be used where a TTY is present to handle the entire flow from authentication, reason required, waiting for approval, canceled, or timed out.
Attributes
session[R]
Public Class Methods
new(reason: nil, command: nil, metadata: {})
click to toggle source
# File lib/cased/cli/interactive_session.rb, line 25 def initialize(reason: nil, command: nil, metadata: {}) @session = Cased::CLI::Session.new( reason: reason, command: command, metadata: metadata, ) @prompt = TTY::Prompt.new end
start(reason: nil, command: nil, metadata: {})
click to toggle source
# File lib/cased/cli/interactive_session.rb, line 15 def self.start(reason: nil, command: nil, metadata: {}) return Cased::CLI::Session.current if Cased::CLI::Session.current&.approved? Cased::CLI::Log.log 'Running under Cased CLI.' new(reason: reason, command: command, metadata: metadata).create end
Public Instance Methods
create()
click to toggle source
# File lib/cased/cli/interactive_session.rb, line 35 def create signal_handler = Signal.trap('SIGINT') do if session.requested? Cased::CLI::Log.log 'Exiting and canceling request…' session.cancel exit 0 elsif signal_handler.respond_to?(:call) # We need to call the original handler if we exit this interactive # session successfully signal_handler.call else raise Interrupt end end if session.create handle_state(session.state) elsif session.reauthenticate? Cased::CLI::Log.log "You must re-authenticate with Cased due to recent changes to this application's settings." identity = Cased::CLI::Identity.new token, ip_address = identity.identify session.authentication.token = token session.forwarded_ip_address = ip_address create elsif session.unauthorized? if session.authentication.exists? Cased::CLI::Log.log "Existing credentials at #{session.authentication.credentials_path} are not valid." else Cased::CLI::Log.log "Could not find credentials at #{session.authentication.credentials_path}, looking up now…" end identity = Cased::CLI::Identity.new token, ip_address = identity.identify session.authentication.token = token session.forwarded_ip_address = ip_address create elsif session.reason_required? reason_prompt && create else Cased::CLI::Log.log 'Could not start CLI session.' exit 1 if Cased.config.guard_deny_if_unreachable? end session end
Private Instance Methods
handle_state(state)
click to toggle source
# File lib/cased/cli/interactive_session.rb, line 108 def handle_state(state) case state when 'approved' Cased::CLI::Log.log 'CLI session has been approved' session.record when 'requested' waiting_for_approval_message wait_for_approval when 'denied' Cased::CLI::Log.log 'CLI session has been denied' exit 1 when 'timed_out' Cased::CLI::Log.log 'CLI session has timed out' exit 1 when 'canceled' Cased::CLI::Log.log 'CLI session has been canceled' exit 0 end end
reason_prompt()
click to toggle source
# File lib/cased/cli/interactive_session.rb, line 86 def reason_prompt reason = @prompt.multiline(Cased::CLI::Log.string('Please enter a reason for access:'), help: '(Press Ctrl+D or Ctrl+Z to submit)') session.reason = reason.join("\n") rescue TTY::Reader::InputInterrupt Cased::CLI::Log.log 'Exiting and canceling request…' exit 0 end
wait_for_approval()
click to toggle source
# File lib/cased/cli/interactive_session.rb, line 94 def wait_for_approval sleep 1 session.refresh && handle_state(session.state) end
waiting_for_approval_message()
click to toggle source
# File lib/cased/cli/interactive_session.rb, line 99 def waiting_for_approval_message return if defined?(@waiting_for_approval_message_displayed) motd = session.guard_application.dig('settings', 'message_of_the_day') waiting_message = motd.blank? ? 'Approval request sent…' : motd Cased::CLI::Log.log "#{waiting_message} (id: #{session.id})" @waiting_for_approval_message_displayed = true end