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
45
41
CONSUMER_KEY = "ubuntuone"
42
CONSUMER_SECRET = "hammertime"
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"])
180
def __init__(self, realm, reactor=reactor):
181
"""Create the instance."""
177
def __init__(self, realm=None, reactor=reactor):
178
"""Create the instance.
180
'realm' is no longer used, but is left as param for API compatibility.
183
183
self.reactor = reactor
184
184
self.factory = SyncClientFactory(self)
189
189
self._status_waiting = []
190
190
self._active_waiters = set()
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"
201
config_section = "default"
204
def get_oauth_option(option):
205
"""Retrieves an option from oauth config."""
207
return oauth_config.get(config_section, option)
208
except ConfigParser.NoOptionError:
209
return oauth_config.get("default", option)
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)
217
192
self.consumer_key = CONSUMER_KEY
218
self.consumer_secret = get_oauth_option("consumer_secret")
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
224
195
def force_shutdown(self):
225
196
"""Forces the client to shut itself down."""
256
227
self._active_waiters.remove(waiter)
259
def obtain_oauth_token(self, create_token):
260
"""Obtains an oauth token, optionally creating one if requried."""
261
token_result = self._get_waiter()
264
def have_token(token):
265
"""When a token is available."""
266
token_result.wake(token)
270
"""When no token is available."""
271
token_result.wake(None)
273
oauth_client = AuthorisationClient(realm=self.realm,
275
self.request_token_url,
276
user_authorisation_url=
277
self.user_authorisation_url,
279
self.access_token_url,
280
consumer_key=self.consumer_key,
282
self.consumer_secret,
283
callback_parent=have_token,
284
callback_denied=no_token,
285
do_login=create_token)
290
"""Obtains or creates a token."""
292
oauth_client.clear_token()
293
oauth_client.ensure_access_token()
295
self.reactor.callFromThread(_obtain_token)
296
token = self._wait(token_result)
298
raise AuthenticationError("Unable to obtain OAuth token.")
302
230
def _change_status(self, status, reason=None):
303
231
"""Changes the client status. Usually called from the reactor
412
340
self._await_status_not("connecting", "connected", "authenticated")
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."""
418
consumer = OAuthConsumer(self.consumer_key, self.consumer_secret)
347
consumer = OAuthConsumer(self.consumer_key, self.consumer_secret)
420
349
def _auth_successful(value):
421
350
"""Callback for successful auth. Changes status to