Changeset 4090 for TI12-security


Ignore:
Timestamp:
04/08/08 16:13:15 (11 years ago)
Author:
pjkersha
Message:

ndg.security.server.wsgi.openid_provider: fixes for login and main page.

File:
1 edited

Legend:

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

    r4082 r4090  
    1616import logging 
    1717log = logging.getLogger(__name__) 
     18_debugLevel = log.getEffectiveLevel() <= logging.DEBUG 
    1819 
    1920import paste.request 
     
    2728import httplib 
    2829import sys 
     30import cgi 
     31quoteattr = lambda s: '"%s"' % cgi.escape(s, 1) 
     32 
    2933 
    3034class OpenIDProviderMiddlewareError(Exception): 
     
    4044                   path_yadis='/yadis', 
    4145                   path_serveryadis='/serveryadis', 
    42                    path_allow='/allow')  
     46                   path_allow='/allow', 
     47                   path_mainpage='/')  
    4348        
    4449    def __init__(self, app,  
     
    4752                 data_path='./', 
    4853                 charset=None, 
     54                 trace=True,#False, 
    4955                 **kw): 
    5056        invalidKw=[k for k in kw if k not in OpenIDProviderMiddleware.defPaths] 
     
    6672        else: 
    6773            self.charset = '; charset='+charset 
     74         
     75        # If True and debug log level is set display content of response 
     76        self._trace = trace 
    6877         
    6978        self.user = None 
     
    107116            log.debug("Calling method %s ..." % self.method[pathMatch])  
    108117             
    109             action = getattr(self, self.method[pathMatch])  
    110             return action(environ, start_response) 
     118            action = getattr(self, self.method[pathMatch]) 
     119            response = action(environ, start_response)  
     120            if self._trace and _debugLevel: 
     121                if isinstance(response, list): 
     122                    log.debug('Output for %s:\n%s', self.method[pathMatch], 
     123                                                    ''.join(response)) 
     124                else: 
     125                    log.debug('Output for %s:\n%s', self.method[pathMatch], 
     126                                                    response) 
     127                     
     128            return response 
    111129        else: 
    112130            log.debug("No match for path %s" % self.path) 
     
    116134    def do_id(self, environ, start_response): 
    117135        '''Handle ID request''' 
    118         log.debug("OpenIDProviderMiddleware.do_id ...") 
    119          
    120         link_tag = '<link rel="openid.server" href="%s%sr">' % \ 
     136         
     137        link_tag = '<link rel="openid.server" href="%s%s">' % \ 
    121138              (self.base_url, self.paths['path_openidserver']) 
    122139        yadis_loc_tag = '<meta http-equiv="x-xrds-location" content="%s">'%\ 
     
    146163                            ''' % (ident, msg)) 
    147164 
    148  
    149     def do_yadis(self, environ, start_response): 
    150         """Generate Yadis document""" 
    151         log.debug("OpenIDProviderMiddleware.do_yadis ...") 
    152  
    153         self.user = self.path.split('/')[-1] 
    154          
    155         endpoint_url = self.base_url + self.paths['path_openidserver'] 
    156         user_url = self.base_url + self.paths['path_id'] + '/' + self.user 
    157         response = """\ 
     165    tmplYadis = """\ 
    158166<?xml version="1.0" encoding="UTF-8"?> 
    159167<xrds:XRDS 
     
    163171 
    164172    <Service priority="0"> 
    165       <Type>%s</Type> 
    166       <Type>%s</Type> 
    167       <URI>%s</URI> 
    168       <LocalID>%s</LocalID> 
     173      <Type>%(openid20type)s</Type> 
     174      <Type>%(openid10type)s</Type> 
     175      <URI>%(endpoint_url)s</URI> 
     176      <LocalID>%(user_url)s</LocalID> 
    169177    </Service> 
    170178 
    171179  </XRD> 
    172 </xrds:XRDS> 
    173 """ % (discover.OPENID_2_0_TYPE, discover.OPENID_1_0_TYPE, 
    174      endpoint_url, user_url) 
     180</xrds:XRDS>""" 
     181 
     182    def do_yadis(self, environ, start_response): 
     183        """Generate Yadis document""" 
     184 
     185        self.user = self.path.split('/')[-1] 
     186         
     187        endpoint_url = self.base_url + self.paths['path_openidserver'] 
     188        user_url = self.base_url + self.paths['path_id'] + '/' + self.user 
     189         
     190        yadisDict = dict(openid20type=discover.OPENID_2_0_TYPE,  
     191                         openid10type=discover.OPENID_1_0_TYPE, 
     192                         endpoint_url=endpoint_url,  
     193                         user_url=user_url) 
     194         
     195        response = OpenIDProviderMiddleware.tmplYadis % yadisDict 
    175196      
    176197        start_response('200 OK', 
    177             [ 
    178                 ('Content-type', 'application/xrds+xml' + self.charset), 
    179                 ('Content-length', str(len(response))) 
    180             ]) 
     198                    [('Content-type', 'application/xrds+xml' + self.charset), 
     199                     ('Content-length', str(len(response)))]) 
    181200        return response 
    182201 
     
    184203    def do_openidserver(self, environ, start_response): 
    185204        """Handle OpenID Server Request""" 
    186         log.debug("OpenIDProviderMiddleware.do_openidserver ...") 
    187205 
    188206        try: 
     
    205223        """Handle allow request - user allow credentials to be passed back to 
    206224        the Relying Party?""" 
    207         log.debug("OpenIDProviderMiddleware.do_openidserver ...") 
    208225         
    209226        # pretend this next bit is keying off the user's session or something, 
     
    228245 
    229246        elif 'no' in self.query: 
     247            # TODO: Check 'no' response is OK - no causes AuthKit's Relying  
     248            # Party implementation to crash with 'openid.return_to' KeyError 
     249            # in uthkit.authenticate.open_id.process 
    230250            response = request.answer(False) 
    231251 
     
    234254 
    235255        return self._displayResponse(response) 
    236  
     256     
     257    tmplServerYadis = """\ 
     258<?xml version="1.0" encoding="UTF-8"?> 
     259<xrds:XRDS 
     260    xmlns:xrds="xri://$xrds" 
     261    xmlns="xri://$xrd*($v*2.0)"> 
     262  <XRD> 
     263 
     264    <Service priority="0"> 
     265      <Type>%(openid20type)s</Type> 
     266      <URI>%(endpoint_url)s</URI> 
     267    </Service> 
     268 
     269  </XRD> 
     270</xrds:XRDS> 
     271""" 
     272 
     273    def do_serveryadis(self, environ, start_response): 
     274        """Handle Server Yadis call""" 
     275        start_response("200 OK", [('Content-type', 'application/xrds+xml')]) 
     276         
     277        endpoint_url = self.base_url + self.paths['path_openidserver'] 
     278        return [OpenIDProviderMiddleware.tmplServerYadis % \ 
     279                {'openid20type': discover.OPENID_IDP_2_0_TYPE,  
     280                 'endpoint_url': endpoint_url}] 
     281 
     282 
     283    def do_login(self, environ, start_response): 
     284         
     285        success_to, fail_to = (self.paths['path_mainpage'],)*2 
     286         
     287        return self._showPage(200, 'Login Page', form='''\ 
     288        <h2>Login</h2> 
     289        <p>You may log in with any name. This server does not use 
     290        passwords because it is just a sample of how to use the OpenID 
     291        library.</p> 
     292        <form method="GET" action="%s"> 
     293          <input type="hidden" name="success_to" value="%s" /> 
     294          <input type="hidden" name="fail_to" value="%s" /> 
     295          <input type="text" name="user" value="" /> 
     296          <input type="submit" name="submit" value="Log In" /> 
     297          <input type="submit" name="cancel" value="Cancel" /> 
     298        </form> 
     299        ''' % (self.paths['path_loginsubmit'], success_to, fail_to)) 
     300 
     301 
     302    def do_loginsubmit(self, environ, start_response): 
     303        if 'submit' in self.query: 
     304            if 'user' in self.query: 
     305                self.user = self.query['user'] 
     306            else: 
     307                self.user = None 
     308            return self._redirect(start_response, self.query['success_to']) 
     309        elif 'cancel' in self.query: 
     310            return self._redirect(start_response, self.query['fail_to']) 
     311        else: 
     312            assert 0, 'strange login %r' % (self.query,)    
     313             
     314 
     315    def do_mainpage(self, environ, start_response): 
     316 
     317        yadis_tag = '<meta http-equiv="x-xrds-location" content="%s">'%\ 
     318            (self.base_url + self.paths['path_serveryadis']) 
     319        if self.user: 
     320            openid_url = self.base_url + self.paths['path_id'] + '/' + \ 
     321                        self.user 
     322            user_message = """\ 
     323            <p>You are logged in as %s. Your OpenID identity URL is 
     324            <tt><a href=%s>%s</a></tt>. Enter that URL at an OpenID 
     325            consumer to test this server.</p> 
     326            """ % (self.user, quoteattr(openid_url), openid_url) 
     327        else: 
     328            user_message = """\ 
     329            <p>This server uses a cookie to remember who you are in 
     330            order to simulate a standard Web user experience. You are 
     331            not <a href='%s'>logged in</a>.</p>""" % self.paths['path_login'] 
     332 
     333        return self._showPage(200, 'Main Page', head_extras=yadis_tag, msg='''\ 
     334        <p>This is a simple OpenID server implemented using the <a 
     335        href="http://openid.schtuff.com/">Python OpenID 
     336        library</a>.</p> 
     337 
     338        %s 
     339 
     340        <p>To use this server with a consumer, the consumer must be 
     341        able to fetch HTTP pages from this web server. If this 
     342        computer is behind a firewall, you will not be able to use 
     343        OpenID consumers outside of the firewall with it.</p> 
     344 
     345        <p>The URL for this server is <a href=%s><tt>%s</tt></a>.</p> 
     346        ''' % (user_message, quoteattr(self.base_url), self.base_url)) 
     347             
     348                         
    237349    def _setUser(self): 
    238350        session = environ[self.session_middleware] 
     
    255367        # and the user should be asked for permission to release 
    256368        # it. 
     369        # TODO: role/user attribute look-up in database vs. username? 
    257370        sreg_data = { 
    258371            'nickname':self.user 
     
    301414        return response 
    302415 
    303     def _doLogin(self): 
    304         if 'submit' in self.query: 
    305             if 'user' in self.query: 
    306                 self.user = self.query['user'] 
    307             else: 
    308                 self.user = None 
    309             self._redirect(self.query['success_to']) 
    310         elif 'cancel' in self.query: 
    311             self._redirect(self.query['fail_to']) 
    312         else: 
    313             assert 0, 'strange login %r' % (self.query,) 
    314  
    315     def _redirect(self, url): 
    316         self.send_response(302) 
    317         self.send_header('Location', url) 
    318         self._writeUserHeader() 
    319  
    320         self.end_headers() 
     416 
     417    def _redirect(self, start_response, url): 
     418        hdr = [('Content-type', 'text/html'+self.charset), 
     419               ('Location', url)] 
     420        hdr += self._writeUserHeader() 
     421 
     422        start_response('302 %s' % httplib.responses[302], hdr) 
     423        return [] 
     424 
    321425 
    322426    def _writeUserHeader(self): 
     
    518622        %s 
    519623        ''' % (ident, msg)) 
    520      
    521     def _showServerYadis(self): 
    522         self.send_response(200) 
    523         self.send_header('Content-type', 'application/xrds+xml') 
    524         self.end_headers() 
    525  
    526         endpoint_url = self.base_url + self.paths['path_openidserver'] 
    527         self.wfile.write("""\ 
    528 <?xml version="1.0" encoding="UTF-8"?> 
    529 <xrds:XRDS 
    530     xmlns:xrds="xri://$xrds" 
    531     xmlns="xri://$xrd*($v*2.0)"> 
    532   <XRD> 
    533  
    534     <Service priority="0"> 
    535       <Type>%s</Type> 
    536       <URI>%s</URI> 
    537     </Service> 
    538  
    539   </XRD> 
    540 </xrds:XRDS> 
    541 """%(discover.OPENID_IDP_2_0_TYPE, endpoint_url,)) 
    542  
    543     def _showMainPage(self): 
    544         yadis_tag = '<meta http-equiv="x-xrds-location" content="%s">'%\ 
    545             (self.base_url + self.paths['path_serveryadis']) 
    546         if self.user: 
    547             openid_url = self.base_url + self.paths['path_id'] + '/' + \ 
    548                         self.user 
    549             user_message = """\ 
    550             <p>You are logged in as %s. Your OpenID identity URL is 
    551             <tt><a href=%s>%s</a></tt>. Enter that URL at an OpenID 
    552             consumer to test this server.</p> 
    553             """ % (self.user, quoteattr(openid_url), openid_url) 
    554         else: 
    555             user_message = """\ 
    556             <p>This server uses a cookie to remember who you are in 
    557             order to simulate a standard Web user experience. You are 
    558             not <a href='%s'>logged in</a>.</p>""" % self.paths['path_login'] 
    559  
    560         self._showPage(200, 'Main Page', head_extras = yadis_tag, msg='''\ 
    561         <p>This is a simple OpenID server implemented using the <a 
    562         href="http://openid.schtuff.com/">Python OpenID 
    563         library</a>.</p> 
    564  
    565         %s 
    566  
    567         <p>To use this server with a consumer, the consumer must be 
    568         able to fetch HTTP pages from this web server. If this 
    569         computer is behind a firewall, you will not be able to use 
    570         OpenID consumers outside of the firewall with it.</p> 
    571  
    572         <p>The URL for this server is <a href=%s><tt>%s</tt></a>.</p> 
    573         ''' % (user_message, quoteattr(self.base_url), self.base_url)) 
    574  
    575     def _showLoginPage(self, success_to, fail_to): 
    576         self._showPage(200, 'Login Page', form='''\ 
    577         <h2>Login</h2> 
    578         <p>You may log in with any name. This server does not use 
    579         passwords because it is just a sample of how to use the OpenID 
    580         library.</p> 
    581         <form method="GET" action="%s"> 
    582           <input type="hidden" name="success_to" value="%s" /> 
    583           <input type="hidden" name="fail_to" value="%s" /> 
    584           <input type="text" name="user" value="" /> 
    585           <input type="submit" name="submit" value="Log In" /> 
    586           <input type="submit" name="cancel" value="Cancel" /> 
    587         </form> 
    588         ''' % (self.paths['loginsubmit'], success_to, fail_to)) 
     624         
    589625 
    590626    def _showPage(self, response_code, title, 
Note: See TracChangeset for help on using the changeset viewer.