opensecret 0.0.9925 → 0.0.9949

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.
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,146 @@
1
+
2
+ # safe jenkins <command>
3
+
4
+
5
+ ### safe jenkins post [aws|docker|git] <<jenkins-host-url>> | introduction
6
+
7
+ Use **`safe jenkins post`** to inject both your **AWS IAM User** and **docker login/password** credentials into your Jenkins 2.0 continuous integration portal reachable by the **jenkins host url** given in the 4th parameter of the safe command.
8
+
9
+ ---
10
+
11
+ ## safe jenkins post | prerequisite
12
+
13
+ Before you can inject credentials into jenkins using **`safe jenkins post`** you must
14
+
15
+ - be logged into your safe
16
+ - have opened the appropriate chapter/verse
17
+ - have put the required credential key/value pairs into the safe
18
+ - have the jenkins service up and running
19
+
20
+ After the post (to jenkins), your continuous integration jobs will be able to access the credential values via their IDs as stated in the below table.
21
+
22
+ ---
23
+
24
+ ## safe jenkins post aws | key names table
25
+
26
+ As credentials are WORO (write once, read often), safe makes the reading part very very easy (and secure) so your effort is frontloaded.
27
+
28
+ | Safe Key | Jenkins Credential IDs | Environment Variable | Description |
29
+ |:-----------:|:----------------------:|:--------------------- |:-------------------------------------------------------- |
30
+ | @access.key | safe.aws.access.key | AWS_ACCESS_KEY_ID | The AWS IAM user's access key credential. |
31
+ | @secret.key | safe.aws.secret.key | AWS_SECRET_ACCESS_KEY | The AWS IAM user's secret key credential. |
32
+ | region.key | safe.aws.region.key | AWS_REGION | The AWS region key that your Jenkins service points to. |
33
+
34
+ So you can see that by convention, safe expects the credential keys in the safe to be named a particular way, and likewise, you can be assured of the IDs it gives those credentials when posted to Jenkins.
35
+
36
+
37
+ ## safe jenkins post | credentials lifecycle
38
+
39
+ The life of the credentials begins when you create an IAM user and record its access and secret keys. Then
40
+
41
+ - you login to safe and store the 3 keys and their values
42
+ - safe jenkins post will read the values and post them to Jenkins
43
+ - Jenkins stores the values in conjunction with the Jenkins Credential IDs
44
+ - pipeline jobs ask Jenkins to put the Credential ID values against environment variables
45
+ - tools like Terraform and AwsCli use the environment variables to work in the cloud
46
+
47
+
48
+ ## Jenkinsfile | Usage in Pipeline Jobs
49
+
50
+ Here is a pipeline declaration within a Jenkinsfile that asks Jenkins to put the credential values in its secrets store into the stated environment variables.
51
+
52
+ environment
53
+ {
54
+ AWS_ACCESS_KEY_ID = credentials( 'safe.aws.access.key' )
55
+ AWS_SECRET_ACCESS_KEY = credentials( 'safe.aws.secret.key' )
56
+ AWS_REGION = credentials( 'safe.aws.region.key' )
57
+ }
58
+
59
+ After **`safe jenkins post aws`** you can **click into the Credentials item in the Jenkins main menu** to assure yourself that the credentials have indeed been properly injected.
60
+
61
+ ---
62
+
63
+ ## How to Write AWS Credentials into your Safe
64
+
65
+ In order to **`safe terraform apply`** or **`safe jenkins post aws <<jenkins-host-url>>`** or `safe visit` you must first put those ubiquitous IAM programmatic user credentials into your safe.
66
+
67
+ $ safe login joebloggs.com # open the book
68
+
69
+ $ safe open iam dev.s3.reader # open chapter and verse
70
+ $ safe put @access.key ABCD1234EFGH5678 # Put IAM access key in safe
71
+ $ safe put @secret.key xyzabcd1234efgh5678 # Put IAM secret key in safe
72
+ $ safe put region.key eu-west-3 # infrastructure in Paris
73
+
74
+ $ safe open iam canary.admin # open chapter and verse
75
+ $ safe put @access.key 4321DCBA8765WXYZ # Put IAM access key in safe
76
+ $ safe put @secret.key 5678uvwx4321abcd9876 # Put IAM secret key in safe
77
+ $ safe put region.key eu-west-1 # infrastructure in Dublin
78
+
79
+ $ safe logout
80
+
81
+
82
+ ---
83
+
84
+
85
+ ## How to write DockerHub Credentials into your Safe
86
+
87
+ #### safe jenkins post docker https://jenkins.example.com
88
+
89
+ Before you can issue a **`safe jenkins post docker http://localhost:8080`** you must insert your docker login credentials in the form of a docker.username and @docker.password into your safe. Remember that any key starting with the `@ sign` tells the safe to keep it a secret like when you issue a **`safe show`** command.
90
+
91
+ $ safe login joebloggs.com # open the book
92
+ $ safe open docker production # at the docker (for production) chapter and verse
93
+ $ safe put docker.username admin # Put the Docker repository login docker.username into the safe
94
+ $ safe put @docker.password s3cr3t # Put the Docker repository login @docker.password into the safe
95
+ $ safe logout
96
+
97
+ When docker credentials are injected into a Jenkins service the safe will expect to find **lines** at the open chapter and verse location with key names **`docker.username`** and **`@docker.password`**.
98
+
99
+ The safe promises to inject credentials with an ID of **safe.docker.login.id** so any jenkins jobs that need to use the docker login docker.username and password must specify this ID when talking to the Jenkins credentials service.
100
+
101
+
102
+ ### DockerHub Credentials Inject Response
103
+
104
+ Here is an example of posting dockerhub credentials into a Jenkins service running on the local machine.
105
+
106
+ ``` bash
107
+ safe jenkins post docker http://localhost:8080
108
+ ```
109
+
110
+ If successful safe provides a polite response detailing what just happened.
111
+
112
+ ```
113
+ - Jenkins Host Url : http://localhost:8080/credentials/store/system/domain/_/createCredentials
114
+ - Credentials ID : safe.docker.login.id
115
+ - Inject Username : devops4me
116
+ - So what is this? : The docker repository login credentials in the shape of a username and password.
117
+
118
+ % Total % Received % Xferd Average Speed Time Time Time Current
119
+ Dload Upload Total Spent Left Speed
120
+ 100 428 0 0 100 428 0 47555 --:--:-- --:--:-- --:--:-- 47555
121
+ ```
122
+
123
+ ---
124
+
125
+
126
+ ## safe integrations | we need your help
127
+
128
+ **You can help to extend safe's integrations.**
129
+
130
+ By design - safe integrations are simple to write. They primarily integrate with producers and consumers. To deliver efficacy to devops engineers safe will endeavour to
131
+
132
+ - **send** credentials to **downstream consumers** and
133
+ - **receive** credentials from **upstream producers**
134
+
135
+ safe needs pull requests from the devops community and it promises to always strive to keep the task of writing an integration extremely simple.
136
+
137
+ ### integrations | what giving takes?
138
+
139
+ Currently, writing an integration entails delivering 3 or 4 artifacts which are
140
+
141
+ - 1 simple Ruby class
142
+ - 1 README.md documenting the command structure, the prerequisites and the expected outcome
143
+ - 1 class containing unit tests
144
+ - (optionaly) an INI file if many configuration and facts are involved
145
+
146
+ Giving doesn't take much so roll up your sleeves (or frocks) and get writing.
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # This docker use case handles the ...
6
+ #
7
+ # safe docker login
8
+ # safe docker logout
9
+
10
+ class Docker < UseCase
11
+
12
+ # The command which currently must be login, logout or
13
+ # an empty string.
14
+ attr_writer :command
15
+
16
+ def execute
17
+
18
+ return unless ops_key_exists?
19
+ master_db = get_master_database()
20
+ return if unopened_envelope?( master_db )
21
+
22
+ # Get the open chapter identifier (id).
23
+ # Decide whether chapter already exists.
24
+ # Then get (or instantiate) the chapter's hash data structure
25
+ chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
26
+ verse_id = master_db[ KEY_PATH ]
27
+ chapter_exists = OpenKey::KeyApi.db_envelope_exists?( master_db[ chapter_id ] )
28
+
29
+ # Unlock the chapter data structure by supplying
30
+ # key/value mini-dictionary breadcrumbs sitting
31
+ # within the master database at the section labelled
32
+ # envelope@<<actual_chapter_id>>.
33
+ chapter_data = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ chapter_id ] ) )
34
+
35
+ key_value_dictionary = chapter_data[ verse_id ]
36
+ docker_username = key_value_dictionary[ "docker.username" ]
37
+ docker_password = key_value_dictionary[ "@docker.password" ]
38
+ docker_login_cmd = "docker login --username #{docker_username} --password #{docker_password} 2>/dev/null"
39
+ docker_logout_cmd = "docker logout"
40
+ docker_cmd = @command.eql?( "logout" ) ? docker_logout_cmd : docker_login_cmd
41
+ system docker_cmd
42
+
43
+ end
44
+
45
+
46
+ end
47
+
48
+
49
+ end
@@ -0,0 +1,43 @@
1
+
2
+ ### safe put | safe delete | safe copy | safe paste
3
+
4
+ # edit use cases | copy | paste | delete
5
+
6
+ The edit use cases create, delete and update the credentials and configuration inside your safe.
7
+
8
+ ## Common Usage
9
+
10
+ Typically you login to a book, open a chapter and verse, then you put **`key/value`** pairs, known as **lines**.
11
+
12
+ ```
13
+ safe login joe@home
14
+
15
+ # -- -------------------------------------------------- -- #
16
+ # -- Create chapter (email) and verse <<email-address>> -- #
17
+ # -- -------------------------------------------------- -- #
18
+ safe open email joebloggs@gmail.com
19
+
20
+ # -- ---------------------------- -- #
21
+ # -- Populate it with credentials -- #
22
+ # -- ---------------------------- -- #
23
+ safe put gmail.id joebloggs
24
+ safe put @password s3cr3et
25
+ safe put recovery.phone 07500875278
26
+
27
+ # -- ----------------------------------------------- -- #
28
+ # -- Now copy and then paste a line (key/value pair) -- #
29
+ # -- ----------------------------------------------- -- #
30
+ safe copy recovery.phone
31
+ safe open email joe@ywork.com
32
+ safe paste
33
+ ```
34
+
35
+ ## editing behaviour
36
+
37
+ **These use cases are intuitive and behave almost like what you would expect.** The safe ethos is for commands to behave according to which of the 5 levels you are at.
38
+
39
+
40
+ | Command | Verse | Chapter | Book |
41
+ |:---------------- |:----------------------------- |:-------------------------------- |:------------------------------- |
42
+ | safe copy <<id>> | Copy one of the verse's lines | Copy one of the chapter's verses | Copy one of the book's chapters |
43
+ | safe copy | Copy all of the verse's lines | Copy all of the chapter's verses | Copy all of the book's chapters |
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # The <b>delete use case</b> delete's one or more of the safe's entities.
6
+ #
7
+ # - at <tt>verse</tt> level - it can delete one or more lines
8
+ # - at <tt>chapter</tt> level - it can delete one or more verses
9
+ # - at <tt>book</tt> level - it can delete one or more chapters
10
+ # - at <tt>safe</tt> level - it can delete one book
11
+ #
12
+ class DeleteMe < UseCase
13
+
14
+ attr_writer :entity_id
15
+
16
+ # Deletion that currently expects an open chapter and verse and always
17
+ # wants to delete only one line (key/value pair).
18
+ def execute
19
+
20
+ return unless ops_key_exists?
21
+ master_db = OpenKey::KeyApi.read_master_db()
22
+ return if unopened_envelope?( master_db )
23
+
24
+ chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
25
+ chapter_exists = OpenKey::KeyApi.db_envelope_exists?( master_db[ chapter_id ] )
26
+ chapter_data = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ chapter_id ] ) ) if chapter_exists
27
+ chapter_data = OpenKey::KeyDb.new() unless chapter_exists
28
+
29
+ content_hdr = create_header()
30
+ master_db[ chapter_id ] = {} unless chapter_exists
31
+ verse_id = master_db[ KEY_PATH ]
32
+
33
+ chapter_data.delete_entry( verse_id, @entity_id )
34
+ chapter_data.delete_entry( verse_id, "#{FILE_KEY_PREFIX}#{@entity_id}" )
35
+
36
+ OpenKey::KeyApi.content_lock( master_db[ chapter_id ], chapter_data.to_json, content_hdr )
37
+ OpenKey::KeyApi.write_master_db( content_hdr, master_db )
38
+ Show.new.flow_of_events
39
+
40
+ end
41
+
42
+
43
+ end
44
+
45
+
46
+ end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # Export the entire book if no chapter and verse is specified (achieved with a safe close),
6
+ # or the chapter if only the chapter is open (safe shut or safe open <<chapter>>, or the
7
+ # mini-dictionary at the verse if both chapter and verse are open.
8
+ class Export < UseCase
9
+
10
+ def get_chapter_data( chapter_key )
11
+ return OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( chapter_key ) )
12
+ end
13
+
14
+ def execute
15
+
16
+ return unless ops_key_exists?
17
+ master_db = OpenKey::KeyApi.read_master_db()
18
+
19
+ return if unopened_envelope?( master_db )
20
+
21
+ chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
22
+ has_chapter = OpenKey::KeyApi.db_envelope_exists?( master_db[ chapter_id ] )
23
+
24
+ unless has_chapter
25
+ puts "{}"
26
+ return
27
+ end
28
+
29
+ chapter_data = get_chapter_data( master_db[ chapter_id ] )
30
+ puts JSON.pretty_generate( chapter_data )
31
+
32
+ return
33
+
34
+ end
35
+
36
+
37
+ end
38
+
39
+
40
+ end
@@ -0,0 +1,37 @@
1
+
2
+ # safe file | ingest and eject files
3
+
4
+ You ingest a file with **safe file** and then **safe eject** will output that file into the present working directory.
5
+
6
+ If safe detects during an eject, that a file already exists with the same name - it backs it up with a timestamp before ejecting and clobbering the existing file.
7
+
8
+ ```bash
9
+ safe open <<chapter-name>> <<verse-name>>
10
+ safe file <<keyname>> <</path/to/private-key.pem>>
11
+ safe eject <<keyname>>
12
+ safe show
13
+ ```
14
+
15
+ To pull in 3 certificate oriented files for Kubernetes one could use these commands.
16
+
17
+ ```bash
18
+ safe open production kubernetes
19
+ safe file kubernetes.cert ~/.kubectl/kube.prod.cert.pem
20
+ safe file kubernetes.ca.cert ~/.kubectl/kube.prod.ca.cert.pem
21
+ safe file kubernetes.key ~/.kubectl/kube.prod.key.pem
22
+ cd /tmp
23
+ safe eject
24
+ ```
25
+
26
+ The safe ingests the files and spits them out whenever you so desire.
27
+ **Binary files** are supported and can be safely pulled in with <tt>safe file</tt> and ejected at any point in the future.
28
+
29
+ ## remote (external) files
30
+
31
+ The **local filesystem** is the most common, but by no means the only file storage location. You can read from and write to
32
+
33
+ - a zip file **`zip://`**
34
+ - an S3 filesystem **`s3://`**
35
+ - SSH locations **`<<user>>@<<hostname>>:/path/to/file`**
36
+ - a git repository **`git@github.com`**
37
+ - a **google drive** store
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # The <b>eject use case</b> writes (or overwrites) a file or files.
6
+ # Files are always ejected into the present working directory. If an
7
+ # overwrite is detected a backup is taken of the about to be clobbered
8
+ # file.
9
+ #
10
+ # If a keyname is provided then only the file against that key is ejected.
11
+ # No keyname will eject every file in the opened chapter and verse.
12
+ class Eject < UseCase
13
+
14
+ attr_writer :file_key
15
+
16
+ # Files are always ejected into the present working directory and any
17
+ # about to be clobbered files are backed up with a timestamp.
18
+ #
19
+ # If a keyname is provided then only the file against that key is ejected.
20
+ # No keyname will eject every file in the opened chapter and verse.
21
+ def execute
22
+
23
+ return unless ops_key_exists?
24
+ master_db = get_master_database()
25
+ return if unopened_envelope?( master_db )
26
+ chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
27
+ verse_id = master_db[ KEY_PATH ]
28
+ chapter_data = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ chapter_id ] ) )
29
+
30
+ base64_content = chapter_data[ verse_id ][ "#{FILE_KEY_PREFIX}#{@file_key}" ][ FILE_CONTENT_KEY ]
31
+ simple_filename = chapter_data[ verse_id ][ "#{FILE_KEY_PREFIX}#{@file_key}" ][ FILE_NAME_KEY ]
32
+ file_full_path = File.join( Dir.pwd, simple_filename )
33
+ backup_filename = OpenKey::KeyNow.yyjjj_hhmm_sst() + "-" + simple_filename
34
+ backup_file_path = File.join( Dir.pwd, backup_filename )
35
+ will_clobber = File.file?( file_full_path )
36
+
37
+ File.write( backup_file_path, File.read( file_full_path ) ) if will_clobber
38
+ ::File.write( file_full_path, Base64.urlsafe_decode64( base64_content ) )
39
+
40
+ puts ""
41
+ puts "File successfully ejected from safe into current directory."
42
+ puts ""
43
+ puts "Clobbered File = #{backup_filename}" if will_clobber
44
+ puts "Current Directory = #{Dir.pwd}"
45
+ puts "Ejected Filename = #{simple_filename}"
46
+ puts "Chapter and Verse = #{master_db[ENV_PATH]}:#{verse_id}"
47
+ puts "Ejected File Key = #{@file_key}"
48
+ puts ""
49
+
50
+ end
51
+
52
+
53
+ end
54
+
55
+
56
+ end
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # The <b>file use case</b> pulls a file in from either an accessible filesystem
6
+ # or from a remote http, https, git, S3, GoogleDrive and/or ssh source.
7
+ #
8
+ # The @file_url is the most common parameter given to this use case.
9
+ class FileMe < UseCase
10
+
11
+ attr_writer :file_key, :file_url
12
+
13
+ # There are 3 maps involved in the implementation and they are all (or in part) retrieved and/or
14
+ # created as necessary. They are
15
+ #
16
+ # - the current chapter as a map
17
+ # - the current verse as a map
18
+ # - the file's keyname as a map
19
+ #
20
+ # Once the maps have been found and/or created if necessary the file's keyname map is either
21
+ # populated or amended with the following data.
22
+ #
23
+ # - filename | {UseCase::FILE_NAME_KEY} | the file's simple name
24
+ # - content64 | {UseCase::FILE_CONTENT_KEY} | the file's base64 content
25
+ def execute
26
+
27
+ return unless ops_key_exists?
28
+ master_db = OpenKey::KeyApi.read_master_db()
29
+ return if unopened_envelope?( master_db )
30
+
31
+ chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
32
+ chapter_exists = OpenKey::KeyApi.db_envelope_exists?( master_db[ chapter_id ] )
33
+ chapter_data = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ chapter_id ] ) ) if chapter_exists
34
+ chapter_data = OpenKey::KeyDb.new() unless chapter_exists
35
+
36
+ content_hdr = create_header()
37
+ master_db[ chapter_id ] = {} unless chapter_exists
38
+ verse_id = master_db[ KEY_PATH ]
39
+
40
+ file_full_path = ::File.absolute_path( @file_url )
41
+ file_base_name = ::File.basename( file_full_path )
42
+ file_content64 = Base64.urlsafe_encode64( ::File.read( file_full_path ) )
43
+
44
+ log.info(x) { "Key name of the file to ingest => #{@file_key}" }
45
+ log.info(x) { "Ingesting file at path => #{file_full_path}" }
46
+ log.info(x) { "The name of the file to ingest is => #{file_base_name}" }
47
+ log.info(x) { "Size of base64 file content => [#{file_content64.length}]" }
48
+
49
+ chapter_data.create_map_entry( verse_id, "#{FILE_KEY_PREFIX}#{@file_key}", FILE_NAME_KEY, file_base_name )
50
+ chapter_data.create_map_entry( verse_id, "#{FILE_KEY_PREFIX}#{@file_key}", FILE_CONTENT_KEY, file_content64 )
51
+
52
+ OpenKey::KeyApi.content_lock( master_db[ chapter_id ], chapter_data.to_json, content_hdr )
53
+ OpenKey::KeyApi.write_master_db( content_hdr, master_db )
54
+
55
+ Show.new.flow_of_events
56
+
57
+ end
58
+
59
+
60
+ private
61
+
62
+
63
+ # Perform pre-conditional validations in preparation to executing the main flow
64
+ # of events for this use case. This method may throw the below exceptions.
65
+ #
66
+ # @raise [SafeDirNotConfigured] if the safe's url has not been configured
67
+ # @raise [EmailAddrNotConfigured] if the email address has not been configured
68
+ # @raise [StoreUrlNotConfigured] if the crypt store url is not configured
69
+ def pre_validation
70
+
71
+
72
+ end
73
+
74
+
75
+ end
76
+
77
+
78
+ end