~mvo/ubuntu-sso-client/strawman-lp711413

631.2.1 by natalia.bidart at canonical
Added encoding declaration on every file. Fixed error passing from GUI in GTK
1
# -*- coding: utf-8 -*-
2
#
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
3
# Copyright (C) 2010 Canonical
4
#
5
# Authors:
6
#  Andrew Higginson
575.1.1 by Alejandro J. Cura
Fixed keyring, with proper testing
7
#  Alejandro J. Cura <alecu@canonical.com>
675.2.10 by Manuel de la Pena
Add creadit to the devels that should have it.
8
#  Natalia B. Bidart <natalia.bidart@canonical.com>
9
#  Manuel de la Pena <manuel@canonical.com>
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
10
#
11
# This program is free software; you can redistribute it and/or modify it under
12
# the terms of the GNU General Public License as published by the Free Software
13
# Foundation; version 3.
14
#
15
# This program is distributed in the hope that it will be useful, but WITHOUT
16
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18
# details.
19
#
20
# You should have received a copy of the GNU General Public License along with
21
# this program; if not, write to the Free Software Foundation, Inc.,
22
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
654.1.1 by Natalia B. Bidart
Remove outdated references to gnome keyring.
24
"""Handle keys in the local kerying."""
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
25
586.4.1 by Alejandro J. Cura
move get_token_name to the keyring module
26
import urllib
27
import urlparse
28
648.1.3 by Alejandro J. Cura
all tests pass
29
from twisted.internet.defer import inlineCallbacks, returnValue
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
30
648.1.7 by Alejandro J. Cura
make synchronous dbus methods use async keyring calls
31
from ubuntu_sso.logger import setup_logging
648.1.3 by Alejandro J. Cura
all tests pass
32
from ubuntu_sso.utils.txsecrets import SecretService
675.2.4 by Manuel de la Pena
Fixed lint issues.
33
from ubuntu_sso.keyring import (
34
    get_token_name,
35
    get_old_token_name,
675.2.5 by Manuel de la Pena
Fixed import issues.
36
    U1_APP_NAME,
675.2.6 by Manuel de la Pena
Fixed issues with tests.
37
    try_old_credentials)
611.2.1 by natalia.bidart at canonical
Removed all the old auth mechanism (LP: #616121).
38
39
626.1.1 by natalia.bidart at canonical
Avoid duplicating logging messages for module "main" (LP: #638981).
40
logger = setup_logging("ubuntu_sso.keyring")
608.1.1 by natalia.bidart at canonical
Token name is now built using '@'.
41
42
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
43
class Keyring(object):
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
44
    """A Keyring for a given application name."""
620.1.1 by natalia.bidart at canonical
Passing a second parameter None to gnomekerying.create_sync (LP: #634465).
45
648.1.3 by Alejandro J. Cura
all tests pass
46
    def __init__(self):
47
        """Initialize this instance."""
48
        self.service = SecretService()
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
49
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
50
    @inlineCallbacks
648.1.3 by Alejandro J. Cura
all tests pass
51
    def _find_keyring_item(self, app_name, attr=None):
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
52
        """Return the keyring item or None if not found."""
608.1.2 by natalia.bidart at canonical
Cleanup of code.
53
        if attr is None:
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
54
            logger.debug("getting attr")
648.1.3 by Alejandro J. Cura
all tests pass
55
            attr = self._get_keyring_attr(app_name)
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
56
        logger.debug("finding all items")
648.1.3 by Alejandro J. Cura
all tests pass
57
        items = yield self.service.search_items(attr)
58
        if len(items) == 0:
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
59
            # if no items found, return None
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
60
            logger.debug("No items found")
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
61
            returnValue(None)
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
62
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
63
        logger.debug("Returning first item found")
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
64
        returnValue(items[0])
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
65
648.1.3 by Alejandro J. Cura
all tests pass
66
    def _get_keyring_attr(self, app_name):
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
67
        """Build the keyring attributes for this credentials."""
68
        attr = {"key-type": "Ubuntu SSO credentials",
648.1.3 by Alejandro J. Cura
all tests pass
69
                "token-name": get_token_name(app_name)}
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
70
        return attr
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
71
648.1.3 by Alejandro J. Cura
all tests pass
72
    @inlineCallbacks
73
    def set_credentials(self, app_name, cred):
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
74
        """Set the credentials of the Ubuntu SSO item."""
75
        # Creates the secret from the credentials
586.4.1 by Alejandro J. Cura
move get_token_name to the keyring module
76
        secret = urllib.urlencode(cred)
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
77
648.1.3 by Alejandro J. Cura
all tests pass
78
        attr = self._get_keyring_attr(app_name)
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
79
        # Add our SSO credentials to the keyring
648.1.3 by Alejandro J. Cura
all tests pass
80
        yield self.service.open_session()
81
        collection = yield self.service.get_default_collection()
82
        yield collection.create_item(app_name, attr, secret, True)
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
83
84
    @inlineCallbacks
648.1.3 by Alejandro J. Cura
all tests pass
85
    def _migrate_old_token_name(self, app_name):
608.1.3 by natalia.bidart at canonical
Fixing typos.
86
        """Migrate credentials with old name, store them with new name."""
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
87
        logger.debug("getting keyring attr")
648.1.3 by Alejandro J. Cura
all tests pass
88
        attr = self._get_keyring_attr(app_name)
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
89
        logger.debug("getting old token name")
648.1.3 by Alejandro J. Cura
all tests pass
90
        attr['token-name'] = get_old_token_name(app_name)
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
91
        logger.debug("finding keyring item")
648.1.3 by Alejandro J. Cura
all tests pass
92
        item = yield self._find_keyring_item(app_name, attr=attr)
608.1.2 by natalia.bidart at canonical
Cleanup of code.
93
        if item is not None:
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
94
            logger.debug("setting credentials")
648.1.3 by Alejandro J. Cura
all tests pass
95
            yield self.set_credentials(app_name,
96
                                       dict(urlparse.parse_qsl(item.secret)))
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
97
            logger.debug("deleting old item")
648.1.3 by Alejandro J. Cura
all tests pass
98
            yield item.delete()
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
99
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
100
        logger.debug("finding keyring item")
648.1.3 by Alejandro J. Cura
all tests pass
101
        result = yield self._find_keyring_item(app_name)
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
102
        logger.debug("returning result value")
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
103
        returnValue(result)
104
105
    @inlineCallbacks
648.1.3 by Alejandro J. Cura
all tests pass
106
    def get_credentials(self, app_name):
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
107
        """A deferred with the secret of the SSO item in a dictionary."""
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
108
        # If we have no attributes, return None
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
109
        logger.debug("getting credentials")
648.1.3 by Alejandro J. Cura
all tests pass
110
        yield self.service.open_session()
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
111
        logger.debug("calling find item")
648.1.3 by Alejandro J. Cura
all tests pass
112
        item = yield self._find_keyring_item(app_name)
608.1.2 by natalia.bidart at canonical
Cleanup of code.
113
        if item is None:
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
114
            logger.debug("migrating token")
648.1.3 by Alejandro J. Cura
all tests pass
115
            item = yield self._migrate_old_token_name(app_name)
608.1.2 by natalia.bidart at canonical
Cleanup of code.
116
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
117
        if item is not None:
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
118
            logger.debug("parsing secret")
648.1.3 by Alejandro J. Cura
all tests pass
119
            secret = yield item.get_value()
120
            returnValue(dict(urlparse.parse_qsl(secret)))
586.4.4 by Alejandro J. Cura
use the keyring api that unlocks the keyring
121
        else:
122
            # if no item found, try getting the old credentials
648.1.3 by Alejandro J. Cura
all tests pass
123
            if app_name == U1_APP_NAME:
648.1.6 by Alejandro J. Cura
replaced log.msg with logger.debug
124
                logger.debug("trying old credentials")
648.1.3 by Alejandro J. Cura
all tests pass
125
                old_creds = yield try_old_credentials(app_name)
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
126
                returnValue(old_creds)
586.4.4 by Alejandro J. Cura
use the keyring api that unlocks the keyring
127
        # nothing was found
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
128
        returnValue(None)
575.1.1 by Alejandro J. Cura
Fixed keyring, with proper testing
129
648.1.2 by Alejandro J. Cura
sync wrapper for async keyring access functions
130
    @inlineCallbacks
648.1.3 by Alejandro J. Cura
all tests pass
131
    def delete_credentials(self, app_name):
575.2.5 by natalia.bidart at canonical
Removed window EOL, fixed style.
132
        """Delete a set of credentials from the keyring."""
648.1.3 by Alejandro J. Cura
all tests pass
133
        attr = self._get_keyring_attr(app_name)
134
        # Add our SSO credentials to the keyring
135
        yield self.service.open_session()
136
        collection = yield self.service.get_default_collection()
137
        yield collection.create_item(app_name, attr, "secret!", True)
138
139
        item = yield self._find_keyring_item(app_name)
586.4.2 by Alejandro J. Cura
use the keyring unlocking gnomekeyring apis
140
        if item is not None:
648.1.3 by Alejandro J. Cura
all tests pass
141
            yield item.delete()