Mailinglist Archive: opensuse-commit (1826 mails)

< Previous Next >
commit system-config-printer
  • From: root@xxxxxxxxxxxxxxx (h_root)
  • Date: Fri, 26 Sep 2008 15:13:02 +0200
  • Message-id: <20080926131302.D5406678159@xxxxxxxxxxxxxxx>

Hello community,

here is the log from the commit of package system-config-printer
checked in at Fri Sep 26 15:13:02 CEST 2008.


--------
--- GNOME/system-config-printer/system-config-printer.changes 2008-09-17
16:42:06.000000000 +0200
+++
/mounts/work_src_done/STABLE/system-config-printer/system-config-printer.changes
2008-09-26 14:27:46.000000000 +0200
@@ -1,0 +2,13 @@
+Fri Sep 26 14:23:41 CEST 2008 - vuntz@xxxxxxxxxx
+
+- Implement fate#4161 and fate#4162:
+ + add cups-pk-helper, which is a PolicyKit helper implementing
+ some parts of the API exposed by pycups.
+ + add system-config-printer-policykit.patch that adds a "backend"
+ for system-config-printer to use cups-pk-helper to do the CUPS
+ calls.
+- It's been discussed a bit with upstream, but no agreement was
+ reached on this so far. The patch is not intrusive, so it's the
+ best solution right now. I'll try to push it again upstream.
+
+-------------------------------------------------------------------



New:
----
cups-pk-helper-0.0.1.tar.bz2
system-config-printer-policykit.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ system-config-printer.spec ++++++
--- /var/tmp/diff_new_pack.n30027/_old 2008-09-26 15:12:22.000000000 +0200
+++ /var/tmp/diff_new_pack.n30027/_new 2008-09-26 15:12:22.000000000 +0200
@@ -22,28 +22,37 @@
License: GPL v2 or later
Group: Hardware/Printing
Version: 1.0.7
-Release: 3
+Release: 4
%define pycups_version 1.9.42
%define pysmbc_version 1.0.5
+%define cups_pk_helper_version 0.0.1
Summary: A printer administration tool
Url: http://cyberelk.net/tim/software/system-config-printer/
Source0:
http://cyberelk.net/tim/data/system-config-printer/1.0.x/system-config-printer-%{version}.tar.bz2
Source1:
http://cyberelk.net/tim/data/pycups/pycups-%{pycups_version}.tar.bz2
Source2:
http://cyberelk.net/tim/data/pysmbc/pysmbc-%{pysmbc_version}.tar.bz2
+Source3: cups-pk-helper-%{cups_pk_helper_version}.tar.bz2
Patch0: system-config-printer-install-python.patch
Patch1: system-config-printer-python-prefix.patch
Patch2: system-config-printer-remove-redhat-base.patch
Patch3: system-config-printer-icon-brp-friendly.patch
Patch4: system-config-printer-forbidden.patch
+Patch5: system-config-printer-policykit.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
+# For cups-pk-helper:
+BuildRequires: PolicyKit-devel
BuildRequires: cups-devel
# For directory ownership
BuildRequires: dbus-1
+# For cups-pk-helper:
+BuildRequires: dbus-1-glib-devel
BuildRequires: desktop-file-utils
BuildRequires: epydoc
BuildRequires: fdupes
BuildRequires: gettext-devel
BuildRequires: gnome-icon-theme
+# For cups-pk-helper:
+BuildRequires: gtk2-devel
# For directory ownership
BuildRequires: hicolor-icon-theme
BuildRequires: intltool
@@ -74,12 +83,13 @@

%lang_package
%prep
-%setup -q -a 1 -a 2
+%setup -q -a 1 -a 2 -a 3
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
+%patch5 -p1

%build
autoreconf -f -i
@@ -92,6 +102,9 @@
make
make doc
popd
+pushd cups-pk-helper-%{cups_pk_helper_version}
+%configure --libexecdir=%{_libdir}/cups-pk-helper
+popd

%install
%makeinstall
@@ -108,6 +121,9 @@
pushd pysmbc-%{pysmbc_version}
make DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} install
popd
+pushd cups-pk-helper-%{cups_pk_helper_version}
+%makeinstall
+popd
%suse_update_desktop_file my-default-printer
%suse_update_desktop_file print-applet
%suse_update_desktop_file system-config-printer
@@ -137,10 +153,25 @@
%{_datadir}/icons/hicolor/*/apps/*
%{_sysconfdir}/xdg/autostart/*.desktop
%{_mandir}/man1/*
+# From cups-pk-helper:
+%{_sysconfdir}/dbus-1/system.d/org.opensuse.CupsPkHelper.Mechanism.conf
+%{_libdir}/cups-pk-helper
+%{_datadir}/dbus-1/system-services/org.opensuse.CupsPkHelper.Mechanism.service
+%{_datadir}/PolicyKit/policy/org.opensuse.cupspkhelper.mechanism.policy

%files lang -f %{name}.lang

%changelog
+* Fri Sep 26 2008 vuntz@xxxxxxxxxx
+- Implement fate#4161 and fate#4162:
+ + add cups-pk-helper, which is a PolicyKit helper implementing
+ some parts of the API exposed by pycups.
+ + add system-config-printer-policykit.patch that adds a "backend"
+ for system-config-printer to use cups-pk-helper to do the CUPS
+ calls.
+- It's been discussed a bit with upstream, but no agreement was
+ reached on this so far. The patch is not intrusive, so it's the
+ best solution right now. I'll try to push it again upstream.
* Wed Sep 17 2008 vuntz@xxxxxxx
- Copy the printer icon from gnome-icon-theme and use it as
system-config-printer in all desktop files. Add

++++++ system-config-printer-policykit.patch ++++++
diff --git a/Makefile.am b/Makefile.am
index cb62cbd..fee240e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -60,6 +60,7 @@ nobase_pkgdata_DATA= \
authconn.py \
config.py \
contextmenu.py \
+ cupspk.py \
debug.py \
errordialogs.py \
jobviewer.py \
diff --git a/authconn.py b/authconn.py
index 6244eee..ad3bfb0 100644
--- a/authconn.py
+++ b/authconn.py
@@ -18,6 +18,7 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

import cups
+import cupspk
import gtk
from debug import *

@@ -120,8 +121,15 @@ class Connection:

def _connect (self):
cups.setUser (self._use_user)
+
+ self._use_pk = self._server[0] == '/' or self._server == 'localhost'
+ if self._use_pk:
+ create_object = cupspk.Connection
+ else:
+ create_object = cups.Connection
+
try:
- self._connection = cups.Connection (host=self._server,
+ self._connection = create_object (host=self._server,
port=self._port,
encryption=self._encryption)
except TypeError:
@@ -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)
- methodtype = type (self._connection.getPrinters)
+ methodtype_lambda = type (self._connection.getPrinters)
+ methodtype_real = type (self._connection.addPrinter)
for fname in dir (self._connection):
if fname[0] == '_':
continue
fn = getattr (self._connection, fname)
- if type (fn) != methodtype:
+ if not type (fn) in [methodtype_lambda, methodtype_real]:
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..a72fc59
--- /dev/null
+++ b/cupspk.py
@@ -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
+
+import tempfile
+
+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 = '/'
+PK_AUTH_IFACE = 'org.freedesktop.PolicyKit.AuthenticationAgent'
+
+CUPS_PK_NAME = 'org.opensuse.CupsPkHelper.Mechanism'
+CUPS_PK_PATH = '/'
+CUPS_PK_IFACE = 'org.opensuse.CupsPkHelper.Mechanism'
+
+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()
+
+ self._connection = cups.Connection(host=host,
+ port=port,
+ encryption=encryption)
+
+ self._hack_subclass()
+
+
+ def _hack_subclass(self):
+ # here's how to subclass without really subclassing. Just provide
+ # the same methods
+ methodtype = type(self._connection.getPrinters)
+ for fname in dir(self._connection):
+ if fname[0] == '_':
+ continue
+ fn = getattr(self._connection, fname)
+ if type(fn) != methodtype:
+ continue
+ if not hasattr(self, fname):
+ 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)
+ return dbus.Interface(object, CUPS_PK_IFACE)
+ except dbus.exceptions.DBusException:
+ return None
+
+
+ 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)
+
+ # 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)
+
+ 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 pk_auth_ret != 0
+
+
+ def _handle_exception_with_auth(self, e, fallback, *args, **kwds):
+ if e.get_dbus_name() != CUPS_PK_NEED_AUTH:
+ fallback(*args, **kwds)
+ return False
+
+ tokens = e.get_dbus_message().split(' ', 2)
+ if len(tokens) != 3:
+ fallback(*args, **kwds)
+ return False
+
+ try:
+ 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, '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(True)
+ return types
+
+ exception = False
+
+ retval = []
+
+ for i in range(len(types)):
+ if type(args[i]) != types[i]:
+ 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])
+
+ retval.append(exception)
+
+ return tuple(retval)
+
+
+ def _kwds_to_vars(self, names, **kwds):
+ ret = []
+
+ for name in names:
+ if kwds.has_key(name):
+ ret.append(kwds[name])
+ else:
+ ret.append('')
+
+ return tuple(ret)
+
+
+# getPrinters
+# getDests
+# getClasses
+# getPPDs
+# getServerPPD
+# getDocument
+# getDevices
+# getJobs
+# getJobAttributes
+# cancelJob
+# cancelAllJobs
+# authenticateJob
+# setJobHoldUntil
+# restartJob
+# getFile
+# putFile
+
+ def addPrinter(self, *args, **kwds):
+ (name, use_pycups) = self._args_to_tuple([str], *args)
+ (filename, ppdname, info, location, device, ppd) =
self._kwds_to_vars(['filename', 'ppdname', 'info', 'location', 'device',
'ppd'], **kwds)
+
+ need_unlink = False
+ if not ppdname and not filename and ppd:
+ (fd, filename) = tempfile.mkstemp ()
+ ppd.writeFd(fd)
+ os.close(fd)
+ need_unlink = True
+
+ if filename and not ppdname:
+ pk_args = (name, device, filename, info, location)
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterAddWithPpdFile', pk_args,
+ self._connection.addPrinter,
+ *args, **kwds)
+ if need_unlink:
+ os.unlink(filename)
+ else:
+ pk_args = (name, device, ppdname, info, location)
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterAdd', pk_args,
+ self._connection.addPrinter,
+ *args, **kwds)
+
+
+ def setPrinterDevice(self, *args, **kwds):
+ (name, device, use_pycups) = self._args_to_tuple([str, str], *args)
+ pk_args = (name, device)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetDevice', pk_args,
+ self._connection.setPrinterDevice,
+ *args, **kwds)
+
+
+ def setPrinterInfo(self, *args, **kwds):
+ (name, info, use_pycups) = self._args_to_tuple([str, str], *args)
+ pk_args = (name, info)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetInfo', pk_args,
+ self._connection.setPrinterInfo,
+ *args, **kwds)
+
+
+ def setPrinterLocation(self, *args, **kwds):
+ (name, location, use_pycups) = self._args_to_tuple([str, str], *args)
+ pk_args = (name, location)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetLocation', pk_args,
+ self._connection.setPrinterLocation,
+ *args, **kwds)
+
+
+ def setPrinterShared(self, *args, **kwds):
+ (name, shared, use_pycups) = self._args_to_tuple([str, bool], *args)
+ pk_args = (name, shared)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetShared', pk_args,
+ self._connection.setPrinterShared,
+ *args, **kwds)
+
+
+ def setPrinterJobSheets(self, *args, **kwds):
+ (name, start, end, use_pycups) = self._args_to_tuple([str, str, str],
*args)
+ pk_args = (name, start, end)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetJobSheets', pk_args,
+ self._connection.setPrinterJobSheets,
+ *args, **kwds)
+
+
+ def setPrinterErrorPolicy(self, *args, **kwds):
+ (name, policy, use_pycups) = self._args_to_tuple([str, str], *args)
+ pk_args = (name, policy)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetErrorPolicy', pk_args,
+ self._connection.setPrinterErrorPolicy,
+ *args, **kwds)
+
+
+ def setPrinterOpPolicy(self, *args, **kwds):
+ (name, policy, use_pycups) = self._args_to_tuple([str, str], *args)
+ pk_args = (name, policy)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetOpPolicy', pk_args,
+ self._connection.setPrinterOpPolicy,
+ *args, **kwds)
+
+
+# setPrinterUsersAllowed
+# setPrinterUsersDenied
+
+ def addPrinterOptionDefault(self, *args, **kwds):
+ #FIXME: value can be a sequence (need to fix dbus API too)
+ (name, option, value, use_pycups) = self._args_to_tuple([str, str,
str], *args)
+ pk_args = (name, option, value)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterAddOptionDefault', pk_args,
+
self._connection.addPrinterOptionDefault,
+ *args, **kwds)
+
+
+ def deletePrinterOptionDefault(self, *args, **kwds):
+ (name, option, use_pycups) = self._args_to_tuple([str, str], *args)
+ pk_args = (name, option)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterDeleteOptionDefault', pk_args,
+
self._connection.deletePrinterOptionDefault,
+ *args, **kwds)
+
+
+ def deletePrinter(self, *args, **kwds):
+ (name, use_pycups) = self._args_to_tuple([str], *args)
+ pk_args = (name,)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterDelete', pk_args,
+ self._connection.deletePrinter,
+ *args, **kwds)
+
+# getPrinterAttributes
+# addPrinterToClass
+# deletePrinterFromClass
+# deleteClass
+# getDefault
+
+ def setDefault(self, *args, **kwds):
+ (name, use_pycups) = self._args_to_tuple([str], *args)
+ pk_args = (name,)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetDefault', pk_args,
+ self._connection.setDefault,
+ *args, **kwds)
+
+# getPPD
+
+ def enablePrinter(self, *args, **kwds):
+ (name, use_pycups) = self._args_to_tuple([str], *args)
+ pk_args = (name, True)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetEnabled', pk_args,
+ self._connection.enablePrinter,
+ *args, **kwds)
+
+
+ def disablePrinter(self, *args, **kwds):
+ (name, use_pycups) = self._args_to_tuple([str], *args)
+ pk_args = (name, False)
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetEnabled', pk_args,
+ self._connection.enablePrinter,
+ *args, **kwds)
+
+
+ def acceptJobs(self, *args, **kwds):
+ (name, use_pycups) = self._args_to_tuple([str], *args)
+ pk_args = (name, True, '')
+
+ self._call_with_pk_and_fallback(use_pycups,
+ 'PrinterSetAcceptJobs', pk_args,
+ self._connection.acceptJobs,
+ *args, **kwds)
+
+
+ def rejectJobs(self, *args, **kwds):
+ (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,
+ 'PrinterSetAcceptJobs', pk_args,
+ self._connection.rejectJobs,
+ *args, **kwds)
+
+
+# printTestPage
+# adminGetServerSettings
+# adminSetServerSettings
+# getSubscriptions
+# createSubscription
+# getNotifications
+# cancelSubscription
+# renewSubscription
+# printFile
+# printFiles

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: opensuse-commit+help@xxxxxxxxxxxx

< Previous Next >
This Thread
  • No further messages