summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Untz <vuntz@novell.com>2008-09-22 05:18:03 +0200
committerVincent Untz <vuntz@novell.com>2008-09-22 05:18:03 +0200
commit8f4dd9428983f7a98c5c500a87b8f1f50a6e3814 (patch)
tree00f2a12116d6942ac0e581b4de5ddb5162d27626
parent30b23465704727a89cfcc2d0e8c9e2225d220d77 (diff)
Improve s-c-p patch (UI not blocking, no repeating password dialogs)cups-pk-helper-0.0.1
And pass distcheck.
-rw-r--r--.gitignore1
-rw-r--r--patches/system-config-printer.patch177
-rw-r--r--po/ChangeLog0
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/test-cups-pk.c4
-rwxr-xr-xsrc/test-cups-pk.py2
6 files changed, 146 insertions, 39 deletions
diff --git a/.gitignore b/.gitignore
index 881056e..9b02d2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
*.sw[nop]
*.o
+*.tar.*
INSTALL
Makefile
Makefile.in
diff --git a/patches/system-config-printer.patch b/patches/system-config-printer.patch
index 7e26f38..d3fd6e1 100644
--- a/patches/system-config-printer.patch
+++ b/patches/system-config-printer.patch
@@ -1,5 +1,5 @@
diff --git a/authconn.py b/authconn.py
-index 6244eee..4fff0d1 100644
+index 6244eee..ad3bfb0 100644
--- a/authconn.py
+++ b/authconn.py
@@ -18,6 +18,7 @@
@@ -27,12 +27,15 @@ index 6244eee..4fff0d1 100644
port=self._port,
encryption=self._encryption)
except TypeError:
-@@ -129,16 +137,17 @@ class Connection:
+@@ -129,16 +137,20 @@ class Connection:
cups.setServer (self._server)
cups.setPort (self._port)
cups.setEncryption (self._encryption)
- self._connection = cups.Connection ()
+ self._connection = create_object ()
++
++ if self._use_pk:
++ self._connection.set_parent(self._parent)
self._user = self._use_user
debugprint ("Connected as user %s" % self._user)
@@ -48,15 +51,46 @@ index 6244eee..4fff0d1 100644
continue
setattr (self, fname, self._make_binding (fname, fn))
+@@ -164,6 +176,8 @@ class Connection:
+ raise cups.IPPError (cups.IPP_NOT_AUTHORIZED, '')
+ break
+ except cups.IPPError, (e, m):
++ if self._use_pk and m == 'pkcancel':
++ raise
+ if not self._cancel and (e == cups.IPP_NOT_AUTHORIZED or
+ e == cups.IPP_FORBIDDEN):
+ self._failed ()
diff --git a/cupspk.py b/cupspk.py
new file mode 100644
-index 0000000..b5d9e7f
+index 0000000..a72fc59
--- /dev/null
+++ b/cupspk.py
-@@ -0,0 +1,365 @@
-+# TODO: UI is blocking. We should do the dbus call async and stay stuck in our main loop
+@@ -0,0 +1,454 @@
++# vim: set ts=4 sw=4 et: coding=UTF-8
++#
++# Copyright (C) 2008 Novell, Inc.
++#
++# Authors: Vincent Untz
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++#
++
++# check FIXME/TODO here
+# check FIXME/TODO in cups-pk-helper
+# define fine-grained policy (more than one level of permission)
++# add missing methods
+
+import os
+
@@ -64,6 +98,10 @@ index 0000000..b5d9e7f
+
+import cups
+import dbus
++import gtk
++
++from dbus.mainloop.glib import DBusGMainLoop
++DBusGMainLoop(set_as_default=True)
+
+PK_AUTH_NAME = 'org.freedesktop.PolicyKit.AuthenticationAgent'
+PK_AUTH_PATH = '/'
@@ -75,11 +113,33 @@ index 0000000..b5d9e7f
+
+CUPS_PK_NEED_AUTH = 'org.opensuse.CupsPkHelper.Mechanism.NotPrivileged'
+
++
++pk_auth_ret = False
++pk_auth_error = None
++pk_auth_running = False
++pk_auth_done = False
++
++def _pk_auth_reply_handler(ret):
++ global pk_auth_ret
++ global pk_auth_done
++
++ pk_auth_ret = ret
++ pk_auth_done = True
++
++def _pk_auth_error_handler(e):
++ global pk_auth_error
++ global pk_auth_done
++
++ pk_auth_error = str(e)
++ pk_auth_done = True
++
++
+# we can't subclass cups.Connection, even when adding
+# Py_TPFLAGS_BASETYPE to cupsconnection.c
+# So we'll hack this...
+class Connection:
+ def __init__(self, host, port, encryption):
++ self._parent = None
+ self._session_bus = dbus.SessionBus()
+ self._system_bus = dbus.SystemBus()
+
@@ -104,6 +164,10 @@ index 0000000..b5d9e7f
+ setattr(self, fname, fn.__call__)
+
+
++ def set_parent(self, parent):
++ self._parent = parent
++
++
+ def _get_cups_pk(self):
+ try:
+ object = self._system_bus.get_object(CUPS_PK_NAME, CUPS_PK_PATH)
@@ -113,15 +177,41 @@ index 0000000..b5d9e7f
+
+
+ def _obtain_auth(self, action, xid = 0):
++ global pk_auth_ret
++ global pk_auth_error
++ global pk_auth_done
++ global pk_auth_running
++
++ if pk_auth_running:
++ # FIXME: raise an exception: this should really never happen
++ return False
++
++ pk_auth_ret = False
++ pk_auth_error = None
++ pk_auth_done = False
++
+ pk_auth_object = self._session_bus.get_object(PK_AUTH_NAME, PK_AUTH_PATH)
+ pk_auth = dbus.Interface(pk_auth_object, PK_AUTH_IFACE)
+
-+ ret = pk_auth.ObtainAuthorization(action, dbus.UInt32(xid), dbus.UInt32(os.getpid()))
++ # We're doing this dbus call asynchronously because we want to not
++ # freeze the UI while a menu is being destroyed. And the windows might
++ # need some repainting while the authorization dialog is displayed.
++ pk_auth_running = True
++
++ pk_auth.ObtainAuthorization(action, dbus.UInt32(xid), dbus.UInt32(os.getpid()), reply_handler=_pk_auth_reply_handler, error_handler=_pk_auth_error_handler)
++
++ while not pk_auth_done:
++ gtk.main_iteration(True)
+
-+ if not type(ret) == dbus.Boolean:
++ pk_auth_running = False
++
++ if pk_auth_error != None:
++ raise dbus.exceptions.DBusException(pk_auth_error)
++
++ if not type(pk_auth_ret) == dbus.Boolean:
+ return False
+
-+ return ret != 0
++ return pk_auth_ret != 0
+
+
+ def _handle_exception_with_auth(self, e, fallback, *args, **kwds):
@@ -135,21 +225,50 @@ index 0000000..b5d9e7f
+ return False
+
+ try:
-+ # FIXME use self._parent from authconn.py
-+ ret = self._obtain_auth(tokens[0], 0)
-+ except dbus.exceptions.DBusException, e_auth:
++ xid = 0
++ if self._parent and getattr(self._parent, 'window') and getattr(self._parent.window, 'xid'):
++ xid = self._parent.window.xid
++
++ # FIXME: is xid working?
++ ret = self._obtain_auth(tokens[0], xid)
++ except dbus.exceptions.DBusException:
+ fallback(*args, **kwds)
+ return False
+
+ if not ret:
-+ raise cups.IPPError(cups.IPP_NOT_AUTHORIZED, '')
++ raise cups.IPPError(cups.IPP_NOT_AUTHORIZED, 'pkcancel')
+
+ return True
+
+
++ def _call_with_pk_and_fallback(self, use_fallback, pk_function_name, pk_args, fallback_function, *args, **kwds):
++ pk_function = None
++
++ if not use_fallback:
++ cups_pk = self._get_cups_pk()
++ if cups_pk:
++ try:
++ pk_function = cups_pk.get_dbus_method(pk_function_name)
++ except dbus.exceptions.DBusException:
++ pass
++
++ if use_fallback or not pk_function:
++ fallback_function(*args, **kwds)
++ return
++
++ while True:
++ try:
++ # FIXME: async call or not?
++ pk_function(*pk_args)
++ break
++ except dbus.exceptions.DBusException, e:
++ if not self._handle_exception_with_auth(e, fallback_function, *args, **kwds):
++ break
++
++
+ def _args_to_tuple(self, types, *args):
+ if len(types) != len(args):
-+ types.append(False)
++ types.append(True)
+ return types
+
+ exception = False
@@ -161,6 +280,10 @@ index 0000000..b5d9e7f
+ if types[i] == str and type(args[i]) == unicode:
+ # we accept a mix between unicode and str
+ pass
++ elif types[i] == str and args[i] == None:
++ # None is an empty string for dbus
++ retval.append('')
++ continue
+ else:
+ exception = True
+ retval.append(args[i])
@@ -177,34 +300,11 @@ index 0000000..b5d9e7f
+ if kwds.has_key(name):
+ ret.append(kwds[name])
+ else:
-+ ret.append(None)
++ ret.append('')
+
+ return tuple(ret)
+
+
-+ def _call_with_pk_and_fallback(self, use_fallback, pk_function_name, pk_args, fallback_function, *args, **kwds):
-+ pk_function = None
-+
-+ if not use_fallback:
-+ cups_pk = self._get_cups_pk()
-+ if cups_pk:
-+ try:
-+ pk_function = cups_pk.get_dbus_method(pk_function_name)
-+ except dbus.exceptions.DBusException:
-+ pass
-+
-+ if use_fallback or not pk_function:
-+ fallback_function(*args, **kwds)
-+ return
-+
-+ while True:
-+ try:
-+ pk_function(*pk_args)
-+ break
-+ except dbus.exceptions.DBusException, e:
-+ if not self._handle_exception_with_auth(e, fallback_function, *args, **kwds):
-+ break
-+
+# getPrinters
+# getDests
+# getClasses
@@ -400,7 +500,8 @@ index 0000000..b5d9e7f
+
+
+ def rejectJobs(self, *args, **kwds):
-+ (name, reason, use_pycups) = self._args_to_tuple([str, str], *args)
++ (name, use_pycups) = self._args_to_tuple([str], *args)
++ (reason,) = self._kwds_to_vars(['reason'], **kwds)
+ pk_args = (name, False, reason)
+
+ self._call_with_pk_and_fallback(use_pycups,
diff --git a/po/ChangeLog b/po/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/po/ChangeLog
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 53c4283..8e9383d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,3 +1,4 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
[encoding: UTF-8]
+src/org.opensuse.cupspkhelper.mechanism.policy.in
diff --git a/src/test-cups-pk.c b/src/test-cups-pk.c
index ec86a30..d797d04 100644
--- a/src/test-cups-pk.c
+++ b/src/test-cups-pk.c
@@ -159,7 +159,9 @@ main (int argc, char **argv)
tokens = g_strsplit (error->message, " ", 2);
g_error_free (error);
if (g_strv_length (tokens) == 2) {
- /* FIXME: this fails because of timeout if the user waits too long */
+ /* Note: the async version fails
+ * because of timeout if the user waits
+ * too long */
try = do_auth (session_bus, tokens[0], tokens[1]);
if (!try)
g_print ("not authorized\n");
diff --git a/src/test-cups-pk.py b/src/test-cups-pk.py
index aba3aca..30cd231 100755
--- a/src/test-cups-pk.py
+++ b/src/test-cups-pk.py
@@ -47,6 +47,8 @@ def handle_exception_with_auth(session_bus, e):
return False
try:
+ # Note: the async version fails because of timeout if the user waits
+ # too long
ret = pk_auth(session_bus, tokens[0], tokens[1])
except dbus.exceptions.DBusException, e_auth:
print 'dbus error: %s' % e_auth