Skip to content

Commit

Permalink
test cli from installed gem (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
jshawl authored Feb 13, 2024
1 parent a2de705 commit f31a834
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Lint code
run: bundle exec rubocop
- name: Install jedisct1/minisign
- name: Install minisign
run: ./spec/install-minisign.sh
- name: Run tests
run: bundle exec rspec
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ doc
test/generated/*
!test/generated/.keep
!test/generated/cli/.keep
*.gem
2 changes: 0 additions & 2 deletions bin/minisign
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ begin
raise OptionParser::InvalidOption if options.keys.empty?
rescue OptionParser::InvalidOption
Minisign::CLI.usage
puts ''
Minisign::CLI.help
exit 1
end

Expand Down
55 changes: 35 additions & 20 deletions lib/minisign/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,47 @@

require 'io/console'

# rubocop:disable Metrics/ModuleLength
module Minisign
# The command line interface
module CLI
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def self.help
puts '-G generate a new key pair'
puts '-R recreate a public key file from a secret key file'
puts '-C change/remove the password of the secret key'
puts '-S sign files'
puts '-f force. Combined with -G, overwrite a previous key pair'
puts '-p <pubkey_file> public key file (default: ./minisign.pub)'
puts '-s <seckey_file> secret key file (default: ~/.minisign/minisign.key)'
puts '-W do not encrypt/decrypt the secret key with a password'
puts '-p <pubkey_file> public key file (default: ./minisign.pub)'
puts '-P <pubkey> public key, as a base64 string'
puts '-x <sigfile> signature file (default: <file>.minisig)'
end
# rubocop:enable Metrics/MethodLength

def self.usage
puts 'Usage:'
puts 'minisign -G [-f] [-p pubkey_file] [-s seckey_file] [-W]'
puts 'minisign -R [-s seckey_file] [-p pubkey_file]'
puts 'minisign -C [-s seckey_file] [-W]'
# rubocop:disable Layout/LineLength
puts 'minisign -S [-l] [-x sig_file] [-s seckey_file] [-c untrusted_comment] [-t trusted_comment] -m file [file ...]'
# rubocop:enable Layout/LineLength
puts 'minisign -S [-l] [-x sig_file] [-s seckey_file] [-c untrusted_comment]'
puts ' [-t trusted_comment] -m file [file ...]'
puts 'minisign -V [-H] [-x sig_file] [-p pubkey_file | -P pubkey] [-o] [-q] -m file'
puts ''
puts '-G generate a new key pair'
puts '-R recreate a public key file from a secret key file'
puts '-C change/remove the password of the secret key'
puts '-S sign files'
puts '-V verify that a signature is valid for a given file'
puts '-m <file> file to sign/verify'
# TODO: implement
puts '-o combined with -V, output the file content after verification'
puts '-p <pubkey_file> public key file (default: ./minisign.pub)'
puts '-P <pubkey> public key, as a base64 string'
puts '-s <seckey_file> secret key file (default: ~/.minisign/minisign.key)'
puts '-W do not encrypt/decrypt the secret key with a password'
puts '-x <sigfile> signature file (default: <file>.minisig)'
puts '-c <comment> add a one-line untrusted comment'
puts '-t <comment> add a one-line trusted comment'
puts '-q quiet mode, suppress output'
puts '-Q pretty quiet mode, only print the trusted comment'
puts '-f force. Combined with -G, overwrite a previous key pair'
puts '-v display version number'
puts ''
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize

def self.prompt
$stdin.noecho(&:gets).chomp
$stdin.tty? ? $stdin.noecho(&:gets).chomp : $stdin.gets.chomp
end

def self.prevent_overwrite!(file)
Expand Down Expand Up @@ -65,8 +74,12 @@ def self.generate(options)
print "\nDeriving a key from the password in order to encrypt the secret key..."
keypair = Minisign::KeyPair.new(password)
File.write(secret_key, keypair.private_key)
File.write(public_key, keypair.public_key)
print " done\n"
puts "The secret key was saved as #{options[:s]} - Keep it secret!"
File.write(public_key, keypair.public_key)
puts "The public key was saved as #{options[:p]} - That one can be public."
pubkey = keypair.public_key.to_s.split("\n").pop
puts "minisign -Vm <file> -P #{pubkey}"
end
end
# rubocop:enable Metrics/MethodLength
Expand Down Expand Up @@ -118,3 +131,5 @@ def self.verify(options)
end
end
end

# rubocop:enable Metrics/ModuleLength
3 changes: 3 additions & 0 deletions spec/install-minisign.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/bash

gem build minisign.gemspec
gem install *.gem

if [[ "$OSTYPE" == "darwin"* ]]; then
url="https://github.com/jedisct1/minisign/releases/download/0.11/minisign-0.11-macos.zip"
curl -sL $url -o test/generated/minisign.zip
Expand Down
26 changes: 26 additions & 0 deletions spec/minisign/e2e_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

describe 'e2e' do
it 'shows help/usage' do
# not implementing legacy formats, for now
jedisct1 = `test/generated/minisign`.gsub(/^-H.*\n/, '').gsub(/^-l.*\n/, '')
expect(`minisign`).to eq(jedisct1)
end
it 'generates a key pair' do
path = 'test/generated/cli'
keyname = 'ruby-encrypted'
exe = 'minisign'
password = SecureRandom.uuid
# TODO: prompt a second time for password confirmation
command = "echo '#{password}' | #{exe} -G -p #{path}/#{keyname}.pub -s #{path}/#{keyname}.key"
`#{command}`
# prompt -f
expect(`#{command} 2>&1`).to match('Key generation aborted:')
output = `#{command} -f`
expect(output).not_to match('Key generation aborted:')
expect(output).to match("The secret key was saved as #{path}/#{keyname}.key - Keep it secret!")
expect(output).to match("The public key was saved as #{path}/#{keyname}.pub - That one can be public.")
public_key = File.read("#{path}/#{keyname}.pub").split("\n").pop
expect(output.gsub('+', '')).to match("minisign -Vm <file> -P #{public_key}".gsub('+', ''))
end
end

0 comments on commit f31a834

Please sign in to comment.