secrit 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/secrit.rb +74 -10
  3. data/test/secrit_test.rb +45 -1
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70cd3930aa08c99cedd7b991a68e67e9136e9eecea9e37936d780ca5ea9ffb5a
4
- data.tar.gz: 40f8176c0130166a9297d30192defb9ef6d7127e226de16832b664a20e1eb915
3
+ metadata.gz: d6faa44d62bd340907b101bf6ba6e56837587d51638f8741452fcc27b5c12095
4
+ data.tar.gz: ce5893a67b02b928ac95a214151cf1bd3bd2daf7332ed2813f4d89798e4d6124
5
5
  SHA512:
6
- metadata.gz: da7895eab947c91fd9d3b5f9e25209b58861b077ea68332292142f79b31e34d43028316e8a6d3c0120246e07251b9d259c957c316d27d4ad69911086cfacb97f
7
- data.tar.gz: a21ae1183cc336b570831eb0dba023672c4bef71266714579c01acb6d8027dff6fd5b622620746eab4c935ad6696b9cef896162ca62b75db5f52e168996b27c9
6
+ metadata.gz: 3f34ba5b85f46dd496c32a388aea79e29737748cead405b268f64c4923ebe91cb51ca58a48b476f8befdd012d2a7a2694be94d193412c502728d457e24f82d30
7
+ data.tar.gz: 2d476217fc7b85149af601e19d6af6471ff7155c8788ffa413e2b2196310d3f795eed4d68623d24f3b6515062c34e8ec6afd861e57538fcc9ecf6c483cbb5024
data/lib/secrit.rb CHANGED
@@ -1,20 +1,84 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'gpgme'
3
3
 
4
- PASSWORD_STORE_PATH = File.expand_path("~/.password-store/")
4
+ # Decryptor provides an interface for decryption. Classes that extend Decryptor
5
+ # must implement the decrypt method.
6
+ class Decryptor
7
+ # Decrypts a file at the given path.
8
+ #
9
+ # @param file_path [String] the path to the file to be decrypted.
10
+ # @raise [NotImplementedError] if the method is called on the Decryptor class
11
+ # itself, rather than a subclass.
12
+ def decrypt(file_path)
13
+ raise NotImplementedError
14
+ end
15
+ end
16
+
17
+ # GPGDecryptor is a default implementation of the Decryptor interface using GPG.
18
+ class GPGDecryptor < Decryptor
19
+ # Decrypts a file at the given path using GPG.
20
+ #
21
+ # @param file_path [String] the path to the file to be decrypted.
22
+ # @return [GPGME::Data] the decrypted data.
23
+ def decrypt(file_path)
24
+ crypto = GPGME::Crypto.new
25
+ decrypted_data = crypto.decrypt(File.open(file_path))
26
+ decrypted_data
27
+ end
28
+ end
5
29
 
30
+ # Secrit provides methods to get encrypted data, allowing optional customization
31
+ # of the decryption process.
6
32
  class Secrit
7
- def self.get(entry_path)
8
- full_path = File.join(PASSWORD_STORE_PATH, "#{entry_path}.gpg")
33
+ attr_accessor :storage
9
34
 
10
- # Ensure the file exists
11
- raise "File not found: #{full_path}" unless File.exist?(full_path)
35
+ # Retrieves decrypted data for a given entry path.
36
+ #
37
+ # @param entry_path [String] the entry path to the encrypted data.
38
+ # @param storage [String] the storage path for the encrypted files (optional).
39
+ # @return [String] the decrypted content as a string.
40
+ def self.get(entry_path, storage: nil)
41
+ new(
42
+ storage: storage
43
+ ).get(entry_path).to_s.strip
44
+ end
12
45
 
13
- # Decrypt the file
14
- crypto = GPGME::Crypto.new
15
- decrypted_data = crypto.decrypt(File.open(full_path))
46
+ # Initializes a new Secrit object with optional customization.
47
+ #
48
+ # @param decryptor [Decryptor] an object that responds to the decrypt method
49
+ # (optional, defaults to GPGDecryptor.new).
50
+ # @param storage [String] the storage path for the encrypted files (optional).
51
+ def initialize(decryptor: GPGDecryptor.new, storage: nil)
52
+ @decryptor = decryptor
53
+ @storage = storage || File.expand_path("~/.password-store/")
54
+ end
55
+
56
+ # Retrieves decrypted data for a given entry path.
57
+ #
58
+ # @param entry_path [String] the entry path to the encrypted data.
59
+ # @return [GPGME::Data] the decrypted data.
60
+ # @raise [RuntimeError] if the file does not exist at the constructed path.
61
+ def get(entry_path)
62
+ full_path = construct_path(entry_path)
63
+ validate_file_existence(full_path)
64
+ @decryptor.decrypt(full_path)
65
+ end
16
66
 
17
- # Return the decrypted content
18
- decrypted_data.to_s.strip
67
+ private
68
+
69
+ # Constructs the full path to an encrypted file based on the entry path.
70
+ #
71
+ # @param entry_path [String] the entry path.
72
+ # @return [String] the full path to the encrypted file.
73
+ def construct_path(entry_path)
74
+ File.join(storage, "#{entry_path}.gpg")
75
+ end
76
+
77
+ # Validates that a file exists at the given path.
78
+ #
79
+ # @param full_path [String] the full path to the file.
80
+ # @raise [RuntimeError] if the file does not exist at the given path.
81
+ def validate_file_existence(full_path)
82
+ raise "File not found: #{full_path}" unless File.exist?(full_path)
19
83
  end
20
84
  end
data/test/secrit_test.rb CHANGED
@@ -4,6 +4,30 @@ require 'mocha/minitest'
4
4
  require_relative '../lib/secrit'
5
5
 
6
6
  class SecritTest < Minitest::Test
7
+ def with_encrypted_file(contents, key_path = 'test_entry')
8
+ Dir.mktmpdir do |temp_dir|
9
+ # Create a temporary GPG file with known content
10
+ test_file_path = File.join(temp_dir, "#{key_path}.gpg")
11
+ file = File.open(test_file_path, 'w+')
12
+
13
+ crypto = GPGME::Crypto.new
14
+ crypto.encrypt(contents, output: file)
15
+
16
+ yield(temp_dir)
17
+ end
18
+ end
19
+
20
+ def test_real_decryption
21
+ # Create a temporary GPG file with known content
22
+ key_path = 'foo_bar'
23
+
24
+ with_encrypted_file('test content', key_path) do |storage|
25
+ # Run the get method and check the result
26
+ result = Secrit.get(key_path, storage: storage)
27
+ assert_equal "test content", result
28
+ end
29
+ end
30
+
7
31
  def test_successful_decryption
8
32
  # Mocking the file existence check
9
33
  File.stubs(:exist?).returns(true)
@@ -21,12 +45,32 @@ class SecritTest < Minitest::Test
21
45
  assert_equal 'decrypted content', result
22
46
  end
23
47
 
48
+ def test_successful_decryption_object
49
+ entry_path = "valid_entry_path"
50
+ expected_decrypted_content = "secret content"
51
+
52
+ # Create a mock decryptor
53
+ mock_decryptor = Minitest::Mock.new
54
+ mock_decryptor.expect(:decrypt, expected_decrypted_content, [String])
55
+ File.stubs(:exist?).returns(true)
56
+
57
+ # Create an instance of Secrit with the mock decryptor
58
+ secrit = Secrit.new(decryptor: mock_decryptor)
59
+
60
+ # Test the get method
61
+ decrypted_content = secrit.get(entry_path)
62
+ assert_equal expected_decrypted_content, decrypted_content
63
+
64
+ # Verify that the mock expectations were met
65
+ mock_decryptor.verify
66
+ end
67
+
24
68
  def test_file_not_found
25
69
  # Mocking the file existence check to return false
26
70
  File.stubs(:exist?).returns(false)
27
71
 
28
72
  # Testing the get method to ensure it raises the correct error
29
- assert_raises(RuntimeError, "File not found: #{File.join(PASSWORD_STORE_PATH, 'non_existent_file.gpg')}") do
73
+ assert_raises(RuntimeError, "File not found: #{File.join(Secrit.new.storage, 'non_existent_file.gpg')}") do
30
74
  Secrit.get('non_existent_file')
31
75
  end
32
76
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secrit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simpthy