~ubuntu-branches/ubuntu/raring/software-center/raring-proposed

« back to all changes in this revision

Viewing changes to softwarecenter/backend/ubuntusso.py

  • Committer: Package Import Robot
  • Author(s): Michael Vogt
  • Date: 2012-10-11 15:33:05 UTC
  • mfrom: (195.1.18 quantal)
  • Revision ID: package-import@ubuntu.com-20121011153305-fm5ln7if3rpzts4n
Tags: 5.4.1.1
* lp:~mvo/software-center/reinstall-previous-purchase-token-fix:
  - fix reinstall previous purchases that have a system-wide
    license key LP: #1065481
* lp:~mvo/software-center/lp1060106:
  - Add missing gettext init for utils/update-software-center-agent
    (LP: #1060106)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
 
23
23
from gi.repository import GObject
 
24
from gettext import gettext as _
24
25
 
25
26
import logging
26
27
import os
27
28
 
 
29
import piston_mini_client.auth
 
30
import piston_mini_client.failhandlers
 
31
 
 
32
 
28
33
import softwarecenter.paths
29
34
 
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
 
40
 
 
41
from softwarecenter.backend.piston.ubuntusso_pristine import (
 
42
    UbuntuSsoAPI as PristineUbuntuSsoAPI,
 
43
    )
 
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
 
48
 
 
49
from softwarecenter.enums import (SOFTWARE_CENTER_NAME_KEYRING,
 
50
                                  SOFTWARE_CENTER_SSO_DESCRIPTION,
 
51
                                  )
 
52
from softwarecenter.utils import clear_token_from_ubuntu_sso_sync
33
53
 
34
54
LOG = logging.getLogger(__name__)
35
55
 
36
56
 
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
 
59
 
 
60
    The methods that work syncronous are suffixed with _sync()
 
61
    """
39
62
 
40
63
    __gsignals__ = {
41
64
        "whoami": (GObject.SIGNAL_RUN_LAST,
48
71
                  ),
49
72
        }
50
73
 
51
 
    def __init__(self):
 
74
    def __init__(self, xid=0):
52
75
        GObject.GObject.__init__(self)
 
76
        self.oauth = None
 
77
        self.xid = xid
 
78
        self.loop = GObject.MainLoop(GObject.main_context_default())
53
79
 
54
80
    def _on_whoami_data(self, spawner, piston_whoami):
 
81
        # once we have data, make sure to save it
 
82
        config = get_config()
 
83
        config.email = piston_whoami["preferred_email"]
 
84
        # emit
55
85
        self.emit("whoami", piston_whoami)
56
86
 
57
87
    def whoami(self):
66
96
        spawner.needs_auth = True
67
97
        spawner.run_generic_piston_helper("UbuntuSsoAPI", "whoami")
68
98
 
69
 
 
70
 
class UbuntuSSOAPIFake(UbuntuSSOAPI):
 
99
    def _login_successful(self, sso_backend, oauth_result):
 
100
        LOG.debug("_login_successful")
 
101
        self.oauth = oauth_result
 
102
        self.loop.quit()
 
103
 
 
104
    # sync calls
 
105
    def verify_token_sync(self, token):
 
106
        """ Verify that the token is valid
 
107
 
 
108
            Note that this may raise httplib2 exceptions if the server
 
109
            is not reachable
 
110
        """
 
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)
 
116
        try:
 
117
            res = api.whoami()
 
118
        except piston_mini_client.failhandlers.APIError as e:
 
119
            LOG.exception("api.whoami failed with APIError: '%s'" % e)
 
120
            return False
 
121
        return len(res) > 0
 
122
 
 
123
    def clear_token(self):
 
124
        clear_token_from_ubuntu_sso_sync(SOFTWARE_CENTER_NAME_KEYRING)
 
125
 
 
126
    def _get_login_backend_and_connect(self):
 
127
        sso = get_login_backend(
 
128
            self.xid,
 
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())
 
134
        return sso
 
135
 
 
136
    def find_oauth_token_sync(self):
 
137
        self.oauth = None
 
138
        sso = self. _get_login_backend_and_connect()
 
139
        sso.find_credentials()
 
140
        self.loop.run()
 
141
        return self.oauth
 
142
 
 
143
    def get_oauth_token_sync(self):
 
144
        self.oauth = None
 
145
        sso = self. _get_login_backend_and_connect()
 
146
        sso.login_or_register()
 
147
        self.loop.run()
 
148
        return self.oauth
 
149
 
 
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
 
153
        if token:
 
154
            # verify token will return false if there is a API error,
 
155
            # but there maybe httplib2 errors if there is no network,
 
156
            # so ignore them
 
157
            try:
 
158
                if not self.verify_token_sync(token):
 
159
                    attempt_relogin = not no_relogin
 
160
                    if attempt_relogin:
 
161
                        self.clear_token()
 
162
                        # re-trigger login once
 
163
                        token = self.get_oauth_token_sync()
 
164
                    else:
 
165
                        return None
 
166
            except Exception as e:
 
167
                LOG.warn(
 
168
                    "token could not be verified (network problem?): %s" % e)
 
169
        return token
 
170
 
 
171
 
 
172
class UbuntuSSOAPIFake(UbuntuSSO):
71
173
 
72
174
    def __init__(self):
73
 
        GObject.GObject.__init__(self)
 
175
        UbuntuSSO.__init__(self)
74
176
        self._fake_settings = FakeReviewSettings()
75
177
 
76
178
    @network_delay
105
207
        ubuntu_sso_class = UbuntuSSOAPIFake()
106
208
        LOG.warn('Using fake Ubuntu SSO API. Only meant for testing purposes')
107
209
    else:
108
 
        ubuntu_sso_class = UbuntuSSOAPI()
 
210
        ubuntu_sso_class = UbuntuSSO()
109
211
    return ubuntu_sso_class
110
212
 
111
213
 
128
230
    password = sys.stdin.readline().strip()
129
231
    sso.login(user, password)
130
232
 
 
233
 
131
234
# interactive test code
132
235
if __name__ == "__main__":
133
236
    def _whoami(sso, result):
140
243
 
141
244
    def _dbus_maybe_login_successful(ssologin, oauth_result):
142
245
        print "got token, verify it now"
143
 
        sso = UbuntuSSOAPI()
 
246
        sso = UbuntuSSO()
144
247
        sso.connect("whoami", _whoami)
145
248
        sso.connect("error", _error)
146
249
        sso.whoami()
149
252
    logging.basicConfig(level=logging.DEBUG)
150
253
    softwarecenter.paths.datadir = "./data"
151
254
 
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()
156
258
    Gtk.main()