Source code for schrodinger.application.matsci.enc

"""
Utilities for encryption.

Copyright Schrodinger, LLC. All rights reserved.
"""

import os

from cryptography.fernet import Fernet

from schrodinger.utils import fileutils

ENC_KEYS_PATH = os.path.join(fileutils.get_mmshare_data_dir(), '.enc_keys')
ENC_FILE_EXT = '.enc'

CG_KEY_FILE_NAME = 'cg'


[docs]def get_encryption_key(key_file_name, key_file_path=None): """ Return the encryption key for the given file name. If the file doesn't exist then an encryption key will be created for it. :type key_file_name: str :param key_file_name: the key file name :type key_file_path: str or None :param key_file_path: the key file path, if None then the default Schrodinger path is used :rtype: bytes :return: the encryption key """ if key_file_path is None: key_file_path = ENC_KEYS_PATH key_file_path = os.path.join(key_file_path, key_file_name) if os.path.exists(key_file_path): with open(key_file_path, 'rb') as f_handle: key = f_handle.read() else: key = Fernet.generate_key() with open(key_file_path, 'wb') as f_handle: f_handle.write(key) return key
[docs]def write_encrypted_file(in_file_path, key_file_name, key_file_path=None): """ Write an encrypted version of the given input file path. :type in_file_path: str :param in_file_path: the in file path to encrypt :type key_file_name: str :param key_file_name: the key file name to use in the encryption :type key_file_path: str or None :param key_file_path: the key file path, if None then the default Schrodinger path is used :raise ValueError: if there is a problem :rtype: str :return: the encrypted file path """ if in_file_path.endswith(ENC_FILE_EXT): raise ValueError('encrypting an encrypted file is not supported') with open(in_file_path) as f_handle: text = f_handle.read() return write_encrypted_text(text, in_file_path, key_file_name, key_file_path=key_file_path)
[docs]def write_encrypted_text(text, in_file_path, key_file_name, key_file_path=None): """ Write the unencrypted text to an encrypted file with the given path. :type text: str :param text: the text to encrypt :type in_file_path: str :param in_file_path: the file path to which to write the encrypted text :type key_file_name: str :param key_file_name: the key file name to use in the encryption :type key_file_path: str or None :param key_file_path: the key file path, if None then the default Schrodinger path is used :rtype: str :return: the encrypted file path """ key = get_encryption_key(key_file_name, key_file_path=key_file_path) f_obj = Fernet(key) token = f_obj.encrypt(text.encode()) out_file_path = in_file_path if not out_file_path.endswith(ENC_FILE_EXT): out_file_path += ENC_FILE_EXT with open(out_file_path, 'wb') as f_handle: f_handle.write(token) return out_file_path
[docs]def get_unencrypted_text(in_file_path, key_file_name, key_file_path=None): """ Return the unencrypted text for the given encrypted input file path. :type in_file_path: str :param in_file_path: the encrypted in file path to unencrypt :type key_file_name: str :param key_file_name: the key file name to use in the unencryption :type key_file_path: str or None :param key_file_path: the key file path, if None then the default Schrodinger path is used :raise ValueError: if there is a problem :rtype: str :return: the unencrypted text """ if not in_file_path.endswith(ENC_FILE_EXT): raise ValueError('the input file is not encrypted') with open(in_file_path, 'rb') as f_handle: token = f_handle.read() key = get_encryption_key(key_file_name, key_file_path=key_file_path) f_obj = Fernet(key) text = f_obj.decrypt(token).decode() return text
[docs]def write_unencrypted_file(in_file_path, key_file_name, key_file_path=None): """ Write an unencrypted version for the given encrypted input file path. :type in_file_path: str :param in_file_path: the encrypted in file path to unencrypt :type key_file_name: str :param key_file_name: the key file name to use in the unencryption :type key_file_path: str or None :param key_file_path: the key file path, if None then the default Schrodinger path is used :rtype: str :return: the unencrypted file path """ text = get_unencrypted_text(in_file_path, key_file_name, key_file_path=key_file_path) out_file_path = fileutils.splitext(in_file_path)[0] with open(out_file_path, 'w') as f_handle: f_handle.write(text) return out_file_path