def from_local_account(host_address, username, password, totp=None): """Creates a :class:`~py42.sdk.SDKClient` object for accessing the Code42 REST APIs using the supplied credentials. This method supports only accounts created within the Code42 console or using the APIs (including py42). Username/passwords that are based on Active Directory, Okta, or other Identity providers cannot be used with this method. Args: host_address (str): The domain name of the Code42 instance being authenticated to, e.g. console.us.code42.com username (str): The username of the authenticating account. password (str): The password of the authenticating account. totp (callable or str, optional): The time-based one-time password of the authenticating account. Include only if the account uses Code42's two-factor authentication. Defaults to None. Returns: :class:`py42.sdk.SDKClient` """ client = SDKClient.from_local_account(host_address, username, password, totp) # test credentials try: client.users.get_current() except Py42UnauthorizedError as err: login_type = client.loginconfig.get_for_user(username)["loginType"] if login_type == "CLOUD_SSO": raise Py42Error( "SSO users are not supported in `from_local_account()`.") msg = f"SDK initialization failed, double-check username/password, and provide two-factor TOTP token if Multi-Factor Auth configured for your user. User LoginConfig: {login_type}" err.args = (msg, ) raise return client
def _stream_file(self, file_generator, checksum): for response in file_generator: if response.status_code == 204: continue try: storage_node_client = self._microservices_client_factory.create_storage_preservation_client( response[u"storageNodeURL"] ) token = storage_node_client.get_download_token( response[u"archiveGuid"], response[u"fileId"], response[u"versionTimestamp"], ) return storage_node_client.get_file(str(token)) except Py42HTTPError: # API searches multiple paths to find the file to be streamed, as returned by # 'get_file_location_detail_by_sha256', hence we keep looking until we find a stream # to return debug.logger.warning( u"Failed to stream file with hash {}, info: {}.".format( checksum, response.text ) ) raise Py42Error( u"No file with hash {} available for download on any storage node.".format( checksum ) )
def _active_state_map(active): _map = {True: u"ACTIVE", False: u"INACTIVE", None: u"ALL"} try: return _map[active] except KeyError: raise Py42Error( "Invalid argument: '{}'. active must be True, False, or None".format(active) )
def __setitem__(self, key, value): try: self._data_root[key] = value except TypeError: data_root_type = type(self._data_root) message = u"The Py42Response root is of type {}, but __setitem__ got a key of {} and value of {}, which is incompatible.".format( data_root_type, key, value) raise Py42Error(message)
def __getitem__(self, key): try: return self._data_root[key] except TypeError: data_root_type = type(self._data_root) message = u"The Py42Response root is of type {}, but __getitem__ got a key of {}, which is incompatible.".format( data_root_type, key) raise Py42Error(message)
def __setitem__(self, key, value): try: self._data_root[key] = value except TypeError: data_root_type = type(self._data_root) message = ( f"The Py42Response root is of type {data_root_type}, but __setitem__ got a key " f"of {key} and value of {value}, which is incompatible.") raise Py42Error(message)
def __getitem__(self, key): try: return self._data_root[key] except TypeError: data_root_type = type(self._data_root) message = ( f"The Py42Response root is of type {data_root_type}, but __getitem__ " f"got a key of {key}, which is incompatible.") raise Py42Error(message)
def _stream_file(self, checksum, version_info): (device_guid, md5_hash, sha256_hash, path) = version_info version = self._get_file_version_for_stream(device_guid, md5_hash, sha256_hash, path) if version: return self._get_file_stream(version) raise Py42Error( f"No file with hash {checksum} available for download.")
def _handle_error(method, url, response): if response is None: msg = f"No response was returned for {method} request to {url}." raise Py42Error(msg) try: response.raise_for_status() except HTTPError as ex: raise_py42_error(ex)
def _extract_backup_sets(self, backup_sets): if isinstance(backup_sets, dict): # number of sets are locked backup_sets = backup_sets["backupSet"] if isinstance(backup_sets, dict): # there's only one set configured return [BackupSet(self, backup_sets)] elif isinstance(backup_sets, list): return [BackupSet(self, bs) for bs in backup_sets] else: raise Py42Error( "Unable to extract backup sets: {}".format(backup_sets)) else: return [BackupSet(self, bs) for bs in backup_sets]
def _stream_file(self, checksum, version_info): (device_guid, md5_hash, sha256_hash, path) = version_info version = self._get_file_version_for_stream(device_guid, md5_hash, sha256_hash, path) if version: pds = self._storage_service_factory.create_preservation_data_service( version[u"storageNodeURL"]) token = pds.get_download_token( version[u"archiveGuid"], version[u"fileId"], version[u"versionTimestamp"], ) return pds.get_file(str(token)) raise Py42Error( u"No file with hash {} available for download on any storage node." .format(checksum))
def _extract_backup_sets(self, backup_sets): if isinstance(backup_sets, dict): # number of sets are locked backup_sets = backup_sets["backupSet"] if isinstance(backup_sets, dict): # there's only one set configured return [BackupSet(self, backup_sets)] elif isinstance(backup_sets, list): return [ BackupSet(self, bs) for bs in backup_sets if not _backup_set_is_legal_hold(bs) ] else: raise Py42Error( f"Unable to extract backup sets: {backup_sets}") else: return [ BackupSet(self, bs) for bs in backup_sets if not _backup_set_is_legal_hold(bs) ]
from py42._compat import str from py42._compat import UserDict from py42._compat import UserList from py42.clients.settings import check_lock from py42.clients.settings import SettingProperty from py42.clients.settings import show_change from py42.clients.settings._converters import bool_to_str from py42.clients.settings._converters import days_to_minutes from py42.clients.settings._converters import minutes_to_days from py42.clients.settings._converters import str_to_bool from py42.exceptions import Py42Error invalid_destination_error = Py42Error( u"Invalid destination guid or destination not offered to device's Org.") destination_not_added_error = Py42Error( u"Destination is not added to device, unable to lock.") class DeviceSettingsDefaults(UserDict, object): """Class used for managing an Organization's Device Default settings. Also acts as a base class for `DeviceSettings` to manage individual device settings.""" def __init__(self, device_dict, org_settings): self.data = device_dict self._org_settings = org_settings self.changes = org_settings.changes self._destinations = org_settings.data[u"settings"][u"destinations"] self.data[u"settings"] = { u"serviceBackupConfig": self.data[u"serviceBackupConfig"] } bs = self.data[u"serviceBackupConfig"][u"backupConfig"][u"backupSets"] self.backup_sets = self._extract_backup_sets(bs)