Back to index

system-config-printer  1.3.9+20120706
Public Member Functions | Private Member Functions | Private Attributes
authconn.Connection Class Reference

List of all members.

Public Member Functions

def __init__

Private Member Functions

def _begin_operation
def _end_operation
def _get_prompt_allowed
def _set_prompt_allowed
def _set_lock
def _connect
def _make_binding
def _authloop
def _ask_retry_server_error
def _on_retry_server_error_response
def _failed
def _password_callback
def _perform_authentication
def _show_not_authorized_dialog
def _on_not_authorized_dialog_response
def _perform_authentication_with_dialog
def _on_authentication_response

Private Attributes

 _use_password
 _parent
 _try_as_root
 _use_user
 _server
 _port
 _encryption
 _prompt_allowed
 _operation_stack
 _lock
 _gui_event
 _use_pk
 _connection
 _user
 _passes
 _retry_response
 _has_failed
 _cancel
 _forbidden
 _auth_called
 _prompt
 _cannot_auth
 _dialog_shown

Detailed Description

Definition at line 147 of file authconn.py.


Constructor & Destructor Documentation

def authconn.Connection.__init__ (   self,
  parent = None,
  try_as_root = True,
  lock = False,
  host = None,
  port = None,
  encryption = None 
)

Definition at line 149 of file authconn.py.

00149 
00150                   host=None, port=None, encryption=None):
00151         if host != None:
00152             cups.setServer (host)
00153         if port != None:
00154             cups.setPort (port)
00155         if encryption != None:
00156             cups.setEncryption (encryption)
00157 
00158         self._use_password = ''
00159         self._parent = parent
00160         self._try_as_root = try_as_root
00161         self._use_user = cups.getUser ()
00162         self._server = cups.getServer ()
00163         self._port = cups.getPort()
00164         self._encryption = cups.getEncryption ()
00165         self._prompt_allowed = True
00166         self._operation_stack = []
00167         self._lock = lock
00168         self._gui_event = threading.Event ()
00169 
00170         self._connect ()


Member Function Documentation

def authconn.Connection._ask_retry_server_error (   self,
  message 
) [private]

Definition at line 283 of file authconn.py.

00283 
00284     def _ask_retry_server_error (self, message):
00285         if self._lock:
00286             gtk.gdk.threads_enter ()
00287 
00288         try:
00289             msg = _("CUPS server error (%s)") % self._operation_stack[0]
00290         except IndexError:
00291             msg = _("CUPS server error")
00292 
00293         d = gtk.MessageDialog (self._parent,
00294                                gtk.DIALOG_MODAL |
00295                                gtk.DIALOG_DESTROY_WITH_PARENT,
00296                                gtk.MESSAGE_ERROR,
00297                                gtk.BUTTONS_NONE,
00298                                msg)
00299                                
00300         d.format_secondary_text (_("There was an error during the "
00301                                    "CUPS operation: '%s'." % message))
00302         d.add_buttons (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
00303                        _("Retry"), gtk.RESPONSE_OK)
00304         d.set_default_response (gtk.RESPONSE_OK)
00305         if self._lock:
00306             d.connect ("response", self._on_retry_server_error_response)
00307             gtk.gdk.threads_leave ()
00308         else:
00309             self._retry_response = d.run ()
00310             d.destroy ()

Here is the call graph for this function:

def authconn.Connection._authloop (   self,
  fname,
  fn,
  args,
  kwds 
) [private]

Definition at line 221 of file authconn.py.

00221 
00222     def _authloop (self, fname, fn, *args, **kwds):
00223         self._passes = 0
00224         c = self._connection
00225         retry = False
00226         while True:
00227             try:
00228                 if self._perform_authentication () == 0:
00229                     break
00230 
00231                 if c != self._connection:
00232                     # We have reconnected.
00233                     fn = getattr (self._connection, fname)
00234                     c = self._connection
00235 
00236                 cups.setUser (self._use_user)
00237 
00238                 result = fn.__call__ (*args, **kwds)
00239 
00240                 if fname == 'adminGetServerSettings':
00241                     # Special case for a rubbish bit of API.
00242                     if result == {}:
00243                         # Authentication failed, but we aren't told that.
00244                         raise cups.IPPError (cups.IPP_NOT_AUTHORIZED, '')
00245                 break
00246             except cups.IPPError, (e, m):
00247                 if self._use_pk and m == 'pkcancel':
00248                     raise cups.IPPError (0, _("Operation canceled"))
00249 
00250                 if not self._cancel and (e == cups.IPP_NOT_AUTHORIZED or
00251                                          e == cups.IPP_FORBIDDEN or
00252                                          e == cups.IPP_AUTHENTICATION_CANCELED):
00253                     self._failed (e == cups.IPP_FORBIDDEN)
00254                 elif not self._cancel and e == cups.IPP_SERVICE_UNAVAILABLE:
00255                     if self._lock:
00256                         self._gui_event.clear ()
00257                         gobject.timeout_add (1, self._ask_retry_server_error, m)
00258                         self._gui_event.wait ()
00259                     else:
00260                         self._ask_retry_server_error (m)
00261 
00262                     if self._retry_response == gtk.RESPONSE_OK:
00263                         debugprint ("retrying operation...")
00264                         retry = True
00265                         self._passes -= 1
00266                         self._has_failed = True
00267                     else:
00268                         self._cancel = True
00269                         raise
00270                 else:
00271                     if self._cancel and not self._cannot_auth:
00272                         raise cups.IPPError (0, _("Operation canceled"))
00273 
00274                     debugprint ("%s: %s" % (e, m))
00275                     raise
00276             except cups.HTTPError, (s,):
00277                 if not self._cancel:
00278                     self._failed (s == cups.HTTP_FORBIDDEN)
00279                 else:
00280                     raise
00281 
00282         return result

Here is the caller graph for this function:

def authconn.Connection._begin_operation (   self,
  operation 
) [private]

Definition at line 171 of file authconn.py.

00171 
00172     def _begin_operation (self, operation):
00173         debugprint ("%s: Operation += %s" % (self, repr (operation)))
00174         self._operation_stack.append (operation)

def authconn.Connection._connect (   self,
  allow_pk = True 
) [private]

Definition at line 188 of file authconn.py.

00188 
00189     def _connect (self, allow_pk=True):
00190         cups.setUser (self._use_user)
00191 
00192         self._use_pk = (allow_pk and
00193                         (self._server[0] == '/' or self._server == 'localhost')
00194                         and os.getuid () != 0)
00195         if self._use_pk:
00196             create_object = cupspk.Connection
00197         else:
00198             create_object = cups.Connection
00199 
00200         self._connection = create_object (host=self._server,
00201                                             port=self._port,
00202                                             encryption=self._encryption)
00203 
00204         if self._use_pk:
00205             self._connection.set_parent(self._parent)
00206 
00207         self._user = self._use_user
00208         debugprint ("Connected as user %s" % self._user)
00209         methodtype_lambda = type (self._connection.getPrinters)
00210         methodtype_real = type (self._connection.addPrinter)
00211         for fname in dir (self._connection):
00212             if fname[0] == '_':
00213                 continue
00214             fn = getattr (self._connection, fname)
00215             if not type (fn) in [methodtype_lambda, methodtype_real]:
00216                 continue
00217             setattr (self, fname, self._make_binding (fname, fn))

Here is the caller graph for this function:

def authconn.Connection._end_operation (   self) [private]

Definition at line 175 of file authconn.py.

00175 
00176     def _end_operation (self):
00177         debugprint ("%s: Operation ended" % self)
00178         self._operation_stack.pop ()

def authconn.Connection._failed (   self,
  forbidden = False 
) [private]

Definition at line 316 of file authconn.py.

00316 
00317     def _failed (self, forbidden=False):
00318         self._has_failed = True
00319         self._forbidden = forbidden

def authconn.Connection._get_prompt_allowed (   self) [private]

Definition at line 179 of file authconn.py.

00179 
00180     def _get_prompt_allowed (self, ):
00181         return self._prompt_allowed

def authconn.Connection._make_binding (   self,
  fname,
  fn 
) [private]

Definition at line 218 of file authconn.py.

00218 
00219     def _make_binding (self, fname, fn):
00220         return lambda *args, **kwds: self._authloop (fname, fn, *args, **kwds)

Here is the call graph for this function:

def authconn.Connection._on_authentication_response (   self,
  dialog,
  response 
) [private]

Definition at line 486 of file authconn.py.

00486 
00487     def _on_authentication_response (self, dialog, response):
00488         (user, self._use_password) = dialog.get_auth_info ()
00489         if user != '':
00490             self._use_user = user
00491         global_authinfocache.cache_auth_info ((self._use_user,
00492                                                self._use_password),
00493                                               host=self._server,
00494                                               port=self._port)
00495         dialog.destroy ()
00496 
00497         if (response == gtk.RESPONSE_CANCEL or
00498             response == gtk.RESPONSE_DELETE_EVENT):
00499             self._cancel = True
00500 
00501         if self._lock:
00502             self._gui_event.set ()

Here is the caller graph for this function:

def authconn.Connection._on_not_authorized_dialog_response (   self,
  dialog,
  response 
) [private]

Definition at line 452 of file authconn.py.

00452 
00453     def _on_not_authorized_dialog_response (self, dialog, response):
00454         self._gui_event.set ()
00455         dialog.destroy ()

Here is the caller graph for this function:

def authconn.Connection._on_retry_server_error_response (   self,
  dialog,
  response 
) [private]

Definition at line 311 of file authconn.py.

00311 
00312     def _on_retry_server_error_response (self, dialog, response):
00313         self._retry_response = response
00314         dialog.destroy ()
00315         self._gui_event.set ()

Here is the caller graph for this function:

def authconn.Connection._password_callback (   self,
  prompt 
) [private]

Definition at line 320 of file authconn.py.

00320 
00321     def _password_callback (self, prompt):
00322         debugprint ("Got password callback")
00323         if self._cancel or self._auth_called:
00324             return ''
00325 
00326         self._auth_called = True
00327         self._prompt = prompt
00328         return self._use_password

Definition at line 329 of file authconn.py.

00329 
00330     def _perform_authentication (self):
00331         self._passes += 1
00332 
00333         creds = global_authinfocache.lookup_auth_info (host=self._server, port=self._port)
00334         if creds != None:
00335             if (creds[0] != 'root' or self._try_as_root):
00336                 (self._use_user, self._use_password) = creds
00337             del creds
00338 
00339         debugprint ("Authentication pass: %d" % self._passes)
00340         if self._passes == 1:
00341             # Haven't yet tried the operation.  Set the password
00342             # callback and return > 0 so we try it for the first time.
00343             self._has_failed = False
00344             self._forbidden = False
00345             self._auth_called = False
00346             self._cancel = False
00347             self._cannot_auth = False
00348             self._dialog_shown = False
00349             cups.setPasswordCB (self._password_callback)
00350             debugprint ("Authentication: password callback set")
00351             return 1
00352 
00353         debugprint ("Forbidden: %s" % self._forbidden)
00354         if not self._has_failed:
00355             # Tried the operation and it worked.  Return 0 to signal to
00356             # break out of the loop.
00357             debugprint ("Authentication: Operation successful")
00358             return 0
00359 
00360         # Reset failure flag.
00361         self._has_failed = False
00362 
00363         if self._passes >= 2:
00364             # Tried the operation without a password and it failed.
00365             if (self._try_as_root and
00366                 self._user != 'root' and
00367                 (self._server[0] == '/' or self._forbidden)):
00368                 # This is a UNIX domain socket connection so we should
00369                 # not have needed a password (or it is not a UDS but
00370                 # we got an HTTP_FORBIDDEN response), and so the
00371                 # operation must not be something that the current
00372                 # user is authorised to do.  They need to try as root,
00373                 # and supply the password.  However, to get the right
00374                 # prompt, we need to try as root but with no password
00375                 # first.
00376                 debugprint ("Authentication: Try as root")
00377                 self._use_user = 'root'
00378                 self._auth_called = False
00379                 try:
00380                     self._connect (allow_pk=False)
00381                 except RuntimeError:
00382                     raise cups.IPPError (cups.IPP_SERVICE_UNAVAILABLE,
00383                                          'server-error-service-unavailable')
00384 
00385                 return 1
00386 
00387         if not self._prompt_allowed:
00388             debugprint ("Authentication: prompting not allowed")
00389             self._cancel = True
00390             return 1
00391 
00392         if not self._auth_called:
00393             # We aren't even getting a chance to supply credentials.
00394             debugprint ("Authentication: giving up")
00395             self._cancel = True
00396             self._cannot_auth = True
00397             return 1
00398 
00399         # Reset the flag indicating whether we were given an auth callback.
00400         self._auth_called = False
00401 
00402         # If we're previously prompted, explain why we're prompting again.
00403         if self._dialog_shown:
00404             if self._lock:
00405                 self._gui_event.clear ()
00406                 gobject.timeout_add (1, self._show_not_authorized_dialog)
00407                 self._gui_event.wait ()
00408             else:
00409                 self._show_not_authorized_dialog ()
00410 
00411         if self._lock:
00412             self._gui_event.clear ()
00413             gobject.timeout_add (1, self._perform_authentication_with_dialog)
00414             self._gui_event.wait ()
00415         else:
00416             self._perform_authentication_with_dialog ()
00417 
00418         if self._cancel:
00419             debugprint ("cancelled")
00420             return -1
00421 
00422         cups.setUser (self._use_user)
00423         debugprint ("Authentication: Reconnect")
00424         try:
00425             self._connect (allow_pk=False)
00426         except RuntimeError:
00427             raise cups.IPPError (cups.IPP_SERVICE_UNAVAILABLE,
00428                                  'server-error-service-unavailable')
00429 
00430         return 1

Definition at line 456 of file authconn.py.

00456 
00457     def _perform_authentication_with_dialog (self):
00458         if self._lock:
00459             gtk.gdk.threads_enter ()
00460 
00461         # Prompt.
00462         if len (self._operation_stack) > 0:
00463             try:
00464                 title = _("Authentication (%s)") % self._operation_stack[0]
00465             except IndexError:
00466                 title = _("Authentication")
00467 
00468             d = AuthDialog (title=title,
00469                             parent=self._parent)
00470         else:
00471             d = AuthDialog (parent=self._parent)
00472 
00473         d.set_prompt (self._prompt)
00474         d.set_auth_info ([self._use_user, ''])
00475         d.field_grab_focus ('password')
00476         d.set_keep_above (True)
00477         d.show_all ()
00478         d.show_now ()
00479         self._dialog_shown = True
00480         if self._lock:
00481             d.connect ("response", self._on_authentication_response)
00482             gtk.gdk.threads_leave ()
00483         else:
00484             response = d.run ()
00485             self._on_authentication_response (d, response)

Here is the call graph for this function:

def authconn.Connection._set_lock (   self,
  whether 
) [private]

Definition at line 185 of file authconn.py.

00185 
00186     def _set_lock (self, whether):
00187         self._lock = whether

def authconn.Connection._set_prompt_allowed (   self,
  allowed 
) [private]

Definition at line 182 of file authconn.py.

00182 
00183     def _set_prompt_allowed (self, allowed):
00184         self._prompt_allowed = allowed

Definition at line 431 of file authconn.py.

00431 
00432     def _show_not_authorized_dialog (self):
00433         if self._lock:
00434             gtk.gdk.threads_enter ()
00435         d = gtk.MessageDialog (self._parent,
00436                                gtk.DIALOG_MODAL |
00437                                gtk.DIALOG_DESTROY_WITH_PARENT,
00438                                gtk.MESSAGE_ERROR,
00439                                gtk.BUTTONS_CLOSE)
00440         d.set_title (_("Not authorized"))
00441         d.set_markup ('<span weight="bold" size="larger">' +
00442                       _("Not authorized") + '</span>\n\n' +
00443                       _("The password may be incorrect."))
00444         if self._lock:
00445             d.connect ("response", self._on_not_authorized_dialog_response)
00446             d.show_all ()
00447             d.show_now ()
00448             gtk.gdk.threads_leave ()
00449         else:
00450             d.run ()
00451             d.destroy ()

Here is the call graph for this function:


Member Data Documentation

Definition at line 325 of file authconn.py.

Definition at line 267 of file authconn.py.

Definition at line 346 of file authconn.py.

Definition at line 199 of file authconn.py.

Definition at line 347 of file authconn.py.

Definition at line 163 of file authconn.py.

Definition at line 318 of file authconn.py.

Definition at line 167 of file authconn.py.

Definition at line 265 of file authconn.py.

Definition at line 166 of file authconn.py.

Definition at line 165 of file authconn.py.

Definition at line 158 of file authconn.py.

Definition at line 222 of file authconn.py.

Definition at line 162 of file authconn.py.

Definition at line 326 of file authconn.py.

Definition at line 164 of file authconn.py.

Definition at line 261 of file authconn.py.

Definition at line 161 of file authconn.py.

Definition at line 159 of file authconn.py.

Definition at line 157 of file authconn.py.

Definition at line 191 of file authconn.py.

Definition at line 160 of file authconn.py.

Definition at line 206 of file authconn.py.


The documentation for this class was generated from the following file: