def create_credential_store(cls) -> CredentialsProviderInterface: """ Factory method for determining which store to use """ keyring_name = KeystoreWrapper.get_keyring_name() if keyring_name in SUPPORTED_BACKENDS: # If the keyring is unlocked then we will use it if KeystoreWrapper.is_keyring_accessible(): return KeystoreCredentialsProvider() return FileCredentialsProvider()
def cleanup_if_exists(self, conjur_url: str): """ For each credential attribute, check if exists for the conjur_url identifier and delete if exists """ for attr in KEYSTORE_ATTRIBUTES: try: if KeystoreWrapper.get_password(conjur_url, attr) is not None: KeystoreWrapper.delete_password(conjur_url, attr) # Catches when credentials do not exist in the keyring. If the key does not exist, # the user has already logged out. we still try to remove other leftovers except Exception: # pylint: disable=broad-except logging.debug(f"Cleanup failed for key '{attr}' from the " f"'{self.keyring_name} credential store.' " f"\n{traceback.format_exc()}")
def remove_credentials(self, conjur_url: str): """ Method for removing user credentials in the system's keyring """ logging.debug("Attempting to remove credentials from " f"the '{self.keyring_name}' credential store...") for attr in KEYSTORE_ATTRIBUTES: try: KeystoreWrapper.delete_password(conjur_url, attr) # Catches when credentials do not exist in the keyring. If the key does not exist, # the user has already logged out. we still try to remove other leftovers except KeyringWrapperDeletionError: logging.debug( f"Unable to delete key '{attr}' from the " f"'{self.keyring_name}' credential store. Key may not exist." f"\n{traceback.format_exc()}") logging.debug("Successfully removed credentials from the " f"'{self.keyring_name}' credential store")
def load(self, conjur_url: str) -> CredentialsData: """ Method for fetching user credentials from the system's keyring """ loaded_credentials = {} if not self.is_exists(conjur_url): raise CredentialRetrievalException for attr in KEYSTORE_ATTRIBUTES: loaded_credentials[attr] = KeystoreWrapper.get_password( conjur_url, attr) return CredentialsData.convert_dict_to_obj(loaded_credentials)
def update_api_key_entry(self, user_to_update: str, credential_data: CredentialsData, new_api_key: str): """ Method for updating user credentials in the system's keyring """ try: KeystoreWrapper.set_password(credential_data.machine, MACHINE, credential_data.machine) KeystoreWrapper.set_password(credential_data.machine, USERNAME, user_to_update) KeystoreWrapper.set_password(credential_data.machine, PASSWORD, new_api_key) except Exception as incomplete_operation: raise OperationNotCompletedException( incomplete_operation) from incomplete_operation
def save(self, credential_data: CredentialsData): """ Method for saving user credentials in the system's keyring """ logging.debug( "Attempting to save credentials to the system's credential store " f"'{self.keyring_name}'...") credential_id = credential_data.machine try: KeystoreWrapper.set_password(credential_id, MACHINE, credential_data.machine) KeystoreWrapper.set_password(credential_id, USERNAME, credential_data.username) KeystoreWrapper.set_password(credential_id, PASSWORD, credential_data.password) logging.debug(f"Credentials saved to the '{self.keyring_name}'" f" credential store") except Exception as incomplete_operation: raise OperationNotCompletedException( incomplete_operation) from incomplete_operation
def is_exists(self, conjur_url) -> bool: for attr in KEYSTORE_ATTRIBUTES: if KeystoreWrapper.get_password(conjur_url, attr) is None: return False return True
def __init__(self): # pragma: no cover self.keyring_name = KeystoreWrapper.get_keyring_name()
def test_get_keyring_name_use_proper_log_level(self): logging.getLogger('keyring').setLevel(logging.DEBUG) KeystoreWrapper.get_keyring_name() self.assertEquals(logging.getLogger('keyring').level, logging.INFO)
def test_get_set_password_use_proper_log_level(self, mock): logging.getLogger('keyring').setLevel(logging.DEBUG) KeystoreWrapper.set_password("", "", "") self.assertEquals(logging.getLogger('keyring').level, logging.INFO)
def test_is_keyring_accessible_returns_false_on_keyring_error(self, mock_keyring): self.assertEquals(False, KeystoreWrapper.is_keyring_accessible())
def test_is_keyring_accessible_return_true_when_get_password(self, mock_keyring): keyring_accessible = KeystoreWrapper.is_keyring_accessible() mock_keyring.assert_called_once_with('test-system', 'test-accessibility') self.assertEquals(True, keyring_accessible)
def test_delete_password_raises_expected_exceptions(self, mock_delete_password): with self.assertRaises(KeyringWrapperDeletionError): KeystoreWrapper.delete_password(TEST_HOSTNAME, "some_key")
def test_delete_password_raises_keyring_error(self, mock_delete_password): with self.assertRaises(KeyringWrapperGeneralError): KeystoreWrapper.delete_password(TEST_HOSTNAME, "some_key")
def test_delete_password_calls_keyring_delete_password(self, mock_keyring): KeystoreWrapper.delete_password(TEST_HOSTNAME, "key") mock_keyring.assert_called_once_with(TEST_HOSTNAME, "key")