def get_state(account, obj=None, skip=[]): state = {} if obj is None: obj = account for name in dir(obj.__class__): attribute = getattr(obj.__class__, name, None) if name in skip: continue if isinstance(attribute, SettingsGroupMeta): state[name] = get_state(account, getattr(obj, name), skip) elif isinstance(attribute, Setting): value = attribute.__getstate__(obj) if value is DefaultValue: value = attribute.default if name == 'password': if isinstance(obj, AuthSettings): label = '%s (%s)' % (NSApp.delegate().applicationName, account.id) keychain_item = EMGenericKeychainItem.genericKeychainItemForService_withUsername_(label, account.id) value = unicode(keychain_item.password()) if keychain_item is not None else '' elif isinstance(obj, LDAPSettingsExtension): label = '%s LDAP (%s)' % (NSApp.delegate().applicationName, account.id) keychain_item = EMGenericKeychainItem.genericKeychainItemForService_withUsername_(label, account.id) value = unicode(keychain_item.password()) if keychain_item is not None else '' if name == 'web_password': label = '%s WEB (%s)' % (NSApp.delegate().applicationName, account.id) keychain_item = EMGenericKeychainItem.genericKeychainItemForService_withUsername_(label, account.id) value = unicode(keychain_item.password()) if keychain_item is not None else '' if name == 'replication_password': label = '%s ChatReplication (%s)' % (NSApp.delegate().applicationName, account.id) keychain_item = EMGenericKeychainItem.genericKeychainItemForService_withUsername_(label, account.id) value = unicode(keychain_item.password()) if keychain_item is not None else '' state[name] = value return state
def _get_state(self, account, obj=None, skip=()): state = {} if obj is None: obj = account application_name = NSApp.delegate().applicationName for name in dir(obj.__class__): attribute = getattr(obj.__class__, name, None) if name in skip: continue if isinstance(attribute, SettingsGroupMeta): state[name] = self._get_state(account, getattr(obj, name), skip) elif isinstance(attribute, Setting): value = attribute.__getstate__(obj) if value is DefaultValue: value = attribute.default if name == 'password': if isinstance(obj, AuthSettings): label = '{} ({})'.format(application_name, account.id) keychain_item = EMGenericKeychainItem.genericKeychainItemForService_withUsername_( label, account.id) value = str(keychain_item.password() ) if keychain_item is not None else '' elif isinstance(obj, LDAPSettingsExtension): label = '{} LDAP ({})'.format(application_name, account.id) keychain_item = EMGenericKeychainItem.genericKeychainItemForService_withUsername_( label, account.id) value = str(keychain_item.password() ) if keychain_item is not None else '' if name == 'web_password': label = '{} WEB ({})'.format(application_name, account.id) keychain_item = EMGenericKeychainItem.genericKeychainItemForService_withUsername_( label, account.id) value = str(keychain_item.password() ) if keychain_item is not None else '' if name == 'replication_password': label = '{} ChatReplication ({})'.format( application_name, account.id) keychain_item = EMGenericKeychainItem.genericKeychainItemForService_withUsername_( label, account.id) value = str(keychain_item.password() ) if keychain_item is not None else '' state[name] = value return state
def updateAccountFromCloud(self, key): def set_state(obj, state): for name, value in state.iteritems(): attribute = getattr(obj.__class__, name, None) if isinstance(attribute, SettingsGroupMeta): group = getattr(obj, name) set_state(group, value) elif isinstance(attribute, Setting): if issubclass(attribute.type, bool) and isinstance(value, bool): value = str(value) try: attribute.__setstate__(obj, value) except ValueError: pass else: attribute.dirty[obj] = True json_data = self.cloud_storage.stringForKey_(key) am = AccountManager() if json_data: try: data = cjson.decode(json_data) except TypeError: # account has been deleted in the mean time try: account = am.get_account(key) if isinstance(account, Account): # don't delete account because iCloud is unreliable # account.delete() pass except KeyError: pass try: account = am.get_account(key) except KeyError: account = Account(key) set_state(account, data) account.save() # update keychain passwords if isinstance(account, Account): passwords = {'auth': {'label': '%s (%s)' % (NSApp.delegate().applicationName, account.id), 'value': account.auth.password}, 'web': {'label': '%s WEB (%s)' % (NSApp.delegate().applicationName, account.id), 'value': account.server.web_password}, 'ldap': {'label': '%s LDAP (%s)' % (NSApp.delegate().applicationName, account.id), 'value': account.ldap.password}, 'chat': {'label': '%s ChatReplication (%s)' % (NSApp.delegate().applicationName, account.id), 'value': account.chat.replication_password} } for p in passwords.keys(): label = passwords[p]['label'] value = passwords[p]['value'] k = EMGenericKeychainItem.genericKeychainItemForService_withUsername_(label, account.id) if k is None and value: EMGenericKeychainItem.addGenericKeychainItemForService_withUsername_password_(label, account.id, value) elif k is not None: if value: k.setPassword_(value) else: k.removeFromKeychain() else: try: account = am.get_account(key) if isinstance(account, Account): pass # don't delete account because iCloud is unreliable # account.delete() except KeyError: pass self.notification_center.post_notification("SIPAccountChangedByICloud", sender=self, data=NotificationData(account=key))
def _update_account_from_cloud(self, key): account_manager = AccountManager() json_data = self.cloud_storage.stringForKey_(key) if json_data: try: data = json.loads(json_data) except (TypeError, json.decoder.JSONDecodeError): # account has been deleted in the mean time. don't delete account locally because iCloud is unreliable. data = {} try: account = account_manager.get_account(key) except KeyError: account = Account(key) self._set_state(account, data) account.save() # update keychain passwords if isinstance(account, Account): application_name = NSApp.delegate().applicationName passwords = { 'auth': { 'label': '{} ({})'.format(application_name, account.id), 'value': account.auth.password }, 'web': { 'label': '{} WEB ({})'.format(application_name, account.id), 'value': account.server.web_password }, 'ldap': { 'label': '{} LDAP ({})'.format(application_name, account.id), 'value': account.ldap.password }, 'chat': { 'label': '{} ChatReplication ({})'.format( application_name, account.id), 'value': account.chat.replication_password } } for p in list(passwords.keys()): label = passwords[p]['label'] value = passwords[p]['value'] k = EMGenericKeychainItem.genericKeychainItemForService_withUsername_( label, account.id) if k is None and value: EMGenericKeychainItem.addGenericKeychainItemForService_withUsername_password_( label, account.id, value) elif k is not None: if value: k.setPassword_(value) else: k.removeFromKeychain() self.notification_center.post_notification( "SIPAccountChangedByICloud", sender=self, data=NotificationData(account=key))