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:
@@ -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)
|
||||||
input_descriptor.close()
|
if close_descriptor:
|
||||||
|
input_descriptor.close()
|
||||||
|
|
||||||
if not result.status:
|
if not result.status:
|
||||||
raise GPGDecryptionError('Unable to decrypt file')
|
raise GPGDecryptionError('Unable to decrypt file')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user