commit f321e8c8b647749916e6a6ffa18bfe5f43b95b6f
parent e3d767fde6ca3a00a1280d0f8f0d9d7fd2f05485
Author: Daniel Barlow <dan@telent.net>
Date: Fri, 13 Aug 2021 14:05:49 +0100
don't overwrite secrets unless forced
Diffstat:
4 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
@@ -184,6 +184,5 @@ security requirements, look elsewhere.
* remove secrets
* copy to clipboard
-* check before overwriting secrets that exist already
* support re-encrypting a subtree when recipients change
* warn or fail if iffy store permissions?
diff --git a/features/moss.feature b/features/moss.feature
@@ -17,6 +17,18 @@ Feature: command-line password management
When I generate a secret for "home/fastmail" with length 12
And "home/fastmail.age" plaintext matches ^[a-zA-Z0-9]{12}$
+ Scenario: it doesn't overwrite secrets without asking
+ Given I am using a temporary password store
+ When I store a secret for "home/ebay" with content "first"
+ Then I cannot store a secret for "home/ebay" with content "second"
+ And "home/ebay.age" plaintext is "first"
+
+ Scenario: it overwrites secrets when forced
+ Given I am using a temporary password store
+ When I store a secret for "home/ebay" with content "first"
+ And I force store a secret for "home/ebay" with content "second"
+ Then "home/ebay.age" plaintext is "second"
+
Scenario: I can view a secret
Given I am using the example password store
When I view the secret "home/ebay"
@@ -118,7 +130,7 @@ Feature: command-line password management
When I run "moss kxdcjghlsdkjfhgslkdjg"
Then I see the string "unrecognised command. See \"moss help\""
-
+
Scenario: argument checking
When I run "moss show"
Then it shows a usage message for "show"
diff --git a/features/step_definitions/steps.rb b/features/step_definitions/steps.rb
@@ -3,9 +3,10 @@ MOSS="./moss.rb"
require 'tmpdir'
require 'fileutils'
-def shell(s)
+def shell(s, permit_failure: false)
output = IO.popen(["bash", "-c", s], "r", 2 => 1) do |f| f.read end
- $?.exitstatus.zero? or raise "#{$?} : #{@i_see}"
+ (permit_failure || $?.exitstatus.zero?) or
+ raise "#{$?} : #{@i_see}"
output
end
@@ -53,6 +54,17 @@ When("I store a secret for {string} with content {string}") do |name, content|
shell "echo -n #{content} | #{MOSS} insert #{name.inspect}"
end
+When("I force store a secret for {string} with content {string}") do |name, content|
+ @stored_secret_name = name
+ shell "echo -n #{content} | #{MOSS} insert #{name.inspect} --force"
+end
+
+Then("I cannot store a secret for {string} with content {string}") do |name, content|
+ @stored_secret_name = name
+ shell "echo -n #{content} | #{MOSS} insert #{name.inspect}", permit_failure: true
+ warn $?
+end
+
Then("I see a {int} character string") do |len|
expect(@i_see.length).to eq len
end
diff --git a/moss.rb b/moss.rb
@@ -94,9 +94,9 @@ class Moss
raise MossError, "Can't find .recipients for #{name}"
end
- def write_secret(name, content, force: false)
+ def write_secret(name, content, overwrite: false)
pathname = store.join("#{name}.age")
- if pathname.exist? && !force
+ if pathname.exist? && !overwrite
raise MossError,"#{pathname.to_s} exists, use --force to overwrite"
end
pathname.dirname.mkpath
@@ -266,15 +266,15 @@ def cli
"Store and retrieve encrypted secrets\n\n" +
"Usage: moss [command] [parameters]...\n\n"
end
- command :generate, "generate a random secret" do |filename:, length:|
+ command :generate, "generate a random secret" do |filename:, length:, force: false|
secret = random_alnum(length.to_i)
print secret
- MOSS.write_secret(filename, secret)
+ MOSS.write_secret(filename, secret, overwrite: force)
end
- command :add, "add a secret to the store" do |filename:, force: false|
+ command :add, "add a secret to the store (reads from standard input)" do |filename:, force: false|
secret = $stdin.read
- MOSS.write_secret(filename, secret)
+ MOSS.write_secret(filename, secret, overwrite: force)
end
link :insert => :add
@@ -301,7 +301,7 @@ def cli
if Kernel.system(ENV["EDITOR"], f.path)
f.rewind
secret = f.read
- MOSS.write_secret(file, secret)
+ MOSS.write_secret(file, secret, overwrite: true)
else
raise MossError, $CHILD_STATUS.to_s
end