Changeset 5674


Ignore:
Timestamp:
28/08/09 13:31:29 (10 years ago)
Author:
pjkersha
Message:

Refactoring SOAPBindingMiddleware to accept a ZSI Service binding input from an upstream middleware component.

  • siteAServer.py now loads with new soap and ZSI middleware changes.
Location:
TI12-security/trunk/python
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/attributeauthority.py

    r5667 r5674  
    1313import os 
    1414 
     15from ndg.security.server.attributeauthority import AttributeAuthority 
    1516from ndg.security.server.wsgi import NDGSecurityMiddlewareBase 
    16 from ndg.security.server.attributeauthority import AttributeAuthority 
    17  
     17from ndg.security.server.wsgi.zsi import SOAPBindingMiddleware 
    1818 
    1919class AttributeAuthorityMiddleware(NDGSecurityMiddlewareBase): 
     
    205205    @classmethod 
    206206    def filter_app_factory(cls, app, global_conf,  
    207                            prefix='attributeauthority.soapbinding.',  
    208                            **app_conf): 
     207        attributeAuthoritySOAPBindingPrefix='attributeauthority.soapbinding.',  
     208        **app_conf): 
    209209        """Set-up Attribute Authority SOAP Binding middleware using a Paste app 
    210210        factory pattern.  Overloaded base class method to enable custom  
     
    221221        dictionary 
    222222        """ 
     223        # Generic Binding middleware intercepts the SOAP_ACTION set in environ 
     224        # and maps it to the matching soap_{SOAP_ACTION} method from this class 
     225        app = SOAPBindingMiddleware.filter_app_factory(app, global_conf, 
     226                                                       **app_conf) 
     227         
    223228        app = cls(app) 
    224229        app.keyName = app_conf.get(cls.ATTRIBUTE_AUTHORITY_KEYNAME_CFG_OPTNAME, 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/soap.py

    r5637 r5674  
    3535class SOAPMiddleware(object): 
    3636    """SOAP WSGI base class""" 
    37     soapFaultSetKey = 'ndg.security.server.wsgi.soap.soapFault' 
     37    SOAP_FAULT_SET_KEYNAME = 'ndg.security.server.wsgi.soap.soapFault' 
     38    SOAP_ACTION_ENVIRON_KEYNAME = 'HTTP_SOAPACTION' 
    3839         
    39     @staticmethod 
    40     def isSOAPMessage(environ): 
     40    @classmethod 
     41    def isSOAPMessage(cls, environ): 
    4142        '''Generic method to filter out non-soap messages 
    4243         
     
    4445        generated content? - If so this test should be moved''' 
    4546        return environ.get('REQUEST_METHOD', '') == 'POST' and \ 
    46                environ.get('HTTP_SOAPACTION') is not None 
     47               environ.get(cls.SOAP_ACTION_ENVIRON_KEYNAME) is not None 
    4748 
    4849    @classmethod 
     
    5051        '''Check environment for SOAP fault flag set.  This variable is set 
    5152        from exception2SOAPFault''' 
    52         return bool(environ.get(cls.soapFaultSetKey, False)) == True 
     53        return environ.get(cls.SOAP_FAULT_SET_KEYNAME, False) == True 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/wssecurity.py

    r5648 r5674  
    3333    Overload pathMatch lambda so that it is more inclusive: the default is 
    3434    for all paths to be processed by the handlers""" 
    35     pathMatch = lambda self, environ: \ 
    36                         environ['PATH_INFO'].startswith(self.app_conf['path']) 
     35    pathMatch = lambda self, environ: environ['PATH_INFO'].startswith(self.path) 
     36 
    3737 
    3838class SignatureFilter(WSSecurityFilter): 
    3939    """Base class for WS-Security signature and signature verification filters 
    4040    """ 
    41     def __init__(self, app, app_conf, **kw): 
    42         super(SignatureFilter, self).__init__(app, app_conf, **kw) 
    43          
    44         wsseCfgFilePath = self.app_conf.get('wsseCfgFilePath')         
    45         wsseCfgFileSection = self.app_conf.get('wsseCfgFileSection') 
    46         wsseCfgFilePrefix = self.app_conf.get('wsseCfgFilePrefix') 
    47          
     41    WSSE_CFG_FILEPATH_OPTNAME = 'wsseCfgFilePath' 
     42    WSSE_CFG_FILE_SECTION_OPTNAME = 'wsseCfgFileSection' 
     43    WSSE_CFG_FILE_PREFIX_OPTNAME = 'wsseCfgFilePrefix' 
     44     
     45    def __init__(self, app): 
     46        super(SignatureFilter, self).__init__(app) 
     47        self.__signatureHandler = None 
     48         
     49    @classmethod 
     50    def filter_app_factory(cls, app, global_conf, **app_conf): 
     51        """Set-up Signature filter using a Paste app factory pattern.   
     52         
     53        @type app: callable following WSGI interface 
     54        @param app: next middleware application in the chain       
     55        @type global_conf: dict         
     56        @param global_conf: PasteDeploy global configuration dictionary 
     57        @type prefix: basestring 
     58        @param prefix: prefix for configuration items 
     59        @type app_conf: dict         
     60        @param app_conf: PasteDeploy application specific configuration  
     61        dictionary 
     62        """ 
     63        app = ZSIMiddleware.filter_app_factory(app, global_conf, **app_conf) 
     64 
    4865        # Where possible remove keywords not applicable to SignatureHandler 
    49         kw.pop('wsseCfgFilePath', None) 
    50         kw.pop('wsseCfgFileSection', None) 
    51         kw.pop('wsseCfgFilePrefix', None) 
    52          
    53         self.signatureHandler = SignatureHandler(cfg=wsseCfgFilePath, 
     66        wsseCfgFilePath = app_conf.pop(cls.WSSE_CFG_FILEPATH_OPTNAME, None) 
     67        wsseCfgFileSection = app_conf.pop(cls.WSSE_CFG_FILE_SECTION_OPTNAME,  
     68                                          None) 
     69        wsseCfgFilePrefix = app_conf.pop(cls.WSSE_CFG_FILE_PREFIX_OPTNAME, None) 
     70         
     71        app.signatureHandler = SignatureHandler(cfg=wsseCfgFilePath, 
    5472                                            cfgFileSection=wsseCfgFileSection, 
    5573                                            cfgFilePrefix=wsseCfgFilePrefix, 
    56                                             **kw) 
     74                                            **app_conf) 
     75        return app 
     76 
     77    def _getSignatureHandler(self): 
     78        return self.__signatureHandler 
     79 
     80    def _setSignatureHandler(self, value): 
     81        if not isinstance(value, SignatureHandler): 
     82            raise TypeError('Expecting %r for "signatureHandler"; got %r' % 
     83                            (SignatureHandler, type(value))) 
     84        self.__signatureHandler = value 
     85 
     86    signatureHandler = property(_getSignatureHandler,  
     87                                _setSignatureHandler,  
     88                                doc="Signature Handler Class") 
    5789            
    5890     
    5991class ApplySignatureFilter(SignatureFilter): 
    6092    '''Apply WS-Security digital signature to SOAP message''' 
    61     def __init__(self, *arg, **kw): 
    62         '''Extend SignatureFilter.__init__ to enable setting of 
    63         WS-Security signature verification filter from config''' 
    64         self.wsseSignatureVerificationFilterID = kw.pop( 
    65                                         'wsseSignatureVerificationFilterID',  
    66                                         None) 
    67          
     93    WSSE_SIGNATURE_VERIFICATION_FILTERID_OPTNAME = \ 
     94        'wsseSignatureVerificationFilterID' 
     95         
     96    def __init__(self, app): 
    6897        super(ApplySignatureFilter, self).__init__(*arg, **kw) 
     98        self.__wsseSignatureVerificationFilterID = None 
     99         
     100    @classmethod 
     101    def filter_app_factory(cls, app, global_conf, **app_conf): 
     102        """Set-up Signature filter using a Paste app factory pattern.   
     103         
     104        @type app: callable following WSGI interface 
     105        @param app: next middleware application in the chain       
     106        @type global_conf: dict         
     107        @param global_conf: PasteDeploy global configuration dictionary 
     108        @type prefix: basestring 
     109        @param prefix: prefix for configuration items 
     110        @type app_conf: dict         
     111        @param app_conf: PasteDeploy application specific configuration  
     112        dictionary 
     113        """ 
     114        app = ZSIMiddleware.filter_app_factory(app, global_conf, **app_conf) 
     115        app.wsseSignatureVerificationFilterID = app_conf.pop( 
     116                            cls.WSSE_SIGNATURE_VERIFICATION_FILTERID_OPTNAME, 
     117                            None) 
     118        return app 
     119 
     120    def _getWsseSignatureVerificationFilterID(self): 
     121        return self.__wsseSignatureVerificationFilterID 
     122 
     123 
     124    def _setWsseSignatureVerificationFilterID(self, value): 
     125        if not isinstance(value, basestring): 
     126            raise TypeError('Expecting string for ' 
     127                            '"wsseSignatureVerificationFilterID"; got %r' % 
     128                            type(value)) 
     129        self.__wsseSignatureVerificationFilterID = value 
     130 
     131    wsseSignatureVerificationFilterID = property( 
     132                                        _getWsseSignatureVerificationFilterID,  
     133                                        _setWsseSignatureVerificationFilterID,  
     134                                        doc="Keyword to reference the " 
     135                                            "Signature Verification filter if " 
     136                                            "any in the WSGI environ") 
    69137 
    70138    def __call__(self, environ, start_response): 
     
    75143                      "path doesn't match SOAP endpoint specified - skipping " 
    76144                      "signature verification") 
    77             return self.app(environ, start_response) 
     145            return self._app(environ, start_response) 
    78146         
    79147        log.debug('Signing outbound message ...') 
     
    108176            sw = self.exception2SOAPFault(environ, e) 
    109177            self.setSOAPWriter(environ, sw) 
    110  
    111              
     178          
    112179        try: 
    113180            self.signatureHandler.sign(sw) 
     
    129196                      "request or path doesn't match SOAP endpoint specified " 
    130197                      "- skipping signature verification") 
    131             return self.app(environ, start_response) 
     198            return self._app(environ, start_response) 
    132199 
    133200        log.debug("Verifying inbound message signature...") 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/zsi.py

    r5667 r5674  
    3939    '''Middleware configurable to a given ZSI SOAP binding'''   
    4040     
    41     soapWriterKey = 'ZSI.writer.SoapWriter' 
    42     parsedSOAPKey = 'ZSI.parse.ParsedSoap' 
    43     soapFaultSetKey = 'ndg.security.server.wsgi.soap.soapFault' 
    44      
    45     def __init__(self, app, app_conf, **kw): 
     41    SOAP_WRITER_KEYNAME = 'ZSI.writer.SoapWriter' 
     42    PARSED_SOAP_KEYNAME = 'ZSI.parse.ParsedSoap' 
     43     
     44    CHARSET_OPTNAME = 'charset' 
     45    DEFAULT_CHARSET = '; charset=utf-8' 
     46    PATH_OPTNAME = 'path' 
     47    WRITE_RESPONSE_OPTNAME = 'writeResponse' 
     48    REFERENCED_FILTERS_OPTNAME = 'referencedFilters' 
     49    PUBLISHED_URI_OPTNAME = 'publishedURI' 
     50    READER_CLASS_OPTNAME = 'readerclass' 
     51    WRITERCLASS_OPTNAME = 'writerclass' 
     52     
     53    def __init__(self, app): 
    4654        log.debug("ZSIMiddleware.__init__ ...") 
    47         self.app = app 
    48         self.app_conf = app_conf 
    49         self.app_conf.update(kw) 
    50          
    51         if 'charset' in self.app_conf: 
    52             self.app_conf['charset'] = '; charset=' + self.app_conf['charset'] 
     55        super(ZSIMiddleware, self).__init__() 
     56         
     57        self._app = app 
     58        self.__charset = ZSIMiddleware.DEFAULT_CHARSET 
     59        self.__path = None 
     60        self.__referencedFilterKeys = None 
     61        self.__publishedURI = None 
     62        self.__readerClass = None 
     63        self.__writerClass = None 
     64        self.__writeResponseSet = None 
     65 
     66    def _getCharset(self): 
     67        return self.__charset 
     68 
     69    def _setCharset(self, value): 
     70        self.__charset = value 
     71 
     72    def _getPath(self): 
     73        return self.__path 
     74 
     75    def _setPath(self, value): 
     76        self.__path = value 
     77 
     78    def _getPublishedURI(self): 
     79        return self.__publishedURI 
     80 
     81    def _setPublishedURI(self, value): 
     82        self.__publishedURI = value 
     83 
     84    def _getReaderClass(self): 
     85        return self.__readerClass 
     86 
     87    def _setReaderClass(self, value): 
     88        self.__readerClass = value 
     89 
     90    def _getWriterClass(self): 
     91        return self.__writerClass 
     92 
     93    def _setWriterClass(self, value): 
     94        self.__writerClass = value 
     95 
     96    def _getWriteResponseSet(self): 
     97        return self.__writeResponseSet 
     98 
     99    def _setWriteResponseSet(self, value): 
     100        self.__writeResponseSet = value 
     101 
     102    def _getFilterID(self): 
     103        return self.__filterID 
     104 
     105    def _setFilterID(self, value): 
     106        self.__filterID = value 
     107 
     108    charset = property(_getCharset, _setCharset,  
     109                       doc="character set for response") 
     110 
     111    path = property(_getPath, _setPath, doc="Path for endpoint") 
     112 
     113    publishedURI = property(_getPublishedURI, _setPublishedURI,  
     114                            doc="fully qualified path for endpoint") 
     115 
     116    readerClass = property(_getReaderClass, _setReaderClass,  
     117                           doc="ZSI Reader class") 
     118 
     119    writeResponseSet = property(_getWriteResponseSet, _setWriteResponseSet,  
     120                                doc="boolean set to True to write out a " 
     121                                    "response from this middleware") 
     122 
     123    writerClass = property(_getWriterClass, _setWriterClass,  
     124                           doc="ZSI Writer Class") 
     125 
     126    filterID = property(_getFilterID, _setFilterID,  
     127                        doc="enable the instance of this middleware to be " 
     128                            "referenced in environ by this identifier") 
     129 
     130    @classmethod 
     131    def filter_app_factory(cls, app, global_conf, **app_conf): 
     132        app = cls(app) 
     133         
     134        if ZSIMiddleware.CHARSET_OPTNAME in app_conf: 
     135            app.charset = '; charset='+app_conf[ZSIMiddleware.CHARSET_OPTNAME] 
    53136        else: 
    54             self.app_conf['charset'] = '; charset=utf-8' 
    55  
    56         if 'path' in self.app_conf: 
    57             if self.app_conf['path'] != '/': 
    58                 self.app_conf['path'] = self.app_conf['path'].rstrip('/') 
     137            app.charset = '; charset=utf-8' 
     138 
     139        if ZSIMiddleware.PATH_OPTNAME in app_conf: 
     140            if app_conf[ZSIMiddleware.PATH_OPTNAME] != '/': 
     141                app.path = app_conf[ZSIMiddleware.PATH_OPTNAME].rstrip('/') 
     142            else: 
     143                app.path = app_conf[ZSIMiddleware.PATH_OPTNAME] 
    59144        else: 
    60             self.app_conf['path'] = '/' 
     145            app.path = '/' 
    61146 
    62147        # This flag if set to True causes this handler to call the  
    63148        # start_response method and output the SOAP response 
    64         self.writeResponseSet = self.app_conf.get('writeResponse', 
    65                                                   'false').lower() == 'true' 
     149        app.writeResponseSet = app_conf.get( 
     150                                        ZSIMiddleware.WRITE_RESPONSE_OPTNAME, 
     151                                        'false').lower() == 'true' 
    66152 
    67153        # Check for a list of other filters to be referenced by this one 
    68         if 'referencedFilters' in self.app_conf: 
     154        if ZSIMiddleware.REFERENCED_FILTERS_OPTNAME in app_conf: 
    69155            # __call__  may reference any filters in environ keyed by these 
    70156            # keywords 
    71             self.referencedFilterKeys = self.app_conf.pop( 
    72                                                 'referencedFilters').split() 
    73                                  
    74             # Remove equivalent keyword if present 
    75             kw.pop('referencedFilters', None) 
     157            app.referencedFilterKeys = app_conf.pop( 
     158                            ZSIMiddleware.REFERENCED_FILTERS_OPTNAME).split() 
     159 
    76160             
    77161        # The endpoint that this services will be referenced from externally. 
     
    79163        # input URI and compare with this value to see if the request is  
    80164        # actually to the local Session Manager instance 
    81         if 'publishedURI' in self.app_conf: 
    82             self.publishedURI = self.app_conf.pop('publishedURI') 
    83              
    84         if 'readerclass' in self.app_conf: 
    85             self.readerclass = importClass(self.app_conf.pop('readerclass')) 
     165        app.publishedURI = app_conf.pop(ZSIMiddleware.PUBLISHED_URI_OPTNAME, 
     166                                        None) 
     167             
     168        if ZSIMiddleware.READER_CLASS_OPTNAME in app_conf: 
     169            readerClassName = app_conf.pop(ZSIMiddleware.READER_CLASS_OPTNAME) 
     170            app.readerClass = importClass(readerClassName) 
    86171        else: 
    87             self.readerclass = DomletteReader 
    88          
    89         if 'writerclass' in self.app_conf: 
    90             self.writerclass = importClass(self.app_conf.pop('writerclass')) 
     172            app.readerClass = DomletteReader 
     173         
     174        if ZSIMiddleware.WRITERCLASS_OPTNAME in app_conf: 
     175            writerClassName = app_conf.pop(ZSIMiddleware.WRITERCLASS_OPTNAME) 
     176            app.writerClass = importClass(writerClassName) 
    91177        else: 
    92             self.writerclass = DomletteElementProxy 
     178            app.writerClass = DomletteElementProxy 
     179             
     180        return app 
    93181             
    94182 
     
    119207        if not self.__class__.isSOAPMessage(environ): 
    120208            log.debug("ZSIMiddleware.__call__: skipping non-SOAP call") 
    121             return self.app(environ, start_response) 
     209            return self._app(environ, start_response) 
    122210         
    123211        elif not self.pathMatch(environ): 
    124212            log.debug("ZSIMiddleware.__call__: path doesn't match SOAP " 
    125213                      "service endpoint") 
    126             return self.app(environ, start_response) 
     214            return self._app(environ, start_response) 
    127215         
    128216        elif self.__class__.isSOAPFaultSet(environ): 
     
    132220            log.debug("ZSIMiddleware.__call__: SOAP fault set by previous " 
    133221                      "SOAP middleware filter") 
    134             return self.app(environ, start_response) 
     222            return self._app(environ, start_response) 
    135223 
    136224        # Parse input into a ZSI ParsedSoap object set as a key in environ 
     
    151239                                             None, 
    152240                                             tb=sys.exc_info()[2]) 
    153         sw = SoapWriter(outputclass=self.writerclass) 
     241        sw = SoapWriter(outputclass=self.writerClass) 
    154242        soapFault.serialize(sw) 
    155         environ[ZSIMiddleware.soapFaultSetKey] = 'True' 
     243        environ[ZSIMiddleware.SOAP_FAULT_SET_KEYNAME] = True 
    156244        return sw 
    157245     
    158     pathMatch = lambda self,environ:environ['PATH_INFO']==self.app_conf['path'] 
     246    pathMatch = lambda self, environ: environ['PATH_INFO'] == self.path 
    159247     
    160248    def parseRequest(self, environ): 
     
    172260        # Check for ParsedSoap object set in environment, if not present, 
    173261        # make one 
    174         ps = environ.get(ZSIMiddleware.parsedSOAPKey) 
     262        ps = environ.get(ZSIMiddleware.PARSED_SOAP_KEYNAME) 
    175263        if ps is None: 
    176264            # TODO: allow for chunked data 
     
    187275            log.debug("_" * 80) 
    188276             
    189             ps = ParsedSoap(soapIn, readerclass=self.readerclass) 
    190             environ[ZSIMiddleware.parsedSOAPKey] = ps 
    191              
    192         return environ[ZSIMiddleware.parsedSOAPKey] 
     277            ps = ParsedSoap(soapIn, readerclass=self.readerClass) 
     278            environ[ZSIMiddleware.PARSED_SOAP_KEYNAME] = ps 
     279             
     280        return environ[ZSIMiddleware.PARSED_SOAP_KEYNAME] 
    193281 
    194282 
     
    202290        # this handler 
    203291        if self.writeResponseSet == False: 
    204             return self.app(environ, start_response) 
     292            return self._app(environ, start_response) 
    205293         
    206294        sw = self.getSOAPWriter(environ) 
    207295        soapOut = str(sw) 
    208         charset = self.app_conf['charset'] 
    209296         
    210297        if errorCode is None: 
     
    219306        log.debug("_" * 80) 
    220307        start_response(errorCode, 
    221                        [('content-type', 'text/xml' + charset), 
     308                       [('content-type', 'text/xml' + self.charset), 
    222309                        ('content-length', str(len(soapOut)))]) 
    223310        return soapOut 
     
    228315        method''' 
    229316         
    230         sw = environ.get(ZSIMiddleware.soapWriterKey) 
     317        sw = environ.get(ZSIMiddleware.SOAP_WRITER_KEYNAME) 
    231318        if sw is None: 
    232319            raise KeyError("Expecting '%s' key in environ: missing call to " 
    233                            "ZSIMiddleware?" % ZSIMiddleware.soapWriterKey) 
     320                           "ZSIMiddleware?" % ZSIMiddleware.SOAP_WRITER_KEYNAME) 
    234321        return sw 
    235322     
     
    237324    def setSOAPWriter(cls, environ, sw): 
    238325        '''Set SoapWriter object in environment'''    
    239         environ[ZSIMiddleware.soapWriterKey] = sw 
     326        environ[ZSIMiddleware.SOAP_WRITER_KEYNAME] = sw 
    240327 
    241328    def addFilter2Environ(self, environ): 
     
    243330        other middleware can reference it.  This is dependent on filterID set 
    244331        in app_conf''' 
    245         filterID = self.app_conf.get('filterID') 
    246         if filterID is not None:            
    247             if filterID in environ: 
     332        if self.filterID is not None:            
     333            if self.filterID in environ: 
    248334                raise ZSIMiddlewareConfigError("An filterID key '%s' is " 
    249335                                                "already set in environ" %  
    250                                                 filterID) 
    251             environ[filterID] = self 
     336                                                self.filterID) 
     337            environ[self.filterID] = self 
    252338 
    253339 
    254340class SOAPBindingMiddleware(ZSIMiddleware):   
    255     '''Apply a ZSI ServiceSOAPBinding type SOAP service''' 
    256           
    257     def __init__(self, *arg, **kw): 
    258          
    259         super(SOAPBindingMiddleware, self).__init__(*arg, **kw) 
     341    '''Interface to apply a ZSI ServiceSOAPBinding type SOAP service''' 
     342     
     343    SERVICE_SOAP_BINDING_CLASSNAME_OPTNAME = 'serviceSOAPBindingClass' 
     344    SERVICE_SOAP_BINDING_PROPPREFIX_OPTNAME = 'serviceSOAPBindingPropPrefix' 
     345    DEFAULT_SERVICE_SOAP_BINDING_PROPPREFIX_OPTNAME = \ 
     346                            'ndg.security.servier.wsgi.zsi.serviceSOAPBinding.' 
     347                             
     348    SERVICE_SOAP_BINDING_ENVIRON_KEYNAME_OPTNAME = \ 
     349                            'serviceSOAPBindingEnvironKeyName'  
     350    DEFAULT_SERVICE_SOAP_BINDING_ENVIRON_KEYNAME = \ 
     351                            'ndg.security.servier.wsgi.zsi.serviceSOAPBinding' 
     352    ENABLE_WSDL_QUERY_OPTNAME = 'enableWSDLQuery'  
     353    DEFAULT_ENABLE_WSDL_QUERY_VALUE = False 
     354    SOAP_METHOD_STRING = 'soap_%s' 
     355     
     356    _str2Bool = lambda str: str.lower() in ["yes", "true", "t", "1"] 
     357    str2Bool = staticmethod(_str2Bool) 
     358     
     359    def __init__(self, app): 
     360        super(SOAPBindingMiddleware, self).__init__(app) 
     361        self.__serviceSOAPBindingKeyName = None 
    260362        self.__serviceSOAPBinding = None 
    261363        self.__enableWSDLQuery = False 
    262  
     364         
    263365    def _getServiceSOAPBinding(self): 
    264366        return self.__serviceSOAPBinding 
     
    267369        """Instance must be ZSI ServiceSOAPBinding derived type""" 
    268370        if not isinstance(value, ServiceSOAPBinding): 
     371            raise TypeError('Expecting %r type for "serviceSOAPBinding"; got ' 
     372                            '%r' % (ServiceSOAPBinding, type(value))) 
     373        self.__serviceSOAPBinding = value 
     374 
     375    serviceSOAPBinding = property(fget=_getServiceSOAPBinding,  
     376                                  fset=_setServiceSOAPBinding,  
     377                                  doc="Instance of ZSI ServiceSOAPBinding " 
     378                                      "derived type determines the behaviour " 
     379                                      "of the SOAP callbacks") 
     380 
     381    def _getServiceSOAPBindingKeyName(self): 
     382        return self.__serviceSOAPBindingKeyName 
     383 
     384    def _setServiceSOAPBindingKeyName(self, value): 
     385        """Instance must be ZSI ServiceSOAPBindingKeyName derived type""" 
     386        if not isinstance(value, basestring): 
    269387            raise TypeError('Expecting bool type for "enableWSDLQuery"; got ' 
    270388                            '%r' % type(value)) 
    271         self.__serviceSOAPBinding = value 
    272  
    273     serviceSOAPBinding = property(fget=_getServiceSOAPBinding,  
    274                                   fset=_setServiceSOAPBinding,  
    275                                   doc="ServiceSOAPBinding's Docstring") 
     389        self.__serviceSOAPBindingKeyName = value 
     390 
     391    serviceSOAPBindingKeyName = property(fget=_getServiceSOAPBindingKeyName,  
     392                                         fset=_setServiceSOAPBindingKeyName,  
     393                                         doc="Keyword to key WSGI environ for " 
     394                                             "SOAP Binding middleware instance") 
    276395 
    277396    def _getEnableWSDLQuery(self): 
     
    286405    enableWSDLQuery = property(fget=_getEnableWSDLQuery,  
    287406                               fset=_setEnableWSDLQuery,  
    288                                doc="EnableWSDLQuery's Docstring") 
    289  
    290          
    291 #        # Check for Service binding in config 
    292 #        if 'ServiceSOAPBindingClass' in self.app_conf: 
    293 #            modName, className = \ 
    294 #                        self.app_conf['ServiceSOAPBindingClass'].rsplit('.', 1) 
    295 # 
    296 #            self.serviceSOAPBinding = instantiateClass(modName, 
    297 #                                   className, 
    298 #                                   objectType=ServiceSOAPBinding, 
    299 #                                   classProperties=self.serviceSOAPBindingKw)             
    300 #        else:  
    301 #            self.serviceSOAPBinding = ServiceSOAPBinding() 
    302 #         
    303 #        # Flag to enable display of WSDL via wsdl query arg in a GET request 
    304 #        self.enableWSDLQuery = self.app_conf.get('enableWSDLQuery', False) and\ 
    305 #                                hasattr(self.serviceSOAPBinding, '_wsdl') 
     407                               doc="Enable service to publish the WSDL via " 
     408                                   "the ?wsdl query argument appended to the " 
     409                                   "endpoint") 
     410 
    306411 
    307412    @classmethod 
    308     def filter_app_factory(cls, app, global_conf, **app_conf): 
    309          
    310         app = cls(app) 
    311          
    312         # Check for Service binding in config 
    313         if 'ServiceSOAPBindingClass' in app.app_conf: 
    314             modName, className = \ 
    315                             app_conf['ServiceSOAPBindingClass'].rsplit('.', 1) 
    316  
    317             self.serviceSOAPBinding = instantiateClass(modName, 
    318                                    className, 
    319                                    objectType=ServiceSOAPBinding, 
    320                                    classProperties=self.serviceSOAPBindingKw)             
     413    def filter_app_factory(cls, app, global_conf, prefix='', **app_conf): 
     414        """Set-up ZSI SOAP Binding middleware interface using a Paste app 
     415        factory pattern.  Overloaded base class method to enable custom  
     416        settings from app_conf 
     417         
     418        @type app: callable following WSGI interface 
     419        @param app: next middleware application in the chain       
     420        @type global_conf: dict         
     421        @param global_conf: PasteDeploy global configuration dictionary 
     422        @type prefix: basestring 
     423        @param prefix: prefix for configuration items 
     424        @type app_conf: dict         
     425        @param app_conf: PasteDeploy application specific configuration  
     426        dictionary 
     427        """ 
     428        app = ZSIMiddleware.filter_app_factory(app, global_conf, **app_conf) 
     429         
     430        serviceSOAPBindingEnvironKeyNameOptName = prefix + \ 
     431                            cls.SERVICE_SOAP_BINDING_ENVIRON_KEYNAME_OPTNAME 
     432        serviceSOAPBindingClassNameOptName = prefix + \ 
     433                            cls.SERVICE_SOAP_BINDING_CLASSNAME_OPTNAME 
     434                             
     435        if serviceSOAPBindingEnvironKeyNameOptName and \ 
     436           serviceSOAPBindingClassNameOptName in app_conf: 
     437            raise ZSIMiddlewareConfigError('Only "%s" or "%s" may be set; not ' 
     438                            ' both' %  
     439                            (cls.SERVICE_SOAP_BINDING_ENVIRON_KEYNAME_OPTNAME, 
     440                             cls.SERVICE_SOAP_BINDING_CLASSNAME_OPTNAME)) 
     441             
     442        if serviceSOAPBindingClassNameOptName in app_conf: 
     443            # Instantiate the binding from the config settings 
     444            modName, className = app_conf[ 
     445                            serviceSOAPBindingClassNameOptName].rsplit('.', 1) 
     446                 
     447            # Filter 
     448            prefixOptName = prefix + cls.SERVICE_SOAP_BINDING_PROPPREFIX_OPTNAME 
     449            prefix = app_conf.get(prefixOptName, 
     450                        cls.DEFAULT_SERVICE_SOAP_BINDING_PROPPREFIX_OPTNAME) 
     451             
     452            serviceSOAPBindingKw = dict([(k.replace(prefix, ''), v) 
     453                                         for k, v in app_conf.items() 
     454                                         if k.startswith(prefix)]) 
     455     
     456            app.serviceSOAPBinding = instantiateClass(modName, 
     457                                       className, 
     458                                       objectType=ServiceSOAPBinding, 
     459                                       classProperties=serviceSOAPBindingKw)            
    321460        else:  
    322             self.serviceSOAPBinding = ServiceSOAPBinding() 
     461            # Alternatively, reference another binding instance made available 
     462            # by upstream middleware via environ 
     463            app.serviceSOAPBindingKeyName = app_conf.get( 
     464                            serviceSOAPBindingEnvironKeyNameOptName, 
     465                            cls.DEFAULT_SERVICE_SOAP_BINDING_ENVIRON_KEYNAME) 
     466         
    323467         
    324468        # Flag to enable display of WSDL via wsdl query arg in a GET request 
    325         app.enableWSDLQuery = self.app_conf.get('enableWSDLQuery', False) and\ 
    326                                 hasattr(self.serviceSOAPBinding, '_wsdl') 
    327                                  
    328         # Check for WSGI Service SOAP Binding 
    329         if callable(self.serviceSOAPBinding): 
    330             app = self.serviceSOAPBinding(app) 
    331              
     469        enableWSDLQueryOptName = prefix + cls.ENABLE_WSDL_QUERY_OPTNAME 
     470        app.enableWSDLQuery = cls.str2Bool(app_conf.get(enableWSDLQueryOptName, 
     471                                                        ''))    
    332472        return app 
    333      
    334     def _getServiceSOAPBindingKw(self): 
    335         '''Extract keywords to specific to SOAP Service Binding set in app_conf 
    336         ''' 
    337         if 'ServiceSOAPBindingPropPrefix' not in self.app_conf: 
    338             return {} 
    339          
    340         prefix = self.app_conf['ServiceSOAPBindingPropPrefix'] + '.' 
    341         serviceSOAPBindingKw = dict([(k.replace(prefix, ''), v) \ 
    342                                      for k, v in self.app_conf.items() \ 
    343                                      if k.startswith(prefix)]) 
    344         return serviceSOAPBindingKw 
    345      
    346     serviceSOAPBindingKw = property(fget=_getServiceSOAPBindingKw) 
    347473     
    348474    def __call__(self, environ, start_response): 
    349475        log.debug("SOAPBindingMiddleware.__call__ ...") 
    350                  
     476              
     477        # Get a reference to the service SOAP binding from environ or if not, 
     478        # from the binding instantiated at initialisation 
     479        serviceSOAPBinding = environ.get(self.serviceSOAPBindingKeyName, 
     480                                         self.serviceSOAPBinding) 
     481                        
    351482        if self.pathMatch(environ) and self.enableWSDLQuery and \ 
    352483           environ.get('REQUEST_METHOD', '') == 'GET' and \ 
    353484           environ.get('QUERY_STRING', '') == 'wsdl': 
    354             wsdl = self.serviceSOAPBinding._wsdl 
     485            wsdl = serviceSOAPBinding._wsdl 
    355486            start_response("200 OK", [('Content-type', 'text/xml'), 
    356487                                      ('Content-length', str(len(wsdl)))]) 
     
    361492        if response is not None: 
    362493            return response 
    363                  
     494           
    364495        try: 
    365496            # Other filters in the middleware chain may be passed by setting 
     
    369500            if hasattr(self, 'referencedFilterKeys'): 
    370501                try: 
    371                     self.serviceSOAPBinding.referencedWSGIFilters = \ 
     502                    serviceSOAPBinding.referencedWSGIFilters = \ 
    372503                                    dict([(i, environ[i])  
    373504                                          for i in self.referencedFilterKeys]) 
    374505                except KeyError: 
    375506                    raise ZSIMiddlewareConfigError('No filter ID "%s" found ' 
    376                                                     'in environ' % i)     
     507                                                   'in environ' % i)     
    377508            ps = self.parseRequest(environ) 
    378509                
    379510            # Map SOAP Action to method in binding class 
    380             soapMethodName = 'soap_%s' % environ['HTTP_SOAPACTION'].strip('"') 
    381              
    382             method = getattr(self.serviceSOAPBinding, soapMethodName)             
     511            soapActionName = environ[ 
     512                            SOAPBindingMiddleware.SOAP_ACTION_ENVIRON_KEYNAME 
     513                            ].strip('"') 
     514            soapMethodName = SOAPBindingMiddleware.SOAP_METHOD_STRING % \ 
     515                            soapActionName 
     516                     
     517             
     518            method = getattr(serviceSOAPBinding, soapMethodName)             
    383519            resp = method(ps) 
    384520        except Exception, e: 
     
    386522        else:  
    387523            # Serialize output using SOAP writer class 
    388             sw = SoapWriter(outputclass=self.writerclass) 
     524            sw = SoapWriter(outputclass=self.writerClass) 
    389525            sw.serialize(resp) 
    390526         
    391527        # Make SoapWriter object available to any SOAP filters that follow 
    392528        self.setSOAPWriter(environ, sw) 
    393          
    394529        soapOut = str(sw) 
    395         charset = self.app_conf['charset'] 
    396530 
    397531        return self.writeResponse(environ, start_response) 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/config/attributeauthority/sitea/site-a.ini

    r5667 r5674  
    3030pipeline = AttributeAuthorityFilter  
    3131                   wsseSignatureVerificationFilter  
    32                    AttributeAuthoritySOAPBindingFilter 
    33                    SOAPServiceBindingFilter 
     32                   AttributeAuthorityWsdlSoapBindingFilter 
    3433                   wsseSignatureFilter  
    35                    AttributeAuthoritySAMLSoapBindingFilter 
     34                   AttributeAuthoritySamlSoapBindingFilter 
    3635                   mainApp 
    3736 
     
    3938[filter:AttributeAuthorityFilter] 
    4039paste.filter_app_factory = ndg.security.server.wsgi.attributeauthority:AttributeAuthorityMiddleware.filter_app_factory 
    41 prefix = attributeauthority. 
     40prefix = attributeAuthority. 
    4241 
    4342# Key name by which the WSDL SOAP based interface may reference this 
    4443# service 
    45 attributeauthority.environKeyName = %(attributeAuthorityEnvironKeyName)s 
     44attributeAuthority.environKeyName = %(attributeAuthorityEnvironKeyName)s 
    4645 
    4746# Key name for the SAML SOAP binding based interface to reference this 
     
    8786 
    8887# SOAP WSDL Based Binding to the Attribute Authority 
    89 [filter:AttributeAuthoritySOAPBindingFilter] 
    90 paste.filter_app_factory = ndg.security.server.wsgi.zsi:SOAPBindingMiddleware 
    91 ServiceSOAPBindingClass = ndg.security.server.wsgi.attributeauthority.AttributeAuthoritySOAPBindingMiddleware.filter_app_factory 
    92 ServiceSOAPBindingPropPrefix = attributeauthority.soapbinding. 
    93 attributeauthority.soapbinding.attributeAuthorityEnvironKeyName = %(attributeAuthorityEnvironKeyName)s 
    94 attributeauthority.soapbinding.wsseSignatureVerificationFilterID = wsseSignatureVerificationFilter01 
     88[filter:AttributeAuthorityWsdlSoapBindingFilter] 
     89paste.filter_app_factory = ndg.security.server.wsgi.attributeauthority:AttributeAuthoritySOAPBindingMiddleware.filter_app_factory 
     90prefix = service.soap.binding. 
     91attributeAuthoritySOAPBindingPrefix = attributeauthority.service.soap.binding. 
    9592 
    96 referencedFilters = wsseSignatureVerificationFilter01 
    97 path = /AttributeAuthority 
    98 enableWSDLQuery = True 
    99 charset = utf-8 
     93service.soap.binding.referencedFilters = wsseSignatureVerificationFilter01 
     94service.soap.binding.path = /AttributeAuthority 
     95service.soap.binding.enableWSDLQuery = True 
     96service.soap.binding.charset = utf-8 
     97service.soap.binding.serviceSOAPBindingEnvironKeyName = ndg.security.server.wsgi.attributeauthority.AttributeAuthoritySOAPBindingMiddleware 
     98 
     99attributeauthority.service.soap.binding.attributeAuthorityEnvironKeyName = %(attributeAuthorityEnvironKeyName)s 
     100attributeauthority.service.soap.binding.wsseSignatureVerificationFilterID = wsseSignatureVerificationFilter01 
    100101 
    101102 
    102103# SAML SOAP Binding to the Attribute Authority 
    103 [filter:AttributeAuthoritySAMLSoapBindingFilter] 
     104[filter:AttributeAuthoritySamlSoapBindingFilter] 
    104105paste.filter_app_factory = ndg.security.server.wsgi.saml:SOAPAttributeInterfaceMiddleware.filter_app_factory 
    105106prefix = saml.soapbinding. 
     
    110111 
    111112[filter:wsseSignatureVerificationFilter] 
    112 paste.filter_app_factory = ndg.security.server.wsgi.wssecurity:SignatureVerificationFilter 
     113paste.filter_app_factory = ndg.security.server.wsgi.wssecurity:SignatureVerificationFilter.filter_app_factory 
    113114filterID = wsseSignatureVerificationFilter01 
    114115 
    115116[filter:wsseSignatureFilter] 
    116 paste.filter_app_factory = ndg.security.server.wsgi.wssecurity:ApplySignatureFilter 
     117paste.filter_app_factory = ndg.security.server.wsgi.wssecurity:ApplySignatureFilter.filter_app_factory 
    117118 
    118119# Reference the verification filter in order to be able to apply signature 
Note: See TracChangeset for help on using the changeset viewer.