23
23
from gi.repository import GObject
24
from gettext import gettext as _
29
import piston_mini_client.auth
30
import piston_mini_client.failhandlers
28
33
import softwarecenter.paths
30
35
# mostly for testing
31
36
from fake_review_settings import FakeReviewSettings, network_delay
32
37
from spawn_helper import SpawnHelper
38
from softwarecenter.config import get_config
39
from softwarecenter.backend.login import get_login_backend
41
from softwarecenter.backend.piston.ubuntusso_pristine import (
42
UbuntuSsoAPI as PristineUbuntuSsoAPI,
44
# patch default_service_root to the one we use
45
from softwarecenter.enums import UBUNTU_SSO_SERVICE
46
# *Don't* append /api/1.0, as it's already included in UBUNTU_SSO_SERVICE
47
PristineUbuntuSsoAPI.default_service_root = UBUNTU_SSO_SERVICE
49
from softwarecenter.enums import (SOFTWARE_CENTER_NAME_KEYRING,
50
SOFTWARE_CENTER_SSO_DESCRIPTION,
52
from softwarecenter.utils import clear_token_from_ubuntu_sso_sync
34
54
LOG = logging.getLogger(__name__)
37
class UbuntuSSOAPI(GObject.GObject):
38
""" Ubuntu SSO interface using the oauth token from the keyring """
57
class UbuntuSSO(GObject.GObject):
58
""" Ubuntu SSO interface using the oauth token from the keyring
60
The methods that work syncronous are suffixed with _sync()
41
64
"whoami": (GObject.SIGNAL_RUN_LAST,
74
def __init__(self, xid=0):
52
75
GObject.GObject.__init__(self)
78
self.loop = GObject.MainLoop(GObject.main_context_default())
54
80
def _on_whoami_data(self, spawner, piston_whoami):
81
# once we have data, make sure to save it
83
config.email = piston_whoami["preferred_email"]
55
85
self.emit("whoami", piston_whoami)
66
96
spawner.needs_auth = True
67
97
spawner.run_generic_piston_helper("UbuntuSsoAPI", "whoami")
70
class UbuntuSSOAPIFake(UbuntuSSOAPI):
99
def _login_successful(self, sso_backend, oauth_result):
100
LOG.debug("_login_successful")
101
self.oauth = oauth_result
105
def verify_token_sync(self, token):
106
""" Verify that the token is valid
108
Note that this may raise httplib2 exceptions if the server
111
LOG.debug("verify_token")
112
auth = piston_mini_client.auth.OAuthAuthorizer(
113
token["token"], token["token_secret"],
114
token["consumer_key"], token["consumer_secret"])
115
api = PristineUbuntuSsoAPI(auth=auth)
118
except piston_mini_client.failhandlers.APIError as e:
119
LOG.exception("api.whoami failed with APIError: '%s'" % e)
123
def clear_token(self):
124
clear_token_from_ubuntu_sso_sync(SOFTWARE_CENTER_NAME_KEYRING)
126
def _get_login_backend_and_connect(self):
127
sso = get_login_backend(
129
SOFTWARE_CENTER_NAME_KEYRING,
130
_(SOFTWARE_CENTER_SSO_DESCRIPTION))
131
sso.connect("login-successful", self._login_successful)
132
sso.connect("login-failed", lambda s: self.loop.quit())
133
sso.connect("login-canceled", lambda s: self.loop.quit())
136
def find_oauth_token_sync(self):
138
sso = self. _get_login_backend_and_connect()
139
sso.find_credentials()
143
def get_oauth_token_sync(self):
145
sso = self. _get_login_backend_and_connect()
146
sso.login_or_register()
150
def get_oauth_token_and_verify_sync(self, no_relogin=False):
151
token = self.get_oauth_token_sync()
152
# check if the token is valid and reset it if it is not
154
# verify token will return false if there is a API error,
155
# but there maybe httplib2 errors if there is no network,
158
if not self.verify_token_sync(token):
159
attempt_relogin = not no_relogin
162
# re-trigger login once
163
token = self.get_oauth_token_sync()
166
except Exception as e:
168
"token could not be verified (network problem?): %s" % e)
172
class UbuntuSSOAPIFake(UbuntuSSO):
72
174
def __init__(self):
73
GObject.GObject.__init__(self)
175
UbuntuSSO.__init__(self)
74
176
self._fake_settings = FakeReviewSettings()
149
252
logging.basicConfig(level=logging.DEBUG)
150
253
softwarecenter.paths.datadir = "./data"
152
from login_sso import get_sso_backend
153
backend = get_sso_backend("", "appname", "help_text")
255
backend = get_login_backend("", "appname", "help_text")
154
256
backend.connect("login-successful", _dbus_maybe_login_successful)
155
257
backend.login_or_register()