opensecret 0.0.9925 → 0.0.9949

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +656 -40
  3. data/lib/configs/README.md +58 -0
  4. data/lib/extension/file.rb +67 -0
  5. data/lib/extension/string.rb +10 -0
  6. data/lib/factbase/facts.opensecret.io.ini +1 -0
  7. data/lib/interprete.rb +334 -61
  8. data/lib/keytools/PRODUCE_RAND_SEQ_USING_DEV_URANDOM.txt +0 -0
  9. data/lib/keytools/kdf.api.rb +9 -15
  10. data/lib/keytools/kdf.bcrypt.rb +69 -19
  11. data/lib/keytools/kdf.pbkdf2.rb +112 -23
  12. data/lib/keytools/key.api.rb +146 -36
  13. data/lib/keytools/key.db.rb +94 -29
  14. data/lib/keytools/key.id.rb +1 -1
  15. data/lib/keytools/key.ident.rb +243 -0
  16. data/lib/keytools/key.local.rb +62 -68
  17. data/lib/keytools/key.pass.rb +2 -2
  18. data/lib/keytools/key.rb +2 -28
  19. data/lib/modules/{cryptology.md → README.md} +0 -0
  20. data/lib/session/fact.finder.rb +65 -428
  21. data/lib/session/time.stamp.rb +1 -28
  22. data/lib/usecase/cmd.rb +127 -54
  23. data/lib/usecase/config/README.md +57 -0
  24. data/lib/usecase/docker/README.md +146 -0
  25. data/lib/usecase/docker/docker.rb +49 -0
  26. data/lib/usecase/edit/README.md +43 -0
  27. data/lib/usecase/edit/delete.rb +46 -0
  28. data/lib/usecase/export.rb +40 -0
  29. data/lib/usecase/files/README.md +37 -0
  30. data/lib/usecase/files/eject.rb +56 -0
  31. data/lib/usecase/files/file_me.rb +78 -0
  32. data/lib/usecase/files/read.rb +169 -0
  33. data/lib/usecase/files/write.rb +89 -0
  34. data/lib/usecase/goto.rb +57 -0
  35. data/lib/usecase/id.rb +1 -1
  36. data/lib/usecase/import.rb +13 -30
  37. data/lib/usecase/init.rb +2 -17
  38. data/lib/usecase/jenkins/README.md +146 -0
  39. data/lib/usecase/jenkins/crazy_ruby_post_attempt.OLD +234 -0
  40. data/lib/usecase/jenkins/jenkins.rb +208 -0
  41. data/lib/usecase/login.rb +6 -5
  42. data/lib/usecase/logout.rb +1 -3
  43. data/lib/usecase/open.rb +11 -66
  44. data/lib/usecase/print.rb +40 -0
  45. data/lib/usecase/put.rb +34 -156
  46. data/lib/usecase/set.rb +2 -4
  47. data/lib/usecase/show.rb +138 -0
  48. data/lib/usecase/terraform/README.md +91 -0
  49. data/lib/usecase/terraform/terraform.rb +121 -0
  50. data/lib/usecase/token.rb +4 -80
  51. data/lib/usecase/update/README.md +55 -0
  52. data/lib/usecase/update/rename.rb +180 -0
  53. data/lib/usecase/use.rb +1 -3
  54. data/lib/usecase/verse.rb +20 -0
  55. data/lib/usecase/view.rb +71 -0
  56. data/lib/usecase/vpn/README.md +150 -0
  57. data/lib/usecase/vpn/vpn.ini +31 -0
  58. data/lib/usecase/vpn/vpn.rb +54 -0
  59. data/lib/version.rb +1 -1
  60. data/opensecret.gemspec +3 -4
  61. metadata +34 -35
  62. data/.travis.yml +0 -5
  63. data/CODE_OF_CONDUCT.md +0 -74
  64. data/LICENSE.txt +0 -21
  65. data/bin/ops +0 -20
  66. data/lib/keytools/binary.map.rb +0 -294
  67. data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +0 -179
  68. data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +0 -190
  69. data/lib/keytools/doc.star.schema.strategy.txt +0 -77
  70. data/lib/keytools/doc.using.pbkdf2.kdf.ruby +0 -95
  71. data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +0 -266
  72. data/lib/keytools/key.mach.rb +0 -248
  73. data/lib/keytools/keydebug.txt +0 -295
  74. data/lib/modules/cryptology/open.bcrypt.rb +0 -170
  75. data/lib/usecase/read.rb +0 -89
  76. data/lib/usecase/safe.rb +0 -92
@@ -0,0 +1,91 @@
1
+
2
+ # safe terraform <command>
3
+
4
+ ### safe terraform | introduction
5
+
6
+ This terraform use case exports the AWS IAM user access key, secret key and region key into (very safe) environment variables and then runs the specified terraform be it **init**, **plan**, **apply** or **destroy**.
7
+
8
+
9
+ ## safe terraform | credential creation
10
+
11
+ The first use case is importing the IAM user credentials into safe.
12
+
13
+ $ safe login joebloggs.com # open the book
14
+ $ safe open iam dev.s3.writer # open chapter and verse
15
+ $ safe put @access.key ABCD1234EFGH5678 # Put IAM access key in safe
16
+ $ safe put @secret.key xyzabcd1234efgh5678 # Put IAM secret key in safe
17
+ $ safe put region.key eu-west-3 # infrastructure in Paris
18
+
19
+ $ safe open iam prod.provisioner # open chapter and verse
20
+ $ safe put @access.key 4321DCBA8765WXYZ # Put IAM access key in safe
21
+ $ safe put @secret.key 5678uvwx4321abcd9876 # Put IAM secret key in safe
22
+ $ safe put region.key eu-west-1 # infrastructure in Dublin
23
+
24
+ safe logout
25
+
26
+ Take care to specify these 3 key names **@access.key**, **@secret.key**, **region.key** and note that safe's convention is to sensitively treat the value's of keys beginning with an **@** sign. **safe show** and other readers **mask out (redact)** these sensitive values.
27
+
28
+
29
+ ## safe terraform | running terraform
30
+
31
+ Now and forever you can return to the chapter and verse and enjoy a secure credentials transfer where safe makes the IAM user credentials available to Terraform via environment variables. **Never do the plain text credentials touch the floor (disk).**
32
+
33
+ ### Why no safe terraform init?
34
+ **safe only gets involved when credentials are involved**.
35
+ **safe** is not trying to wrap command willy nilly. safe's policy is to keep external tool interfaces as **small** as possible. **`terraform init .`** does not involve credentials so safe does not get involved.
36
+
37
+ $ cd /path/to/terraform/dir # go to directory holding your .tf file
38
+ $ safe login joebloggs.com # login to your chosen book
39
+ $ safe open iam dev.s3.writer # open chapter and verse holding IAM creds
40
+ $ terraform init . # the usual terraform init command
41
+ $ safe terraform plan # credentials are exported then terraform plan is run
42
+ $ safe terraform apply # credentials are exported then terraform apply is run
43
+ $ safe terraform destroy # credentials are exported then terraform destroy is run
44
+
45
+ You can even change directories and run other terraform projects against the opened IAM user. You can also open an IAM user, run commands, open another run commands and then reopen the first and run commands.
46
+
47
+ As long as you stay within your shell window - your safe login will persist. Once your session is finished you either logout or exit the shell.
48
+
49
+ ### Shortcut Alert
50
+
51
+ **safe terraform** is a shortcut for **safe terraform apply**
52
+
53
+ $ safe terraform apply
54
+ $ safe terraform
55
+
56
+ ## safe terraform | pre-conditions
57
+
58
+ To enact a successful safe terraform call you will need
59
+
60
+ - to have created an IAM user
61
+ - to open chapter and verse which
62
+ - has these 3 keys @access.key @secret.key and region.key (at least)
63
+ - terraform installed on the machine or container
64
+
65
+
66
+ ## safe terraform | benefits
67
+
68
+ The safe terraform command is both an ultra secure and extremely convenient way of launching terraform.
69
+
70
+ Your precious AWS IAM user credentials do not leave the safe and exist within (environment variable) memory only for the duration of the terraform command.
71
+
72
+ It is safe as you need neither expose your AWS credentials in plain text in **~/.aws/credentials**, nor risk them sliding into version control. It is convenient because switching IAM users and AWS regions is as easy as typing the now ubiquitous safe open command.
73
+
74
+
75
+ ## quick tip | view then goto
76
+
77
+ No need to type out the safe open command everytime. Use it the very first time you create a path to chapter and verse.
78
+
79
+ safe open <<chapter>> <<verse>>
80
+
81
+ Then use safe view and safe goto instead of safe open.
82
+
83
+ $ safe view # list all chapter and verses
84
+ $ safe goto <<index>> # use the number from safe view to open the location
85
+ $ safe show # look at your mini dictionary
86
+
87
+
88
+ ## safe terraform | only for aws
89
+
90
+ This command currently only supports the AWS provider but will be extended to support Google's Compute Engine and more besides.
91
+
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # This terraform use case exports the AWS IAM user access key, secret key and region key
6
+ # into (very safe) environment variables and then runs terraform init, plan, apply or destroy.
7
+ #
8
+ # This is both ultra secure and extremely convenient because the credentials do not leave
9
+ # the safe and exist within (environment variable) memory only for the duration of the
10
+ # terraform command.
11
+ #
12
+ # It is safe because you do not need to expose your AWS credentials in plain text.
13
+ # It is convenient because switching IAM users and AWS regions is as easy as typing the now
14
+ # ubiquitous safe open command.
15
+ #
16
+ # safe open <<chapter>> <<verse>>
17
+ class Terraform < UseCase
18
+
19
+ attr_writer :command
20
+
21
+ # This prefix is tagged onto environment variables which Terraform will read
22
+ # and convert for consumption into module input variables.
23
+ TERRAFORM_EVAR_PREFIX = "TF_VAR_"
24
+
25
+ def execute
26
+
27
+ return unless ops_key_exists?
28
+ master_db = get_master_database()
29
+ return if unopened_envelope?( master_db )
30
+
31
+ # Get the open chapter identifier (id).
32
+ # Decide whether chapter already exists.
33
+ # Then get (or instantiate) the chapter's hash data structure
34
+ chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
35
+ verse_id = master_db[ KEY_PATH ]
36
+ chapter_exists = OpenKey::KeyApi.db_envelope_exists?( master_db[ chapter_id ] )
37
+
38
+
39
+ # -- @todo begin
40
+ # -- Throw an exception (error) if the chapter
41
+ # -- either exists and is empty or does not exist.
42
+ # -- @todo end
43
+
44
+
45
+ # Unlock the chapter data structure by supplying
46
+ # key/value mini-dictionary breadcrumbs sitting
47
+ # within the master database at the section labelled
48
+ # envelope@<<actual_chapter_id>>.
49
+ chapter_data = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ chapter_id ] ) )
50
+
51
+ # Now read the three AWS IAM credentials @access.key, @secret.key and region.key
52
+ # into the 3 environment variables terraform expects to find.
53
+
54
+ # ############## | ############################################################
55
+ # @todo refactor | ############################################################
56
+ # -------------- | 000000000000000000000000000000000000000000000000000000000000
57
+ # export-then-execute
58
+ # -------------------
59
+ # Put all the code above in a generic export-then-execute use case
60
+ # Then you pass in a Key/Value Dictionary
61
+ #
62
+ # { "AWS_ACCESS_KEY_ID" => "@access_key",
63
+ # "AWS_SECRET_ACCESS_KEY" => "@secret_key",
64
+ # "AWS_DEFAULT_REGION" => "region_key"
65
+ # }
66
+ #
67
+ # And pass in a command array [ "terraform #{command_name} #{auto_approve}", "terraform graph ..." ]
68
+ #
69
+ # Validation is done by the generic use case (which loops checking that every value exists
70
+ # as a key at the opened location.
71
+ #
72
+ # If all good the generic use case exports the ENV vars and runs each command in the list.
73
+ # PS - configure map in INI not code file
74
+ #
75
+ # The extra power will speed up generation of environment variable use cases including
76
+ # ansible, s3 bucket operations, git interactions and more.
77
+ #
78
+ # ############## | ############################################################
79
+ # ############## | ############################################################
80
+
81
+ puts ""
82
+ puts "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
83
+ puts ""
84
+
85
+ ENV[ "AWS_ACCESS_KEY_ID" ] = chapter_data[ verse_id ][ "@access.key" ]
86
+ ENV[ "AWS_SECRET_ACCESS_KEY" ] = chapter_data[ verse_id ][ "@secret.key" ]
87
+ ENV[ "AWS_DEFAULT_REGION" ] = chapter_data[ verse_id ][ "region.key" ]
88
+
89
+ mini_dictionary = chapter_data[ verse_id ]
90
+ mini_dictionary.each do | key_str, value_object |
91
+
92
+ is_env_var = key_str.start_with?( ENV_VAR_PREFIX_A ) || key_str.start_with?( ENV_VAR_PREFIX_B )
93
+ next unless is_env_var
94
+
95
+ env_var_name = key_str[ ENV_VAR_PREFIX_A.length .. -1 ] if key_str.start_with? ENV_VAR_PREFIX_A
96
+ env_var_name = key_str[ ENV_VAR_PREFIX_B.length .. -1 ] if key_str.start_with? ENV_VAR_PREFIX_B
97
+ env_var_keyname = TERRAFORM_EVAR_PREFIX + env_var_name
98
+ ENV[ env_var_keyname ] = value_object
99
+ puts "Environment variable #{env_var_keyname} has been set."
100
+
101
+ end
102
+
103
+ puts ""
104
+ puts "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
105
+ puts ""
106
+
107
+ auto_approve = @command && @command.eql?( "plan" ) ? "" : "-auto-approve"
108
+ command_name = @command ? @command : "apply"
109
+ system "terraform #{command_name} #{auto_approve}"
110
+
111
+ puts ""
112
+ puts "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
113
+ puts ""
114
+
115
+ end
116
+
117
+
118
+ end
119
+
120
+
121
+ end
@@ -3,88 +3,12 @@
3
3
  module OpenSecret
4
4
 
5
5
  # The <tt>token use case</tt> prints out an encrypted session token tied
6
- # to the workstation and shell environment. It should be called like this
7
- # and <tt>printenv</tt> can be used to verify that a shell-scoped
8
- # environment variable tying OPEN_SESSION_TOKEN to a 150 character session
9
- # token, has been created.
10
- #
11
- # export OPEN_SESSION_TOKEN=`ops token`
12
- # printenv
13
- #
14
- # Note the <b>back-ticks</b> surrounding the <tt>ops token</tt> call.
15
- #
16
- # When the shell closes OPEN_SESSION_TOKEN disappears forever. However if you want to
17
- # continue using the same shell you can wipe this away.
18
- #
19
- # $ unset OPEN_SESSION_TOKEN # Delete the shell session token
20
- # $ env | grep OPEN_SESSION_TOKEN # Check OPEN_SESSION_TOKEN is deleted
21
- #
22
- # You can also delete every env var created by this shell.
23
- #
24
- # $ env -i bash # Rewind to (after) login variables
25
- #
26
- # == How to instantiate a Command Line Session
27
- #
28
- # Initialize the session by generating a random high entropy shell token
29
- # and then generating an obfuscator key which we use to lock the shell
30
- # key and return a triply segmented text token that can be used to decrypt
31
- # and deliver the shell key as long as the same shell on the same machine
32
- # is employed to make the call.
33
- #
34
- # == The 3 Session Token Segments
35
- #
36
- # The session token is divided up into 3 segments with a total of 150
37
- # characters.
38
- #
39
- # | -------- | ------------ | ------------------------------------- |
40
- # | Segment | Length | Purpose |
41
- # | -------- | ------------ | ------------------------------------- |
42
- # | 1 | 16 bytes | AES Encrypt Initialization Vector(IV) |
43
- # | 2 | 80 bytes | Cipher text from Random Key AES crypt |
44
- # | 3 | 22 chars | Salt for obfuscator key derivation |
45
- # | -------- | ------------ | ------------------------------------- |
46
- # | Total | 150 chars | Session Token in Environment Variable |
47
- # | -------- | ------------ | ------------------------------------- |
48
- #
49
- # Why is the <b>16 byte salt and the 80 byte BCrypt ciphertext</b> represented
50
- # by <b>128 base64 characters</b>?
51
- #
52
- # 16 bytes + 80 bytes = 96 bytes
53
- # 96 bytes x 8 bits = 768 bits
54
- # 768 bits / 6 bits = 128 base64 characters
55
- #
56
- # == Other ways to instantiate the session token
57
- #
58
- # The session token environment variable can be delivered
59
- #
60
- # - with the export command
61
- # - via a docker run ENV parameter
62
- # - using the dot profile script
63
- #
64
- class Token < Command
6
+ # to the workstation and shell environment. See the root README.md on how
7
+ # to export it and create a simple command alias for it in the ~/.bash_aliases
8
+ # script which is executed when the shell starts.
9
+ class Token < UseCase
65
10
 
66
11
 
67
- # The <tt>token use case</tt> prints out an encrypted session token tied
68
- # to the workstation and shell environment. It should be called like this
69
- # and <tt>printenv</tt> can be used to verify that a shell-scoped
70
- # environment variable tying OPEN_SESSION_TOKEN to an (approximately) 48 character
71
- # session password, has been created.
72
- #
73
- # export OPEN_SESSION_TOKEN=`ops token`
74
- # printenv
75
- #
76
- # Note the <b>back-ticks</b> surrounding the <tt>ops token</tt> call.
77
- #
78
- # <b>How to instantiate a Command Line Session</b>
79
- #
80
- # $ printenv
81
- # $ export OPEN_SESSION_TOKEN=`ops token`
82
- # $ printenv
83
- #
84
- # The 2nd printenv should reveal a shell specific environment variable.
85
- #
86
- # OPEN_SESSION_TOKEN=FvxETEpmoVUetyJ0jJk19aus1pQkzLZ8OVJccatYnC9GxDE4Iy3AyWNZ...
87
- #
88
12
  def execute
89
13
 
90
14
  print OpenKey::KeyLocal.generate_shell_key_and_token()
@@ -0,0 +1,55 @@
1
+
2
+
3
+ # safe rename
4
+
5
+ Changing your mind is a basic human right! In lieu of this, safe provides a **rename** use case that can be used to rename
6
+
7
+ - a chapter
8
+ - a verse
9
+ - a key (at a chapter and verse location)
10
+
11
+ <blockquote>
12
+ As yet safe has no command for renaming books. You can achieve this by first cloning the book then deleting the original.
13
+ </blockquote>
14
+
15
+ ## safe rename | chapter
16
+
17
+ To rename a chapter you must not have an open location. If you do you must first close it before renaming.
18
+
19
+ $ safe close
20
+ $ safe view
21
+ $ safe rename <old-name> <new-name>
22
+
23
+ When safe sees that the book is not open, it knows that you want to rename the chapter.
24
+
25
+ The rename command returns a view allowing you to check that the chapter name has indeed been updated.
26
+
27
+
28
+ ## safe rename | verse
29
+
30
+ To rename the verse you must have its chapter (and only its chapter) open.
31
+
32
+ $ safe close
33
+ $ safe open <chapter>
34
+ $ safe view
35
+ $ safe rename <old-name> <new-name>
36
+
37
+ The rename command returns a view of all the verses in the open chapter allowing you to check that the verse name has indeed been updated.
38
+
39
+ ## safe rename | key
40
+
41
+ Most of the time you will want to rename keys in the mini-dictionary at a chapter and verse location. To do this you must open the chapter and verse first.
42
+
43
+ $ safe open <chapter> <verse>
44
+ $ safe show
45
+ $ safe rename <old-name> <new-name>
46
+
47
+ The rename command shows you the mini-dictionary (hashing out sensitive credentials) allowing you to check that the key name has indeed been updated.
48
+
49
+ ## safe rename | be aware
50
+
51
+ Be aware of the following when renaming.
52
+
53
+ - key names that start with @ guard the key's value during a safe show
54
+ - renaming keys that are required for integration functionality will need you pass the --force switch
55
+
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # The <b>put use case</b> follows <b>open</b> and it adds secrets into an
6
+ # <em>(encrypted at rest)</em> <b>envelope</b>. Put can be called many times
7
+ # and when done, the <b>lock use case</b> can be called to commit all opened
8
+ # secrets into the configured storage engines.
9
+ #
10
+ # Calling <em>put</em> <b>before</b> calling open or <b>after</b> calling lock
11
+ # is not allowed and will result in an error.
12
+ #
13
+ # == Put Pre-Conditions
14
+ #
15
+ # When the put use case is called - the below conditions ring true.
16
+ #
17
+ # - the <b>folder path</b> ending in ../../my must exist
18
+ # - a session id, filename and encryption key ( in workstation config )
19
+ #
20
+ # == Observable Value
21
+ #
22
+ # The observable value delivered by +put+ boils down to
23
+ #
24
+ # - a new <b>friends.xyz123abc.os.txt</b> file if this is the first put.
25
+ # - a new group_name/key_name (like monica/surname) entry is added if required
26
+ # - a secret value is added against the key or updated if it already exists
27
+ # - a new session id and encryption key is generated and used to re-encrypt
28
+ #
29
+ # == Example | Bill Clinton's Secrets
30
+ #
31
+ # In our fictitious example Bill Clinton uses opensecret to lock away the
32
+ # names and dates of his lady friends.
33
+ #
34
+ # $ opensecret init bill.clinton@example.com
35
+ # $ opensecret open my/friends
36
+ #
37
+ # $ opensecret put monica/surname lewinsky
38
+ # $ opensecret put monica/from "April 1989"
39
+ # $ opensecret put monica/to "September 1994"
40
+ #
41
+ # $ opensecret put hilary/surname clinton
42
+ # $ opensecret put hilary/from "January 1988"
43
+ # $ opensecret put hilary/to "Present Day"
44
+ #
45
+ # $ opensecret lock
46
+ #
47
+ # Soon follow up use cases will be unveiled, enabling us to
48
+ #
49
+ # - <b>get</b>
50
+ # - <b>read</b>
51
+ # - <b>list</b>
52
+ # - <b>look</b>
53
+ # - <b>peep</b> and
54
+ # - <b>peek</b>
55
+ class Rename < UseCase
56
+
57
+
58
+ attr_writer :secret_id, :secret_value
59
+
60
+
61
+ # The <b>put use case</b> follows <b>open</b> and it adds secrets into an
62
+ # <em>(encrypted at rest)</em> envelope. Put can be called many times to
63
+ # add secrets. Finally the <b>lock use case</b> commits all opened secrets
64
+ # into the configured storage engines.
65
+ #
66
+ # Calling <em>put</em> <b>before</b> calling open or <b>after</b> calling lock
67
+ # is not allowed and will result in an error.
68
+ #
69
+ # == Put Pre-Conditions
70
+ #
71
+ # When the put use case is called - the below conditions ring true.
72
+ #
73
+ # - the <b>folder path</b> ending in ../../my must exist
74
+ # - a session id, filename and encryption key ( in workstation config )
75
+ #
76
+ # == Observable Value
77
+ #
78
+ # The observable value delivered by +put+ boils down to
79
+ #
80
+ # - a new <b>friends.xyz123abc.os.txt</b> file if this is the first put.
81
+ # - a new group_name/key_name (like monica/surname) entry is added if required
82
+ # - a secret value is added against the key or updated if it already exists
83
+ # - a new session id and encryption key is generated and used to re-encrypt
84
+ #
85
+ # == How to Pretty Print a Hash in JSON Format
86
+ #
87
+ # This pretty prints a Hash (dictionary) data structure in JSON format.
88
+ #
89
+ # puts "---\n"
90
+ # puts JSON.pretty_generate( master_db )
91
+ # puts "---\n"
92
+ #
93
+ def execute
94
+
95
+ return unless ops_key_exists?
96
+ master_db = OpenKey::KeyApi.read_master_db()
97
+
98
+ return if unopened_envelope?( master_db )
99
+
100
+ envelope_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
101
+ has_content = OpenKey::KeyApi.db_envelope_exists?( master_db[ envelope_id ] )
102
+
103
+ # --
104
+ # -- To get hold of the content we must either
105
+ # --
106
+ # -- a) unlock it using the breadcrumbs or
107
+ # -- b) start afresh with a new content db
108
+ # --
109
+ content_box = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ envelope_id ] ) ) if has_content
110
+ content_box = OpenKey::KeyDb.new() unless has_content
111
+ content_hdr = create_header()
112
+
113
+ # --
114
+ # -- If no content envelope exists we need to place
115
+ # -- an empty one inside the appdb content database.
116
+ # --
117
+ master_db[ envelope_id ] = {} unless has_content
118
+
119
+ # --
120
+ # -- This is the PUT use case so we append a
121
+ # --
122
+ # -- a) key for the new dictionary entry
123
+ # -- b) value for the new dictionary entry
124
+ # --
125
+ # -- into the current content envelope and write
126
+ # -- the envelope to the content filepath.
127
+ # --
128
+ crumbs_dict = master_db[ envelope_id ]
129
+ content_box.create_entry( master_db[ KEY_PATH ], @secret_id, @secret_value )
130
+ OpenKey::KeyApi.content_lock( crumbs_dict, content_box.to_json, content_hdr )
131
+
132
+ # --
133
+ # -- Three envelope crumbs namely the external ID, the
134
+ # -- random iv and the crypt key are written afresh into
135
+ # -- the master database.
136
+ # --
137
+ OpenKey::KeyApi.write_master_db( content_hdr, master_db )
138
+ print_put_success
139
+
140
+ # ---> secret_ids = @secret_id.split("/")
141
+ # ---> if ( envelope.has_key? secret_ids.first )
142
+ # ---> envelope[secret_ids.first][secret_ids.last] = @secret_value
143
+ # ---> else
144
+ # ---> envelope[secret_ids.first] = { secret_ids.last => @secret_value }
145
+ # ---> end
146
+
147
+ end
148
+
149
+
150
+ private
151
+
152
+
153
+ def print_put_success
154
+
155
+ puts ""
156
+ puts "Success putting a key/value pair into the open envelope."
157
+ puts "You can put more in and then close the envelope."
158
+ puts ""
159
+ puts " #{COMMANDMENT} close"
160
+ puts ""
161
+
162
+ end
163
+
164
+
165
+ # Perform pre-conditional validations in preparation to executing the main flow
166
+ # of events for this use case. This method may throw the below exceptions.
167
+ #
168
+ # @raise [SafeDirNotConfigured] if the safe's url has not been configured
169
+ # @raise [EmailAddrNotConfigured] if the email address has not been configured
170
+ # @raise [StoreUrlNotConfigured] if the crypt store url is not configured
171
+ def pre_validation
172
+
173
+
174
+ end
175
+
176
+
177
+ end
178
+
179
+
180
+ end