Changeset 4122
- Timestamp:
- 14/08/08 11:47:20 (12 years ago)
- Location:
- TI12-security/trunk/python
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/trunk/python/Tests/openid-provider/op/development.ini
r4121 r4122 24 24 25 25 authkit.setup.method = form, cookie 26 authkit.form.template.string = <html><body>%s</body></html>27 # <head><title>NDG Sign In</title></head>28 # <body>29 # <h1>Please Sign In</h1>30 # <form action="%s" method="post">31 # <dl>32 # <dt>Username:</dt>33 # <dd><input type="text" name="username"></dd>34 # <dt>Password:</dt>35 # <dd><input type="password" name="password"></dd>36 # </dl>37 # <input type="submit" name="authform" value="Sign In" />38 # </form>39 # </body>40 #</html>41 42 26 authkit.form.authenticate.user.data = visitor:open_sesame 43 27 authkit.cookie.secret = secret string … … 54 38 #set debug = false 55 39 56 40 # OpenID Provider config 41 openid_provider.path.openidserver=/openidserver 42 openid_provider.path.login=/login 43 openid_provider.path.loginsubmit=/loginsubmit 44 openid_provider.path.id=/id 45 openid_provider.path.yadis=/yadis 46 openid_provider.path.serveryadis=/serveryadis 47 openid_provider.path.allow=/allow 48 openid_provider.path.decide=/decide 49 openid_provider.path.mainpage=/ 50 openid_provider.session_middleware=beaker.session 51 openid_provider.base_url=http://localhost:8700 52 openid_provider.consumer_store_dirpath=./ 53 openid_provider.charset=None 54 openid_provider.trace=False 55 openid_provider.renderingClass=op.lib.rendering.OpenIDProviderKidRendering 56 openid_provider.getSRegData= 57 57 58 # Logging configuration 58 59 [loggers] 59 keys = root, ndg 60 keys = root, ndg, op 60 61 61 62 [handlers] -
TI12-security/trunk/python/Tests/openid-provider/op/op/config/middleware.py
r4105 r4122 44 44 45 45 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) 46 app = OpenIDProviderMiddleware(app, base_url='http://localhost:8700',47 renderingClass=OpenIDProviderKidRendering)46 app = OpenIDProviderMiddleware(app, app_conf) 47 #renderingClass=OpenIDProviderKidRendering) 48 48 app = authkit.authenticate.middleware(app, app_conf) 49 49 app = SessionMiddleware(app) -
TI12-security/trunk/python/Tests/openid-provider/op/op/lib/rendering.py
r4121 r4122 3 3 from pylons import config 4 4 import ndg.security.server.sso.sso.lib.helpers as h 5 import logging 6 log = logging.getLogger(__name__) 5 7 6 8 class MyBuffet(Buffet): … … 24 26 25 27 class State: 26 def __init__(self ):28 def __init__(self, urls={}, session={}): 27 29 self.title = '' 28 30 self.xml = '' 29 31 self.headExtras = '' 30 self.session = {}32 self.session = session 31 33 self.loginStatus = True 34 self.urls = urls 32 35 33 36 def _render(templateName, **kw): … … 44 47 config['pylons.g'].stfcLink = 'http://ceda.stfc.ac.uk/' 45 48 config['pylons.g'].stfcImage = config['pylons.g'].server+'/layout/stfc-circle-sm.gif' 49 config['pylons.g'].helpIcon = config['pylons.g'].server+'/layout/icons/help.png' 46 50 47 51 from ndg.security.server.wsgi.openid_provider import RenderingInterface … … 52 56 def renderLogin(self, environ, success_to=None, fail_to=None): 53 57 """Set-up Kid template for OpenID Provider Login""" 54 c = State() 55 c.loginStatus = False 58 c = State(urls=self.urls, session=self.session) 56 59 c.title = "OpenID Login" 57 c.path_loginsubmit = self.paths['path_loginsubmit'] 58 c.success_to = success_to or self.paths['path_mainpage'] 59 c.fail_to = fail_to or self.paths['path_mainpage'] 60 c.xml = '' 60 c.success_to = success_to or self.urls['url_mainpage'] 61 c.fail_to = fail_to or self.urls['url_mainpage'] 61 62 62 63 return _render('ndg.security.login', c=c, g=config['pylons.g'], h=h) … … 65 66 def renderMainPage(self, environ): 66 67 """Set-up Kid template for OpenID Provider Login""" 67 c = State() 68 c.session = environ['beaker.session'] 68 c = State(urls=self.urls, session=self.session) 69 69 c.title = "OpenID Provider" 70 c.path_serveryadis = self.paths['path_serveryadis'] 71 c.headExtras = '<meta http-equiv="x-xrds-location" content="%s%s"/>'%\ 72 (self.base_url, c.path_serveryadis) 70 c.headExtras = '<meta http-equiv="x-xrds-location" content="%s"/>' % \ 71 self.urls['url_serveryadis'] 73 72 74 73 return _render('ndg.security.mainPage', c=c, g=config['pylons.g'], h=h) 75 74 75 76 76 def renderDecidePage(self, environ, oidRequest): 77 id_url_base = self.base_url+self.paths['path_id'] + '/' 78 79 # XXX: This may break if there are any synonyms for id_url_base, 80 # such as referring to it by IP address or a CNAME. 81 82 # TODO: OpenID 2.0 Allows oidRequest.identity to be set to 83 # http://specs.openid.net/auth/2.0/identifier_select. See, 84 # http://openid.net/specs/openid-authentication-2_0.html. This code 85 # implements this overriding the behaviour of the example code on 86 # which this is based. - Check is the example code based on OpenID 1.0 87 # and therefore wrong for this behaviour? 88 # assert oidRequest.identity.startswith(id_url_base), \ 89 # repr((oidRequest.identity, id_url_base)) 90 expected_user = oidRequest.identity[len(id_url_base):] 91 c = State() 77 """Handle user interaction required before final submit back to Relying 78 Party""" 79 c = State(urls=self.urls, session=self.session) 92 80 c.title = 'Approve OpenID Request?' 93 c.path_allow = self.paths['path_allow']94 c.id_url_base = id_url_base95 81 c.trust_root = oidRequest.trust_root 96 82 c.oidRequest = oidRequest 83 84 return _render('ndg.security.decidePage', c=c,g=config['pylons.g'],h=h) 97 85 98 if oidRequest.idSelect(): # We are being asked to select an ID99 msg = '''\100 <p>A site has asked for your identity. You may select an101 identifier by which you would like this site to know you.102 On a production site this would likely be a drop down list103 of pre-created accounts or have the facility to generate104 a random anonymous identifier.105 </p>106 '''107 108 fdata = {109 'path_allow': self.paths['path_allow'],110 'id_url_base': id_url_base,111 'trust_root': oidRequest.trust_root,112 }113 form = '''\114 <form method="POST" action="%(path_allow)s">115 <table>116 <tr><td>Identity:</td>117 <td>%(id_url_base)s<input type='text' name='identifier'></td></tr>118 <tr><td>Trust Root:</td><td>%(trust_root)s</td></tr>119 </table>120 <p>Allow this authentication to proceed?</p>121 <input type="checkbox" id="remember" name="remember" value="yes"122 /><label for="remember">Remember this123 decision</label><br />124 <input type="submit" name="yes" value="yes" />125 <input type="submit" name="no" value="no" />126 </form>127 '''%fdata128 129 else:130 msg = '''\131 <p>A new site has asked to confirm your identity. If you132 approve, the site represented by the trust root below will133 be told that you control identity URL listed below. (If134 you are using a delegated identity, the site will take135 care of reversing the delegation on its own.)</p>'''136 86 137 fdata = { 138 'path_allow': self.paths['path_allow'], 139 'identity': oidRequest.identity, 140 'trust_root': oidRequest.trust_root, 141 } 142 form = '''\ 143 <table> 144 <tr><td>Identity:</td><td>%(identity)s</td></tr> 145 <tr><td>Trust Root:</td><td>%(trust_root)s</td></tr> 146 </table> 147 <p>Allow this authentication to proceed?</p> 148 <form method="POST" action="%(path_allow)s"> 149 <input type="checkbox" id="remember" name="remember" value="yes" 150 /><label for="remember">Remember this 151 decision</label><br /> 152 <input type="submit" name="yes" value="yes" /> 153 <input type="submit" name="no" value="no" /> 154 </form>''' % fdata 155 156 return _render('ndg.security.decidePage', c=c,g=config['pylons.g'],h=h) 87 def renderErrorPage(self, environ, msg): 88 c = State(urls=self.urls, session=self.session) 89 c.title = 'Error with OpenID Provider' 90 c.xml = msg 91 return _render('ndg.security.error', c=c, g=config['pylons.g'], h=h) -
TI12-security/trunk/python/Tests/openid-provider/op/op/templates/ndg/security/decidePage.kid
r4121 r4122 2 2 <head> 3 3 <replace py:replace="pagehead()"/> 4 <script src="$g.server/js/wmsc.js"></script> 5 <script src="$g.server/js/prototype.js"></script> 6 <script src="http://www.openlayers.org/api/OpenLayers.js"></script> 7 <script src="$g.server/js/openlayers-x.js"/> 8 <script src="$g.server/js/dimensionControl.js"/> 9 <script src="$g.server/js/mapControl.js"/> 4 10 </head> 5 11 <body> 6 12 <div py:replace="header()"/> 7 <div class="decidePageContent" style="text-indent:5px"> 13 <div class="decidePageContent" style="text-indent:5px"> 14 <?python 15 if c.oidRequest.idSelect(): 16 identityURL = c.urls['url_id']+'/'+c.session['username'] 17 else: 18 identityURL = c.oidRequest.identity 19 ?> 8 20 <h2>Login to $c.oidRequest.trust_root?</h2> 9 <form method="POST" action="$c.path_allow"> 21 <!-- <div class="loginHdr">Login<span py:replace="helpIcon('fts_help')"/></div> 22 <div id="fts_help" class="hidden"> 23 <div class="helptxt"> 24 <p> 25 Although you are logged into this site, you also need 26 to decide whether to allow your details to be 27 returned to $c.oidRequest.trust_root so that you are 28 logged in there too. The details passed back include 29 the OpenID identifier given below. The details don't 30 include you login password. 31 </p> 32 </div> 33 </div> 34 --> 35 <form method="POST" action="${c.urls['url_allow']}"> 10 36 <table> 11 37 <tr> … … 17 43 <tr> 18 44 <td> 19 $c.oidRequest.identity45 <pre><b>$identityURL</b></pre> 20 46 </td> 21 47 </tr> … … 35 61 <tr> 36 62 <td align="right"> 37 <input type="checkbox" id="remember" name="remember" value="yes"/> 38 <label for="remember">Remember this decision</label> 63 <div py:if="c.oidRequest.trust_root not in c.session.get('approved', {})"> 64 <input type="checkbox" id="remember" name="remember" value="yes"/> 65 <label for="remember">Remember this decision</label> 66 </div> 39 67 </td> 40 68 </tr> -
TI12-security/trunk/python/Tests/openid-provider/op/op/templates/ndg/security/error.kid
r4105 r4122 6 6 <div id="entirepage"> 7 7 <div py:replace="header()"/> 8 <div id=" ${id}">8 <div id="errorContent"> 9 9 <div class="error" py:if="c.xml"> 10 10 $c.xml 11 11 </div> 12 <pre py:if="c.doc is not None">13 $c.doc14 </pre>15 12 </div> 16 13 <div py:replace="footer()"/> -
TI12-security/trunk/python/Tests/openid-provider/op/op/templates/ndg/security/login.kid
r4120 r4122 2 2 3 3 <div py:def="loginForm()" class="loginForm"> 4 <form action="$ c.path_loginsubmit" method="POST">4 <form action="${c.urls['url_loginsubmit']}" method="POST"> 5 5 <input type="hidden" name="success_to" value="$c.success_to" /> 6 6 <input type="hidden" name="fail_to" value="$c.fail_to" /> … … 32 32 <p>${XML(c.xml)}</p> 33 33 </div> 34 <div py:replace="footer( showLoginStatus=False)"/>34 <div py:replace="footer()"/> 35 35 </body> 36 36 -
TI12-security/trunk/python/Tests/openid-provider/op/op/templates/ndg/security/ndgPage.kid
r4120 r4122 65 65 --> 66 66 <?python 67 logOutLink='%s/loginsubmit?submit=true&success_to=%s/login' % ((g.server,)*2) 67 logOutLink='%s?submit=true&success_to=%s&fail_to=%s' % \ 68 (c.urls['url_loginsubmit'], 69 c.urls['url_login'], 70 c.urls['url_mainpage']) 68 71 ?> 69 72 Logged in as ${c.session['username']}. … … 75 78 <div py:if="'username' not in c.session" id="loggedOut"> 76 79 <table><tbody><tr><td> 77 Other services may be available if you <a href="$ g.server/login">login</a>.80 Other services may be available if you <a href="${c.urls['url_login']}">login</a>. 78 81 </td></tr></tbody></table> 79 82 </div> -
TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid_provider.py
r4121 r4122 19 19 20 20 import paste.request 21 from paste.util.import_string import eval_import 22 21 23 from authkit.authenticate import AuthKitConfigError 22 24 … … 30 32 import cgi 31 33 quoteattr = lambda s: '"%s"' % cgi.escape(s, 1) 32 34 getInvalidKw = lambda kw: [k for k in kw if k not in \ 35 OpenIDProviderMiddleware.defKw] 33 36 34 37 class OpenIDProviderMiddlewareError(Exception): … … 38 41 """WSGI Middleware to implement an OpenID Provider""" 39 42 40 defPaths = dict(path_openidserver='/openidserver', 41 path_login='/login', 42 path_loginsubmit='/loginsubmit', 43 path_id='/id', 44 path_yadis='/yadis', 45 path_serveryadis='/serveryadis', 46 path_allow='/allow', 47 path_decide='/decide', 48 path_mainpage='/') 49 50 def __init__(self, app, 51 session_middleware='beaker.session', 52 base_url=None, 53 data_path='./', 54 charset=None, 55 trace=False, 56 renderingClass=None, 57 **kw): 58 invalidKw=[k for k in kw if k not in OpenIDProviderMiddleware.defPaths] 43 defKw = dict(path_openidserver='/openidserver', 44 path_login='/login', 45 path_loginsubmit='/loginsubmit', 46 path_id='/id', 47 path_yadis='/yadis', 48 path_serveryadis='/serveryadis', 49 path_allow='/allow', 50 path_decide='/decide', 51 path_mainpage='/', 52 session_middleware='beaker.session', 53 base_url='', 54 consumer_store_dirpath='./', 55 charset=None, 56 trace=False, 57 renderingClass=None, 58 getSRegData=None) 59 60 defPaths=dict([(k,v) for k,v in defKw.items() if k.startswith('path_')]) 61 method = dict([(v, k.replace('path_', 'do_')) for k,v in defPaths.items()]) 62 63 def __init__(self, app, app_conf=None, prefix='openid_provider.', **kw): 64 ''' 65 @type app_conf: dict 66 @param app_conf: PasteDeploy application configuration dictionary 67 ''' 68 69 opt = OpenIDProviderMiddleware.defKw.copy() 70 kw2AppConfOpt = {} 71 if app_conf is not None: 72 # Update from application config dictionary - filter from using 73 # prefix 74 for k,v in app_conf.items(): 75 if k.startswith(prefix): 76 subK = k.replace(prefix, '') 77 filtK = '_'.join(subK.split('.')) 78 opt[filtK] = v 79 kw2AppConfOpt[filtK] = k 80 81 invalidOpt = getInvalidKw(opt) 82 if len(invalidOpt) > 0: 83 raise TypeError("Unexpected app_conf option(s): %s" % \ 84 (", ".join([kw2AppConfOpt[i] for i in invalidOpt]))) 85 86 # Convert from string type where required 87 opt['charset'] = eval(opt.get('charset', 'None')) 88 opt['trace'] = bool(eval(opt.get('trace', 'False'))) 89 90 renderingClassVal = opt.get('renderingClass', None) 91 if renderingClassVal: 92 opt['renderingClass'] = eval_import(renderingClassVal) 93 94 getSRegDataVal = opt.get('getSRegData', None) 95 if getSRegDataVal: 96 opt['getSRegData'] = eval_import(getSRegDataVal) 97 else: 98 opt['getSRegData'] = None 99 100 invalidKw = getInvalidKw(kw) 59 101 if len(invalidKw) > 0: 60 raise TypeError("Unexpected keywords: %s" % ", ".join(invalidKw)) 61 62 self.paths = OpenIDProviderMiddleware.defPaths.copy() 63 self.paths.update(kw) 64 65 66 self.method = dict([(v, k.replace('path_', 'do_')) \ 67 for k,v in OpenIDProviderMiddleware.defPaths.items()]) 68 69 self.session_middleware = session_middleware 70 self.base_url = base_url 71 72 if charset is None: 102 raise TypeError("Unexpected keyword(s): %s" % ", ".join(invalidKw)) 103 104 # Update options from keywords - matching app_conf ones will be 105 # overwritten 106 opt.update(kw) 107 log.debug("opt=%r", opt) 108 109 # Paths relative to base URL 110 self.paths = dict([(k, opt[k]) \ 111 for k in OpenIDProviderMiddleware.defPaths]) 112 113 if not opt['base_url']: 114 raise TypeError("base_url is not set") 115 116 self.base_url = opt['base_url'] 117 118 # Full Paths 119 self.urls = dict([(k.replace('path_', 'url_'), self.base_url+v) \ 120 for k,v in self.paths.items()]) 121 122 self.session_middleware = opt['session_middleware'] 123 124 if opt['charset'] is None: 73 125 self.charset = '' 74 126 else: … … 76 128 77 129 # If True and debug log level is set display content of response 78 self._trace = trace130 self._trace = opt['trace'] 79 131 80 132 # Pages can be customised by setting external rendering interface 81 133 # class 82 if renderingClass is None: 83 renderingClass = RenderingInterface 84 85 elif not issubclass(renderingClass, RenderingInterface): 134 renderingClass = opt.get('renderingClass', None) or RenderingInterface 135 if not issubclass(renderingClass, RenderingInterface): 86 136 raise OpenIDProviderMiddlewareError("Rendering interface " 87 137 "class %r is not a %r " … … 91 141 92 142 try: 93 self._renderer = renderingClass(self.base_url, self. paths)143 self._renderer = renderingClass(self.base_url, self.urls) 94 144 except Exception, e: 95 145 log.error("Error instantiating rendering interface...") 96 146 raise 97 147 148 # Callable for setting of additional attributes in HTTP header of 149 # response to Relying Party 150 self.getSRegData = opt.get('getSRegData', None) 151 if self.getSRegData and not callable(self.getSRegData): 152 raise OpenIDProviderMiddlewareError("Expecting callable for " 153 "getSRegData keyword, got %r"%\ 154 self.getSRegData) 155 98 156 self.app = app 99 157 … … 101 159 # were connecting to a database, you would create the database 102 160 # connection and instantiate an appropriate store here. 103 store = FileOpenIDStore(data_path) 104 self.oidserver=server.Server(store, 105 base_url+self.paths['path_openidserver']) 106 107 self.approved = {} 108 self.lastCheckIDRequest = {} 161 store = FileOpenIDStore(opt['consumer_store_dirpath']) 162 self.oidserver = server.Server(store, self.urls['url_openidserver']) 109 163 110 164 … … 121 175 self.environ = environ 122 176 self.start_response = start_response 177 self.session = environ[self.session_middleware] 178 self._renderer.session = self.session 123 179 124 180 # Match against the first level in the path only to allow for the 'id' … … 180 236 username = self.path.split('/')[-1] 181 237 182 endpoint_url = self. base_url + self.paths['path_openidserver']183 user_url = self. base_url + self.paths['path_id'] + '/' + username238 endpoint_url = self.urls['url_openidserver'] 239 user_url = self.urls['url_id'] + '/' + username 184 240 185 241 yadisDict = dict(openid20type=discover.OPENID_2_0_TYPE, … … 224 280 the Relying Party?""" 225 281 226 oidRequest = environ[self.session_middleware].get('lastCheckIDRequest')282 oidRequest = self.session.get('lastCheckIDRequest') 227 283 228 284 if 'Yes' in self.query: 229 285 if oidRequest.idSelect(): 230 identity = self.base_url+self.paths['path_id']+'/'+\ 231 self.query['identifier'] 286 identity = self.urls['url_id']+'/'+self.session['username'] 232 287 else: 233 288 identity = oidRequest.identity … … 235 290 trust_root = oidRequest.trust_root 236 291 if self.query.get('remember', 'no') == 'yes': 237 session = environ[self.session_middleware] 238 session['approved'] = {trust_root: 'always'} 239 session.save() 292 self.session['approved'] = {trust_root: 'always'} 293 self.session.save() 240 294 241 295 oidResponse = self._identityApproved(oidRequest, identity) … … 275 329 start_response("200 OK", [('Content-type', 'application/xrds+xml')]) 276 330 277 endpoint_url = self. base_url + self.paths['path_openidserver']331 endpoint_url = self.urls['url_openidserver'] 278 332 return [OpenIDProviderMiddleware.tmplServerYadis % \ 279 333 {'openid20type': discover.OPENID_IDP_2_0_TYPE, … … 294 348 """Handle user submission from login and logout""" 295 349 296 session = environ[self.session_middleware]297 298 350 if 'submit' in self.query: 299 351 if 'username' in self.query: 300 352 # login 301 if 'username' in se ssion:353 if 'username' in self.session: 302 354 log.error("Attempting login for user %s: user %s is " 303 "already logged in", session['username'], 304 session['username']) 305 # TODO: display error page 306 return self._redirect(start_response, 307 self.query['fail_to']) 355 "already logged in", self.session['username'], 356 self.session['username']) 357 return self._redirect(start_response,self.query['fail_to']) 308 358 309 session['username'] = self.query['username'] 310 session.save() 359 self.session['username'] = self.query['username'] 360 self.session['approved'] = {} 361 self.session.save() 311 362 else: 312 363 # logout 313 if 'username' not in se ssion:364 if 'username' not in self.session: 314 365 log.error("No user is logged in") 315 # TODO: display error page316 return self._redirect(start_response,317 self.query['fail_to'])318 del session['username']319 se ssion.save()366 return self._redirect(start_response,self.query['fail_to']) 367 368 del self.session['username'] 369 self.session.pop('approved', None) 370 self.session.save() 320 371 321 372 return self._redirect(start_response, self.query['success_to']) … … 324 375 return self._redirect(start_response, self.query['fail_to']) 325 376 else: 326 # TODO: display error page 327 raise OpenIDProviderMiddlewareError('Login input not recognised ' 328 '%r' % self.query) 377 log.error('Login input not recognised %r' % self.query) 378 return self._redirect(start_response, self.query['fail_to']) 329 379 330 380 … … 341 391 """Display page prompting the user to decide whether to trust the site 342 392 requesting their credentials""" 343 session = environ[self.session_middleware] 344 oidRequest = se ssion.get('lastCheckIDRequest')393 394 oidRequest = self.session.get('lastCheckIDRequest') 345 395 if oidRequest is None: 346 396 log.error("No OpenID request set in session") 347 397 return self.do_mainpage(environ, start_response) 348 398 349 approvedRoots = session.get('approved', {}) 350 351 if oidRequest.trust_root in approvedRoots: 399 approvedRoots = self.session.get('approved', {}) 400 401 if oidRequest.trust_root in approvedRoots and \ 402 not oidRequest.idSelect(): 352 403 response = self._identityApproved(oidRequest, oidRequest.identity) 353 404 return self._displayResponse(response) … … 360 411 return response 361 412 362 def _identityIsAuthorized(self, identity_url): 413 414 def _identityIsAuthorized(self, oidRequest): 363 415 '''The given identity URL matches with a logged in user''' 364 session = self.environ[self.session_middleware] 365 username = se ssion.get('username')416 417 username = self.session.get('username') 366 418 if username is None: 367 419 return False 368 420 369 if identity_url != self.base_url+self.paths['path_id']+'/'+username: 421 if oidRequest.idSelect(): 422 log.debug("OpenIDProviderMiddleware._identityIsAuthorized - " 423 "ID Select mode set but user is already logged in") 424 return True 425 426 identityURL = self.urls['url_id']+'/'+username 427 if oidRequest.identity != identityURL: 428 log.debug("OpenIDProviderMiddleware._identityIsAuthorized - " 429 "user is already logged in with a different ID=%s" % \ 430 username) 370 431 return False 371 432 433 log.debug("OpenIDProviderMiddleware._identityIsAuthorized - " 434 "user is logged in with ID matching ID URL") 372 435 return True 436 373 437 374 438 def _trustRootIsAuthorized(self, trust_root): 375 439 '''The given trust root (Relying Party) has previously been approved 376 440 by the user''' 377 session = self.environ[self.session_middleware] 378 approvedRoots = session.get('approved', {}) 441 approvedRoots = self.session.get('approved', {}) 379 442 return approvedRoots.get(trust_root) is not None 380 443 381 444 382 445 def _addSRegResponse(self, request, response): 446 '''Add additional attributes to response to Relying Party''' 447 if self.getSRegData is None: 448 return 449 383 450 sreg_req = sreg.SRegRequest.fromOpenIDRequest(request) 384 451 385 # In a real application, this data would be user-specific, 386 # and the user should be asked for permission to release 387 # it. 388 # TODO: role/user attribute look-up in database vs. username? 389 sreg_data = { 390 'nickname':self.environ[self.session_middleware]['username'] 391 } 452 # Callout to external callable sets additional user attributes to be 453 # returned in response to Relying Party 454 sreg_data = self.getSRegData(self.session.get('username')) 392 455 393 456 sreg_resp = sreg.SRegResponse.extractResponse(sreg_req, sreg_data) … … 405 468 406 469 log.debug("OpenIDProviderMiddleware._handleCheckIDRequest ...") 407 session = self.environ[self.session_middleware] 408 409 if self._identityIsAuthorized(oidRequest.identity): 410 # User is logged in 411 if self._trustRootIsAuthorized(oidRequest.trust_root): 470 471 if self._identityIsAuthorized(oidRequest): 472 473 # User is logged in - check for ID Select type request i.e. the 474 # user entered their IdP address at the Relying Party and not their 475 # OpenID Identifier. In this case, the identity they wish to use 476 # must be confirmed. 477 if oidRequest.idSelect(): 478 # OpenID identifier must be confirmed 479 return self.do_decide(self.environ, self.start_response) 480 481 elif self._trustRootIsAuthorized(oidRequest.trust_root): 412 482 # User has approved this Relying Party 413 483 oidResponse = self._identityApproved(oidRequest) … … 421 491 422 492 else: 423 session = self.environ[self.session_middleware] 424 session['lastCheckIDRequest'] = oidRequest 425 session.save() 493 # User is not logged in - save request 494 self.session['lastCheckIDRequest'] = oidRequest 495 self.session.save() 496 497 # Call login and if successful then call decide page to confirm 498 # user wishes to trust the Relying Party. 426 499 response = self.do_login(self.environ, 427 500 self.start_response, 428 success_to=self. paths['path_decide'])501 success_to=self.urls['url_decide']) 429 502 return response 430 503 … … 435 508 except server.EncodingError, why: 436 509 text = why.response.encodeToKVForm() 437 # TODO: Error template page 438 return self._renderer.renderErrorPage(self.environ) 439 510 return self.showErrorPage(text) 511 440 512 hdr = webresponse.headers.items() 441 513 … … 461 533 462 534 535 def _showErrorPage(self, msg, code=500): 536 response = self._renderer.renderErrorPage(self.environ,cgi.escape(msg)) 537 self.start_response('%d %s' % (code, httplib.responses[code]), 538 [('Content-type', 'text/html'+self.charset), 539 ('Content-length', str(len(msg)))]) 540 return response 541 542 463 543 class RenderingInterface(object): 464 544 """Interface class for rendering of OpenID Provider pages. Create a … … 467 547 keyword to OpenIDProviderMiddleware.__init__""" 468 548 469 def __init__(self, base_url, paths):549 def __init__(self, base_url, urls): 470 550 self.base_url = base_url 471 self. paths = paths551 self.urls = urls 472 552 473 553 def renderIdentityPage(self, environ): … … 475 555 path = environ.get('PATH_INFO') 476 556 477 link_tag = '<link rel="openid.server" href="%s %s">' % \478 (self.base_url, self.paths['path_openidserver'])557 link_tag = '<link rel="openid.server" href="%s">' % \ 558 self.urls['url_openidserver'] 479 559 480 560 yadis_loc_tag = '<meta http-equiv="x-xrds-location" content="%s">'%\ 481 (self. base_url+self.paths['path_yadis']+'/'+path[4:])561 (self.urls['url_yadis']+'/'+path[4:]) 482 562 483 563 disco_tags = link_tag + yadis_loc_tag 484 564 ident = self.base_url + path 485 565 486 # approved_trust_roots = []487 # for (aident, trust_root) in self.approved.keys():488 # if aident == ident:489 # trs = '<li><tt>%s</tt></li>\n' % cgi.escape(trust_root)490 # approved_trust_roots.append(trs)491 #492 # if approved_trust_roots:493 # prepend = '<p>Approved trust roots:</p>\n<ul>\n'494 # approved_trust_roots.insert(0, prepend)495 # approved_trust_roots.append('</ul>\n')496 # msg = ''.join(approved_trust_roots)497 # else:498 # msg = ''499 566 msg = '' 500 567 return self._showPage(environ, … … 510 577 511 578 if success_to is None: 512 success_to = self. paths['path_mainpage']579 success_to = self.urls['url_mainpage'] 513 580 514 581 if fail_to is None: 515 fail_to = self. paths['path_mainpage']582 fail_to = self.urls['url_mainpage'] 516 583 517 584 return self._showPage(environ, … … 525 592 <input type="submit" name="cancel" value="Cancel" /> 526 593 </form> 527 ''' % (self. paths['path_loginsubmit'], success_to, fail_to))594 ''' % (self.urls['url_loginsubmit'], success_to, fail_to)) 528 595 529 596 … … 532 599 533 600 yadis_tag = '<meta http-equiv="x-xrds-location" content="%s">' % \ 534 (self.base_url + self.paths['path_serveryadis'])601 self.urls['url_serveryadis'] 535 602 username = environ['beaker.session']['username'] 536 603 if username: 537 openid_url = self.base_url + self.paths['path_id'] + '/' + \ 538 username 604 openid_url = self.urls['url_id'] + '/' + username 539 605 user_message = """\ 540 606 <p>You are logged in as %s. Your OpenID identity URL is … … 544 610 else: 545 611 user_message = "<p>You are not <a href='%s'>logged in</a>.</p>" % \ 546 self. paths['path_login']612 self.urls['url_login'] 547 613 548 614 return self._showPage(environ, … … 556 622 557 623 def renderDecidePage(self, environ, oidRequest): 558 id_url_base = self. base_url+self.paths['path_id'] + '/'624 id_url_base = self.urls['url_id'] + '/' 559 625 560 626 # XXX: This may break if there are any synonyms for id_url_base, … … 582 648 ''' 583 649 fdata = { 584 'path_allow': self. paths['path_allow'],650 'path_allow': self.urls['url_allow'], 585 651 'id_url_base': id_url_base, 586 652 'trust_root': oidRequest.trust_root, … … 611 677 612 678 fdata = { 613 'path_allow': self. paths['path_allow'],679 'path_allow': self.urls['url_allow'], 614 680 'identity': oidRequest.identity, 615 681 'trust_root': oidRequest.trust_root, … … 641 707 642 708 fdata = { 643 'path_allow': self. paths['path_allow'],709 'path_allow': self.urls['url_allow'], 644 710 'identity': oidRequest.identity, 645 711 'trust_root': oidRequest.trust_root, … … 676 742 '<a href="%s?submit=true&'\ 677 743 'success_to=%s">Log out</a>' % \ 678 (self. paths['path_id'], username, username,679 self. paths['path_loginsubmit'],680 self. paths['path_login'])744 (self.urls['url_id'], username, username, 745 self.urls['url_loginsubmit'], 746 self.urls['url_login']) 681 747 682 748 body = '' … … 788 854 789 855 return response 856 857 def renderErrorPage(self, environ, msg): 858 response = self._showPage(environ, 'Error Processing Request', err='''\ 859 <p>%s</p> 860 <!-- 861 862 This is a large comment. It exists to make this page larger. 863 That is unfortunately necessary because of the "smart" 864 handling of pages returned with an error code in IE. 865 866 ************************************************************* 867 ************************************************************* 868 ************************************************************* 869 ************************************************************* 870 ************************************************************* 871 ************************************************************* 872 ************************************************************* 873 ************************************************************* 874 ************************************************************* 875 ************************************************************* 876 ************************************************************* 877 ************************************************************* 878 ************************************************************* 879 ************************************************************* 880 ************************************************************* 881 ************************************************************* 882 ************************************************************* 883 ************************************************************* 884 ************************************************************* 885 ************************************************************* 886 ************************************************************* 887 ************************************************************* 888 ************************************************************* 889 890 --> 891 ''' % msg) 892 893 return response
Note: See TracChangeset
for help on using the changeset viewer.