@@ -16,7 +16,7 @@ class TranscryptAPI:
1616 'digest' : 'md5' ,
1717 'use_pbkdf2' : '0' ,
1818 'salt_method' : 'password' ,
19- 'custom_salt ' : '' ,
19+ 'config_salt ' : '' ,
2020 }
2121
2222 def __init__ (self , dpath , config = None , verbose = 2 , transcript_exe = None ):
@@ -37,7 +37,7 @@ def login(self):
3737 "{transcript_exe} -c '{cipher}' -p '{password}' "
3838 "-md '{digest}' --use-pbkdf2 '{use_pbkdf2}' "
3939 "-sm '{salt_method}' "
40- "-cs '{custom_salt }' "
40+ "-cs '{config_salt }' "
4141 "-y"
4242 ).format (transcript_exe = self .transcript_exe , ** self .config )
4343 self .cmd (command )
@@ -51,11 +51,11 @@ def display(self):
5151 def export_gpg (self , recipient ):
5252 self .cmd (f'{ self .transcript_exe } --export-gpg "{ recipient } "' )
5353 self .crypt_dpath = self .cmd ('git config --local transcrypt.crypt-dir' )['out' ] or self .dpath / '.git/crypt'
54- asc_fpath = (self .crypt_dpath / (recipient + '.asc' )). exists ()
54+ asc_fpath = (self .crypt_dpath / (recipient + '.asc' ))
5555 return asc_fpath
5656
5757 def import_gpg (self , asc_fpath ):
58- command = f"{ self .transcript_exe } --import-gpg '{ asc_fpath } '"
58+ command = f"{ self .transcript_exe } --import-gpg '{ asc_fpath } ' -y "
5959 self .cmd (command )
6060
6161 def show_raw (self , fpath ):
@@ -106,13 +106,11 @@ def _setup_gpg(self):
106106 key_curve = 'Ed25519' ,
107107 subkey_curve = 'Curve25519'
108108 )
109-
110109 # Fix GNUPG permissions
111- dpath = os .environ .get ('GNUPGHOME' , ub .expandpath ('$HOME/.gnupg' ))
112110 (self .gpg_home / 'private-keys-v1.d' ).ensuredir ()
113111 # 600 for files and 700 for directories
114- ub .cmd ('find ' + dpath + r' -type f -exec chmod 600 {} \;' , shell = True , verbose = self .verbose )
115- ub .cmd ('find ' + dpath + r' -type d -exec chmod 700 {} \;' , shell = True , verbose = self .verbose )
112+ ub .cmd ('find ' + str ( self . gpg_home ) + r' -type f -exec chmod 600 {} \;' , shell = True , verbose = self .verbose , cwd = self . gpg_home )
113+ ub .cmd ('find ' + str ( self . gpg_home ) + r' -type d -exec chmod 700 {} \;' , shell = True , verbose = self .verbose , cwd = self . gpg_home )
116114
117115 def _setup_git (self ):
118116 import git
@@ -157,20 +155,60 @@ def _setup_transcrypt(self):
157155 self .tc .env ['GNUPGHOME' ] = str (self .gpg_home )
158156
159157 def test_round_trip (self ):
160- content = self .tc .show_raw (self .secret_fpath )
161- assert content .startswith (SALTED )
162- assert self .secret_fpath .read_text ().startswith ('secret content' )
158+ ciphertext = self .tc .show_raw (self .secret_fpath )
159+ plaintext = self .secret_fpath .read_text ()
160+ assert ciphertext .startswith (SALTED )
161+ assert plaintext .startswith ('secret content' )
162+ assert not plaintext .startswith (SALTED )
163+
163164 self .tc .logout ()
164- assert self .secret_fpath .read_text ().startswith (SALTED )
165+ logged_out_text = self .secret_fpath .read_text ()
166+ assert logged_out_text == ciphertext
167+
165168 self .tc .login ()
166- assert self .secret_fpath .read_text ().startswith ('secret content' )
169+ logged_in_text = self .secret_fpath .read_text ()
170+
171+ assert logged_out_text == ciphertext
172+ assert logged_in_text == plaintext
167173
168174 def test_export_gpg (self ):
169175 self .tc .display ()
170176 asc_fpath = self .tc .export_gpg (self .gpg_fpr )
177+
178+ info = self .tc .cmd (f'gpg --batch --quiet --decrypt "{ asc_fpath } "' )
179+ content = info ['out' ]
180+
181+ got_config = dict ([p .split ('=' , 1 ) for p in content .split ('\n ' ) if p ])
182+ config = self .tc .config .copy ()
183+ is_ok = got_config == config
184+ if not is_ok :
185+ if config ['salt_method' ] == 'configured' :
186+ if config ['config_salt' ] == '' :
187+ config .pop ('config_salt' )
188+ got_config .pop ('config_salt' )
189+ is_ok = got_config == config
190+ else :
191+ config .pop ('config_salt' )
192+ got_config .pop ('config_salt' )
193+ is_ok = got_config == config
194+
195+ if not is_ok :
196+ print (f'got_config={ got_config } ' )
197+ print (f'config={ config } ' )
198+ raise AssertionError
199+
200+ # content = io.StringIO()
201+ # with open(asc_fpath, 'r') as file:
202+ # ciphertext = file.read()
203+ # self.gpg_store.decrypt(ciphertext, content)
204+
205+ assert asc_fpath .exists ()
171206 self .tc .logout ()
172207 self .tc .import_gpg (asc_fpath )
173208
209+ plaintext = self .secret_fpath .read_text ()
210+ assert plaintext .startswith ('secret content' )
211+
174212
175213def run_tests ():
176214 """
@@ -184,12 +222,38 @@ def run_tests():
184222 >>> self = TestEnvironment()
185223 >>> self.setup()
186224 >>> self.tc._manual_hack_info()
187-
188225 >>> self.test_round_trip()
189226 >>> self.test_export_gpg()
190227
191228 self = TestEnvironment(config={'use_pbkdf2': 1})
192229 self.setup()
193230 self.test_round_trip()
194231 self.test_export_gpg()
232+
233+ self = TestEnvironment(config={'use_pbkdf2': 1})
234+ """
235+
236+ # Test that transcrypt works under a variety of config conditions
237+ basis = {
238+ 'cipher' : ['aes-256-cbc' ],
239+ 'password' : ['correct horse battery staple' ],
240+ 'digest' : ['md5' , 'sha256' ],
241+ 'use_pbkdf2' : ['0' , '1' ],
242+ 'salt_method' : ['password' , 'configured' ],
243+ 'config_salt' : ['' , 'mylittlecustomsalt' ],
244+ }
245+
246+ for params in ub .named_product (basis ):
247+ config = params .copy ()
248+ self = TestEnvironment (config = config )
249+ self .setup ()
250+ self .test_round_trip ()
251+ self .test_export_gpg ()
252+
253+
254+ if __name__ == '__main__' :
255+ """
256+ CommandLine:
257+ python ~/code/transcrypt/tests/test_transcrypt.py
195258 """
259+ run_tests ()
0 commit comments