source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/provider/renderinginterface/buffet/__init__.py @ 5080

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/provider/renderinginterface/buffet/__init__.py@5080
Revision 5080, 7.7 KB checked in by pjkersha, 13 years ago (diff)

ndg.security.test.integration.openid: working combined OpenID Provider and Relying Party in same WSGI stack

  • Removed call to paste.request.parse_formvars in ndg.security.server.wsgi.openid.relyingparty.OpenIDRelyingPartyMiddleware.__call__: for Paste 1.7.1 this seems to gobbled up environwsgi.input? such that a 2nd call to it yields nothing!
  • TODO: add login to OpenID Relying Party template so that for a given site, home users can skip OpenID URI entry and login directly.
Line 
1"""NDG Security Pylons Buffet based Rendering Interface for
2OpenIDProviderMiddleware
3
4NERC Data Grid Project
5"""
6__author__ = "P J Kershaw"
7__date__ = "14/08/08"
8__copyright__ = "(C) 2009 Science and Technology Facilities Council"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = "$Id$"
11__license__ = "BSD - see LICENSE file in top-level directory"
12import logging
13log = logging.getLogger(__name__)
14
15import httplib
16from pylons.templating import Buffet
17
18from openid.consumer import discover
19
20# Rendering classes for OpenID Provider must derive from generic render
21# interface
22from ndg.security.server.wsgi.openid.provider import RenderingInterface, \
23    RenderingInterfaceConfigError
24   
25from ndg.security.server.wsgi.openid.provider import OpenIDProviderMiddleware
26
27# Boiler plate to create renderer
28class OpenIDProviderRenderingBuffet(Buffet):
29    def _update_names(self, ns):
30        return ns
31
32class BuffetRendering(RenderingInterface):
33    """Provide Templating for OpenID Provider Middleware via Buffet
34    class"""
35
36    propNames = (
37        'templateType', 
38        'templateRoot',
39        'baseURL',
40        'leftLogo',
41        'leftAlt',
42        'ndgLink',
43        'ndgImage',
44        'disclaimer',
45        'stfcLink',
46        'stfcImage',
47        'helpIcon',
48    )
49       
50    def __init__(self, *arg, **opt):
51        '''Extend RenderingInterface to include config and set-up for Buffet
52        object
53       
54        @type *arg: tuple
55        @param *arg: RenderingInterface parent class arguments
56        @type **opt: dict
57        @param **opt: additional keywords to set-up Buffet rendering'''
58        super(BuffetRendering, self).__init__(*arg, **opt)
59       
60        try:
61            for i in opt:
62                setattr(self, i, opt[i])
63        except KeyError, e:
64            raise RenderingInterfaceConfigError("Missing property: %s" % e)   
65         
66        self._buffet = OpenIDProviderRenderingBuffet(self.templateType, 
67                                            template_root=self.templateRoot)
68       
69        self.title = ''
70        self.xml = ''
71        self.headExtras = ''
72        self.loginStatus = True
73       
74    def _render(self, templateName, c=None, **kw):
75        '''Wrapper for Buffet.render'''
76        if c is None:
77            c = self
78           
79        kw['c'] = c
80       
81        rendering = self._buffet.render(template_name=templateName, 
82                                        namespace=kw)
83        return rendering
84
85
86    def yadis(self, environ, start_response):
87        """Render Yadis document containing user URL - override base
88        implementation to specify Yadis based discovery for user URL
89       
90        @type environ: dict
91        @param environ: dictionary of environment variables
92        @type start_response: callable
93        @param start_response: WSGI start response function.  Should be called
94        from this method to set the response code and HTTP header content
95        @rtype: basestring
96        @return: WSGI response
97        """
98        userIdentifier = OpenIDProviderMiddleware.parseIdentityURI(
99                                                    environ['PATH_INFO'])[-1]
100       
101        # This is where this implementation differs from the base class one
102        user_url = OpenIDProviderMiddleware.createIdentityURI(
103                                                        self.urls['url_yadis'],
104                                                        userIdentifier)
105       
106        yadisDict = dict(openid20type=discover.OPENID_2_0_TYPE, 
107                         openid10type=discover.OPENID_1_0_TYPE,
108                         endpoint_url=self.urls['url_openidserver'], 
109                         user_url=user_url)
110       
111        response = RenderingInterface.tmplYadis % yadisDict
112     
113        start_response('200 OK',
114                       [('Content-type', 'application/xrds+xml'+self.charset),
115                        ('Content-length', str(len(response)))])
116        return response
117 
118    def login(self, environ, start_response, success_to=None, fail_to=None, 
119              msg=''):
120        """Set-up template for OpenID Provider Login"""
121        self.title = "OpenID Login"
122        self.success_to = success_to or self.urls['url_mainpage']
123        self.fail_to = fail_to or self.urls['url_mainpage'] 
124        self.xml = msg
125       
126        response = self._render('ndg.security.login')
127        start_response('200 OK', 
128                       [('Content-type', 'text/html'+self.charset),
129                        ('Content-length', str(len(response)))])
130        self.xml = ''
131        return response
132       
133       
134    def mainPage(self, environ, start_response):
135        """Set-up template for OpenID Provider Login"""
136        self.title = "OpenID Provider"
137        self.headExtras = '<meta http-equiv="x-xrds-location" content="%s"/>'%\
138                        self.urls['url_serveryadis']
139   
140        response = self._render('ndg.security.mainPage')
141        start_response('200 OK', 
142                       [('Content-type', 'text/html'+self.charset),
143                        ('Content-length', str(len(response)))])
144        return response
145
146
147    def identityPage(self, environ, start_response):
148        """This page would normally render the user's Identity page but it's
149        not needed for Yadis only based discovery"""
150
151        self.xml = 'Invalid page requested for OpenID Provider'
152        response = self._render('ndg.security.error') 
153        self.xml = ''   
154        start_response("404 Not Found", 
155                       [('Content-type', 'text/html'+self.charset),
156                        ('Content-length', str(len(response)))])
157        return response
158
159   
160    def decidePage(self, environ, start_response, oidRequest):
161        """Handle user interaction required before final submit back to Relying
162        Party"""
163        self.title = 'Approve OpenID Request?'
164        self.trust_root = oidRequest.trust_root
165        self.oidRequest = oidRequest
166        self.environ = environ
167       
168        if oidRequest.idSelect():
169            if 'username' not in self.session:
170                log.error("No 'username' key set in sessin object for "
171                          "idselect mode do decide page")
172                msg = ('An internal error has occurred.  Please contact '
173                       'your system administrator')
174                response = self.errorPage(environ, start_response, msg)
175                return response
176               
177            userIdentifier = self._authN.username2UserIdentifiers(
178                                            environ,
179                                            self.session['username'])[0]
180                                           
181            # Use the Yadis path because we want to use Yadis only
182            # based discovery
183            self.identityURI = OpenIDProviderMiddleware.createIdentityURI(
184                                                        self.urls['url_yadis'],
185                                                        userIdentifier)
186        else:
187            self.identityURI = oidRequest.identity
188       
189        response = self._render('ndg.security.decidePage')
190        self.identityURI = ''
191       
192        start_response("200 OK", 
193                       [('Content-type', 'text/html'+self.charset),
194                        ('Content-length', str(len(response)))])
195        return response
196
197       
198    def errorPage(self, environ, start_response, msg, code=500):
199        '''Display error information'''
200        self.title = 'Error with OpenID Provider'
201        self.xml = msg
202        response = self._render('ndg.security.error')
203        start_response('%d %s' % (code, httplib.responses[code]), 
204                       [('Content-type', 'text/html'+self.charset),
205                        ('Content-length', str(len(response)))])
206        self.xml = ''
207        return response
Note: See TracBrowser for help on using the repository browser.