Changeset 4082 for TI12-security/trunk


Ignore:
Timestamp:
04/08/08 10:35:20 (11 years ago)
Author:
pjkersha
Message:

Further cleaning up of OpenID Provider code - TODO: AuthKit? and templating (if any) integration

Location:
TI12-security/trunk/python
Files:
7 added
3 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/Tests/openid-provider/op/development.ini

    r4081 r4082  
    2222beaker.session.key = op 
    2323beaker.session.secret = somesecret 
     24 
     25authkit.setup.method = form, cookie 
     26authkit.form.authenticate.user.data = visitor:open_sesame 
     27authkit.cookie.secret = secret string 
     28authkit.cookie.signin = /auth/signin 
    2429 
    2530# If you'd like to fine-tune the individual locations of the cache data dirs 
  • TI12-security/trunk/python/Tests/openid-provider/op/op/config/middleware.py

    r4081 r4082  
    1515from ndg.security.server.wsgi.openid_provider import OpenIDProviderMiddleware 
    1616from beaker.middleware import SessionMiddleware 
     17import authkit.authenticate 
    1718 
    1819def make_app(global_conf, full_stack=True, **app_conf): 
     
    4243    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) 
    4344    app = OpenIDProviderMiddleware(app, base_url='http://localhost:8700') 
    44     app = SessionMiddleware( 
    45         app,  
    46         key='authkit.open_id',  
    47         secret='some secret', 
    48     ) 
     45    app = authkit.authenticate.middleware(app, app_conf) 
     46    app = SessionMiddleware(app) 
    4947     
    5048    if asbool(full_stack): 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid_provider.py

    r4081 r4082  
    2525from openid.consumer import discover 
    2626 
     27import httplib 
     28import sys 
    2729 
    2830class OpenIDProviderMiddlewareError(Exception): 
     
    102104             
    103105        if pathMatch in self.method: 
    104             requestType = environ.get('REQUEST_METHOD') 
    105             if requestType == 'GET': 
    106                 pass 
    107             elif requestType == 'POST': 
    108                 pass 
    109106            self.query = dict(paste.request.parse_formvars(environ))  
    110             log.debug("Calling method %s ..." % self.method[pathMatch])    
    111             return getattr(self,self.method[pathMatch])(environ,start_response) 
     107            log.debug("Calling method %s ..." % self.method[pathMatch])  
     108             
     109            action = getattr(self, self.method[pathMatch])  
     110            return action(environ, start_response) 
    112111        else: 
    113112            log.debug("No match for path %s" % self.path) 
     
    116115 
    117116    def do_id(self, environ, start_response): 
    118         link_tag = '<link rel="openid.server" href="%s/openidserver">' %\ 
    119               self.base_url 
     117        '''Handle ID request''' 
     118        log.debug("OpenIDProviderMiddleware.do_id ...") 
     119         
     120        link_tag = '<link rel="openid.server" href="%s%sr">' % \ 
     121              (self.base_url, self.paths['path_openidserver']) 
    120122        yadis_loc_tag = '<meta http-equiv="x-xrds-location" content="%s">'%\ 
    121             (self.base_url+'/yadis/'+self.path[4:]) 
     123            (self.base_url+self.paths['path_yadis']+'/'+self.path[4:]) 
    122124        disco_tags = link_tag + yadis_loc_tag 
    123125        ident = self.base_url + self.path 
     
    137139            msg = '' 
    138140 
    139         return self.showPage(200, 'An Identity Page',  
     141        return self._showPage(200, 'An Identity Page',  
    140142                             head_extras=disco_tags,  
    141143                             msg='''\ 
     
    146148 
    147149    def do_yadis(self, environ, start_response): 
    148          
     150        """Generate Yadis document""" 
     151        log.debug("OpenIDProviderMiddleware.do_yadis ...") 
     152 
    149153        self.user = self.path.split('/')[-1] 
    150154         
    151         endpoint_url = self.base_url + '/openidserver' 
    152         user_url = self.base_url + '/id/' + self.user 
     155        endpoint_url = self.base_url + self.paths['path_openidserver'] 
     156        user_url = self.base_url + self.paths['path_id'] + '/' + self.user 
    153157        response = """\ 
    154158<?xml version="1.0" encoding="UTF-8"?> 
     
    179183 
    180184    def do_openidserver(self, environ, start_response): 
     185        """Handle OpenID Server Request""" 
     186        log.debug("OpenIDProviderMiddleware.do_openidserver ...") 
     187 
    181188        try: 
    182189            request = self.oidserver.decodeRequest(self.query) 
    183190        except server.ProtocolError, why: 
    184             return self.displayResponse(why) 
     191            return self._displayResponse(why) 
    185192 
    186193        if request is None: 
    187194            # Display text indicating that this is an endpoint. 
    188             return self.showAboutPage() 
     195            return self._showAboutPage() 
    189196 
    190197        if request.mode in ["checkid_immediate", "checkid_setup"]: 
    191             return self.handleCheckIDRequest(request) 
     198            return self._handleCheckIDRequest(request) 
    192199        else: 
    193200            response = self.oidserver.handleRequest(request) 
    194             return self.displayResponse(response) 
     201            return self._displayResponse(response) 
    195202             
    196              
    197     def do_GET(self): 
    198         import pdb;pdb.set_trace() 
    199         try: 
    200             self.parsed_uri = urlparse(self.path) 
    201             self.query = {} 
    202             for k, v in cgi.parse_qsl(self.parsed_uri[4]): 
    203                 self.query[k] = v 
    204  
    205             self.setUser() 
    206  
    207             path = self.parsed_uri[2].lower() 
    208  
    209             if path == '/': 
    210                 self.showMainPage() 
    211             elif path == '/openidserver': 
    212                 self.serverEndPoint(self.query) 
    213  
    214             elif path == '/login': 
    215                 self.showLoginPage('/', '/') 
    216             elif path == '/loginsubmit': 
    217                 self.doLogin() 
    218             elif path.startswith('/id/'): 
    219                 self.showIdPage(path) 
    220             elif path.startswith('/yadis/'): 
    221                 self.showYadis(path[7:]) 
    222             elif path == '/serveryadis': 
    223                 self.showServerYadis() 
    224             else: 
    225                 self.send_response(404) 
    226                 self.end_headers() 
    227  
    228         except (KeyboardInterrupt, SystemExit): 
    229             raise 
    230         except: 
    231             self.send_response(500) 
    232             self.send_header('Content-type', 'text/html') 
    233             self.end_headers() 
    234             self.wfile.write(cgitb.html(sys.exc_info(), context=10)) 
    235  
    236     def do_POST(self): 
    237         import pdb;pdb.set_trace() 
    238         try: 
    239             self.parsed_uri = urlparse(self.path) 
    240  
    241             self.setUser() 
    242             content_length = int(self.headers['Content-Length']) 
    243             post_data = self.rfile.read(content_length) 
    244  
    245             self.query = {} 
    246             for k, v in cgi.parse_qsl(post_data): 
    247                 self.query[k] = v 
    248  
    249             path = self.parsed_uri[2] 
    250             if path == '/openidserver': 
    251                 self.serverEndPoint(self.query) 
    252  
    253             elif path == '/allow': 
    254                 self.handleAllow(self.query) 
    255             else: 
    256                 self.send_response(404) 
    257                 self.end_headers() 
    258  
    259         except (KeyboardInterrupt, SystemExit): 
    260             raise 
    261         except: 
    262             self.send_response(500) 
    263             self.send_header('Content-type', 'text/html') 
    264             self.end_headers() 
    265             self.wfile.write(cgitb.html(sys.exc_info(), context=10)) 
    266203 
    267204    def do_allow(self, environ, start_response): 
     205        """Handle allow request - user allow credentials to be passed back to 
     206        the Relying Party?""" 
     207        log.debug("OpenIDProviderMiddleware.do_openidserver ...") 
     208         
    268209        # pretend this next bit is keying off the user's session or something, 
    269210        # right? 
     
    275216 
    276217            if request.idSelect(): 
    277                 identity = self.base_url + '/id/' + self.query['identifier'] 
     218                identity = self.base_url+self.paths['path_id']+'/'+\ 
     219                            self.query['identifier'] 
    278220            else: 
    279221                identity = request.identity 
     
    283225                self.approved[(identity, trust_root)] = 'always' 
    284226 
    285             response = self.identityApproved(request, identity) 
     227            response = self._identityApproved(request, identity) 
    286228 
    287229        elif 'no' in self.query: 
     
    291233            assert False, 'Expecting yes/no in allow post.  %r' % (self.query,) 
    292234 
    293         return self.displayResponse(response) 
    294  
    295     def setUser(self): 
     235        return self._displayResponse(response) 
     236 
     237    def _setUser(self): 
    296238        session = environ[self.session_middleware] 
    297239        self.user = session.get('openid_provider_username') 
    298240         
    299     def isAuthorized(self, identity_url, trust_root): 
     241    def _isAuthorized(self, identity_url, trust_root): 
    300242        if self.user is None: 
    301243            return False 
    302244 
    303         if identity_url != self.base_url + '/id/' + self.user: 
     245        if identity_url != self.base_url+self.paths['path_id']+'/'+self.user: 
    304246            return False 
    305247 
     
    307249        return self.approved.get(key) is not None 
    308250 
    309     def addSRegResponse(self, request, response): 
     251    def _addSRegResponse(self, request, response): 
    310252        sreg_req = sreg.SRegRequest.fromOpenIDRequest(request) 
    311253 
     
    320262        response.addExtension(sreg_resp) 
    321263 
    322     def identityApproved(self, request, identifier=None): 
     264    def _identityApproved(self, request, identifier=None): 
    323265        response = request.answer(True, identity=identifier) 
    324         self.addSRegResponse(request, response) 
     266        self._addSRegResponse(request, response) 
    325267        return response 
    326268 
    327     def handleCheckIDRequest(self, request): 
    328         is_authorized = self.isAuthorized(request.identity, request.trust_root) 
     269    def _handleCheckIDRequest(self, request): 
     270        is_authorized = self._isAuthorized(request.identity,request.trust_root) 
    329271        if is_authorized: 
    330             response = self.identityApproved(request) 
    331             return self.displayResponse(response) 
     272            response = self._identityApproved(request) 
     273            return self._displayResponse(response) 
    332274        elif request.immediate: 
    333275            response = request.answer(False) 
    334             return self.displayResponse(response) 
     276            return self._displayResponse(response) 
    335277        else: 
    336278            self.lastCheckIDRequest[self.user] = request 
    337             return self.showDecidePage(request) 
    338  
    339     def displayResponse(self, response): 
     279            return self._showDecidePage(request) 
     280 
     281    def _displayResponse(self, response): 
    340282        try: 
    341283            webresponse = self.oidserver.encodeResponse(response) 
    342284        except server.EncodingError, why: 
    343285            text = why.response.encodeToKVForm() 
    344             return self.showErrorPage('<pre>%s</pre>' % cgi.escape(text)) 
    345  
    346         hdr = webresponse.headers.items() + self.writeUserHeader() 
     286            return self._showErrorPage('<pre>%s</pre>' % cgi.escape(text)) 
     287 
     288        hdr = webresponse.headers.items() + self._writeUserHeader() 
    347289         
    348290        lenWebResponseBody = len(webresponse.body) 
     
    354296        hdr += [('Content-length', str(lenWebResponseBody))] 
    355297             
    356         # TODO: fix status message 
    357         self.start_response('%d OK' % webresponse.code, hdr) 
     298        self.start_response('%d %s' % (webresponse.code,  
     299                                       httplib.responses[webresponse.code]),  
     300                            hdr) 
    358301        return response 
    359302 
    360     def doLogin(self): 
     303    def _doLogin(self): 
    361304        if 'submit' in self.query: 
    362305            if 'user' in self.query: 
     
    364307            else: 
    365308                self.user = None 
    366             self.redirect(self.query['success_to']) 
     309            self._redirect(self.query['success_to']) 
    367310        elif 'cancel' in self.query: 
    368             self.redirect(self.query['fail_to']) 
     311            self._redirect(self.query['fail_to']) 
    369312        else: 
    370313            assert 0, 'strange login %r' % (self.query,) 
    371314 
    372     def redirect(self, url): 
     315    def _redirect(self, url): 
    373316        self.send_response(302) 
    374317        self.send_header('Location', url) 
    375         self.writeUserHeader() 
     318        self._writeUserHeader() 
    376319 
    377320        self.end_headers() 
    378321 
    379     def writeUserHeader(self): 
     322    def _writeUserHeader(self): 
    380323        if self.user is None: 
    381324            t1970 = time.gmtime(0) 
     
    386329            return [('Set-Cookie', 'user=%s' % self.user)] 
    387330 
    388     def showAboutPage(self): 
    389         endpoint_url = self.base_url + '/openidserver' 
     331    def _showAboutPage(self): 
     332        endpoint_url = self.base_url + self.paths['path_openidserver'] 
    390333 
    391334        def link(url): 
     
    406349        resource_markup = ''.join([term(url, text) for url, text in resources]) 
    407350 
    408         return self.showPage(200, 'This is an OpenID server', msg="""\ 
     351        return self._showPage(200, 'This is an OpenID server', msg="""\ 
    409352        <p>%s is an OpenID server endpoint.<p> 
    410353        <p>For more information about OpenID, see:</p> 
     
    414357        """ % (link(endpoint_url), resource_markup,)) 
    415358 
    416     def showErrorPage(self, error_message): 
    417         return self.showPage(400, 'Error Processing Request', err='''\ 
     359    def _showErrorPage(self, error_message): 
     360        return self._showPage(400, 'Error Processing Request', err='''\ 
    418361        <p>%s</p> 
    419362        <!-- 
     
    450393        ''' % error_message) 
    451394 
    452     def showDecidePage(self, request): 
    453         id_url_base = self.base_url+'/id/' 
     395    def _showDecidePage(self, request): 
     396        id_url_base = self.base_url+self.paths['path_id'] + '/' 
    454397        # XXX: This may break if there are any synonyms for id_url_base, 
    455398        # such as referring to it by IP address or a CNAME. 
     
    468411            ''' 
    469412            fdata = { 
     413                'path_allow': self.paths['path_allow'], 
    470414                'id_url_base': id_url_base, 
    471415                'trust_root': request.trust_root, 
    472416                } 
    473417            form = '''\ 
    474             <form method="POST" action="/allow"> 
     418            <form method="POST" action="%(path_allow)s"> 
    475419            <table> 
    476420              <tr><td>Identity:</td> 
     
    495439 
    496440            fdata = { 
     441                'path_allow': self.paths['path_allow'], 
    497442                'identity': request.identity, 
    498443                'trust_root': request.trust_root, 
     
    504449            </table> 
    505450            <p>Allow this authentication to proceed?</p> 
    506             <form method="POST" action="/allow"> 
     451            <form method="POST" action="%(path_allow)s"> 
    507452              <input type="checkbox" id="remember" name="remember" value="yes" 
    508453                  /><label for="remember">Remember this 
     
    524469 
    525470            fdata = { 
     471                'path_allow': self.paths['path_allow'], 
    526472                'identity': request.identity, 
    527473                'trust_root': request.trust_root, 
     
    534480            </table> 
    535481            <p>Allow this authentication to proceed?</p> 
    536             <form method="POST" action="/allow"> 
     482            <form method="POST" action="%(path_allow)s"> 
    537483              <input type="checkbox" id="remember" name="remember" value="yes" 
    538484                  /><label for="remember">Remember this 
     
    543489            </form>''' % fdata 
    544490 
    545         return self.showPage(200, 'Approve OpenID request?', msg=msg,form=form) 
    546  
    547  
    548     def showIdPage(self, path): 
     491        return self._showPage(200, 'Approve OpenID request?',msg=msg,form=form) 
     492 
     493 
     494    def _showIdPage(self, path): 
    549495        link_tag = '<link rel="openid.server" href="%sopenidserver">' %\ 
    550               self.server.base_url 
     496              self.base_url 
    551497        yadis_loc_tag = '<meta http-equiv="x-xrds-location" content="%s">'%\ 
    552             (self.server.base_url+'yadis/'+path[4:]) 
     498            (self.base_url+self.paths['path_yadis']+'/'+path[4:]) 
    553499        disco_tags = link_tag + yadis_loc_tag 
    554         ident = self.server.base_url + path[1:] 
     500        ident = self.base_url + path[1:] 
    555501 
    556502        approved_trust_roots = [] 
    557         for (aident, trust_root) in self.server.approved.keys(): 
     503        for (aident, trust_root) in self.approved.keys(): 
    558504            if aident == ident: 
    559505                trs = '<li><tt>%s</tt></li>\n' % cgi.escape(trust_root) 
     
    568514            msg = '' 
    569515 
    570         self.showPage(200, 'An Identity Page', head_extras=disco_tags, msg='''\ 
     516        self._showPage(200, 'An Identity Page',head_extras=disco_tags, msg='''\ 
    571517        <p>This is an identity page for %s.</p> 
    572518        %s 
    573519        ''' % (ident, msg)) 
    574520     
    575     def showServerYadis(self): 
     521    def _showServerYadis(self): 
    576522        self.send_response(200) 
    577523        self.send_header('Content-type', 'application/xrds+xml') 
    578524        self.end_headers() 
    579525 
    580         endpoint_url = self.server.base_url + 'openidserver' 
     526        endpoint_url = self.base_url + self.paths['path_openidserver'] 
    581527        self.wfile.write("""\ 
    582528<?xml version="1.0" encoding="UTF-8"?> 
     
    595541"""%(discover.OPENID_IDP_2_0_TYPE, endpoint_url,)) 
    596542 
    597     def showMainPage(self): 
     543    def _showMainPage(self): 
    598544        yadis_tag = '<meta http-equiv="x-xrds-location" content="%s">'%\ 
    599             (self.server.base_url + 'serveryadis') 
     545            (self.base_url + self.paths['path_serveryadis']) 
    600546        if self.user: 
    601             openid_url = self.server.base_url + 'id/' + self.user 
     547            openid_url = self.base_url + self.paths['path_id'] + '/' + \ 
     548                        self.user 
    602549            user_message = """\ 
    603550            <p>You are logged in as %s. Your OpenID identity URL is 
     
    609556            <p>This server uses a cookie to remember who you are in 
    610557            order to simulate a standard Web user experience. You are 
    611             not <a href='/login'>logged in</a>.</p>""" 
    612  
    613         self.showPage(200, 'Main Page', head_extras = yadis_tag, msg='''\ 
     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='''\ 
    614561        <p>This is a simple OpenID server implemented using the <a 
    615562        href="http://openid.schtuff.com/">Python OpenID 
     
    624571 
    625572        <p>The URL for this server is <a href=%s><tt>%s</tt></a>.</p> 
    626         ''' % (user_message, quoteattr(self.server.base_url), self.server.base_url)) 
    627  
    628     def showLoginPage(self, success_to, fail_to): 
    629         self.showPage(200, 'Login Page', form='''\ 
     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='''\ 
    630577        <h2>Login</h2> 
    631578        <p>You may log in with any name. This server does not use 
    632579        passwords because it is just a sample of how to use the OpenID 
    633580        library.</p> 
    634         <form method="GET" action="/loginsubmit"> 
     581        <form method="GET" action="%s"> 
    635582          <input type="hidden" name="success_to" value="%s" /> 
    636583          <input type="hidden" name="fail_to" value="%s" /> 
     
    639586          <input type="submit" name="cancel" value="Cancel" /> 
    640587        </form> 
    641         ''' % (success_to, fail_to)) 
    642  
    643     def showPage(self, response_code, title, 
     588        ''' % (self.paths['loginsubmit'], success_to, fail_to)) 
     589 
     590    def _showPage(self, response_code, title, 
    644591                 head_extras='', msg=None, err=None, form=None): 
    645592 
     
    647594            user_link = '<a href="/login">not logged in</a>.' 
    648595        else: 
    649             user_link = 'logged in as <a href="/id/%s">%s</a>.<br />'\ 
    650                         '<a href="/loginsubmit?submit=true&'\ 
    651                         'success_to=/login">Log out</a>'%(self.user, self.user) 
     596            user_link = 'logged in as <a href="%s/%s">%s</a>.<br />'\ 
     597                        '<a href="%s?submit=true&'\ 
     598                        'success_to=%s">Log out</a>' % \ 
     599                        (self.paths['path_id'], self.user, self.user,  
     600                         self.paths['path_loginsubmit'], 
     601                         self.paths['path_login']) 
    652602 
    653603        body = '' 
     
    758708''' % contents 
    759709 
    760         # TODO: fix response message to match code 
    761         self.start_response('%s OK' % response_code,  
     710        self.start_response('%s %s' % (response_code,  
     711                                       httplib.responses[response_code]),  
    762712                [ 
    763713                    ('Content-type', 'text/html'+self.charset), 
Note: See TracChangeset for help on using the changeset viewer.