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
-
{grab} read the value at key_name from the default section
-
{stash} put directive key/value pair in default section
-
{read} read the value at key_name from the parameter section
-
{write} put directive key/value pair in parameter section
Constants
- COMMANDMENT
- ENV_VAR_KEY_NAME
Public Class Methods
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
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
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 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
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
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
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
Override me if you need to
# File lib/controller/abstract/controller.rb, line 167 def pre_validation end
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
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
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
–> 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