|
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
|