Update file access to be smarter and accept either file like objects of file names, use less code to do so too

This commit is contained in:
Roberto Rosario
2012-01-01 20:12:13 -04:00
parent 6cafb394e9
commit 796475dfd9

View File

@@ -1,5 +1,5 @@
import types import types
from StringIO import StringIO
from pickle import dumps from pickle import dumps
import logging import logging
import tempfile import tempfile
@@ -151,6 +151,17 @@ class Key(object):
class GPG(object): class GPG(object):
@staticmethod
def get_descriptor(file_input):
try:
# Is it a file like object?
file_input.seek(0)
except AttributeError:
# If not, try open it.
return open(file_input, 'rb')
else:
return file_input
def __init__(self, binary_path=None, home=None, keyring=None, keyservers=None): def __init__(self, binary_path=None, home=None, keyring=None, keyservers=None):
kwargs = {} kwargs = {}
if binary_path: if binary_path:
@@ -167,52 +178,46 @@ class GPG(object):
self.gpg = gnupg.GPG(**kwargs) self.gpg = gnupg.GPG(**kwargs)
def verify_w_retry(self, file_input, detached_signature=None): def verify_w_retry(self, file_input, detached_signature=None):
if isinstance(file_input, types.StringTypes): logger.debug('file_input type: %s' % type(file_input))
input_descriptor = open(file_input, 'rb')
elif isinstance(file_input, types.FileType) or isinstance(file_input, File): input_descriptor = GPG.get_descriptor(file_input)
input_descriptor = file_input
elif issubclass(file_input.__class__, StringIO):
input_descriptor = file_input
else:
raise ValueError('Invalid file_input argument type')
try: try:
verify = self.verify_file(input_descriptor, detached_signature) verify = self.verify_file(input_descriptor, detached_signature, close_descriptor=False)
if verify.status == 'no public key': if verify.status == 'no public key':
# Try to fetch the public key from the keyservers # Try to fetch the public key from the keyservers
try: try:
self.receive_key(verify.key_id) self.receive_key(verify.key_id)
return self.verify_w_retry(file_input, detached_signature) return self.verify_w_retry(input_descriptor, detached_signature)
except KeyFetchingError: except KeyFetchingError:
return verify return verify
else: else:
input_descriptor.close()
return verify return verify
except IOError: except IOError:
return False return False
def verify_file(self, file_input, detached_signature=None): def verify_file(self, file_input, detached_signature=None, close_descriptor=True):
""" '''
Verify the signature of a file. Verify the signature of a file.
""" '''
if isinstance(file_input, types.StringTypes):
descriptor = open(file_input, 'rb') input_descriptor = GPG.get_descriptor(file_input)
elif isinstance(file_input, types.FileType) or isinstance(file_input, File) or isinstance(file_input, StringIO):
descriptor = file_input
else:
raise ValueError('Invalid file_input argument type')
if detached_signature: if detached_signature:
# Save the original data and invert the argument order # Save the original data and invert the argument order
# Signature first, file second # Signature first, file second
file_descriptor, filename = tempfile.mkstemp(prefix='django_gpg') file_descriptor, filename = tempfile.mkstemp(prefix='django_gpg')
file_data = file_input.read() file_data = input_descriptor.read()
file_input.close() file_input.close()
os.write(file_descriptor, file_data) os.write(file_descriptor, file_data)
os.close(file_descriptor) os.close(file_descriptor)
verify = self.gpg.verify_file(detached_signature, data_filename=filename) verify = self.gpg.verify_file(detached_signature, data_filename=filename)
else: else:
verify = self.gpg.verify_file(descriptor) verify = self.gpg.verify_file(input_descriptor)
descriptor.close()
if close_descriptor:
input_descriptor.close()
if verify: if verify:
return verify return verify
@@ -232,12 +237,13 @@ class GPG(object):
raise GPGVerificationError(verify.status) raise GPGVerificationError(verify.status)
def sign_file(self, file_input, key=None, destination=None, key_id=None, passphrase=None, clearsign=False): def sign_file(self, file_input, key=None, destination=None, key_id=None, passphrase=None, clearsign=False):
""" '''
Signs a filename, storing the signature and the original file Signs a filename, storing the signature and the original file
in the destination filename provided (the destination file is in the destination filename provided (the destination file is
overrided if it already exists), if no destination file name is overrided if it already exists), if no destination file name is
provided the signature is returned. provided the signature is returned.
""" '''
kwargs = {} kwargs = {}
kwargs['clearsign'] = clearsign kwargs['clearsign'] = clearsign
@@ -250,14 +256,7 @@ class GPG(object):
if passphrase: if passphrase:
kwargs['passphrase'] = passphrase kwargs['passphrase'] = passphrase
if isinstance(file_input, types.StringTypes): input_descriptor = GPG.get_descriptor(file_input)
input_descriptor = open(file_input, 'rb')
elif isinstance(file_input, types.FileType) or isinstance(file_input, File):
input_descriptor = file_input
elif issubclass(file_input.__class__, StringIO):
input_descriptor = file_input
else:
raise ValueError('Invalid file_input argument type')
if destination: if destination:
output_descriptor = open(destination, 'wb') output_descriptor = open(destination, 'wb')
@@ -277,16 +276,13 @@ class GPG(object):
if not destination: if not destination:
return signed_data return signed_data
def decrypt_file(self, file_input): def decrypt_file(self, file_input, close_descriptor=True):
if isinstance(file_input, types.StringTypes): input_descriptor = GPG.get_descriptor(file_input)
input_descriptor = open(file_input, 'rb')
elif isinstance(file_input, types.FileType) or isinstance(file_input, File) or isinstance(file_input, StringIO):
input_descriptor = file_input
else:
raise ValueError('Invalid file_input argument type')
result = self.gpg.decrypt_file(input_descriptor) result = self.gpg.decrypt_file(input_descriptor)
if close_descriptor:
input_descriptor.close() input_descriptor.close()
if not result.status: if not result.status:
raise GPGDecryptionError('Unable to decrypt file') raise GPGDecryptionError('Unable to decrypt file')