Commit bc995f44 authored by Dan Pascu's avatar Dan Pascu

Simplified google authorization token class definition and how is used

parent 5390a8c7
...@@ -30,6 +30,7 @@ from sipsimple.configuration.settings import SIPSimpleSettings ...@@ -30,6 +30,7 @@ from sipsimple.configuration.settings import SIPSimpleSettings
from sipsimple.util import makedirs from sipsimple.util import makedirs
from blink.configuration.account import AccountExtension, BonjourAccountExtension from blink.configuration.account import AccountExtension, BonjourAccountExtension
from blink.configuration.datatypes import InvalidToken
from blink.configuration.settings import SIPSimpleSettingsExtension from blink.configuration.settings import SIPSimpleSettingsExtension
from blink.logging import LogManager from blink.logging import LogManager
from blink.mainwindow import MainWindow from blink.mainwindow import MainWindow
...@@ -190,9 +191,12 @@ class Blink(QApplication): ...@@ -190,9 +191,12 @@ class Blink(QApplication):
def _NH_SIPApplicationDidStart(self, notification): def _NH_SIPApplicationDidStart(self, notification):
self.fetch_account() self.fetch_account()
self.main_window.show() self.main_window.show()
settings = SIPSimpleSettings()
accounts = AccountManager().get_accounts() accounts = AccountManager().get_accounts()
if not accounts or (self.first_run and accounts==[BonjourAccount()]): if not accounts or (self.first_run and accounts==[BonjourAccount()]):
self.main_window.add_account_dialog.open_for_create() self.main_window.add_account_dialog.open_for_create()
if settings.google_contacts.authorization_token is InvalidToken:
self.main_window.google_contacts_dialog.open_for_incorrect_password()
self.update_manager.initialize() self.update_manager.initialize()
def _initialize_sipsimple(self): def _initialize_sipsimple(self):
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"""Definitions of datatypes for use in settings extensions.""" """Definitions of datatypes for use in settings extensions."""
__all__ = ['ApplicationDataPath', 'SoundFile', 'DefaultPath', 'CustomSoundFile', 'HTTPURL', 'InvalidToken', 'AuthorizationToken'] __all__ = ['ApplicationDataPath', 'SoundFile', 'DefaultPath', 'CustomSoundFile', 'HTTPURL', 'AuthorizationToken', 'InvalidToken']
import os import os
import re import re
...@@ -113,33 +113,26 @@ class HTTPURL(unicode): ...@@ -113,33 +113,26 @@ class HTTPURL(unicode):
return value return value
class InvalidToken(object): class AuthorizationTokenMeta(type):
def __init__(cls, name, bases, dic):
super(AuthorizationTokenMeta, cls).__init__(name, bases, dic)
cls._instances = {}
def __call__(cls, *args):
if len(args) > 1:
raise TypeError('%s() takes at most 1 argument (%d given)' % (cls.__name__, len(args)))
key = args[0] if args else ''
if key not in cls._instances:
cls._instances[key] = super(AuthorizationTokenMeta, cls).__call__(*args)
return cls._instances[key]
class AuthorizationToken(str):
__metaclass__ = AuthorizationTokenMeta
def __repr__(self): def __repr__(self):
return self.__class__.__name__ if self is InvalidToken:
return 'InvalidToken'
class AuthorizationToken(object):
def __init__(self, token=None):
self.token = token
def __getstate__(self):
if self.token is InvalidToken:
return u'invalid'
else: else:
return u'value:%s' % (self.__dict__['token']) return '%s(%s)' % (self.__class__.__name__, str.__repr__(self))
def __setstate__(self, state): InvalidToken = AuthorizationToken() # a valid token is never empty
match = re.match(r'^(?P<type>invalid|value:)(?P<token>.+?)?$', state)
if match is None:
raise ValueError('illegal value: %r' % state)
data = match.groupdict()
if data.pop('type') == 'invalid':
data['token'] = InvalidToken
self.__init__(data['token'])
def __nonzero__(self):
return self.token is not InvalidToken
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.token)
...@@ -340,10 +340,10 @@ class GoogleContactsManager(object): ...@@ -340,10 +340,10 @@ class GoogleContactsManager(object):
def _NH_CFGSettingsObjectDidChange(self, notification): def _NH_CFGSettingsObjectDidChange(self, notification):
if 'google_contacts.authorization_token' in notification.data.modified: if 'google_contacts.authorization_token' in notification.data.modified:
authorization_token = notification.sender.google_contacts.authorization_token
if self._load_timer is not None and self._load_timer.active(): if self._load_timer is not None and self._load_timer.active():
self._load_timer.cancel() self._load_timer.cancel()
self._load_timer = None self._load_timer = None
authorization_token = notification.sender.google_contacts.authorization_token
if authorization_token: if authorization_token:
call_in_gui_thread(self.contact_model.addGroup, self.contact_model.google_contacts_group) call_in_gui_thread(self.contact_model.addGroup, self.contact_model.google_contacts_group)
self.stop_adding_contacts = False self.stop_adding_contacts = False
...@@ -369,7 +369,7 @@ class GoogleContactsManager(object): ...@@ -369,7 +369,7 @@ class GoogleContactsManager(object):
self._load_timer = None self._load_timer = None
settings = SIPSimpleSettings() settings = SIPSimpleSettings()
self.client.auth_token = ClientLoginToken(settings.google_contacts.authorization_token.token) self.client.auth_token = ClientLoginToken(settings.google_contacts.authorization_token)
try: try:
if self.group.id is None: if self.group.id is None:
...@@ -407,7 +407,7 @@ class GoogleContactsManager(object): ...@@ -407,7 +407,7 @@ class GoogleContactsManager(object):
self.update_contacts(updated_contacts) self.update_contacts(updated_contacts)
feed = self.client.get_next(feed) if feed.find_next_link() is not None else None feed = self.client.get_next(feed) if feed.find_next_link() is not None else None
except Unauthorized: except Unauthorized:
settings.google_contacts.authorization_token = AuthorizationToken(InvalidToken) settings.google_contacts.authorization_token = InvalidToken
settings.save() settings.save()
except (ConnectionLost, RequestError, httplib.HTTPException, socket.error): except (ConnectionLost, RequestError, httplib.HTTPException, socket.error):
self._load_timer = reactor.callLater(60, self.load_contacts) self._load_timer = reactor.callLater(60, self.load_contacts)
......
...@@ -24,6 +24,7 @@ from blink.aboutpanel import AboutPanel ...@@ -24,6 +24,7 @@ from blink.aboutpanel import AboutPanel
from blink.accounts import AccountModel, ActiveAccountModel, AddAccountDialog, ServerToolsAccountModel, ServerToolsWindow from blink.accounts import AccountModel, ActiveAccountModel, AddAccountDialog, ServerToolsAccountModel, ServerToolsWindow
from blink.contacts import BonjourNeighbour, Contact, ContactGroup, ContactEditorDialog, ContactModel, ContactSearchModel, GoogleContactsDialog from blink.contacts import BonjourNeighbour, Contact, ContactGroup, ContactEditorDialog, ContactModel, ContactSearchModel, GoogleContactsDialog
from blink.sessions import SessionManager, SessionModel from blink.sessions import SessionManager, SessionModel
from blink.configuration.datatypes import InvalidToken
from blink.resources import Resources from blink.resources import Resources
from blink.util import call_in_auxiliary_thread, run_in_gui_thread from blink.util import call_in_auxiliary_thread, run_in_gui_thread
from blink.widgets.buttons import SwitchViewButton from blink.widgets.buttons import SwitchViewButton
...@@ -297,7 +298,7 @@ class MainWindow(base_class, ui_class): ...@@ -297,7 +298,7 @@ class MainWindow(base_class, ui_class):
def _AH_GoogleContactsActionTriggered(self): def _AH_GoogleContactsActionTriggered(self):
settings = SIPSimpleSettings() settings = SIPSimpleSettings()
if settings.google_contacts.authorization_token: if settings.google_contacts.authorization_token is not None:
settings.google_contacts.authorization_token = None settings.google_contacts.authorization_token = None
settings.save() settings.save()
else: else:
...@@ -515,15 +516,10 @@ class MainWindow(base_class, ui_class): ...@@ -515,15 +516,10 @@ class MainWindow(base_class, ui_class):
settings = SIPSimpleSettings() settings = SIPSimpleSettings()
self.silent_action.setChecked(settings.audio.silent) self.silent_action.setChecked(settings.audio.silent)
self.silent_button.setChecked(settings.audio.silent) self.silent_button.setChecked(settings.audio.silent)
if settings.google_contacts.authorization_token: if settings.google_contacts.authorization_token is None:
self.google_contacts_action.setText(u'Disable Google Contacts')
elif settings.google_contacts.authorization_token is not None:
# Token is invalid
self.google_contacts_action.setText(u'Disable Google Contacts')
# Maybe this should be moved to DidStart so that the dialog is shown *after* the MainWindow. -Saul
self.google_contacts_dialog.open_for_incorrect_password()
else:
self.google_contacts_action.setText(u'Enable Google Contacts') self.google_contacts_action.setText(u'Enable Google Contacts')
else:
self.google_contacts_action.setText(u'Disable Google Contacts')
self.google_contacts_action.triggered.connect(self._AH_GoogleContactsActionTriggered) self.google_contacts_action.triggered.connect(self._AH_GoogleContactsActionTriggered)
account_manager = AccountManager() account_manager = AccountManager()
notification_center = NotificationCenter() notification_center = NotificationCenter()
...@@ -594,13 +590,12 @@ class MainWindow(base_class, ui_class): ...@@ -594,13 +590,12 @@ class MainWindow(base_class, ui_class):
action.setChecked(True) action.setChecked(True)
if 'google_contacts.authorization_token' in notification.data.modified: if 'google_contacts.authorization_token' in notification.data.modified:
authorization_token = notification.sender.google_contacts.authorization_token authorization_token = notification.sender.google_contacts.authorization_token
if authorization_token: if authorization_token is None:
self.google_contacts_action.setText(u'Enable Google Contacts')
else:
self.google_contacts_action.setText(u'Disable Google Contacts') self.google_contacts_action.setText(u'Disable Google Contacts')
elif authorization_token is not None: if authorization_token is InvalidToken:
# Token is invalid
self.google_contacts_dialog.open_for_incorrect_password() self.google_contacts_dialog.open_for_incorrect_password()
else:
self.google_contacts_action.setText(u'Enable Google Contacts')
elif isinstance(notification.sender, (Account, BonjourAccount)): elif isinstance(notification.sender, (Account, BonjourAccount)):
account = notification.sender account = notification.sender
if 'enabled' in notification.data.modified: if 'enabled' in notification.data.modified:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment