Example #1
0
 def _create_sip_account(self, username, password, email_address, display_name, timezone=None):
     red = '#cc0000'
     if timezone is None and sys.platform != 'win32':
         try:
             timezone = open('/etc/timezone').read().strip()
         except (OSError, IOError):
             try:
                 timezone = '/'.join(os.readlink('/etc/localtime').split('/')[-2:])
             except (OSError, IOError):
                 pass
     enrollment_data = dict(username=username.lower().encode('utf-8'),
                            password=password.encode('utf-8'),
                            email=email_address.encode('utf-8'),
                            display_name=display_name.encode('utf-8'),
                            tzinfo=timezone)
     try:
         settings = SIPSimpleSettings()
         data = urllib.parse.urlencode(dict(enrollment_data))
         response = urllib.request.urlopen(settings.server.enrollment_url, data.encode())
         response_data = json.loads(response.read().decode('utf-8').replace(r'\/', '/'))
         response_data = defaultdict(lambda: None, response_data)
         if response_data['success']:
             try:
                 passport = response_data['passport']
                 if passport is not None:
                     certificate_path = self._save_certificates(response_data['sip_address'], passport['crt'], passport['key'], passport['ca'])
                 else:
                     certificate_path = None
             except (GNUTLSError, IOError, OSError):
                 certificate_path = None
             account_manager = AccountManager()
             try:
                 account = Account(response_data['sip_address'])
             except DuplicateIDError:
                 account = account_manager.get_account(response_data['sip_address'])
             account.enabled = True
             account.display_name = display_name or None
             account.auth.password = password
             account.sip.outbound_proxy = response_data['outbound_proxy']
             account.nat_traversal.msrp_relay = response_data['msrp_relay']
             account.xcap.xcap_root = response_data['xcap_root']
             account.tls.certificate = certificate_path
             account.server.conference_server = response_data['conference_server']
             account.server.settings_url = response_data['settings_url']
             account.save()
             account_manager.default_account = account
             call_in_gui_thread(self.accept)
         elif response_data['error'] == 'user_exists':
             call_in_gui_thread(self.username_editor.addException, username)
         else:
             call_in_gui_thread(setattr, self.create_status_label, 'value', Status(response_data['error_message'], color=red))
     except (json.decoder.JSONDecodeError, KeyError):
         call_in_gui_thread(setattr, self.create_status_label, 'value', Status('Illegal server response', color=red))
     except urllib.error.URLError as e:
         call_in_gui_thread(setattr, self.create_status_label, 'value', Status('Failed to contact server: %s' % e.reason, color=red))
     finally:
         call_in_gui_thread(self.setEnabled, True)
Example #2
0
 def _AH_HistoryMenuTriggered(self, action):
     account_manager = AccountManager()
     session_manager = SessionManager()
     try:
         account = account_manager.get_account(action.entry.account_id)
     except KeyError:
         account = None
     contact, contact_uri = URIUtils.find_contact(action.entry.uri)
     session_manager.create_session(contact, contact_uri, [StreamDescription('audio')], account=account) # TODO: memorize media type and use it? -Saul (not sure about history in/out -Dan)
Example #3
0
 def _AH_HistoryMenuTriggered(self, action):
     account_manager = AccountManager()
     session_manager = SessionManager()
     try:
         account = account_manager.get_account(action.entry.account_id)
     except KeyError:
         account = None
     contact, contact_uri = URIUtils.find_contact(action.entry.uri)
     session_manager.create_session(contact, contact_uri, [StreamDescription('audio')], account=account)  # TODO: memorize media type and use it? -Saul (not sure about history in/out -Dan)
Example #4
0
 def _create_sip_account(self, username, password, email_address, display_name, timezone=None):
     red = '#cc0000'
     if timezone is None and sys.platform != 'win32':
         try:
             timezone = open('/etc/timezone').read().strip()
         except (OSError, IOError):
             try:
                 timezone = '/'.join(os.readlink('/etc/localtime').split('/')[-2:])
             except (OSError, IOError):
                 pass
     enrollment_data = dict(username=username.lower().encode('utf-8'),
                            password=password.encode('utf-8'),
                            email=email_address.encode('utf-8'),
                            display_name=display_name.encode('utf-8'),
                            tzinfo=timezone)
     try:
         settings = SIPSimpleSettings()
         response = urllib2.urlopen(settings.server.enrollment_url, urllib.urlencode(dict(enrollment_data)))
         response_data = cjson.decode(response.read().replace(r'\/', '/'))
         response_data = defaultdict(lambda: None, response_data)
         if response_data['success']:
             from blink import Blink
             try:
                 certificate_path = None
                 passport = response_data['passport']
                 if passport is not None:
                     certificate_path = Blink().save_certificates(response_data['sip_address'], passport['crt'], passport['key'], passport['ca'])
             except (GNUTLSError, IOError, OSError):
                 pass
             account_manager = AccountManager()
             try:
                 account = Account(response_data['sip_address'])
             except DuplicateIDError:
                 account = account_manager.get_account(response_data['sip_address'])
             account.enabled = True
             account.display_name = display_name or None
             account.auth.password = password
             account.sip.outbound_proxy = response_data['outbound_proxy']
             account.nat_traversal.msrp_relay = response_data['msrp_relay']
             account.xcap.xcap_root = response_data['xcap_root']
             account.tls.certificate = certificate_path
             account.server.conference_server = response_data['conference_server']
             account.server.settings_url = response_data['settings_url']
             account.save()
             account_manager.default_account = account
             call_in_gui_thread(self.accept)
         elif response_data['error'] == 'user_exists':
             call_in_gui_thread(self.username_editor.addException, username)
         else:
             call_in_gui_thread(setattr, self.create_status_label, 'value', Status(response_data['error_message'], color=red))
     except (cjson.DecodeError, KeyError):
         call_in_gui_thread(setattr, self.create_status_label, 'value', Status('Illegal server response', color=red))
     except urllib2.URLError, e:
         call_in_gui_thread(setattr, self.create_status_label, 'value', Status('Failed to contact server: %s' % e.reason, color=red))
Example #5
0
 def cloudStorgeDidChange_(self, notification):
     BlinkLogger().log_info(u"iCloud storage has changed")
     reason = notification.userInfo()["NSUbiquitousKeyValueStoreChangeReasonKey"]
     if reason == 2:
         BlinkLogger().log_info(u"iCloud quota exeeded")
     for key in notification.userInfo()["NSUbiquitousKeyValueStoreChangedKeysKey"]:
         if '@' in key:
             am = AccountManager()
             try:
                 account = am.get_account(key)
                 local_json = self.getJsonAccountData(account)
                 remote_json = self.cloud_storage.stringForKey_(key)
                 if self.hasDifference(account, local_json, remote_json, True):
                     BlinkLogger().log_info(u"Updating %s from iCloud" % key)
                     self.updateAccountFromCloud(key)
             except KeyError:
                 BlinkLogger().log_info(u"Adding %s from iCloud" % key)
                 self.updateAccountFromCloud(key)
Example #6
0
 def cloudStorageDidChange_(self, notification):
     BlinkLogger().log_info("iCloud storage has changed")
     reason = notification.userInfo(
     )["NSUbiquitousKeyValueStoreChangeReasonKey"]
     if reason == 2:
         BlinkLogger().log_info("iCloud quota exceeded")
     for key in notification.userInfo(
     )["NSUbiquitousKeyValueStoreChangedKeysKey"]:
         if '@' in key:
             account_manager = AccountManager()
             try:
                 account = account_manager.get_account(key)
                 local_json = self._get_account_data(account)
                 remote_json = self.cloud_storage.stringForKey_(key)
                 if self._has_difference(account, local_json, remote_json,
                                         True):
                     BlinkLogger().log_info("Updating %s from iCloud" % key)
                     self._update_account_from_cloud(key)
             except KeyError:
                 BlinkLogger().log_info("Adding %s from iCloud" % key)
                 self._update_account_from_cloud(key)
Example #7
0
            return
        except cjson.DecodeError, e:
            BlinkLogger().log_error(u"Failed to decode json data from ~/.blink_account: %s" % e)
            return
        finally:
            unlink(filename)

        data = defaultdict(lambda: None, data)
        account_id = data['sip_address']
        if account_id is None:
            return

        account_manager = AccountManager()

        try:
            account = account_manager.get_account(account_id)
        except KeyError:
            account = Account(account_id)
            account.display_name = data['display_name']
            default_account = account
        else:
            default_account = account_manager.default_account

        account.auth.username            = data['auth_username']
        account.auth.password            = data['password'] or ''
        account.sip.outbound_proxy       = data['outbound_proxy']
        account.xcap.xcap_root           = data['xcap_root']
        account.nat_traversal.msrp_relay = data['msrp_relay']
        account.server.settings_url      = data['settings_url']
        account.web_alert.alert_url      = data['web_alert_url']
        account.server.web_password      = data['web_password']
Example #8
0
    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))
Example #9
0
     data = cjson.decode(data.replace(r'\/', '/'))
 except (OSError, IOError), e:
     print "Failed to read json data from ~/.blink_account: %s" % e
     return
 except cjson.DecodeError, e:
     print "Failed to decode json data from ~/.blink_account: %s" % e
     return
 finally:
     unlink(filename)
 data = defaultdict(lambda: None, data)
 account_id = data['sip_address']
 if account_id is None:
     return
 account_manager = AccountManager()
 try:
     account = account_manager.get_account(account_id)
 except KeyError:
     account = Account(account_id)
     account.display_name = data['display_name'] or None
     default_account = account
 else:
     default_account = account_manager.default_account
 account.auth.username = data['auth_username']
 account.auth.password = data['password'] or ''
 account.sip.outbound_proxy = data['outbound_proxy']
 account.xcap.xcap_root = data['xcap_root']
 account.nat_traversal.msrp_relay = data['msrp_relay']
 account.server.conference_server = data['conference_server']
 account.server.settings_url = data['settings_url']
 if data['passport'] is not None:
     try:
Example #10
0
    def _create_sip_account(self, username, password, email_address, display_name, timezone=None):
        red = "#cc0000"
        if timezone is None and sys.platform != "win32":
            try:
                timezone = open("/etc/timezone").read().strip()
            except (OSError, IOError):
                try:
                    timezone = "/".join(os.readlink("/etc/localtime").split("/")[-2:])
                except (OSError, IOError):
                    pass
        enrollment_data = dict(
            username=username.lower().encode("utf-8"),
            password=password.encode("utf-8"),
            email=email_address.encode("utf-8"),
            display_name=display_name.encode("utf-8"),
            tzinfo=timezone,
        )
        try:
            settings = SIPSimpleSettings()
            response = urllib2.urlopen(settings.server.enrollment_url, urllib.urlencode(dict(enrollment_data)))
            response_data = cjson.decode(response.read().replace(r"\/", "/"))
            response_data = defaultdict(lambda: None, response_data)
            if response_data["success"]:
                from blink import Blink

                try:
                    certificate_path = None
                    passport = response_data["passport"]
                    if passport is not None:
                        certificate_path = Blink().save_certificates(
                            response_data["sip_address"], passport["crt"], passport["key"], passport["ca"]
                        )
                except (GNUTLSError, IOError, OSError):
                    pass
                account_manager = AccountManager()
                try:
                    account = Account(response_data["sip_address"])
                except AccountExists:
                    account = account_manager.get_account(response_data["sip_address"])
                account.enabled = True
                account.display_name = display_name
                account.auth.password = password
                account.sip.outbound_proxy = response_data["outbound_proxy"]
                account.nat_traversal.msrp_relay = response_data["msrp_relay"]
                account.xcap.xcap_root = response_data["xcap_root"]
                account.tls.certificate = certificate_path
                account.server.settings_url = response_data["settings_url"]
                account.save()
                account_manager.default_account = account
                call_in_gui_thread(self.accept)
            elif response_data["error"] == "user_exists":
                call_in_gui_thread(self.username_editor.addException, username)
            else:
                call_in_gui_thread(
                    setattr, self.create_status_label, "value", Status(response_data["error_message"], color=red)
                )
        except (cjson.DecodeError, KeyError):
            call_in_gui_thread(setattr, self.create_status_label, "value", Status("Illegal server response", color=red))
        except urllib2.URLError, e:
            call_in_gui_thread(
                setattr, self.create_status_label, "value", Status("Failed to contact server: %s" % e.reason, color=red)
            )
Example #11
0
    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))
Example #12
0
    def fetch_account(self):
        """Fetch the SIP account from ~/.blink_account and create/update it as needed"""
        filename = os.path.expanduser('~/.blink_account')
        if not os.path.exists(filename):
            return
        try:
            data = open(filename).read()
            data = json.loads(data.decode().replace('\\/', '/'))
        except (OSError, IOError) as e:
            BlinkLogger().log_error("Failed to read json data from ~/.blink_account: %s" % e)
            return
        except ValueError as e:
            BlinkLogger().log_error("Failed to decode json data from ~/.blink_account: %s" % e)
            return
        finally:
            unlink(filename)

        data = defaultdict(lambda: None, data)
        account_id = data['sip_address']
        if account_id is None:
            return

        account_manager = AccountManager()

        try:
            account = account_manager.get_account(account_id)
        except KeyError:
            account = Account(account_id)
            account.display_name = data['display_name']
            default_account = account
        else:
            default_account = account_manager.default_account

        account.auth.username            = data['auth_username']
        account.auth.password            = data['password'] or ''
        account.sip.outbound_proxy       = data['outbound_proxy']
        account.xcap.xcap_root           = data['xcap_root']
        account.nat_traversal.msrp_relay = data['msrp_relay']
        account.server.settings_url      = data['settings_url']
        account.web_alert.alert_url      = data['web_alert_url']
        account.server.web_password      = data['web_password']
        account.conference.server_address = data['conference_server']

        if data['ldap_hostname']:
            account.ldap.enabled  = True
            account.ldap.hostname = data['ldap_hostname']
            account.ldap.dn       = data['ldap_dn']
            account.ldap.username = data['ldap_username']

            if data['ldap_password']:
                account.ldap.password = data['ldap_password']

            if data['ldap_transport']:
                account.ldap.transport = data['ldap_transport']

            if data['ldap_port']:
                account.ldap.port = data['ldap_port']

        if data['passport'] is not None:
            cert_path = self.save_certificates(data)
            if cert_path:
                account.tls.certificate = cert_path

        account.enabled = True
        account.save()

        account_manager.default_account = default_account

        settings = SIPSimpleSettings()
        settings.service_provider.name      = data['service_provider_name']
        settings.service_provider.help_url  = data['service_provider_help_url']
        settings.service_provider.about_url = data['service_provider_about_url']
        settings.save()