1
# -*- coding: utf-8 -*-
3
# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
5
# Copyright 2010 Canonical Ltd.
7
# This program is free software: you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License version 3, as published
9
# by the Free Software Foundation.
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranties of
13
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14
# PURPOSE. See the GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License along
17
# with this program. If not, see <http://www.gnu.org/licenses/>.
19
"""Ubuntu One credentials management dbus service."""
28
from ubuntu_sso.credentials import (HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY,
31
from ubuntuone.logger import (basic_formatter, logging,
32
CustomRotatingFileHandler, LOGFOLDER)
33
from ubuntuone.clientdefs import GETTEXT_PACKAGE
36
Q_ = lambda string: gettext.dgettext(GETTEXT_PACKAGE, string)
37
NO_OP = lambda *args, **kwargs: None
39
LOG_LEVEL = logging.DEBUG
40
path = os.path.join(LOGFOLDER, 'credentials.log')
41
MAIN_HANDLER = CustomRotatingFileHandler(path)
42
MAIN_HANDLER.setFormatter(basic_formatter)
43
MAIN_HANDLER.setLevel(LOG_LEVEL)
45
logger = logging.getLogger("ubuntuone.credentials")
46
logger.setLevel(LOG_LEVEL)
47
logger.addHandler(MAIN_HANDLER)
49
if os.environ.get('DEBUG'):
50
debug_handler = logging.StreamHandler(sys.stderr)
51
debug_handler.setFormatter(basic_formatter)
52
debug_handler.setLevel(LOG_LEVEL)
53
logger.addHandler(debug_handler)
56
DBUS_BUS_NAME = "com.ubuntuone.Credentials"
57
DBUS_CREDENTIALS_PATH = "/credentials"
58
DBUS_CREDENTIALS_IFACE = "com.ubuntuone.CredentialsManagement"
60
APP_NAME = "Ubuntu One"
61
TC_URL = "https://one.ubuntu.com/terms/"
62
PING_URL = "https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/"
63
DESCRIPTION = Q_('Ubuntu One requires an Ubuntu Single Sign On (SSO) account. '
64
'This process will allow you to create a new account, '
65
'if you do not yet have one.')
68
class CredentialsManagement(dbus.service.Object):
69
"""DBus object that manages Ubuntu One credentials."""
71
def __init__(self, *args, **kwargs):
72
super(CredentialsManagement, self).__init__(*args, **kwargs)
74
self.sso_proxy = self._get_sso_proxy()
76
def _signal_handler(self, *args, **kwargs):
77
"""Generic signal handler."""
78
member = kwargs.get('member', None)
79
app_name = args[0] if len(args) > 0 else None
80
logger.debug('Handling DBus signal for member: %r, app_name: %r.',
83
if app_name != APP_NAME:
84
logger.info('Received %r but app_name %r does not match %r, ' \
85
'exiting.', member, app_name, APP_NAME)
88
sig = getattr(self, member)
90
if member in ('CredentialsFound', 'CredentialsError'):
91
# this are the only signals that will forward the parameter
92
logger.info('%r', member)
98
def _get_sso_proxy(self):
99
"""Get the SSO dbus proxy."""
100
bus = dbus.SessionBus()
101
# register signal handlers for each kind of error
102
self.sso_match = bus.add_signal_receiver(self._signal_handler,
103
member_keyword='member',
104
dbus_interface=ubuntu_sso.DBUS_CREDENTIALS_IFACE)
106
obj = bus.get_object(ubuntu_sso.DBUS_BUS_NAME,
107
ubuntu_sso.DBUS_CREDENTIALS_PATH,
108
follow_name_owner_changes=True)
109
proxy = dbus.Interface(obj, ubuntu_sso.DBUS_CREDENTIALS_IFACE)
111
logger.exception('get_sso_proxy:')
116
# Operator not preceded by a space (fails with dbus decorators)
117
# pylint: disable=C0322
119
@dbus.service.signal(DBUS_CREDENTIALS_IFACE)
120
def AuthorizationDenied(self):
121
"""Signal thrown when the user denies the authorization."""
122
logger.info('%s: emitting AuthorizationDenied.',
123
self.__class__.__name__)
125
@dbus.service.signal(DBUS_CREDENTIALS_IFACE, signature='a{ss}')
126
def CredentialsFound(self, credentials):
127
"""Signal thrown when the credentials are found."""
128
logger.info('%s: emitting CredentialsFound.',
129
self.__class__.__name__)
131
@dbus.service.signal(DBUS_CREDENTIALS_IFACE)
132
def CredentialsNotFound(self):
133
"""Signal thrown when the credentials are not found."""
134
logger.info('%s: emitting CredentialsNotFound.',
135
self.__class__.__name__)
137
@dbus.service.signal(DBUS_CREDENTIALS_IFACE)
138
def CredentialsCleared(self):
139
"""Signal thrown when the credentials were cleared."""
140
logger.info('%s: emitting CredentialsCleared.',
141
self.__class__.__name__)
143
@dbus.service.signal(DBUS_CREDENTIALS_IFACE)
144
def CredentialsStored(self):
145
"""Signal thrown when the credentials were cleared."""
146
logger.info('%s: emitting CredentialsStored.',
147
self.__class__.__name__)
149
@dbus.service.signal(DBUS_CREDENTIALS_IFACE, signature='a{ss}')
150
def CredentialsError(self, error_dict):
151
"""Signal thrown when there is a problem getting the credentials."""
152
logger.error('%s: emitting CredentialsError with error_dict %r.',
153
self.__class__.__name__, error_dict)
155
@dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
156
async_callbacks=("reply_handler", "error_handler"))
157
def find_credentials(self, reply_handler=NO_OP, error_handler=NO_OP):
158
"""Ask the Ubuntu One credentials."""
159
self.sso_proxy.find_credentials(APP_NAME, {},
160
reply_handler=reply_handler, error_handler=error_handler)
163
@dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
164
async_callbacks=("reply_handler", "error_handler"))
165
def clear_credentials(self, reply_handler=NO_OP, error_handler=NO_OP):
166
"""Clear the Ubuntu One credentials."""
167
self.sso_proxy.clear_credentials(APP_NAME, {},
168
reply_handler=reply_handler, error_handler=error_handler)
170
@dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
171
in_signature='a{ss}',
172
async_callbacks=("reply_handler", "error_handler"))
173
def store_credentials(self, credentials,
174
reply_handler=NO_OP, error_handler=NO_OP):
175
"""Store the token for Ubuntu One application."""
176
self.sso_proxy.store_credentials(APP_NAME, credentials,
177
reply_handler=reply_handler, error_handler=error_handler)
179
@dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
180
async_callbacks=("reply_handler", "error_handler"))
181
def register(self, reply_handler=NO_OP, error_handler=NO_OP):
182
"""Get credentials if found else prompt to register to Ubuntu One."""
183
params = {HELP_TEXT_KEY: DESCRIPTION, TC_URL_KEY: TC_URL,
184
PING_URL_KEY: PING_URL, WINDOW_ID_KEY: '0'}
185
self.sso_proxy.register(APP_NAME, params,
186
reply_handler=reply_handler, error_handler=error_handler)
188
@dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
189
async_callbacks=("reply_handler", "error_handler"))
190
def login(self, reply_handler=NO_OP, error_handler=NO_OP):
191
"""Get credentials if found else prompt to login to Ubuntu One."""
192
self.register(reply_handler, error_handler)
194
@dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
195
async_callbacks=("reply_handler", "error_handler"))
196
def shutdown(self, reply_handler=NO_OP, error_handler=NO_OP):
197
"""Disconnect signals from SSO backend."""
198
bus = dbus.SessionBus()
200
bus.remove_signal_receiver(self.sso_match, member_keyword='member',
201
dbus_interface=ubuntu_sso.DBUS_CREDENTIALS_IFACE)