~mandel/ubuntu-sso-client/pinned-certs

« back to all changes in this revision

Viewing changes to bin/ubuntuone-login

  • Committer: natalia.bidart at canonical
  • Date: 2010-06-08 11:54:48 UTC
  • Revision ID: natalia.bidart@canonical.com-20100608115448-aqeiwm4ki1nljaw1
Built correct structure.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
# ubuntuone-login - Client side log-in utility for Ubuntu One
 
4
#
 
5
# Author: Rodney Dawes <rodney.dawes@canonical.com>
 
6
#
 
7
# Copyright 2009 Canonical Ltd.
 
8
#
 
9
# This program is free software: you can redistribute it and/or modify it
 
10
# under the terms of the GNU General Public License version 3, as published
 
11
# by the Free Software Foundation.
 
12
#
 
13
# This program is distributed in the hope that it will be useful, but
 
14
# WITHOUT ANY WARRANTY; without even the implied warranties of
 
15
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
16
# PURPOSE.  See the GNU General Public License for more details.
 
17
#
 
18
# You should have received a copy of the GNU General Public License along
 
19
# with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
 
 
21
import pygtk
 
22
pygtk.require('2.0')
 
23
import gtk
 
24
import pango
 
25
import sys
 
26
import gettext
 
27
#from ubuntuone import clientdefs
 
28
 
 
29
import dbus.service
 
30
 
 
31
from dbus.mainloop.glib import DBusGMainLoop
 
32
from ubuntuone.oauthdesktop.main import Login
 
33
 
 
34
from ubuntuone.oauthdesktop.logger import setupLogging
 
35
logger = setupLogging("ubuntuone-login")
 
36
 
 
37
DBusGMainLoop(set_as_default=True)
 
38
 
 
39
_ = gettext.gettext
 
40
ngettext = gettext.ngettext
 
41
 
 
42
DBUS_IFACE_AUTH_NAME = "com.ubuntuone.Authentication"
 
43
 
 
44
OAUTH_REALM = "https://ubuntuone.com"
 
45
OAUTH_CONSUMER = "ubuntuone"
 
46
 
 
47
NOTIFY_ICON_SIZE = 48
 
48
 
 
49
# Why thank you GTK+ for enforcing style-set and breaking API
 
50
RCSTYLE = """
 
51
style 'dialogs' {
 
52
  GtkDialog::action-area-border = 12
 
53
  GtkDialog::button-spacing = 6
 
54
  GtkDialog::content-area-border = 0
 
55
}
 
56
widget_class '*Dialog*' style 'dialogs'
 
57
"""
 
58
 
 
59
 
 
60
class LoginMain(object):
 
61
    """Main login manager process class."""
 
62
 
 
63
    def __init__(self, *args, **kw):
 
64
        """Initializes the child threads and dbus monitor."""
 
65
        gtk.rc_parse_string(RCSTYLE)
 
66
 
 
67
        #logger.info(_("Starting Ubuntu One login manager version %s") %
 
68
        #            clientdefs.VERSION)
 
69
 
 
70
        self.__bus = dbus.SessionBus()
 
71
 
 
72
    def _connect_dbus_signals(self):
 
73
        """Set up some signal handlers for DBus signals."""
 
74
        self.__bus.add_signal_receiver(
 
75
              handler_function=self.new_credentials,
 
76
              signal_name="NewCredentials",
 
77
              dbus_interface=DBUS_IFACE_AUTH_NAME)
 
78
        self.__bus.add_signal_receiver(
 
79
              handler_function=self.auth_denied,
 
80
              signal_name="AuthorizationDenied",
 
81
              dbus_interface=DBUS_IFACE_AUTH_NAME)
 
82
        self.__bus.add_signal_receiver(
 
83
              handler_function=self.got_oauth_error,
 
84
              signal_name="OAuthError",
 
85
              dbus_interface=DBUS_IFACE_AUTH_NAME)
 
86
 
 
87
 
 
88
    def new_credentials(self, realm=None, consumer_key=None, sender=None):
 
89
        """Signal callback for when we get new credentials."""
 
90
        self.set_up_desktopcouch_pairing(consumer_key)
 
91
 
 
92
        def got_port(*args, **kwargs):
 
93
            # Discard the value.  We don't really care about the port, here.
 
94
            pass
 
95
 
 
96
        def got_error(*args, **kwargs):
 
97
            logger.warn("On trying to start desktopcouch-service via DBus, "
 
98
                    "we got an error.  %s %s" % (args, kwargs,))
 
99
 
 
100
        # We have auth, so start desktopcouch service by asking for its port.
 
101
        dc_serv_proxy = self.__bus.get_object("org.desktopcouch.CouchDB", "/")
 
102
        dc_serv_proxy.getPort(reply_handler=got_port, error_handler=got_error)
 
103
 
 
104
    def auth_denied(self):
 
105
        """Signal callback for when auth was denied by user."""
 
106
        logger.info(_("Access to Ubuntu One was denied."))
 
107
 
 
108
        from twisted.internet import reactor
 
109
        reactor.stop()
 
110
 
 
111
    def got_oauth_error(self, message=None):
 
112
        """Signal callback for when an OAuth error occured."""
 
113
        def dialog_response(dialog, response):
 
114
            """Handle the dialog closing."""
 
115
            dialog.destroy()
 
116
 
 
117
        if message:
 
118
            logger.error(message)
 
119
            dialog = gtk.Dialog(title=_("Ubuntu One: Error"),
 
120
                                flags=gtk.DIALOG_NO_SEPARATOR,
 
121
                                buttons=(gtk.STOCK_CLOSE,
 
122
                                         gtk.RESPONSE_CLOSE))
 
123
            dialog.set_default_response(gtk.RESPONSE_CLOSE)
 
124
            dialog.set_icon_name("ubuntuone-client")
 
125
 
 
126
            area = dialog.get_content_area()
 
127
 
 
128
            hbox = gtk.HBox(spacing=12)
 
129
            hbox.set_border_width(12)
 
130
            area.pack_start(hbox)
 
131
            hbox.show()
 
132
 
 
133
            image = gtk.Image()
 
134
            image.set_from_icon_name("dialog-error", gtk.ICON_SIZE_DIALOG)
 
135
            image.set_alignment(0.5, 0.0)
 
136
            image.show()
 
137
            hbox.pack_start(image, False, False)
 
138
 
 
139
            vbox = gtk.VBox(spacing=12)
 
140
            vbox.show()
 
141
            hbox.pack_start(vbox)
 
142
 
 
143
            label = gtk.Label("<b>%s</b>" % _("Authorization Error"))
 
144
            label.set_use_markup(True)
 
145
            label.set_alignment(0.0, 0.5)
 
146
            label.show()
 
147
            vbox.pack_start(label, False, False)
 
148
 
 
149
            label = gtk.Label(message)
 
150
            label.set_line_wrap(True)
 
151
            label.set_max_width_chars(64)
 
152
            label.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
 
153
            label.set_alignment(0.0, 0.0)
 
154
            label.show()
 
155
            vbox.pack_start(label, True, True)
 
156
 
 
157
            dialog.connect('close', dialog_response, gtk.RESPONSE_CLOSE)
 
158
            dialog.connect('response', dialog_response)
 
159
 
 
160
            dialog.show()
 
161
        else:
 
162
            logger.error(_("Got an OAuth error with no message."))
 
163
 
 
164
    def set_up_desktopcouch_pairing(self, consumer_key):
 
165
        """Add a pairing record between desktopcouch and Ubuntu One"""
 
166
        try:
 
167
            from desktopcouch.pair.couchdb_pairing.couchdb_io import \
 
168
                 put_static_paired_service
 
169
            from desktopcouch.records.server import CouchDatabase
 
170
        except ImportError:
 
171
            # desktopcouch is not installed
 
172
            logger.debug(_("Not adding desktopcouch pairing since"
 
173
                " desktopcouch is not installed"))
 
174
            return
 
175
        # Check whether there is already a record of the Ubuntu One service
 
176
        db = CouchDatabase("management", create=True)
 
177
        if not db.view_exists("ubuntu_one_pair_record","ubuntu_one_pair_record"):
 
178
            map_js = """function(doc) {
 
179
                if (doc.service_name == "ubuntuone") {
 
180
                    if (doc.application_annotations &&
 
181
                        doc.application_annotations["Ubuntu One"] &&
 
182
                        doc.application_annotations["Ubuntu One"]["private_application_annotations"] &&
 
183
                        doc.application_annotations["Ubuntu One"]["private_application_annotations"]["deleted"]) {
 
184
                        emit(doc._id, 1);
 
185
                    } else {
 
186
                        emit(doc._id, 0)
 
187
                    }
 
188
                }
 
189
            }"""
 
190
            db.add_view("ubuntu_one_pair_record", map_js, None,
 
191
                "ubuntu_one_pair_record")
 
192
        results = db.execute_view("ubuntu_one_pair_record",
 
193
            "ubuntu_one_pair_record")
 
194
        found = False
 
195
        # Results should contain either one row or no rows
 
196
        # If there is one row, its value will be 0, meaning that there is
 
197
        #   already an Ubuntu One pairing record, or 1, meaning that there
 
198
        #   was an Ubuntu One pairing record but it has since been unpaired
 
199
        # Only create a new record if there is not one already. Specifically,
 
200
        #   do not add the record if there is a deleted one, as this means
 
201
        #   that the user explicitly unpaired it!
 
202
        for row in results:
 
203
            found = True
 
204
            if row.value == 1:
 
205
                logger.debug(_("Not adding desktopcouch pairing since"
 
206
                " the user has explicitly unpaired with Ubuntu One"))
 
207
            else:
 
208
                logger.debug(_("Not adding desktopcouch pairing since"
 
209
                " we are already paired"))
 
210
        if not found:
 
211
            put_static_paired_service(None, "ubuntuone")
 
212
            logger.debug(_("Pairing desktopcouch with Ubuntu One"))
 
213
 
 
214
    def main(self):
 
215
        """Starts the gtk main loop."""
 
216
        self._connect_dbus_signals()
 
217
 
 
218
        from twisted.internet import reactor
 
219
        reactor.run()
 
220
 
 
221
 
 
222
if __name__ == "__main__":
 
223
    #gettext.bindtextdomain(clientdefs.GETTEXT_PACKAGE, clientdefs.LOCALEDIR)
 
224
    #gettext.textdomain(clientdefs.GETTEXT_PACKAGE)
 
225
 
 
226
    # Register DBus service for making sure we run only one instance
 
227
    bus = dbus.SessionBus()
 
228
    if bus.request_name(DBUS_IFACE_AUTH_NAME, dbus.bus.NAME_FLAG_DO_NOT_QUEUE) == dbus.bus.REQUEST_NAME_REPLY_EXISTS:
 
229
        print _("Ubuntu One login manager already running, quitting")
 
230
        sys.exit(0)
 
231
 
 
232
    from twisted.internet import gtk2reactor
 
233
    gtk2reactor.install()
 
234
 
 
235
    login = Login(dbus.service.BusName(DBUS_IFACE_AUTH_NAME,
 
236
                                       bus=dbus.SessionBus()))
 
237
    manager = LoginMain()
 
238
    manager.main()