def update_session_info(self, infos): """Send session meta-data to all registered UIs. @param infos: Dictionary with the following keys: last_commit_client_id, last_commit_client_hostname, last_commit_client_platform', last_commit_timestamp, used_space, user_quota, basis, plan, status, expires_on. """ self._logger.debug( 'Info received from server %s', format_to_log(infos)) keys = [ 'last_commit_client_id', 'last_commit_client_hostname', 'last_commit_client_platform', 'last_commit_timestamp', 'used_space', 'user_quota', 'plan', 'status', 'expires_on' ] for key in keys: if not key in infos: infos[key] = None for key in ['last_commit_timestamp', 'used_space', 'user_quota']: if infos[key] is not None: self._metadata_db.set(key, infos[key]) for ui in self._user_interfaces: ui.updateSessionInformation(infos)
def update_session_info(self, infos): """Send session meta-data to all registered UIs. @param infos: Dictionary with the following keys: last_commit_client_id, last_commit_client_hostname, last_commit_client_platform', last_commit_timestamp, used_space, user_quota, basis, plan, status, expires_on. """ self._logger.debug('Info received from server %s', format_to_log(infos)) keys = [ 'last_commit_client_id', 'last_commit_client_hostname', 'last_commit_client_platform', 'last_commit_timestamp', 'used_space', 'user_quota', 'plan', 'status', 'expires_on' ] for key in keys: if not key in infos: infos[key] = None for key in ['last_commit_timestamp', 'used_space', 'user_quota']: if infos[key] is not None: self._metadata_db.set(key, infos[key]) for ui in self._user_interfaces: ui.updateSessionInformation(infos)
def _fetch_client_update_info(self): """ Fetch client update info from update server """ connection = None try: # Create HTTPSConnection object connection = https_downloader.HTTPSValidatedConnection( CLIENT_UPDATE_INFO_HOST, self.update_server_cachain, timeout=UPDATE_SERVER_TIMEOUT) # Sets POST params (current_version, platform, arch) request_parameters = { 'current_version': CURRENT_CLIENT_VERSION, 'platform': self.get_platform(), 'arch': platform.architecture()[0], 'platform_version': self.get_os_version() } params = urllib.urlencode(request_parameters) headers = { "Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain" } connection.request('POST', CLIENT_UPDATE_INFO_URI, params, headers) response = connection.getresponse() # HTTP response must be 200 OK assert int(response.status) == 200, ( u"Server response was not 200 OK (got %s %s, content: %s)" % (response.status, response.reason, response.read())) # Unpack json & check the presence of all required parameters client_update_info = json.loads(response.read()) for param in [ 'latest_version', 'download_url', 'expected_checksum', 'upgrade_type', 'transition' ]: assert param in client_update_info, "Missing response parameter '%s'" % param # Put response parameters into Updater instance attributes self.latest_version = client_update_info['latest_version'] self.download_url = urllib.unquote( client_update_info['download_url']) self.update_checksum = client_update_info['expected_checksum'] self.upgrade_type = client_update_info['upgrade_type'] self.transition = client_update_info['transition'] self.logger.debug("Latest client info: %s" % format_to_log(client_update_info)) except Exception as e: raise ClientUpdateInfoRetrievingException("%s" % e) finally: if connection is not None: connection.close()
def _fetch_client_update_info(self): """ Fetch client update info from update server """ connection = None try: # Create HTTPSConnection object connection = https_downloader.HTTPSValidatedConnection(CLIENT_UPDATE_INFO_HOST, self.update_server_cachain, timeout=UPDATE_SERVER_TIMEOUT ) # Sets POST params (current_version, platform, arch) request_parameters = { 'current_version' : CURRENT_CLIENT_VERSION, 'platform' : self.get_platform(), 'arch' : platform.architecture()[0], 'platform_version' : self.get_os_version() } params = urllib.urlencode(request_parameters) headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} connection.request('POST', CLIENT_UPDATE_INFO_URI, params, headers) response = connection.getresponse() # HTTP response must be 200 OK assert int(response.status) == 200, (u"Server response was not 200 OK (got %s %s, content: %s)" % (response.status, response.reason, response.read())) # Unpack json & check the presence of all required parameters client_update_info = json.loads(response.read()) for param in ['latest_version', 'download_url', 'expected_checksum', 'upgrade_type', 'transition']: assert param in client_update_info, "Missing response parameter '%s'" % param # Put response parameters into Updater instance attributes self.latest_version = client_update_info['latest_version'] self.download_url = urllib.unquote(client_update_info['download_url']) self.update_checksum = client_update_info['expected_checksum'] self.upgrade_type = client_update_info['upgrade_type'] self.transition = client_update_info['transition'] self.logger.debug("Latest client info: %s" % format_to_log(client_update_info) ) except Exception as e: raise ClientUpdateInfoRetrievingException("%s" % e) finally: if connection is not None: connection.close()
def _handle_message_SYNC_FILES_LIST(self, message): """Received the remote filelist from the server. Compute differences, perform integrity checks on it and ask the user confirmation to proceed with the synchronization. Message: SYNC_FILES_LIST Parameters: last_commit_client_id: String or None last_commit_client_hostname: String or None last_commit_client_platform: String or None last_commit_timestamp: Number used_space: Number basis: String user_quota: Number """ storage_content = message.getParameter('dataset') self.storage_content = storage_content self._validate_storage_content(storage_content) self.server_basis = message.getParameter('basis') self.candidate_basis = self._context._try_load_candidate_basis() self.client_basis = self._context._load_trusted_basis() fields = [ 'last_commit_client_id', 'last_commit_client_hostname', 'last_commit_client_platform', 'last_commit_timestamp', 'used_space', 'user_quota' ] info = dict(map(lambda f: (f, message.getParameter(f)), fields)) self._context._ui_controller.update_session_info(info) # No blacklisted pathname should be found on the storage. If any, tell # the user and then shut down the application. remote_pathnames = [entry['key'] for entry in storage_content] blacklisted = filter( lambda x: self._context.warebox.is_blacklisted(x), remote_pathnames) if len(blacklisted) > 0: self.logger.critical( 'The following blacklisted pathnames have been found on the ' 'storage %s' % format_to_log(blacklisted)) self._context._ui_controller.ask_for_user_input( 'blacklisted_pathname_on_storage', blacklisted) # self._internal_facade.terminate() self._context._internal_facade.pause() return # Detect actions to be taken for synchronization as well as conflicts self.logger.debug(u"Starting computing the three-way diff...") self._context.startup_synchronization.prepare(storage_content) self.logger.debug(u"Finished computing the three-way diff.") # Conflicts on encrypted files need extra data from the server to be # solved. If there are any, handle them. encrypted_pathnames = CryptoUtils.filter_encrypted_pathname( self._context.startup_synchronization.edit_conflicts) if len(encrypted_pathnames) > 0: self.logger.debug( u'Encrypted file in conflict: %r' % encrypted_pathnames) message = SYNC_GET_ENCRYPTED_FILES_IVS( 'SYNC_GET_ENCRYPTED_FILES_IVS', {'requested_files_list': encrypted_pathnames}) self._context.output_message_queue.put(message) return # If there are no conflicts on encrypted files, just proceed normally. try: if self._check_hash_mismatch(): self._start_syncing() else: # self._internal_facade.terminate() self._context._internal_facade.pause() except HashMismatchException as excp: self.logger.critical('BASISMISMATCH %s' % excp) self._set_next_state(StateRegister.get('BasisMismatchState'))
def _handle_message_SYNC_FILES_LIST(self, message): """Received the remote filelist from the server. Compute differences, perform integrity checks on it and ask the user confirmation to proceed with the synchronization. Message: SYNC_FILES_LIST Parameters: last_commit_client_id: String or None last_commit_client_hostname: String or None last_commit_client_platform: String or None last_commit_timestamp: Number used_space: Number basis: String user_quota: Number optional parameters: plan: a dictionary as follows (mandatory) { id: <plan_id>, # a number space: <plan_space_in_GB>, # a number (within a plan this is mandatory and 'not None') price: <price_in_$>, # a number (if absent or ==None it means "free") payment_type: <(SINGLE|SUBSCRIPTION)>, # unicode (present if price is not None) payment_recurrence: <(MONTHLY|YEARLY)> # unicode (present if price is not None) } expires_on: <GMT-Date-or-None> # a number representing a unix timestamp UTC (mandatory) (it might None if plan is "forever", this is the expiration date of the subscription, it does not change when in grace time). status: <(TRIAL|ACTIVE|GRACE|SUSPENDED|MAINTAINANCE)> # unicode (mandatory) """ storage_content = message.getParameter('dataset') self.storage_content = storage_content self._validate_storage_content(storage_content) self.server_basis = message.getParameter('basis') self.candidate_basis = self._try_load_candidate_basis() self.client_basis = self._load_trusted_basis() fields = [ 'last_commit_client_id', 'last_commit_client_hostname', 'last_commit_client_platform', 'last_commit_timestamp', 'used_space', 'user_quota', 'plan', 'status', 'expires_on' ] info = dict(map(lambda f: (f, message.getParameter(f)), fields)) # trial # info.update(status='ACTIVE_TRIAL', # expires_on=1366814411, # plan=dict( # space=1 # ) # ) # beta # info.update(status='ACTIVE_BETA', # expires_on=None, # plan=dict( # space=3 # ) # ) # expired # info.update(status='ACTIVE_GRACE', # expires_on=1366810000, # plan=dict( # space=1, # payment_type='SUBSCRIPTION', # payment_recurrence='MONTHLY' # ) # ) # good yearly # info.update(status='ACTIVE_PAID', # expires_on=1366810000, # plan=dict( # space=1, # payment_type='SUBSCRIPTION', # payment_recurrence='YEARLY' # ) # ) self._context._ui_controller.update_session_info(info) # No blacklisted pathname should be found on the storage. If any, tell # the user and then shut down the application. remote_pathnames = [entry['key'] for entry in storage_content] blacklisted = filter(lambda x: self._context.warebox.is_blacklisted(x), remote_pathnames) if len(blacklisted) > 0: self.logger.critical( 'The following blacklisted pathnames have been found on the ' 'storage %s' % format_to_log(blacklisted)) self._context._ui_controller.ask_for_user_input( 'blacklisted_pathname_on_storage', blacklisted) # self._internal_facade.terminate() self._context._internal_facade.pause() return # Detect actions to be taken for synchronization as well as conflicts self.logger.debug(u"Starting computing the three-way diff...") try: self._context.startup_synchronization.prepare( storage_content, self._context.must_die) except ExecutionInterrupted: self.logger.debug(u'ExecutionInterrupted, terminating...') self._set_next_state(StateRegister.get('DisconnectedState')) return self.logger.debug(u"Finished computing the three-way diff.") # Conflicts on encrypted files need extra data from the server to be # solved. If there are any, handle them. encrypted_pathnames = CryptoUtils.filter_encrypted_pathname( self._context.startup_synchronization.edit_conflicts) if len(encrypted_pathnames) > 0: self.logger.debug(u'Encrypted file in conflict: %r' % encrypted_pathnames) message = SYNC_GET_ENCRYPTED_FILES_IVS( 'SYNC_GET_ENCRYPTED_FILES_IVS', {'requested_files_list': encrypted_pathnames}) self._context.output_message_queue.put(message) return # If there are no conflicts on encrypted files, just proceed normally. try: if self._check_hash_mismatch(): self._start_syncing() else: # self._internal_facade.terminate() self._context._internal_facade.pause() except HashMismatchException as excp: self.logger.critical('Integrity error %s' % excp) self._set_next_state(StateRegister.get('IntegrityErrorState'))
def _handle_message_SYNC_FILES_LIST(self, message): """Received the remote filelist from the server. Compute differences, perform integrity checks on it and ask the user confirmation to proceed with the synchronization. Message: SYNC_FILES_LIST Parameters: last_commit_client_id: String or None last_commit_client_hostname: String or None last_commit_client_platform: String or None last_commit_timestamp: Number used_space: Number basis: String user_quota: Number optional parameters: plan: a dictionary as follows (mandatory) { id: <plan_id>, # a number space: <plan_space_in_GB>, # a number (within a plan this is mandatory and 'not None') price: <price_in_$>, # a number (if absent or ==None it means "free") payment_type: <(SINGLE|SUBSCRIPTION)>, # unicode (present if price is not None) payment_recurrence: <(MONTHLY|YEARLY)> # unicode (present if price is not None) } expires_on: <GMT-Date-or-None> # a number representing a unix timestamp UTC (mandatory) (it might None if plan is "forever", this is the expiration date of the subscription, it does not change when in grace time). status: <(TRIAL|ACTIVE|GRACE|SUSPENDED|MAINTAINANCE)> # unicode (mandatory) """ storage_content = message.getParameter('dataset') self.storage_content = storage_content self._validate_storage_content(storage_content) self.server_basis = message.getParameter('basis') self.candidate_basis = self._try_load_candidate_basis() self.client_basis = self._load_trusted_basis() fields = [ 'last_commit_client_id', 'last_commit_client_hostname', 'last_commit_client_platform', 'last_commit_timestamp', 'used_space', 'user_quota', 'plan', 'status', 'expires_on' ] info = dict(map(lambda f: (f, message.getParameter(f)), fields)) # trial # info.update(status='ACTIVE_TRIAL', # expires_on=1366814411, # plan=dict( # space=1 # ) # ) # beta # info.update(status='ACTIVE_BETA', # expires_on=None, # plan=dict( # space=3 # ) # ) # expired # info.update(status='ACTIVE_GRACE', # expires_on=1366810000, # plan=dict( # space=1, # payment_type='SUBSCRIPTION', # payment_recurrence='MONTHLY' # ) # ) # good yearly # info.update(status='ACTIVE_PAID', # expires_on=1366810000, # plan=dict( # space=1, # payment_type='SUBSCRIPTION', # payment_recurrence='YEARLY' # ) # ) self._context._ui_controller.update_session_info(info) # No blacklisted pathname should be found on the storage. If any, tell # the user and then shut down the application. remote_pathnames = [entry['key'] for entry in storage_content] blacklisted = filter( lambda x: self._context.warebox.is_blacklisted(x), remote_pathnames) if len(blacklisted) > 0: self.logger.critical( 'The following blacklisted pathnames have been found on the ' 'storage %s' % format_to_log(blacklisted)) self._context._ui_controller.ask_for_user_input( 'blacklisted_pathname_on_storage', blacklisted) # self._internal_facade.terminate() self._context._internal_facade.pause() return # Detect actions to be taken for synchronization as well as conflicts self.logger.debug(u"Starting computing the three-way diff...") try: self._context.startup_synchronization.prepare( storage_content, self._context.must_die) except ExecutionInterrupted: self.logger.debug(u'ExecutionInterrupted, terminating...') self._set_next_state(StateRegister.get('DisconnectedState')) return self.logger.debug(u"Finished computing the three-way diff.") # Conflicts on encrypted files need extra data from the server to be # solved. If there are any, handle them. encrypted_pathnames = CryptoUtils.filter_encrypted_pathname( self._context.startup_synchronization.edit_conflicts) if len(encrypted_pathnames) > 0: self.logger.debug( u'Encrypted file in conflict: %r' % encrypted_pathnames) message = SYNC_GET_ENCRYPTED_FILES_IVS( 'SYNC_GET_ENCRYPTED_FILES_IVS', {'requested_files_list': encrypted_pathnames}) self._context.output_message_queue.put(message) return # If there are no conflicts on encrypted files, just proceed normally. try: if self._check_hash_mismatch(): self._start_syncing() else: # self._internal_facade.terminate() self._context._internal_facade.pause() except HashMismatchException as excp: self.logger.critical('Integrity error %s' % excp) self._set_next_state(StateRegister.get('IntegrityErrorState'))