class SafeDb::Controller

The parent SafeDb use case is designed to be extended by the cli (command line) use cases like {SafeDb::Open}, {SafeDb::Put} and {SafeDb::Lock} because it describes behaviour common to at least two (but usually more) of the use cases.

Common Use Case Behaviour

This {SafeDb::Controller} use case is designed to be extended and does preparatory work to create favourable and useful conditions to make use cases readable, less repetitive, simpler and concise.

Machine (Workstation) Configuration File

The global configuration filepath is found off the home directory using {Dir.home}.

~/.safedb.net/safedb.net.configuration.ini

The global configuration file in INI format is managed through the methods

Constants

COMMANDMENT
ENV_VAR_KEY_NAME

Public Class Methods

new() click to toggle source

All controllers are initialized here meaning that there will be automatic execution of very frequently used setup behaviour. This includes

  • checking for (and reporting a lack of) the safe token environment variable

  • asimilating a fact file if employed by the specific use case (controller)

# File lib/controller/abstract/controller.rb, line 35
    def initialize

      class_name = self.class.name.split(":").last.downcase
      is_no_token_uc = [ "token", "init", "id", "obliterate" ].include? class_name
      return if is_no_token_uc
      exit(100) unless ops_key_exists?

      return if [ "login", "push", "pull" ].include? class_name

      not_logged_in = StateInspect.not_logged_in?()
      puts TextChunk.not_logged_in_message() if not_logged_in
      exit(100) if not_logged_in

      @book = Book.new()
      return

=begin
      Fact Functionality
      ======================
      fact_filepath = File.sister_filepath( self, "ini", :execute )
      log.info(x) { "Search location for INI factfile is [#{fact_filepath}]" }
      return unless File.exists?( fact_filepath )

      @facts = FactFind.new()
      add_secret_facts @facts
      @facts.assimilate_ini_file( fact_filepath )
      @dictionary = @facts.f[ @facts.to_symbol( class_name ) ]
=end

    end

Public Instance Methods

check_post_conditions() click to toggle source

After the main flow of events certain state conditions must hold true thus demonstrating that the observable value has indeed ben delivered.

Child classes should subclass this method and place any post execution (post condition) checks in it and then make a call to this method through the “super” keyword.

# File lib/controller/abstract/controller.rb, line 179
def check_post_conditions

  begin
    post_validation
  rescue OpenError::CliError => e

    puts ""
    puts "Your command did not complete successfully."
    puts "Post validation checks failed."
    puts ""
    puts "   => #{e.message}"
    ####        puts "   => #{e.culprit}"
    puts ""
    abort e.message
  end

end
check_pre_conditions() click to toggle source

Validate the input parameters and check that the current state is perfect for executing the use case.

If either of the above fail - the validation function should set a human readable string and then throw an exception.

# File lib/controller/abstract/controller.rb, line 148
def check_pre_conditions

  begin
    pre_validation
  rescue OpenError::CliError => e

    puts ""
    puts "Your command did not complete successfully."
    puts "Pre validation checks failed."
    puts ""
    puts "   => #{e.message}"
    puts ""
    abort e.message
  end

end
execute() click to toggle source

Execute the main flow of events of the use case. Any exceptions thrown are captured and if the instance variale [@human_readable_message] is set - tell the user about it. Without any message - just tell the user something went wrong and tell them where the logs are that might carry more information.

# File lib/controller/abstract/controller.rb, line 213
def execute

end
flow() click to toggle source

Execute the use cases's flow from beginning when you validate the input and parameters through the memorize and execute.

# File lib/controller/abstract/controller.rb, line 134
def flow()

  check_pre_conditions
  execute
  check_post_conditions

end
open_remote_backend_location() click to toggle source

Login to the book and open the chapter and verse location that holds information about the remote backend that we push and pull to.

To do this we must discover which book, chapter and verse holds the backend storage properties. This information should be available in the master keys file set by safe remote --provision

After this call the @verse key/value map will contain properties pertaining to the safe#s backend remote store.

# File lib/controller/abstract/controller.rb, line 76
def open_remote_backend_location

  verse_coordinates = Master.new().get_backend_coordinates()
  the_book_id = verse_coordinates.split("/")[0]
  the_chapter = verse_coordinates.split("/")[1]
  the_verse = verse_coordinates.split("/")[2]

  puts "" 
  puts "Will login to book with id #{the_book_id}"

  login_uc = Login.new()
  login_uc.login_book_id = the_book_id
  login_uc.suppress_output = true
  login_uc.flow()
  
  puts "Login successful. Opening #{the_chapter}/#{the_verse}"

  @book = Book.new()
  @book.set_open_chapter_name( the_chapter )
  @book.set_open_verse_name( the_verse )
  @verse = @book.get_open_verse_data()
  @book.write_open_chapter()

end
post_validation() click to toggle source

Child classes should subclass this method and place any post execution (post condition) checks in it and then make a call to this method through the “super” keyword if this method gets any global behaviour in it worth calling.

# File lib/controller/abstract/controller.rb, line 202
def post_validation

end
pre_validation() click to toggle source

Override me if you need to

# File lib/controller/abstract/controller.rb, line 167
def pre_validation

end
read_verse() click to toggle source

This parental behaviour decrypts and reads the ubiquitous chapter and verse data structures and indices.

# File lib/controller/abstract/controller.rb, line 112
def read_verse()

  exit(100) if @book.unopened_chapter_verse?()
  @verse = @book.get_open_verse_data()

end
set_verse( incoming_verse ) click to toggle source

Set the verse data structure for this controller. Usually called from another controller that wants to pass in a predefined map. @param incoming_verse [Hash] the incoming verse map to set

# File lib/controller/abstract/controller.rb, line 106
def set_verse( incoming_verse )
  @verse = incoming_verse
end
update_verse() click to toggle source

This parental behaviour encrypts and writes out the in-play chapter and verse data. This behaviour also deletes the crypt file belonging to the now superceeded chapter state.

# File lib/controller/abstract/controller.rb, line 123
def update_verse()

  @book.write_open_chapter()
  Show.new.flow()

end

Private Instance Methods

ops_key_exists?() click to toggle source

–> end

# File lib/controller/abstract/controller.rb, line 241
def ops_key_exists?

  if ( ENV.has_key? ENV_VAR_KEY_NAME )
    return true
  end

  puts ""
  puts "safe needs you to create a shell token."
  puts "To automate this step see the documentation."
  puts "To create the key run the below command."
  puts ""
  puts "    export #{ENV_VAR_KEY_NAME}=`#{COMMANDMENT} token`"
  puts ""
  puts "Those are backticks surrounding `#{COMMANDMENT} token`"
  puts "Not apostrophes."
  puts ""

  return false

end