~smcgrath23/gvoicebox/trunk

2.1.15 by Steve McGrath
Major commit, this implements the preferences model and login/keyring handling system.
1
# This file is part of GVoiceBox. Copyright (c) 2009 Steve McGrath
2
#
3
# GVoiceBox is free software: you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation, either version 3 of the License, or
6
# (at your option) any later version.
7
#
8
# GVoiceBox is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with GVoiceBox.  If not, see <http://www.gnu.org/licenses/>.
15
16
import logging
17
import gnomekeyring
18
import gtk
19
from gtkmvc import Controller
20
21
from gvoicebox.utils.error import *
22
23
class AuthCtrl(Controller):
24
    """Controller class for authentication. Interacts with
25
    Gnome-Keyring. Needs a reference to the application's
26
    preferences model to get the relevant keyring_id and
27
    'remember password' setting.
28
    """
29
    def __init__(self, model, view, prefs):
30
        """Creates a new AuthCtrl objects.
31
        model: We need a gtkmvc.Model instance, though we don't use it.
32
        view: Should be an AuthView instance.
33
        prefs: the application's PrefsModel instance.
34
        """
5 by Steve McGrath
Finally, the preferences code is working properly. Many thanks to Roberto Cavada.
35
        # We have to listen to spurious updates due to the strange hack
36
        # in PrefsModel and derivitives. Look there for details.
37
        Controller.__init__(self, model, view, spurious=True)
2.1.15 by Steve McGrath
Major commit, this implements the preferences model and login/keyring handling system.
38
        self.prefs = prefs
39
        self.keyring = gnomekeyring.get_default_keyring_sync()
40
        self.observe_model(prefs.auth)
41
42
    def register_view(self, view):
43
        """Called as a gtk idle function sometime after __init__ for each
44
        registered view
45
        """
46
    
47
    def run_dialog(self):
48
        """Display the AuthView dialog and return a login, password
49
        pair. Also sets prefs.auth['remember_password'] if selected
50
        by user, and stores login, password in gnomekeyring.
51
        """
52
        dlg = self.view['dialog']
53
        entryuser = self.view['entryUser']
54
        entrypass = self.view['entryPass']
55
        cbremember = self.view['cbRemember']
56
        cbremember.set_active(self.prefs.auth.save_password)
57
        try:
58
            login, password = self.get_auth()
59
            entryuser.set_text(login)
60
            entrypass.set_text(password)
61
        except AuthError:
62
            login = None
63
            password = None
64
        dlg.show_all()
65
        while True:
66
            response = dlg.run()
67
            if response == gtk.RESPONSE_OK:
68
                login = entryuser.get_text()
69
                password = entrypass.get_text()
70
                self.prefs.auth.save_password = cbremember.get_active()
71
                if not login or not password:
72
                    continue
73
                if self.prefs.auth.save_password:
74
                    self.set_auth(login, password)
75
                dlg.hide()
76
                return login, password
77
            else:
78
                dlg.hide()
79
                raise AuthError("User cancelled auth dialog")
80
81
    def get_auth(self):
82
        """Attempts to get login and password in Gnome-Keyring with ID
83
        specified in the auth/keyring_id GConf key.
84
        Returns a login, password pair
85
        """
86
        keyid = self.prefs.auth.keyring_id
87
        if keyid == 0:
88
            raise AuthError("keyring_id not set")
89
        try:
90
            secret = gnomekeyring.item_get_info_sync(self.keyring, keyid).get_secret()
91
            logging.debug("AuthCtrl.get_auth: got secret from gnomekeyring")
92
        except gnomekeyring.DeniedError:
93
            logging.warn("AuthCtrl.get_auth: got gnomekeyring.DeniedError")
94
        except gnomekeyring.NoMatchError:
95
            logging.debug("AuthCtrl.get_auth: gnomekeyring.NoMatchError, rasing AuthError")
96
            raise AuthError("secret not in keyring")
97
        else:
98
            login, password = secret.split('\n')
99
            return login, password
100
    
101
    def set_auth(self, login, password):
102
        """Attempts to store login and password into Gnome-Keyring,
103
        and sets the prefs.auth.keyring_id property to the resulting key id
104
        """
105
        keyid = gnomekeyring.item_create_sync(
106
                            self.keyring,
107
                            gnomekeyring.ITEM_GENERIC_SECRET,
108
                            "GVoiceBox Google Voice ID",
109
                            dict(appname='GVoiceBox'),
110
                            '\n'.join((login, password)), True)
111
        self.prefs.auth.keyring_id = keyid
112
113
    #---Notifications---#000000#FFFFFF----------------------------------------------
114
115
    def property_save_password_value_change(self, model, old, new):
5 by Steve McGrath
Finally, the preferences code is working properly. Many thanks to Roberto Cavada.
116
        logging.debug("prop_save_pass_val_change etc")
2.1.15 by Steve McGrath
Major commit, this implements the preferences model and login/keyring handling system.
117
        if new == False:
118
            logging.debug("AuthCtrl: Forgetting secret from gnomekeyring")
119
            gnomekeyring.item_delete_sync(self.keyring, self.prefs.auth.keyring_id)
120
            self.prefs.auth.keyring_id = 0
121
            return
122
        return