Back to index

plone3  3.1.7
ChallengeProtocolChooser.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights
00004 # Reserved.
00005 #
00006 # This software is subject to the provisions of the Zope Public License,
00007 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this
00008 # distribution.
00009 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00010 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00011 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00012 # FOR A PARTICULAR PURPOSE.
00013 #
00014 ##############################################################################
00015 """ Classes: ChallengeProtocolChooser
00016 
00017 $Id: ChallengeProtocolChooser.py 73955 2007-03-31 14:11:32Z alecm $
00018 """
00019 
00020 from Acquisition import aq_parent
00021 from AccessControl import ClassSecurityInfo
00022 from BTrees.OOBTree import OOBTree
00023 from Globals import InitializeClass
00024 
00025 from zope.interface import Interface
00026 
00027 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
00028 
00029 from Products.PluggableAuthService.interfaces.plugins \
00030     import IRequestTypeSniffer
00031 from Products.PluggableAuthService.interfaces.plugins \
00032     import IChallengeProtocolChooser
00033 from Products.PluggableAuthService.interfaces.plugins \
00034      import IChallengePlugin
00035 from Products.PluggableAuthService.interfaces.request \
00036     import IBrowserRequest
00037 from Products.PluggableAuthService.interfaces.request \
00038     import IWebDAVRequest
00039 from Products.PluggableAuthService.interfaces.request \
00040     import IFTPRequest
00041 from Products.PluggableAuthService.interfaces.request \
00042     import IXMLRPCRequest
00043 
00044 from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
00045 from Products.PluggableAuthService.utils import classImplements
00046 
00047 class IChallengeProtocolChooserPlugin(Interface):
00048     """ Marker interface.
00049     """
00050 
00051 _request_types = ()
00052 _request_type_bmap = {}
00053 
00054 def registerRequestType(label, iface):
00055     global _request_types
00056     registry = list(_request_types)
00057     registry.append((label, iface))
00058     _request_types = tuple(registry)
00059     _request_type_bmap[iface] = label
00060 
00061 def listRequestTypesLabels():
00062     return _request_type_bmap.values()
00063 
00064 manage_addChallengeProtocolChooserForm = PageTemplateFile(
00065     'www/cpcAdd', globals(), __name__='manage_addChallengeProtocolChooserForm' )
00066 
00067 def addChallengeProtocolChooserPlugin( dispatcher, id, title=None,
00068                                        mapping=None, REQUEST=None ):
00069     """ Add a ChallengeProtocolChooserPlugin to a Pluggable Auth Service. """
00070 
00071     cpc = ChallengeProtocolChooser(id, title=title, mapping=mapping)
00072     dispatcher._setObject(cpc.getId(), cpc)
00073 
00074     if REQUEST is not None:
00075         REQUEST['RESPONSE'].redirect(
00076                                 '%s/manage_workspace'
00077                                 '?manage_tabs_message='
00078                                 'ChallengeProtocolChooser+added.'
00079                             % dispatcher.absolute_url())
00080 
00081 
00082 class ChallengeProtocolChooser( BasePlugin ):
00083 
00084     """ PAS plugin for choosing challenger protocol based on request
00085     """
00086     meta_type = 'Challenge Protocol Chooser Plugin'
00087 
00088     security = ClassSecurityInfo()
00089 
00090     manage_options = (({'label': 'Mapping',
00091                         'action': 'manage_editProtocolMapping'
00092                         },
00093                        )
00094                       + BasePlugin.manage_options
00095                       )
00096 
00097     def __init__(self, id, title=None, mapping=None):
00098         self._id = self.id = id
00099         self.title = title
00100         self._map = OOBTree()
00101         if mapping is not None:
00102             self.manage_updateProtocolMapping(mapping=mapping)
00103 
00104     security.declarePrivate('chooseProtocols')
00105     def chooseProtocols(self, request):
00106         pas_instance = self._getPAS()
00107         plugins = pas_instance._getOb('plugins')
00108 
00109         sniffers = plugins.listPlugins( IRequestTypeSniffer )
00110 
00111         for sniffer_id, sniffer in sniffers:
00112             request_type = sniffer.sniffRequestType(request)
00113             if request_type is not None:
00114                 return self._getProtocolsFor(request_type)
00115 
00116     def _getProtocolsFor(self, request_type):
00117         label = _request_type_bmap.get(request_type, None)
00118         if label is None:
00119             return
00120         return self._map.get(label, None)
00121 
00122 
00123     def _listProtocols(self):
00124         pas_instance = self._getPAS()
00125         plugins = pas_instance._getOb('plugins')
00126 
00127         challengers = plugins.listPlugins( IChallengePlugin )
00128         found = []
00129 
00130         for challenger_id, challenger in challengers:
00131             protocol = getattr(challenger, 'protocol', challenger_id)
00132             if protocol not in found:
00133                 found.append(protocol)
00134 
00135         return found
00136 
00137     manage_editProtocolMappingForm = PageTemplateFile(
00138         'www/cpcEdit', globals(),
00139         __name__='manage_editProtocolMappingForm')
00140 
00141     def manage_editProtocolMapping(self, REQUEST=None):
00142         """ Edit Protocol Mapping
00143         """
00144         info = []
00145         available_protocols = self._listProtocols()
00146 
00147         request_types = listRequestTypesLabels()
00148         request_types.sort()
00149 
00150         for label in request_types:
00151             settings = []
00152             select_any = False
00153             info.append(
00154                 {'label': label,
00155                  'settings': settings
00156                  })
00157             protocols = self._map.get(label, None)
00158             if not protocols:
00159                 select_any = True
00160             for protocol in available_protocols:
00161                 selected = False
00162                 if protocols and protocol in protocols:
00163                     selected = True
00164                 settings.append({'label': protocol,
00165                                  'selected': selected,
00166                                  'value': protocol,
00167                                  })
00168 
00169             settings.insert(0, {'label': '(any)',
00170                                 'selected': select_any,
00171                                 'value': '',
00172                                 })
00173         return self.manage_editProtocolMappingForm(info=info, REQUEST=REQUEST)
00174 
00175     def manage_updateProtocolMapping(self, mapping, REQUEST=None):
00176         """ Update mapping of Request Type to Protocols
00177         """
00178         for key, value in mapping.items():
00179             value = filter(None, value)
00180             if not value:
00181                 if self._map.has_key(key):
00182                     del self._map[key]
00183             else:
00184                 self._map[key] = value
00185 
00186         if REQUEST is not None:
00187             REQUEST['RESPONSE'].redirect(
00188                 '%s/manage_editProtocolMapping'
00189                 '?manage_tabs_message='
00190                 'Protocol+Mappings+Changed.'
00191                 % self.absolute_url())
00192 
00193 classImplements(ChallengeProtocolChooser,
00194                 IChallengeProtocolChooserPlugin,
00195                 IChallengeProtocolChooser,
00196                )
00197 
00198 InitializeClass(ChallengeProtocolChooser)
00199 
00200 for label, iface in (('Browser', IBrowserRequest),
00201                      ('WebDAV', IWebDAVRequest),
00202                      ('FTP', IFTPRequest),
00203                      ('XML-RPC', IXMLRPCRequest)):
00204     registerRequestType(label, iface)