Skip to content

Commit

Permalink
add with_deep_deundescored_keys
Browse files Browse the repository at this point in the history
  • Loading branch information
svanhesteren committed Jul 10, 2024
1 parent c04cc1d commit 6a8d52a
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
eyaml (0.4.0)
eyaml (0.4.2)
rbnacl (~> 7.1)
thor (~> 1.1)

Expand Down
3 changes: 2 additions & 1 deletion lib/eyaml/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ class ConflictError < StandardError
# for a public/private key in the key directory (either $EJSON_KEYDIR, if set, or /opt/ejson/keys)
cipherdata = YAML.load_file(file)
secrets = EYAML.decrypt(cipherdata, private_key: ENV[PRIVATE_KEY_ENV_VAR])
.except("_public_key")
secrets = EYAML::Util.with_deep_deundescored_keys(secrets)
.deep_symbolize_keys
.except(:_public_key)

break Rails.application.send(secrets_or_credentials).deep_merge!(secrets)
end
Expand Down
29 changes: 29 additions & 0 deletions lib/eyaml/util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,35 @@ class << self
def pretty_yaml(some_hash)
some_hash.to_yaml.delete_prefix("---\n")
end

# This will look for any keys that starts with an underscore and duplicates that key-value pair
# but without the starting underscore.
# So {_a: "abab"} will become {_a: "abab", a: "abab"}
# This so we can easilly access our unencrypted secrets without having to add an underscore
def with_deep_deundescored_keys(hash)
hash.each_with_object({}) do |pair, total|
key, value = pair
case value
when Hash
child_hash = with_deep_deundescored_keys(value)

if key.start_with?("_")
raise KeyError, "De-underscored key '#{key[1..]}' already exists." if total.key?(key[1..])

total[key[1..]] = child_hash
end

total[key] = child_hash
else
if key.start_with?("_")
raise KeyError, "De-underscored key '#{key[1..]}' already exists." if total.key?(key[1..])

total[key[1..]] = value
end
total[key] = value
end
end
end
end
end
end
12 changes: 12 additions & 0 deletions spec/eyaml/railtie_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,21 @@
remove_auth_files_that_dont_end_with(".eyaml")
run_load_hooks
expect(credentials).to(include(_extension: "eyaml"))
expect(credentials).to(include(extension: "eyaml"))
end

it "eyml" do
remove_auth_files_that_dont_end_with(".eyml")
run_load_hooks
expect(credentials).to(include(_extension: "eyml"))
expect(credentials).to(include(extension: "eyml"))
end

it "ejson" do
remove_auth_files_that_dont_end_with(".ejson")
run_load_hooks
expect(credentials).to(include(_extension: "ejson"))
expect(credentials).to(include(extension: "ejson"))
end
end

Expand All @@ -99,19 +102,22 @@
remove_auth_files_that_dont_end_with(".eyaml")
run_load_hooks
expect(credentials).to(include(_extension: "eyaml"))
expect(credentials).to(include(extension: "eyaml"))
end

it "eyml" do
remove_auth_files_that_dont_end_with(".eyml")

run_load_hooks
expect(credentials).to(include(_extension: "eyml"))
expect(credentials).to(include(extension: "eyml"))
end

it "ejson" do
remove_auth_files_that_dont_end_with(".ejson")
run_load_hooks
expect(credentials).to(include(_extension: "ejson"))
expect(credentials).to(include(extension: "ejson"))
end
end

Expand Down Expand Up @@ -185,18 +191,21 @@
remove_auth_files_that_dont_end_with(".eyaml")
run_load_hooks
expect(secrets).to(include(_extension: "eyaml"))
expect(secrets).to(include(extension: "eyaml"))
end

it "eyml" do
remove_auth_files_that_dont_end_with(".eyml")
run_load_hooks
expect(secrets).to(include(_extension: "eyml"))
expect(secrets).to(include(extension: "eyml"))
end

it "ejson" do
remove_auth_files_that_dont_end_with(".ejson")
run_load_hooks
expect(secrets).to(include(_extension: "ejson"))
expect(secrets).to(include(extension: "ejson"))
end
end

Expand All @@ -210,19 +219,22 @@
remove_auth_files_that_dont_end_with(".eyaml")
run_load_hooks
expect(secrets).to(include(_extension: "eyaml"))
expect(secrets).to(include(extension: "eyaml"))
end

it "eyml" do
remove_auth_files_that_dont_end_with(".eyml")

run_load_hooks
expect(secrets).to(include(_extension: "eyml"))
expect(secrets).to(include(extension: "eyml"))
end

it "ejson" do
remove_auth_files_that_dont_end_with(".ejson")
run_load_hooks
expect(secrets).to(include(_extension: "ejson"))
expect(secrets).to(include(extension: "ejson"))
end
end

Expand Down
16 changes: 15 additions & 1 deletion spec/eyaml/util_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,21 @@
describe ".pretty_yaml" do
it "will return a hash as YAML without the three dash prefix" do
yaml_without_prefix = File.read(fixtures_root.join("pretty.yml"))
expect(EYAML::Util.pretty_yaml({"a" => "1", "b" => "2"})).to eq(yaml_without_prefix)
expect(EYAML::Util.pretty_yaml({"a"=>"1", "b"=>"2", "_c"=>{"_d"=>"3"}})).to eq(yaml_without_prefix)
end
end

describe ".with_deep_deundescored_keys" do
it "will return a hash with all undescored entries duplicated" do
yaml_without_prefix = YAML.load_file(fixtures_root.join("pretty.yml"))

expect(EYAML::Util.with_deep_deundescored_keys(yaml_without_prefix)).to eq({"a"=>"1", "b"=>"2", "c"=>{"d"=>"3", "_d"=>"3"}, "_c"=>{"d"=>"3", "_d"=>"3"}})
end

it "will raise when a de-underscored key already exists" do
yaml_without_prefix = YAML.load_file(fixtures_root.join("pretty.yml")).merge!("_b" => "X")

expect { EYAML::Util.with_deep_deundescored_keys(yaml_without_prefix) }.to raise_error(KeyError)
end
end
end
3 changes: 2 additions & 1 deletion spec/fixtures/data.ejson
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"_skip_me": "not_secret",
"_extension": "ejson",
"_dont_skip_me": {
"another_secret": "EJ[1:vr6e0PrO6xzH5N9c6Rs8ERt+DJXZeS0rZPDIZxMJWDg=:B1Iyfp3NBN/Kox9kQXWLV7F8BkNCckTA:MJh0KNGPimGadsUbQUZY21/nZFlFtw==]"
"another_secret": "EJ[1:vr6e0PrO6xzH5N9c6Rs8ERt+DJXZeS0rZPDIZxMJWDg=:B1Iyfp3NBN/Kox9kQXWLV7F8BkNCckTA:MJh0KNGPimGadsUbQUZY21/nZFlFtw==]",
"_underscored_secret": "not encrypted"
}
}
1 change: 1 addition & 0 deletions spec/fixtures/data.eyaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ _skip_me: "not_secret"
_extension: "eyaml"
_dont_skip_me:
another_secret: "ssshhh"
_underscored_secret: "not encrypted"
1 change: 1 addition & 0 deletions spec/fixtures/data.eyml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ _skip_me: "not_secret"
_extension: "eyml"
_dont_skip_me:
another_secret: "ssshhh"
_underscored_secret: "not encrypted"
2 changes: 2 additions & 0 deletions spec/fixtures/pretty.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
a: '1'
b: '2'
_c:
_d: '3'
3 changes: 2 additions & 1 deletion spec/support/encryption_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ module EncryptionHelper
"_skip_me" => "not_secret",
"_extension" => "ejson", # This is only the correct value for data.ejson
"_dont_skip_me" => {
"another_secret" => "ssshhh"
"another_secret" => "ssshhh",
"_underscored_secret" => "not encrypted"
}
}
}
Expand Down

0 comments on commit 6a8d52a

Please sign in to comment.