safedb 0.7.1001 → 0.10.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +50 -3
- data/Dockerfile +46 -0
- data/Jenkinsfile +45 -0
- data/README.md +16 -0
- data/Rakefile +2 -2
- data/cucumber-test.sh +55 -0
- data/lib/cli.rb +20 -7
- data/lib/controller/abstract/controller.rb +2 -3
- data/lib/controller/access/init.rb +11 -7
- data/lib/controller/access/login.rb +0 -2
- data/lib/controller/book/commit.rb +1 -0
- data/lib/controller/db/obliterate.feature +45 -0
- data/lib/controller/db/obliterate.rb +58 -0
- data/lib/controller/db/pull.rb +10 -26
- data/lib/controller/db/push.rb +29 -321
- data/lib/controller/db/{remote.rb → remote-github-keypair.rb} +11 -6
- data/lib/controller/db/remote-github-token.rb +69 -0
- data/lib/controller/db/state.rb +63 -0
- data/lib/controller/query/publish.rb +27 -0
- data/lib/controller/requirer.rb +0 -1
- data/lib/manual/git-interaction.md +176 -0
- data/lib/manual/remote.md +0 -1
- data/lib/model/book.rb +13 -1
- data/lib/model/checkin.feature +15 -27
- data/lib/model/content.rb +25 -27
- data/lib/model/indices.rb +35 -8
- data/lib/model/state_evolve.rb +21 -0
- data/lib/model/text_chunk.rb +1 -1
- data/lib/utils/extend/string.rb +28 -0
- data/lib/utils/git/gitflow.rb +565 -0
- data/lib/utils/git/github.rb +69 -0
- data/lib/utils/identity/machine.id.rb +2 -2
- data/lib/utils/keys/keypair.rb +93 -0
- data/lib/utils/logs/logger.rb +3 -4
- data/lib/utils/time/timestamp.rb +2 -0
- data/lib/version.rb +1 -1
- data/pod-image-builder.yaml +27 -0
- data/pod-image-safetty.yaml +18 -0
- data/safedb.gemspec +1 -6
- metadata +17 -64
- data/genius-decision.txt +0 -25
- data/lib/controller/db/model_git_service.rb +0 -399
- data/lib/plugin/github.rb +0 -53
- data/lib/utils/store/github.rb +0 -27
@@ -0,0 +1,176 @@
|
|
1
|
+
|
2
|
+
# safe | git interaction
|
3
|
+
|
4
|
+
safe uses git for local synchronization and also as one of the many remote backend storage engines together with S3, SSH and Google Drive. As such, the git client is a prerequisite on systems running the safe command line interface (CLI).
|
5
|
+
|
6
|
+
With Git comes the ability to revert state to any point in time after state-changing command transactions.
|
7
|
+
|
8
|
+
Now we document the safe use cases that employ the git version control system and we discuss the circumstances surrounding its use.
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
## **`safe init`**
|
13
|
+
|
14
|
+
The safe init use case creates a book and creates the **`safedb-master-keys.ini`** file and a chapter crypt file under a new book directory.
|
15
|
+
|
16
|
+
| **git action** | **when is it done?** | **what is done and/or the circumstances in which git is used** |
|
17
|
+
|:-------------- |:-------------------- |:------------------------------------------------------------------- |
|
18
|
+
| _git init_ | at the beginning | done only once if the master crypts folder is not under git control |
|
19
|
+
| _git add_ | just before the end | every init adds master keys and the just created book folder to git |
|
20
|
+
| _git commit_ | at the end | the git commit is issued if and only if the git add was invoked |
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
## **`safe login`**
|
25
|
+
|
26
|
+
The safe init use case creates a book and creates the **`safedb-master-keys.ini`** file and a chapter crypt file under a new book directory.
|
27
|
+
|
28
|
+
| **git action** | **what is done andr the circumstances under which git is used** |
|
29
|
+
|:------------------ |:------------------------------------------------------------------- |
|
30
|
+
| _git rm FILENAME_ | remove the outgoing master crypt content file from the repository and working copy |
|
31
|
+
| _git add FILENAME_ | add the incoming master crypt content file into git version management |
|
32
|
+
| _git add FILENAME_ | add the master indices INI which may have new keys, a new content ID and maybe bootup ID |
|
33
|
+
| _git commit_ | commit the hot-swapped crypt files and the master indices file as an atomic (ACID) transaction |
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
## **`safe commit`**
|
38
|
+
|
39
|
+
The **`safe commit`** use case uses git to **protect the master database from the ills of concurrent access**. The git interactions are not **_spray and pray_**. They are specific to each given file that is added, removed and/or updated.
|
40
|
+
|
41
|
+
| **git action** | **when is it done?** | **what is done and/or the circumstances in which git is used** |
|
42
|
+
|:---------------- |:-------------------- |:------------------------------------------------------------------- |
|
43
|
+
| **_git add_** | just before the end | new files incoming to the master crypts are brought under vc |
|
44
|
+
| **_git rm_** | just before the end | removed files are expunged from the git repository |
|
45
|
+
| **_git commit_** | at the end | the git commit is issued if either git add or git rm was invoked |
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
## **`safe pull`**
|
50
|
+
|
51
|
+
If the local safe is already under version control the **`safe pull`** command will check for equivalence between the git repository url and the upstream url registered by **`git remote`**. If it isn't - a **`git clone`** will suffice to pull down the safe repository assets.
|
52
|
+
|
53
|
+
### safe pull invalidates every branch
|
54
|
+
|
55
|
+
**Important** - **`safe pull`** invalidates both the master branch and all active branches. Before you issue a safe pull you must **`safe commit`** on every shell branch that contains changes.
|
56
|
+
|
57
|
+
The commit provides a route back to a previous revision if the pull goes belly up and turns out to be something other than what you expected. Use **`safe compare`** to detail all the active branches that will be invalidated including the their login time and most recent access and change times.
|
58
|
+
|
59
|
+
| **git action** | **when is it done?** | **what is done and/or the circumstances in which git is used** |
|
60
|
+
|:---------------- |:-------------------- |:------------------------------------------------------------------- |
|
61
|
+
| **_git remote_** | at the beginning | the upstream url is compared to the url safe pull has a handle to |
|
62
|
+
| **_git clone_** | towards the end | if there are no crypts to speak of the git clone pulls them in |
|
63
|
+
| **_git pull_** | towards the end | this is a git fetch and git merge to integrate remote repo changes |
|
64
|
+
|
65
|
+
After a **`safe pull`** you must issue a **`safe login`** to continue working.
|
66
|
+
|
67
|
+
### pull first | ask questions later
|
68
|
+
|
69
|
+
A **`safe pull`** is recommended at the start of your session. Do a **`safe diff`** which does not require you to login in order to assess the differences between the local and remote master crypts.
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
## **`safe push`**
|
74
|
+
|
75
|
+
After one or more commits a **`safe push`** is called upon to sync the local crypt state with the registered remote repository.
|
76
|
+
|
77
|
+
However a git push may not be possible if the remote has moved further ahead than the local. This matter would be reported and the user encouraged to perform a **`safe pull`** first followed by a **`safe refresh`**, changes, **`safe commit`** and finally another **`safe push`**.
|
78
|
+
|
79
|
+
| **git action** | **when is it done?** | **what is done and/or the circumstances in which git is used** |
|
80
|
+
|:---------------- |:-------------------- |:------------------------------------------------------------------- |
|
81
|
+
| **_git push_** | towards the end | if this is a git fetch and git merge to integrate remote repo changes |
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
## **`safe remote`** or **`safe stage`**
|
86
|
+
|
87
|
+
**`safe remote`** prints a report on the difference between the local and remote databi.
|
88
|
+
|
89
|
+
git ls-files --stage --abbrev=8
|
90
|
+
|
91
|
+
The `ls-files` command is used to list the files that are staged and ready to be pushed up to the remote repository.
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
## **`safe remote --provision`**
|
96
|
+
|
97
|
+
The **`safe remote`** command is primed to do four key tasks. It
|
98
|
+
|
99
|
+
- _automagically_ creates a remote repository (using for example **Github's API** integration)
|
100
|
+
- it provisions and installs **SSH keypairs** for **`safe push`** to write to the remote backend
|
101
|
+
- it uses **`set-upstream-url`** to tell the local repository where to **pull from** and **push to**
|
102
|
+
- urges the user commit branch changes **`safe commit`** and mirror them remotely **`safe push`**
|
103
|
+
|
104
|
+
A safe remote only acts to provision a remote mirror for your crypts when the **local git reposiotory is virginal** in that it has never been paired with a remote repository. In other words the local crypts have been created using **`safe init <<book-name>>`** as opposed to **`safe pull`**.
|
105
|
+
|
106
|
+
| **git action** | **when is it done?** | **what is done and/or the circumstances in which git is used** |
|
107
|
+
|:---------------------------- |:-------------------- |:----------------------------------------------------------------- |
|
108
|
+
| **_git set-upstream-url_** | at the beginning | if remote creates the 2nd remote repo the upstream url is changed |
|
109
|
+
|
110
|
+
|
111
|
+
The remote's last responsibility is to urge the user to issue a **`safe commit`** followed by a **`safe push`** so as to make the remote repository mirrors the state of the local safe.
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
## **`safe compare`**
|
116
|
+
|
117
|
+
The **`safe diff`** command reports on the difference between the local master book and the present local branch book.
|
118
|
+
|
119
|
+
**`safe compare`** on the other hand tells you that
|
120
|
+
|
121
|
+
- the remote branch has changed (leaving you behind needing to **`safe pull`**)
|
122
|
+
- the local branch has changed (putting you ahead needing to **`safe push`**)
|
123
|
+
- you cannot access the remote repository and cannot ascertain the above info
|
124
|
+
|
125
|
+
| **git action** | **what is done and/or the circumstances in which git is used** |
|
126
|
+
|:------------------ |:-------------------------------------------------------------- |
|
127
|
+
| **_git compare_** | this command is used to ascertain local vs remote differences |
|
128
|
+
| **_git rev-diff_** | another command to ascertain local vs remote differences |
|
129
|
+
|
130
|
+
So safe compare reports on the local commits informing you which branch made them, when and a rough change count. On the other hand it tells you about the remote commits, who made them and when.
|
131
|
+
|
132
|
+
### the worst of both worlds
|
133
|
+
|
134
|
+
When commits have moved on both the local and remote master branches you are in the worst ofboth worlds. Thankfully this scenario is extremely rare. The rough steps to resolve this are to
|
135
|
+
|
136
|
+
- export the local books as json
|
137
|
+
- pull the remote books down then export them as json
|
138
|
+
- externally compare the json and merge them into one
|
139
|
+
- import the merged json to create new books
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
## safe remote architecture
|
144
|
+
|
145
|
+
Due to its meticulous planning the safe adheres to a number of high level design rules. Let's cover these in the context of operating alongside a remote _git_ backend repository.
|
146
|
+
|
147
|
+
|
148
|
+
### 1. stand alone
|
149
|
+
|
150
|
+
The term **_stand alone_** refers to a non-networked computer that has no access neither to the internet nor to other computers in its vicinity.
|
151
|
+
|
152
|
+
The **safe cli** must be able to operate on a stand alone machine. Features like the remote backend mirror must provide succinct legible error messages when remote access is unavailable.
|
153
|
+
|
154
|
+
Furthermore, the following commands must not be impaired when the machine is in standalone mode.
|
155
|
+
|
156
|
+
- **`safe diff`** (does not report on remote differences)
|
157
|
+
- **`safe commit`** (only changes the master branch)
|
158
|
+
- **`safe init`** (only creates a local git repository
|
159
|
+
|
160
|
+
And these commands must degrade gracefully in standalone mode
|
161
|
+
|
162
|
+
- **`safe remote`**
|
163
|
+
- **`safe push`**
|
164
|
+
- **`safe pull`**
|
165
|
+
- **`safe compare`**
|
166
|
+
|
167
|
+
|
168
|
+
### 2. cap theorem
|
169
|
+
|
170
|
+
#### consistency trumps availability
|
171
|
+
|
172
|
+
In reference to the CAP theorem, the safe is designed such that **consistency trumps availability**.
|
173
|
+
|
174
|
+
Failed commits in a manner of speaking are preferable to corrupted files and race conditions. Without git, these corruptions would arise through the use of basic file operations.
|
175
|
+
|
176
|
+
Automatons like scripts will typically branch and read the database. It is envisaged that humans will perform the vast majority of commits, pushes and pulls thus reducing the frequency of commit failures.
|
data/lib/manual/remote.md
CHANGED
@@ -12,7 +12,6 @@ Before you use safe remote to provision a github git repository backend for your
|
|
12
12
|
- you have a github account (with username)
|
13
13
|
- you have created a (40 character hexadecimal) github access token
|
14
14
|
- you have inserted this data at a suitable chapter and verse
|
15
|
-
- you run **`safe remote --provision`** from this opened book/chapter/verse
|
16
15
|
|
17
16
|
Below is the sequence of commands leading up to **`safe remote --provision`**
|
18
17
|
|
data/lib/model/book.rb
CHANGED
@@ -384,13 +384,25 @@ module SafeDb
|
|
384
384
|
end
|
385
385
|
|
386
386
|
|
387
|
+
|
388
|
+
# Print a notie stating the book followed by and open chapter and
|
389
|
+
# verse names only if the book is currently opened at a specific
|
390
|
+
# chapter and verse. Right after book creation for example there
|
391
|
+
# is no open chapter or verse and this method simply prints out
|
392
|
+
# a carriage return.
|
387
393
|
def print_book_mark()
|
388
|
-
|
394
|
+
|
389
395
|
puts ""
|
396
|
+
return unless is_opened?()
|
397
|
+
|
398
|
+
bcv_name = "#{book_name()}:#{get_open_chapter_name()}/#{get_open_verse_name()}"
|
390
399
|
puts "#{bcv_name} (#{get_open_verse_data().length()})\n"
|
391
400
|
puts ""
|
401
|
+
|
392
402
|
end
|
393
403
|
|
404
|
+
|
405
|
+
|
394
406
|
# Is the verse name in the parameter the book's open verse? An exception
|
395
407
|
# is thrown if the parameter verse name is nil.
|
396
408
|
# @param this_verse_name [String] the name of the verse to test
|
data/lib/model/checkin.feature
CHANGED
@@ -1,33 +1,21 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
Feature: test safedb's version command
|
3
3
|
|
4
|
-
|
4
|
+
This test will run both `safe version` and `safe --version`
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
% USECASE [dir] 1080 Dired by name /home/apollo/projects/safedb.net/lib/usecase/
|
10
|
-
% safedb.net 924 Dired by name /home/apollo/projects/safedb.net/
|
11
|
-
* SAFE 2 [shell] 16 Shell:run /home/apollo/
|
12
|
-
* SAFE 1 [shell] 16 Shell:run /home/apollo/
|
6
|
+
# --> Scenario: hip hop hoooray is the value I GET
|
7
|
+
# --> When I run `safe version`
|
8
|
+
# --> Then the output should contain "v0.8"
|
13
9
|
|
14
|
-
#
|
10
|
+
# --> Scenario: right overy here is the blood and the sweat
|
11
|
+
# --> When I run `safe --version`
|
12
|
+
# --> Then the output should contain "v0.8"
|
15
13
|
|
16
|
-
## In one shell
|
17
14
|
|
18
|
-
safe init boys
|
19
|
-
safe login boys
|
20
|
-
safe import ~/safedb.test.data.json
|
21
|
-
safe view
|
22
|
-
safe show (failure because no open chapter has been set)
|
23
|
-
safe goto 3
|
24
|
-
safe checkin
|
25
|
-
|
26
|
-
|
27
|
-
## In Another shell
|
28
|
-
|
29
|
-
safe login boys
|
30
|
-
|
31
|
-
Failure occurs
|
32
|
-
|
33
|
-
R{\370\204m\265^v}\276\223^RZ(\320^N\333e.time":"Wed Apr 10 09:06:37 2019","book.name":"boys","book.init.version":"safedb-v0.3.1012","book.chapter.keys":{"dbms.accounts":{"content.id":"00cxarwaia0s4g","content.iv":"VzbG5IBQEuFdpRFerzGqHPejVKdKekcl","chapter.key.crypt":"Rx5BWXXM9uK5cbiH006WupaHVciXL8q%XooFdogSazMdHnqlJHuulMoeBtZxxJse"},"aws.console.accounts":{"content.id":"r6sc5ope3n3sfi","content.iv":"Jgh4c2aeh2Qjwt@ZaTEJxfK@6A%dzUoz","chapter.key.crypt":"9t5xxjDgyN4jQGQyw%9CHvTzGqJU@MiOWFGFKpGAuz@@fT8FJVO2fjoQIHEjTDfa"},"ops":{"content.id":"uk2u9bnzpynizc","content.iv":"AnvTgyJPbZpBju8kSsT8es0NmHlv2j9d","chapter.key.crypt":"TYyASQ71sgMbzNOxGVgojdb28M1%4iPDDsSDQz8TevjABYY887hqoPTRpvx18xUT"},"git":{"content.id":"r3dso6qr88l5lm","content.iv":"I9hykwLIGrvgp0j2jMQyMJC3QhWg0xSD","chapter.key.crypt":"0QLO7FawspMzEpRnB%6Wb3dVyjiJ36IX5SRp7QNOkU5ut@sMy9%KNYQ42XKA8yTj"}},"book.open.chapter":"aws.console.accounts","book.open.verse":"aimbrain.prod"}
|
15
|
+
# --> safe init boys
|
16
|
+
# --> safe login boys
|
17
|
+
# --> safe import ~/safedb.test.data.json
|
18
|
+
# --> safe view
|
19
|
+
# --> safe show (failure because no open chapter has been set)
|
20
|
+
# --> safe goto 3
|
21
|
+
# --> safe checkin
|
data/lib/model/content.rb
CHANGED
@@ -11,6 +11,24 @@ module SafeDb
|
|
11
11
|
class Content
|
12
12
|
|
13
13
|
|
14
|
+
# Use the content's external id to find the ciphertext file that is to be unlocked.
|
15
|
+
# Then use the unlock key from the parameter along with the random IV that is inside
|
16
|
+
# the {DataMap} or {DataStore} to decrypt and return the ciphertext.
|
17
|
+
#
|
18
|
+
# @param unlock_key [Key] symmetric key that was used to encrypt the ciphertext
|
19
|
+
# @param data_store [DataMap] either {DataMap} or {DataStore} containing content id and random iv
|
20
|
+
# @return [String] the resulting decrypted text that was encrypted with the parameter key
|
21
|
+
def self.unlock_master( unlock_key, data_store )
|
22
|
+
|
23
|
+
book_id = data_store.section()
|
24
|
+
crypt_path = FileTree.master_crypts_filepath( book_id, data_store.get( Indices::CONTENT_IDENTIFIER ) )
|
25
|
+
random_iv = KeyIV.in_binary( data_store.get( Indices::CONTENT_RANDOM_IV ) )
|
26
|
+
return unlock_it( crypt_path, unlock_key, random_iv )
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
14
32
|
# Lock the content body provided - place the resulting ciphertext
|
15
33
|
# inside a file named by a random identifier, then write this identifier
|
16
34
|
# along wih the initialization and encryption key into the provided
|
@@ -19,6 +37,8 @@ module SafeDb
|
|
19
37
|
# The content ciphertext derived from encrypting the body is stored
|
20
38
|
# in a file underneath the provided content header.
|
21
39
|
#
|
40
|
+
# Finally
|
41
|
+
#
|
22
42
|
# @param book_id [String] used to determine the book's master crypt folder
|
23
43
|
# @param crypt_key [Key] the key used to (symmetrically) encrypt the content provided
|
24
44
|
# @param data_store [DataMap] either DataMap or DataStore containing the content id and random iv
|
@@ -79,16 +99,12 @@ module SafeDb
|
|
79
99
|
|
80
100
|
|
81
101
|
|
82
|
-
#
|
83
|
-
#
|
84
|
-
# along wih the initialization and encryption key into the provided
|
85
|
-
# key-value map (hash).
|
86
|
-
#
|
87
|
-
# The content ciphertext derived from encrypting the body is stored
|
88
|
-
# in a file underneath the provided content header.
|
102
|
+
# Use the crypt key and random init vector to transform the plain text
|
103
|
+
# message into an encrypted ciphertext message.
|
89
104
|
#
|
90
|
-
#
|
91
|
-
#
|
105
|
+
# Use the chunk of plain text (header) information along with the ciphertext
|
106
|
+
# and the expected file location at the crypt path to write out the crypt
|
107
|
+
# and header content into a file.
|
92
108
|
#
|
93
109
|
# @param crypt_path [File] path to the crypt file holding the encrypted ciphertext
|
94
110
|
# @param crypt_key [Key] the key used to (symmetrically) encrypt the content provided
|
@@ -104,24 +120,6 @@ module SafeDb
|
|
104
120
|
|
105
121
|
|
106
122
|
|
107
|
-
# Use the content's external id to find the ciphertext file that is to be unlocked.
|
108
|
-
# Then use the unlock key from the parameter along with the random IV that is inside
|
109
|
-
# the {DataMap} or {DataStore} to decrypt and return the ciphertext.
|
110
|
-
#
|
111
|
-
# @param unlock_key [Key] symmetric key that was used to encrypt the ciphertext
|
112
|
-
# @param data_store [DataMap] either {DataMap} or {DataStore} containing content id and random iv
|
113
|
-
# @return [String] the resulting decrypted text that was encrypted with the parameter key
|
114
|
-
def self.unlock_master( unlock_key, data_store )
|
115
|
-
|
116
|
-
book_id = data_store.section()
|
117
|
-
crypt_path = FileTree.master_crypts_filepath( book_id, data_store.get( Indices::CONTENT_IDENTIFIER ) )
|
118
|
-
random_iv = KeyIV.in_binary( data_store.get( Indices::CONTENT_RANDOM_IV ) )
|
119
|
-
return unlock_it( crypt_path, unlock_key, random_iv )
|
120
|
-
|
121
|
-
end
|
122
|
-
|
123
|
-
|
124
|
-
|
125
123
|
# Use the content's external id to find the ciphertext file that is to be unlocked.
|
126
124
|
# Then use the unlock key from the parameter along with the random IV that is inside
|
127
125
|
# the {DataMap} or {DataStore} to decrypt and return the ciphertext.
|
data/lib/model/indices.rb
CHANGED
@@ -13,11 +13,14 @@ module SafeDb
|
|
13
13
|
# The short url name of the safe personal database.
|
14
14
|
SAFE_URL_NAME = "safedb.net"
|
15
15
|
|
16
|
+
# The name of the safe application and the safe gem as known by the operating system.
|
17
|
+
SAFE_APP_NAME = "safedb"
|
18
|
+
|
16
19
|
# The desired length of a safe book ergonomic identifier.
|
17
20
|
SAFE_BOOK_ID_LENGTH = 12
|
18
21
|
|
19
22
|
# The file-system location of the safe database tree
|
20
|
-
SAFE_DATABASE_FOLDER = File.join( Dir.home, "
|
23
|
+
SAFE_DATABASE_FOLDER = File.join( File.join( Dir.home, ".config" ), SAFE_APP_NAME )
|
21
24
|
|
22
25
|
# The fully qualified domain name of the safedb home website
|
23
26
|
SAFE_GEM_WEBSITE = "https://www.#{SAFE_URL_NAME}"
|
@@ -25,6 +28,11 @@ module SafeDb
|
|
25
28
|
# The safe database github clonable url for the ruby software
|
26
29
|
SAFE_GITHUB_URL = "https://github.com/devops4me/#{SAFE_URL_NAME}"
|
27
30
|
|
31
|
+
|
32
|
+
### #################################### ###
|
33
|
+
### paths to the master crypts resources ###
|
34
|
+
### #################################### ###
|
35
|
+
|
28
36
|
# The name of the master crypts folder.
|
29
37
|
MASTER_CRYPTS_FOLDER_NAME = "safedb-master-crypts"
|
30
38
|
|
@@ -34,6 +42,23 @@ module SafeDb
|
|
34
42
|
# The path to the master crypts .git directory.
|
35
43
|
MASTER_CRYPTS_GIT_PATH = File.join( MASTER_CRYPTS_FOLDER_PATH, ".git" )
|
36
44
|
|
45
|
+
# The master indices file name
|
46
|
+
MASTER_INDICES_FILE_NAME = "safedb-master-keys.ini"
|
47
|
+
|
48
|
+
# The path to the master indices file
|
49
|
+
MASTER_INDICES_FILEPATH = File.join( MASTER_CRYPTS_FOLDER_PATH, MASTER_INDICES_FILE_NAME )
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
# The name of the backup master crypts folder.
|
54
|
+
BACKUP_CRYPTS_FOLDER_NAME = "safedb-backup-crypts"
|
55
|
+
|
56
|
+
# The path of the backup master crypts folder.
|
57
|
+
BACKUP_CRYPTS_FOLDER_PATH = File.join( SAFE_DATABASE_FOLDER, BACKUP_CRYPTS_FOLDER_NAME )
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
|
37
62
|
# The name of the branch indices folder.
|
38
63
|
BRANCH_INDICES_FOLDER_NAME = "safedb-branch-keys"
|
39
64
|
|
@@ -46,12 +71,6 @@ module SafeDb
|
|
46
71
|
# The path to the branch crypts folder.
|
47
72
|
BRANCH_CRYPTS_FOLDER_PATH = File.join( SAFE_DATABASE_FOLDER, BRANCH_CRYPTS_FOLDER_NAME )
|
48
73
|
|
49
|
-
# The master indices file name
|
50
|
-
MASTER_INDICES_FILE_NAME = "safedb-master-keys.ini"
|
51
|
-
|
52
|
-
# The path to the master indices file
|
53
|
-
MASTER_INDICES_FILEPATH = File.join( SAFE_DATABASE_FOLDER, MASTER_INDICES_FILE_NAME )
|
54
|
-
|
55
74
|
# The path to the remote storage configuration INI file
|
56
75
|
MACHINE_CONFIG_FILEPATH = File.join( SAFE_DATABASE_FOLDER, "safedb-remote-storage.ini" )
|
57
76
|
|
@@ -60,6 +79,7 @@ module SafeDb
|
|
60
79
|
|
61
80
|
|
62
81
|
|
82
|
+
|
63
83
|
# The keyname whose value denotes a local folder path to clone to
|
64
84
|
GIT_CLONE_BASE_PATH = "git.clone.base.path"
|
65
85
|
|
@@ -207,7 +227,7 @@ module SafeDb
|
|
207
227
|
OPENED_VERSE_NAME = "book.open.verse"
|
208
228
|
|
209
229
|
# The application version that oversaw this book's initialization.
|
210
|
-
|
230
|
+
SAFE_PRE_VERSION_STRING = "safedb-v"
|
211
231
|
|
212
232
|
# Handle to the key name of the ingested file in the submap verse
|
213
233
|
INGESTED_FILE_LINE_NAME_KEY = "safedb.file::"
|
@@ -231,6 +251,13 @@ module SafeDb
|
|
231
251
|
ELLIPTIC_CURVE_KEY_TYPE = "secp384r1"
|
232
252
|
|
233
253
|
|
254
|
+
### ##################################### ###
|
255
|
+
### Strings printed to the user interface ###
|
256
|
+
### ##################################### ###
|
257
|
+
|
258
|
+
NOTHING_TO_OBLITERATE = "There is nothing to obliterate."
|
259
|
+
|
260
|
+
|
234
261
|
end
|
235
262
|
|
236
263
|
|
data/lib/model/state_evolve.rb
CHANGED
@@ -68,12 +68,26 @@ module SafeDb
|
|
68
68
|
the_crypt_key = old_human_key.do_decrypt_key( book_keys.get( Indices::CRYPT_CIPHER_TEXT ) )
|
69
69
|
plain_content = Content.unlock_master( the_crypt_key, book_keys )
|
70
70
|
|
71
|
+
remove_crypt_path = FileTree.master_crypts_filepath( the_book_id, book_keys.get( Indices::CONTENT_IDENTIFIER ) )
|
72
|
+
|
71
73
|
first_login_since_boot = StateInspect.is_first_login?( book_keys )
|
72
74
|
the_crypt_key = Key.from_random if first_login_since_boot
|
73
75
|
recycle_keys( the_crypt_key, the_book_id, human_secret, book_keys, plain_content )
|
74
76
|
set_bootup_id( book_keys ) if first_login_since_boot
|
75
77
|
|
78
|
+
create_crypt_path = FileTree.master_crypts_filepath( the_book_id, book_keys.get( Indices::CONTENT_IDENTIFIER ) )
|
76
79
|
branch_id = Identifier.derive_branch_id( Branch.to_token() )
|
80
|
+
commit_msg = "safe login to #{the_book_id} at branch #{branch_id} on #{TimeStamp.readable()}."
|
81
|
+
|
82
|
+
# Remove the master chapter crypt file from the local git repository and add
|
83
|
+
# the new master chapter crypt to the local git repository.
|
84
|
+
GitFlow.del_file( Indices::MASTER_CRYPTS_FOLDER_PATH, remove_crypt_path )
|
85
|
+
GitFlow.add_file( Indices::MASTER_CRYPTS_FOLDER_PATH, create_crypt_path )
|
86
|
+
GitFlow.add_file( Indices::MASTER_CRYPTS_FOLDER_PATH, Indices::MASTER_INDICES_FILEPATH )
|
87
|
+
GitFlow.list( Indices::MASTER_CRYPTS_FOLDER_PATH )
|
88
|
+
GitFlow.list( Indices::MASTER_CRYPTS_FOLDER_PATH, true )
|
89
|
+
GitFlow.commit( Indices::MASTER_CRYPTS_FOLDER_PATH, commit_msg )
|
90
|
+
|
77
91
|
clone_book_into_branch( the_book_id, branch_id, book_keys, the_crypt_key )
|
78
92
|
|
79
93
|
return true
|
@@ -177,6 +191,13 @@ module SafeDb
|
|
177
191
|
master_keys.set( Indices::CONTENT_IDENTIFIER, branch_keys.get( Indices::CONTENT_IDENTIFIER ) )
|
178
192
|
master_keys.set( Indices::CONTENT_RANDOM_IV, branch_keys.get( Indices::CONTENT_RANDOM_IV ) )
|
179
193
|
|
194
|
+
commit_msg = "safe commit for #{book.book_name()} in branch #{book.branch_id()} on #{TimeStamp.readable()}."
|
195
|
+
|
196
|
+
GitFlow.stage( Indices::MASTER_CRYPTS_FOLDER_PATH )
|
197
|
+
GitFlow.list( Indices::MASTER_CRYPTS_FOLDER_PATH )
|
198
|
+
GitFlow.list( Indices::MASTER_CRYPTS_FOLDER_PATH, true )
|
199
|
+
GitFlow.commit( Indices::MASTER_CRYPTS_FOLDER_PATH, commit_msg )
|
200
|
+
|
180
201
|
end
|
181
202
|
|
182
203
|
|
data/lib/model/text_chunk.rb
CHANGED
@@ -21,7 +21,7 @@ module SafeDb
|
|
21
21
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
22
22
|
Safe Book Id := #{book_id}
|
23
23
|
Time Created := #{TimeStamp.readable()}
|
24
|
-
Safe Version := #{Indices::
|
24
|
+
Safe Version := #{Indices::SAFE_PRE_VERSION_STRING}#{SafeDb::VERSION}
|
25
25
|
Safe Website := #{Indices::SAFE_GEM_WEBSITE}
|
26
26
|
RubyGems.org := https://rubygems.org/gems/safedb
|
27
27
|
CRYPT_HEADER
|
data/lib/utils/extend/string.rb
CHANGED
@@ -561,6 +561,17 @@ class String
|
|
561
561
|
# The INFO log level is used to log the lines - if this is not
|
562
562
|
# appropriate create a (level) parameterized log lines method.
|
563
563
|
def log_lines
|
564
|
+
log_info()
|
565
|
+
end
|
566
|
+
|
567
|
+
|
568
|
+
# Log at the INFO level the string which is expected to be
|
569
|
+
# delineated. If the string originated from a file it will
|
570
|
+
# be logged line by line.
|
571
|
+
#
|
572
|
+
# If no line delineation the string will be dumped just as
|
573
|
+
# a blob.
|
574
|
+
def log_info
|
564
575
|
|
565
576
|
self.each_line do |line|
|
566
577
|
clean_line = line.chomp.gsub("\\n","")
|
@@ -569,4 +580,21 @@ class String
|
|
569
580
|
|
570
581
|
end
|
571
582
|
|
583
|
+
|
584
|
+
# Log at the INFO level the string which is expected to be
|
585
|
+
# delineated. If the string originated from a file it will
|
586
|
+
# be logged line by line.
|
587
|
+
#
|
588
|
+
# If no line delineation the string will be dumped just as
|
589
|
+
# a blob.
|
590
|
+
def log_debug
|
591
|
+
|
592
|
+
self.each_line do |line|
|
593
|
+
clean_line = line.chomp.gsub("\\n","")
|
594
|
+
log.debug(x) { line } if clean_line.length > 0
|
595
|
+
end
|
596
|
+
|
597
|
+
end
|
598
|
+
|
599
|
+
|
572
600
|
end
|