source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/base.py @ 2959

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/base.py@2959
Revision 2959, 7.9 KB checked in by pjkersha, 12 years ago (diff)

ows_server/ows_server/controllers/login.py:

  • removed call - BaseController?.call supplies all the needed functionality
  • added to before - filter out getCredentials from return to address - getCredentials can contain cred args so should be removed. The code here is a 2nd line of defence - BaseController?.call removes getCredentials from request URLs so return to should nvere get assigned a getCredenials call.

ows_server/ows_server/controllers/logout.py:

  • same mod to before call as login.py listed above.

ows_server/ows_server/lib/security_util.py:

  • constructURL function - not used but a starting point for attempting to encapsulate security related code and remove it from BaseController?.call

ows_server/ows_server/lib/base.py:

  • if c.requestURL contains getCredentials filter it out and redirect to /discovery instead. getCredentials recives username/password from login form. Without this check these fields can be exposed as URL query args in a c.returnTo address(!)
Line 
1import urllib
2from urlparse import urlsplit, urlunsplit
3from base64 import urlsafe_b64encode
4from pylons import Response, c, g, cache, request, session
5from pylons.controllers import WSGIController
6from pylons.decorators import jsonify, validate
7from pylons.templating import render, render_response
8from pylons.helpers import abort, redirect_to, etag_cache
9from pylons.i18n import N_, _, ungettext
10from paste.request import construct_url
11import ows_server.models as model
12import ows_server.lib.helpers as h
13from ows_server.lib.security_util import setSecuritySession, LoginServiceQuery
14from ows_common import exceptions as OWS_E
15from ows_common.operations_metadata import OperationsMetadata, Operation, RequestMethod
16from ows_common.get_capabilities import ServiceMetadata
17import ows_common.xml
18
19
20try:
21    from xml.etree import ElementTree as ET
22except ImportError:
23    from elementtree import ElementTree as ET
24
25import logging
26logger = logging.getLogger(__name__)
27
28# Configure
29EXCEPTION_TYPE = request.environ['ndgConfig'].get('OWS_SERVER', 'exception_type', 'ogc').lower()
30
31
32
33class BaseController(WSGIController):
34   
35    def __call__(self, environ, start_response):       
36        # Insert any code to be run per request here. The Routes match
37        # is under environ['pylons.routes_dict'] should you want to check
38        # the action or route vars here
39
40        logger.debug("BaseController.__call__ ...")
41       
42        # construct URL picking up setting of server name from config to
43        # avoid exposing absolute URL hidden behind mod_proxy see #857
44        # Also, avoid returning to getCredentials and potentially exposing
45        # username/pass-phrase on URL.
46        # TODO: rework getCredentials get-out for more modular solution
47        pathInfo = urllib.quote(environ.get('PATH_INFO', '')) 
48        if 'getCredentials' in pathInfo:
49            logger.debug(\
50                "Reverting request URL from getCredentials to discovery...")
51            c.requestURL = g.server + '/discovery'       
52        else:
53            c.requestURL = g.server + pathInfo
54            query='&'.join(["%s=%s"%item for item in request.params.items()])
55            if query:
56                c.requestURL += '?' + query
57       
58        # Base 64 encode to enable passing around in 'r' argument of query
59        # string for use with login/logout
60        c.b64encRequestURL = urlsafe_b64encode(c.requestURL)
61
62        if 'h' in request.params:
63            # 'h' corresponds to the setting of a session manager host i.e.
64            # the request has come from a completed login from the login
65            # service
66            logger.debug("Setting security session from URL query args ...")
67           
68            # Copy the query arguments into security session keys
69            setSecuritySession()
70           
71            if 'panelView' not in session:
72                session['panelView']='History'
73            session.save()
74           
75            # Re-construct the URL removing the security related arguments
76            qs = LoginServiceQuery.stripFromURI()
77
78            logger.debug('Switching from https to http...')
79            cc = g.server + urllib.quote(environ.get('PATH_INFO',''))
80            if qs:
81                cc += "?" + qs
82               
83            logger.debug('URL transport switched to http: "%s"' % cc)
84            h.redirect_to(cc)
85
86               
87        #organise the information needed by pagetabs ...
88        # TODO avoid this for the server controllers ...
89       
90        c.pageTabs=[('Search',g.discoveryURL)]
91        if 'results' in session: c.pageTabs.append(('Results',session['results']))
92        if 'lastViewed' in session: c.pageTabs.append(('Display',session['lastViewed']))
93       
94        if 'selection' in session:
95            c.pageTabs.append(('Selections',h.url_for(controller='selection',action='index')))
96            c.pageTabs.append(('Visualise',h.url_for(controller='visualise', action='index')))
97            c.pageTabs.append(('Download','Blah'))
98
99        return WSGIController.__call__(self, environ, start_response)
100   
101class OwsController(BaseController):
102    def __call__(self, environ, start_response):
103
104        # All OWS parameter names are case insensitive.
105        req = request._current_obj()
106        self.ows_params = {}
107        for k in req.params:
108            self.ows_params[k.lower()] = req.params[k]       
109
110        # If the EXCEPTION_TYPE is 'pylons' let Pylons catch any exceptions.
111        # Otherwise send an OGC exception report for any OWS_E.OwsError
112        if 'pylons' in EXCEPTION_TYPE:
113            self._fixOwsAction(environ)
114            return super(OwsController, self).__call__(environ, start_response)
115        else:
116            try:
117                self._fixOwsAction(environ)
118                return super(OwsController, self).__call__(environ, start_response)
119            except OWS_E.OwsError, e:
120                logger.exception(e)
121
122                r=render_response('exception_report', report=e.report, format='xml')
123                r.headers['content-type'] = 'text/xml'
124                return r
125
126
127    def _fixOwsAction(self, environ):
128        # Override the Routes action from the request query parameter
129        try:
130            action = self.ows_params['request']
131        except KeyError:
132            raise OWS_E.MissingParameterValue('REQUEST parameter not specified', 'REQUEST')
133
134        # Check action is a method in self
135        if not getattr(self, action):
136            raise OWS_E.InvalidParameterValue('request=%s not supported' % action, 'REQUEST')
137
138        # override routes action with request
139        environ['pylons.routes_dict']['action'] = action
140        del self.ows_params['request']
141
142    def _loadCapabilities(self):
143        """
144        creates an ows_common.get_capabilities.ServiceMetadata object
145        by consulting the paste configuration and annotations in the
146        controller definition.
147
148        """
149        # Deduce ows_endpoint from routes
150        ows_endpoint = h.url_for(controller=request.environ['pylons.routes_dict']['controller'])
151       
152        #Deduce base_url from config
153        base_url =request.environ['ndgConfig'].get('DEFAULT','server')
154
155       
156        # Get the server-level configuration data from an XML file
157        config = request.environ['paste.config']
158        sm_tree = ET.parse(config['ows_common_config'])
159        sm = ows_common.xml.service_metadata(sm_tree.getroot())
160       
161        # Extract service-level parameters and constraint
162        parameters = getattr(self, '_ows_parameters', {})
163        constraints = getattr(self, '_ows_constraints', {})
164        versions = getattr(self, '_ows_versions', [])
165       
166        # Extract operation-level parameters and constraints
167        od = {}
168        for attr in dir(self):
169            op = getattr(self, attr)
170            if hasattr(op, '_ows_name'):
171                p = getattr(op, '_ows_parameters', {})
172                c = getattr(op, '_ows_constraints', {})
173                od[op._ows_name] = Operation(get=RequestMethod(href=base_url+ows_endpoint),
174                                             post=None,
175                                             parameters=p,
176                                             constraints=c,
177                                             name=op._ows_name)
178       
179        sm.operationsMetadata = OperationsMetadata(od, constraints, parameters)
180        sm.serviceIdentification.serviceTypeVersions = versions
181        return sm
182
183    def _renderCapabilities(self, template='ows/get_capabilities'):
184        """
185        The standard way of returning a Capabilities document.
186
187        Each subclass should implement self._load_capabilities() and call
188        this method to return a response object.
189
190        """
191        c.service_metadata = self._loadCapabilities()       
192        r = render_response(template, format='xml')
193        r.headers['content-type'] = 'text/xml'
194        return r
195
196
197# Include the '_' function in the public names
198__all__ = [__name for __name in locals().keys() if not __name.startswith('_') \
199           or __name == '_']
Note: See TracBrowser for help on using the repository browser.