[Checkins] SVN: z3c.soap/trunk/ Handle correctly Unauthorized exception

Jean-Fran�ois Roche jfroche at jfroche.be
Fri Nov 14 08:04:31 EST 2008


Log message for revision 92921:
  Handle correctly Unauthorized exception

Changed:
  U   z3c.soap/trunk/docs/HISTORY.txt
  U   z3c.soap/trunk/setup.py
  U   z3c.soap/trunk/z3c/soap/HTTPRequest.py
  U   z3c.soap/trunk/z3c/soap/README.txt
  U   z3c.soap/trunk/z3c/soap/patch.py
  U   z3c.soap/trunk/z3c/soap/soap.py

-=-
Modified: z3c.soap/trunk/docs/HISTORY.txt
===================================================================
--- z3c.soap/trunk/docs/HISTORY.txt	2008-11-14 10:30:22 UTC (rev 92920)
+++ z3c.soap/trunk/docs/HISTORY.txt	2008-11-14 13:04:30 UTC (rev 92921)
@@ -1,8 +1,13 @@
 Changelog
 =========
 
-0.1 - Unreleased
-----------------
+0.2 - (2008-11-14)
+------------------
 
+* Handle correctly Unauthorized exception
+
+0.1 - (2008-11-13)
+------------------
+
 * Initial release
 

Modified: z3c.soap/trunk/setup.py
===================================================================
--- z3c.soap/trunk/setup.py	2008-11-14 10:30:22 UTC (rev 92920)
+++ z3c.soap/trunk/setup.py	2008-11-14 13:04:30 UTC (rev 92921)
@@ -1,7 +1,7 @@
 from setuptools import setup, find_packages
 import os
 
-version = '0.1'
+version = '0.2'
 
 setup(name='z3c.soap',
       version=version,
@@ -29,6 +29,7 @@
       zip_safe=False,
       install_requires=[
           'setuptools',
+          'Products.PluggableAuthService==1.5.3',
           'ZSI'],
       entry_points="""
       # -*- Entry points: -*-

Modified: z3c.soap/trunk/z3c/soap/HTTPRequest.py
===================================================================
--- z3c.soap/trunk/z3c/soap/HTTPRequest.py	2008-11-14 10:30:22 UTC (rev 92920)
+++ z3c.soap/trunk/z3c/soap/HTTPRequest.py	2008-11-14 13:04:30 UTC (rev 92921)
@@ -54,6 +54,7 @@
         other=self.other
         taintedform=self.taintedform
 
+
         meth=None
         fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
         if not hasattr(fs,'list') or fs.list is None:
@@ -721,6 +722,6 @@
 HTTPRequest.processInputs = processInputs
 import logging
 logger = logging.getLogger('Zope')
-logger.info("""SOAPSupport: modified ZPublisher.HTTPRequest.processInputs, Dirk Datzert, 2007-02-06, version for Zope-2.8.x/Zope-2.9.x/Zope-2.10.x\n""")
+logger.info("z3c.soap: modified ZPublisher.HTTPRequest.processInputs")
 
 # vi:ts=4

Modified: z3c.soap/trunk/z3c/soap/README.txt
===================================================================
--- z3c.soap/trunk/z3c/soap/README.txt	2008-11-14 10:30:22 UTC (rev 92920)
+++ z3c.soap/trunk/z3c/soap/README.txt	2008-11-14 13:04:30 UTC (rev 92921)
@@ -164,7 +164,11 @@
   ... </SOAP-ENV:Envelope>
   ... """)
   HTTP/1.0 401 Unauthorized
-  ...
+  Content-Length: ...
+  Content-Type: text/xml
+  Www-Authenticate: basic realm="Zope2"
+  <BLANKLINE>
+  <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Not authorized</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
 
 
 Parameters
@@ -575,16 +579,6 @@
 
 
 
-Complex Types
--------------
-
-For ZSI to successfully marshal complex values (instances of classes),
-you must define a typecode that describes the object (see the ZSI docs
-for details on defining typecodes). Once the typecode is defined, it must
-be accessible through an instance via the attribute name 'typecode' to
-be automatically marshalled.
-
-
 Faults
 ------
 
@@ -617,16 +611,20 @@
   Content-Length: ...
   Content-Type: text/xml
   <BLANKLINE>
-  <SOAP-ENV:Envelope ...
-  Processing Failure
-  <BLANKLINE>
-  Unparseable integer
+  <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Processing Failure</faultstring><detail><ZSI:FaultDetail><ZSI:string>
   ...
 
 
 Complex Types
 -------------
 
+For ZSI to successfully marshal complex values (instances of classes),
+you must define a typecode that describes the object (see the ZSI docs
+for details on defining typecodes). Once the typecode is defined, it must
+be accessible through an instance via the attribute name 'typecode' to
+be automatically marshalled.
+
+
   >>> print http(r"""
   ... POST /test_folder_1_ HTTP/1.0
   ... Authorization: Basic %s:%s

Modified: z3c.soap/trunk/z3c/soap/patch.py
===================================================================
--- z3c.soap/trunk/z3c/soap/patch.py	2008-11-14 10:30:22 UTC (rev 92920)
+++ z3c.soap/trunk/z3c/soap/patch.py	2008-11-14 13:04:30 UTC (rev 92921)
@@ -142,3 +142,54 @@
 
 import ZPublisher.Publish
 ZPublisher.Publish.publish = publish
+
+from Products.PluggableAuthService.plugins.CookieAuthHelper import CookieAuthHelper
+from urllib import quote
+
+
+def unauthorized(self):
+        req = self.REQUEST
+        resp = req['RESPONSE']
+
+        # If we set the auth cookie before, delete it now.
+        if self.cookie_name in resp.cookies:
+            del resp.cookies[self.cookie_name]
+
+        # Redirect if desired.
+        url = self.getLoginURL()
+        if ISOAPRequest.providedBy(req):
+            #no need to redirect if it's a soap request
+            return 0
+
+        if url is not None:
+            came_from = req.get('came_from', None)
+
+            if came_from is None:
+                came_from = req.get('URL', '')
+                query = req.get('QUERY_STRING')
+                if query:
+                    if not query.startswith('?'):
+                        query = '?' + query
+                    came_from = came_from + query
+            else:
+                # If came_from contains a value it means the user
+                # must be coming through here a second time
+                # Reasons could be typos when providing credentials
+                # or a redirect loop (see below)
+                req_url = req.get('URL', '')
+
+                if req_url and req_url == url:
+                    # Oops... The login_form cannot be reached by the user -
+                    # it might be protected itself due to misconfiguration -
+                    # the only sane thing to do is to give up because we are
+                    # in an endless redirect loop.
+                    return 0
+
+            url = url + '?came_from=%s' % quote(came_from)
+            resp.redirect(url, lock=1)
+            return 1
+
+        # Could not challenge.
+        return 0
+
+CookieAuthHelper.unauthorized = unauthorized

Modified: z3c.soap/trunk/z3c/soap/soap.py
===================================================================
--- z3c.soap/trunk/z3c/soap/soap.py	2008-11-14 10:30:22 UTC (rev 92920)
+++ z3c.soap/trunk/z3c/soap/soap.py	2008-11-14 13:04:30 UTC (rev 92921)
@@ -91,8 +91,6 @@
     def setBody(self, body, title='', is_error=0, bogus_str_search=None):
         if isinstance(body, Fault):
             # Convert Fault object to SOAP response.
-            #body = buildSOAP(args=body, config=Config)
-            body = ZSI.FaultFromException(body, 0)
             body = body.AsSOAP()
         else:
             # Marshall our body as an SOAP response. Strings will be sent
@@ -101,7 +99,6 @@
             try:
                 target = self._method
                 body = premarshal(body)
-                #output = StringIO()
                 result = body
                 if hasattr(result, 'typecode'):
                     tc = result.typecode
@@ -122,35 +119,27 @@
 
     def exception(self, fatal=0, info=None,
                   absuri_match=None, tag_search=None):
-        # Fetch our exception info. t is type, v is value and tb is the
-        # traceback object.
-        if type(info) is type(()) and len(info)==3:
+        if isinstance(info, tuple) and len(info)==3:
             t, v, tb = info
         else:
             t, v, tb = sys.exc_info()
 
         content = "".join(traceback.format_tb(tb))
         logger = logging.getLogger('Zope')
-        logger.info('SOAPException: %s' % tb)
+        logger.info('SOAPException: %s' % content)
+        f=None
         if t == 'Unauthorized' or t == Unauthorized or (
            isinstance(t, types.ClassType) and issubclass(t, Unauthorized)):
             realm=self._real.realm
             if realm:
                 self._real.setHeader('WWW-Authenticate',
                                      'basic realm="%s"' % realm, 1)
-                self._real.setStatus(401)
-            return None
-
-        # Create an appropriate Fault object. Unfortunately, we throw away
-        # most of the debugging information. More useful error reporting is
-        # left as an exercise for the reader.
-        f=None
-        if not isinstance(v, Fault):
+            self._real.setStatus(401)
+            f = ZSI.Fault(Fault.Server, "Not authorized")
+        elif not isinstance(v, Fault):
+            self._real.setStatus(500)
             f = ZSI.FaultFromException(u"%s : %s" % (v, content), 0)
-        # Do the damage.
         self.setBody(f)
-        self._real.setStatus(500)
-
         return tb
 
     def _setHeader(self):



More information about the Checkins mailing list