~nataliabidart/ubuntuone-client/extend-oauth

« back to all changes in this revision

Viewing changes to ubuntuone/u1sync/client.py

  • Committer: Tarmac
  • Author(s): natalia.bidart at canonical
  • Date: 2010-09-10 13:06:33 UTC
  • mfrom: (682.1.7 fix-u1sync)
  • Revision ID: tarmac-20100910130633-ck05au3crekbf4q8
* Made u1sync client work from the command line. No more "authorize" option, only --oauth (LP: #634337).

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
from Queue import Queue
29
29
from threading import Lock
30
30
import zlib
31
 
import urlparse
32
 
import ConfigParser
33
31
from cStringIO import StringIO
34
32
 
35
33
from twisted.internet import reactor, defer
37
35
from ubuntuone.logger import LOGFOLDER
38
36
from ubuntuone.storageprotocol.content_hash import crc32
39
37
from ubuntuone.storageprotocol.context import get_ssl_context
40
 
from ubuntu_sso.config import get_config as get_oauth_config
41
 
from ubuntu_sso.auth import AuthorisationClient
42
38
from ubuntuone.u1sync.genericmerge import MergeNode
43
39
from ubuntuone.u1sync.utils import should_sync
44
40
 
45
41
CONSUMER_KEY = "ubuntuone"
 
42
CONSUMER_SECRET = "hammertime"
46
43
 
47
44
from oauth.oauth import OAuthConsumer
48
45
from ubuntuone.storageprotocol.client import (
177
174
    """U1 storage client facade."""
178
175
    required_caps = frozenset(["no-content", "fix462230"])
179
176
 
180
 
    def __init__(self, realm, reactor=reactor):
181
 
        """Create the instance."""
182
 
 
 
177
    def __init__(self, realm=None, reactor=reactor):
 
178
        """Create the instance.
 
179
 
 
180
        'realm' is no longer used, but is left as param for API compatibility.
 
181
 
 
182
        """
183
183
        self.reactor = reactor
184
184
        self.factory = SyncClientFactory(self)
185
185
 
189
189
        self._status_waiting = []
190
190
        self._active_waiters = set()
191
191
 
192
 
        self.realm = realm
193
 
 
194
 
        oauth_config = get_oauth_config()
195
 
        if oauth_config.has_section(realm):
196
 
            config_section = realm
197
 
        elif self.realm.startswith("http://localhost") and \
198
 
             oauth_config.has_section("http://localhost"):
199
 
            config_section = "http://localhost"
200
 
        else:
201
 
            config_section = "default"
202
 
 
203
 
        @log_timing
204
 
        def get_oauth_option(option):
205
 
            """Retrieves an option from oauth config."""
206
 
            try:
207
 
                return oauth_config.get(config_section, option)
208
 
            except ConfigParser.NoOptionError:
209
 
                return oauth_config.get("default", option)
210
 
 
211
 
        @log_timing
212
 
        def get_oauth_url(option):
213
 
            """Retrieves an absolutized URL from the OAuth config."""
214
 
            suffix = get_oauth_option(option)
215
 
            return urlparse.urljoin(realm, suffix)
216
 
 
217
192
        self.consumer_key = CONSUMER_KEY
218
 
        self.consumer_secret = get_oauth_option("consumer_secret")
219
 
 
220
 
        self.request_token_url = get_oauth_url("request_token_url")
221
 
        self.user_authorisation_url = get_oauth_url("user_authorisation_url")
222
 
        self.access_token_url = get_oauth_url("access_token_url")
 
193
        self.consumer_secret = CONSUMER_SECRET
223
194
 
224
195
    def force_shutdown(self):
225
196
        """Forces the client to shut itself down."""
256
227
                    self._active_waiters.remove(waiter)
257
228
 
258
229
    @log_timing
259
 
    def obtain_oauth_token(self, create_token):
260
 
        """Obtains an oauth token, optionally creating one if requried."""
261
 
        token_result = self._get_waiter()
262
 
 
263
 
        @log_timing
264
 
        def have_token(token):
265
 
            """When a token is available."""
266
 
            token_result.wake(token)
267
 
 
268
 
        @log_timing
269
 
        def no_token():
270
 
            """When no token is available."""
271
 
            token_result.wake(None)
272
 
 
273
 
        oauth_client = AuthorisationClient(realm=self.realm,
274
 
                                           request_token_url=
275
 
                                           self.request_token_url,
276
 
                                           user_authorisation_url=
277
 
                                           self.user_authorisation_url,
278
 
                                           access_token_url=
279
 
                                           self.access_token_url,
280
 
                                           consumer_key=self.consumer_key,
281
 
                                           consumer_secret=
282
 
                                           self.consumer_secret,
283
 
                                           callback_parent=have_token,
284
 
                                           callback_denied=no_token,
285
 
                                           do_login=create_token)
286
 
 
287
 
 
288
 
        @log_timing
289
 
        def _obtain_token():
290
 
            """Obtains or creates a token."""
291
 
            if create_token:
292
 
                oauth_client.clear_token()
293
 
            oauth_client.ensure_access_token()
294
 
 
295
 
        self.reactor.callFromThread(_obtain_token)
296
 
        token = self._wait(token_result)
297
 
        if token is None:
298
 
            raise AuthenticationError("Unable to obtain OAuth token.")
299
 
        return token
300
 
 
301
 
    @log_timing
302
230
    def _change_status(self, status, reason=None):
303
231
        """Changes the client status.  Usually called from the reactor
304
232
        thread.
412
340
        self._await_status_not("connecting", "connected", "authenticated")
413
341
 
414
342
    @log_timing
415
 
    def oauth_from_token(self, token):
 
343
    def oauth_from_token(self, token, consumer=None):
416
344
        """Perform OAuth authorisation using an existing token."""
417
345
 
418
 
        consumer = OAuthConsumer(self.consumer_key, self.consumer_secret)
 
346
        if consumer is None:
 
347
            consumer = OAuthConsumer(self.consumer_key, self.consumer_secret)
419
348
 
420
349
        def _auth_successful(value):
421
350
            """Callback for successful auth.  Changes status to