~ubuntu-branches/ubuntu/precise/ubuntu-sso-client/precise

« back to all changes in this revision

Viewing changes to ubuntu_sso/main/windows.py

Tags: upstream-1.3.2
ImportĀ upstreamĀ versionĀ 1.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# -*- coding: utf-8 -*-
2
 
# Author: Manuel de la Pena <manuel@canonical.com>
 
2
# Authors: Manuel de la Pena <manuel@canonical.com>
 
3
#          Alejandro J. Cura <alecu@canonical.com>
3
4
#
4
5
# Copyright 2011 Canonical Ltd.
5
6
#
16
17
# with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18
"""Main implementation on windows."""
18
19
 
19
 
import subprocess
 
20
# pylint: disable=F0401
 
21
from _winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx
20
22
 
21
23
from functools import wraps
22
24
 
23
25
from twisted.internet import defer, reactor
24
26
from twisted.internet.threads import deferToThread
25
 
from twisted.spread.pb import Referenceable, Root, PBClientFactory
26
 
 
27
 
# pylint: disable=F0401
28
 
from win32con import NameSamCompatible
29
 
from win32api import GetUserNameEx
30
 
from _winreg import OpenKey, HKEY_LOCAL_MACHINE, QueryValueEx
31
 
# pylint: enable=F0401
 
27
from twisted.spread.pb import (
 
28
    DeadReferenceError,
 
29
    PBClientFactory,
 
30
    Referenceable,
 
31
    Root,
 
32
)
32
33
 
33
34
from ubuntu_sso import NO_OP
34
35
from ubuntu_sso.account import Account
36
37
from ubuntu_sso.logger import setup_logging
37
38
from ubuntu_sso.main import (CredentialsManagementRoot, SSOLoginRoot,
38
39
                             SSOCredentialsRoot, except_to_errdict)
39
 
 
 
40
from ubuntu_sso.utils.tcpactivation import ActivationConfig, ActivationClient
40
41
 
41
42
logger = setup_logging("ubuntu_sso.main.windows")
42
43
NAMED_PIPE_URL = '\\\\.\\pipe\\ubuntu_sso\\%s'
43
 
U1_REG_PATH = r'Software\\Ubuntu One'
 
44
U1_REG_PATH = r'Software\Ubuntu One'
44
45
SSO_INSTALL_PATH = 'SSOInstallPath'
 
46
LOCALHOST = "127.0.0.1"
 
47
SSO_DEFAULT_PB_PORT = 50001
 
48
SSO_SERVICE_NAME = "ubuntu-sso-client"
 
49
 
 
50
 
 
51
def get_sso_pb_hostport():
 
52
    """Get the host and port on which the SSO pb is running."""
 
53
    return LOCALHOST, SSO_DEFAULT_PB_PORT
45
54
 
46
55
 
47
56
def remote_handler(handler):
51
60
    return lambda: None
52
61
 
53
62
 
 
63
def get_activation_cmdline(service_name):
 
64
    """Get the command line to activate an executable."""
 
65
    key = OpenKey(HKEY_LOCAL_MACHINE, U1_REG_PATH)
 
66
    # pylint: disable=W0612
 
67
    value, registry_type = QueryValueEx(key, "path-" + service_name)
 
68
    return value
 
69
 
 
70
 
 
71
def get_activation_config():
 
72
    """Get the configuration to activate the sso service."""
 
73
    _, port = get_sso_pb_hostport()
 
74
    service_name = SSO_SERVICE_NAME
 
75
    cmdline = get_activation_cmdline(service_name)
 
76
    return ActivationConfig(service_name, cmdline, port)
 
77
 
 
78
 
54
79
def blocking(f, app_name, result_cb, error_cb):
55
80
    """Run f in a thread; return or throw an exception thru the callbacks."""
56
81
    d = deferToThread(f)
106
131
    def emit_signal(self, signal_name, *args, **kwargs):
107
132
        """Emit the given signal to the clients."""
108
133
        for current_client in self.clients:
109
 
            d = current_client.callRemote(signal_name, *args, **kwargs)
110
 
            d.addErrback(self._emit_failure)
 
134
            try:
 
135
                d = current_client.callRemote(signal_name, *args, **kwargs)
 
136
                d.addErrback(self._emit_failure)
 
137
            except DeadReferenceError:
 
138
                self.remote_unregister_to_signals(current_client)
111
139
 
112
140
 
113
141
class SSOLogin(Referenceable, SignalBroadcaster):
311
339
 
312
340
    def login_or_register_to_get_credentials(self, app_name,
313
341
                                             terms_and_conditions_url,
314
 
                                             help_text, window_id):
 
342
                                             help_text, window_id,
 
343
                                             ui_module='ubuntu_sso.qt.gui'):
315
344
        """Get credentials if found else prompt GUI to login or register.
316
345
 
317
346
        'app_name' will be displayed in the GUI.
328
357
                                                self.emit_credentials_found,
329
358
                                                self._process_error,
330
359
                                                self.emit_authorization_denied,
331
 
                                                ui_module='ubuntu_sso.qt.gui')
 
360
                                                ui_module=ui_module)
332
361
 
333
362
    def login_to_get_credentials(self, app_name, help_text, window_id):
334
363
        """Get credentials if found else prompt GUI just to login
911
940
        self.cred_management = CredentialsManagementClient(cred_management)
912
941
        defer.returnValue(self)
913
942
 
 
943
    @defer.inlineCallbacks
914
944
    def connect(self):
915
945
        """Connect to the sso service."""
916
 
        # pylint: disable=W0702
917
 
        try:
918
 
            pipe = NAMED_PIPE_URL % GetUserNameEx(NameSamCompatible)
919
 
            # got the pipe, lets try and  connect to it and get the diff
920
 
            # remote objects for the wrappers
921
 
            self.factory = PBClientFactory()
922
 
            # the reactor does have a connectTCP method
923
 
            # pylint: disable=E1101
924
 
            self.client = reactor.connectPipe(pipe, self.factory)
925
 
            # pylint: enable=E1101
926
 
            d = self.factory.getRootObject()
927
 
            d.addCallback(self._request_remote_objects)
928
 
            return d
929
 
        except:
930
 
            logger.info('The ubuntu sso process is not running!')
931
 
        # try to start the sso process and for that we need to know
932
 
        # its location which should have been stored in the registry
933
 
        key = OpenKey(HKEY_LOCAL_MACHINE, U1_REG_PATH)
934
 
        path = QueryValueEx(key, SSO_INSTALL_PATH)[0]
935
 
        subprocess.Popen([path, ])
936
 
        # try to connect again
937
 
        self.connect()
938
 
        # pylint: disable=W0702
 
946
        ac = ActivationClient(get_activation_config())
 
947
        port = yield ac.get_active_port()
 
948
        # got the port, lets try and connect to it and get the diff
 
949
        # remote objects for the wrappers
 
950
        self.factory = PBClientFactory()
 
951
        # the reactor does have a connectTCP method
 
952
        # pylint: disable=E1101
 
953
        self.client = reactor.connectTCP(LOCALHOST, port, self.factory)
 
954
        # pylint: enable=E1101
 
955
        root = yield self.factory.getRootObject()
 
956
        client = yield self._request_remote_objects(root)
 
957
        defer.returnValue(client)
939
958
 
940
959
    def disconnect(self):
941
960
        """Disconnect from the process."""