Skip to content

Commit

Permalink
Add ability to hide unwanted fields.
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotwutingfeng committed Feb 28, 2024
1 parent 7991d05 commit 373e822
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 8 deletions.
6 changes: 3 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ AllCops:
NewCops: enable
TargetRubyVersion: 2.0
Metrics/AbcSize:
Max: 26
Max: 35
Metrics/BlockLength:
Max: 45
Max: 53
Metrics/CyclomaticComplexity:
Max: 12
Metrics/MethodLength:
Max: 28
Max: 35
Naming/MethodParameterName:
Enabled: false
Metrics/PerceivedComplexity:
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,26 @@ b25f8815-007f-40f7-a700-ce058ac05435 hotp Mason WWE 5VAML3X35THCE
5b11ae3b-6fc3-4d46-8ca7-cf0aea7de920 steam Sophia Boeing JRZCL47CMXVOQMNPZR2F7J4RGI 30 5 SHA1
```

### Hiding unwanted fields

When the `-f / --format` option is set to `csv` or `pretty`, you can use the `-e / --except` option to hide unwanted fields.

```bash
# Enter the above password when prompted
ruby lib/decrypt.rb test/encrypted_test.json -f pretty -e icon,info.counter,uuid
```

```csv
type name issuer info.secret info.period info.digits info.algo
totp Mason Deno 4SJHB4GSD43FZBAI7C2HLRJGPQ 30 6 SHA1
totp James SPDX 5OM4WOOGPLQEF6UGN3CPEOOLWU 20 7 SHA256
totp Elijah Airbnb 7ELGJSGXNCCTV3O6LKJWYFV2RA 50 8 SHA512
hotp James Issuu YOOMIXWS5GN6RTBPUFFWKTW5M4 6 SHA1
hotp Benjamin Air Canada KUVJJOM753IHTNDSZVCNKL7GII 7 SHA256
hotp Mason WWE 5VAML3X35THCEBVRLV24CGBKOY 8 SHA512
steam Sophia Boeing JRZCL47CMXVOQMNPZR2F7J4RGI 30 5 SHA1
```

## Testing

```bash
Expand Down
18 changes: 13 additions & 5 deletions lib/decrypt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,33 +226,41 @@ def decrypt_vault(filename)
#
def main
formats = %i[json csv pretty]
options = { :format => :json }
options = { :format => :json, :except => [] }

parser = OptionParser.new do |opts|
opts.banner = "Usage: #{$PROGRAM_NAME} <filename> [options]"
opts.on('-f FORMAT', '--format FORMAT', formats,
"Plaintext vault output format; pick one from #{formats.map(&:to_s)}") do |f|
options[:format] = f
end
opts.on('-h', '--help', 'Show this message') do
opts.on('-e', '--except x,y,z', Array, 'Specify fields to hide; for example, `-e icon,info.counter,uuid`') do |e|
options[:except] = e
end
opts.on_tail('-h', '--help', 'Show this message') do
puts opts
exit 0
end
end

begin
parser.parse! ARGV
raise StandardError, "invalid number of arguments: expected 1, got #{ARGV.length}" if ARGV.length != 1
raise StandardError, "invalid number of arguments: expected 1, got #{ARGV.length}" if ARGV.length != 1

if options[:format] == :json && !options[:except].empty?
raise StandardError,
'hiding fields is only supported for `csv` and `pretty` formats'
end
rescue StandardError => e
terminate "#{e}\n#{parser}"
end

plain_text = decrypt_vault(ARGV[0])
$stdout.write case options[:format]
when :pretty
beautify entries_to_csv plain_text
beautify remove_fields(entries_to_csv(plain_text), options[:except])
when :csv
entries_to_csv plain_text
remove_fields(entries_to_csv(plain_text), options[:except])
else
plain_text
end
Expand Down
16 changes: 16 additions & 0 deletions lib/pretty.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,22 @@ def entries_to_csv(plain_text)
end
end

#
# Remove specified fields from a CSV string. Non-existent fields are silently ignored.
#
# @param [String] raw_csv CSV String
# @param [Array<String>] fields_to_remove Field names to be removed from the CSV String
#
# @return [String] CSV String with specified fields removed
#
def remove_fields(raw_csv, fields_to_remove)
csv_data = CSV.parse(raw_csv, :headers => true)
fields_to_remove.each do |field_name|
csv_data.delete field_name
end
csv_data.to_s
end

#
# Make a beautiful CSV-like String padded with spaces.
#
Expand Down
8 changes: 8 additions & 0 deletions spec/decrypt_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ def decryption_test(args, expected_plaintext_filename)
end
end
end
it 'Terminates if format is `json` and `--except` fields are included' do
silence do
ARGV.replace [ENCRYPTED_TEST_VAULT, '-f', 'json', '-e', 'field']
expect { main }.to raise_error(SystemExit) do |error|
expect(error.status).to eq(1)
end
end
end
it 'Shows help' do
ARGV.replace ['--help']
output = nil
Expand Down
6 changes: 6 additions & 0 deletions spec/pretty_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
end
end

describe 'remove_fields' do
it 'Removes fields from CSV String correctly' do
expect(CSV.parse(remove_fields("a,b,c\n1,2,3", %w[a c]), :headers => true).headers).to eq ['b']
end
end

describe 'beautify' do
it 'Pretty prints plain text vault as a CSV-like String padded with spaces' do
expect(beautify(entries_to_csv(File.read('test/plaintext_test.json',
Expand Down

0 comments on commit 373e822

Please sign in to comment.