source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/sso/sso/controllers/logout.py @ 4900

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/sso/sso/controllers/logout.py@4900
Revision 4900, 4.9 KB checked in by pjkersha, 11 years ago (diff)
  • fixed occurred typo
  • fixed badcpage.kid login/logout link
Line 
1"""Single Sign On Service Logout Controller
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "10/12/08"
7__copyright__ = "(C) 2009 Science and Technology Facilities Council"
8__license__ = "BSD - see LICENSE file in top-level directory"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = '$Id$'
11from ndg.security.server.sso.sso.lib.base import *
12from ndg.security.common.pylons.security_util import SecuritySession
13import logging
14log = logging.getLogger(__name__)
15
16import sys # include in case tracefile is set to sys.stderr
17import base64 # decode the return to address
18from urlparse import urlsplit, urlunsplit
19
20from ndg.security.server.wsgi.utils.sessionmanagerclient import \
21    WSGISessionManagerClient, SessionExpired, AttributeRequestDenied
22
23
24class LogoutController(BaseController):
25    '''Provides the pylons controller for logging out and removing security
26    session cookie content
27    '''
28
29    def index(self):
30        '''Logout - remove session from Session Manager tidy up cookie'''
31
32        log.info("LogoutController.index ...")
33       
34        # Convenience alias
35        cfg = g.ndg.security.server.sso.cfg
36       
37
38        if 'ndgSec' not in session:
39            # There's no handle to a security session
40            log.error("logout called but no 'ndgSec' key in session object")
41            c.loggedIn = False
42            return self._redirect()
43       
44        try:
45            smClnt = WSGISessionManagerClient(uri=session['ndgSec']['h'],
46                        environ=request.environ,
47                        tracefile=cfg.tracefile,
48                        sslCACertFilePathList=cfg.sslCACertFilePathList,
49                        **cfg.wss)       
50        except Exception, e:
51            log.error("logout - creating Session Manager client: %s" % e)
52            return self._cleanupAndRedirect() 
53       
54        # Disconnect from Session Manager
55        log.info('Calling Session Manager "%s" disconnect for logout...' %
56                 session['ndgSec']['h'])
57        try:
58            smClnt.disconnect(sessID=session['ndgSec']['sid'])
59        except Exception, e:
60            log.error("Error with Session Manager logout: %s" % e)
61            # don't exit here - instead proceed to delete session and
62            # redirect ...
63
64        c.loggedIn = False
65        return self._cleanupAndRedirect()
66
67
68    def _cleanupAndRedirect(self):
69        """Remove security session and call _redirect"""
70        try:
71            # easy to kill our cookie
72            SecuritySession.delete()
73            if 'ndgCleared' in session: del session['ndgCleared']
74            session.save()
75           
76        except Exception, e:   
77            log.error("logout - clearing security session: %s" % e)
78
79        return self._redirect()
80   
81   
82    def _redirect(self):
83        """Handle redirect back to previous page"""
84       
85        # Redirect URL is held in 'r' URL arg of this request
86        b64encReturnTo = str(request.params.get('r', ''))
87
88        if b64encReturnTo:
89            # Decode the return to address
90            try:
91                b64decReturnTo = base64.urlsafe_b64decode(b64encReturnTo)
92            except Exception, e:
93                log.error("logout - decoding return URL: %s" % e) 
94                c.xml = "Error carrying out browser redirect following logout"
95                response.status_code = 400
96                return render('ndg.security.kid', 'ndg.security.error')
97           
98            # Check for 'getCredentials' - avoid in case username/password
99            # contained in the URL!
100            getCredentialsIdx = b64decReturnTo.rfind('/getCredentials')
101            if getCredentialsIdx != -1:
102                log.debug("Reverting request URL from getCredentials to "
103                          "login...")
104                b64decReturnTo = b64decReturnTo[:getCredentialsIdx] + '/login'
105           
106            # Add flag indicating to caller that logout succeeded.  The caller
107            # can use this to remove any security cookie present in their
108            # domain - See:
109            # ndg.security.client.ssoclient.ssoclient.lib.base.BaseController
110            if '?' in b64decReturnTo:
111                b64decReturnTo += '&logout=1'
112            else:
113                b64decReturnTo += '?logout=1'
114
115            # and now go back to whence we had come
116            log.debug("LogoutController._redirect: redirect to %s" %
117                                                              b64decReturnTo)
118            h.redirect_to(b64decReturnTo)
119        else:
120            log.debug("LogoutController._redirect: no redirect URL set.")
121            response.status_code = 400
122            c.errorPageHeading = "Log out"
123            if getattr(c, "loggedIn", False):
124                c.xml = "Logged out"
125            else:
126                c.xml = ("An error occurred logging out.  Please report the "
127                         "problem to your site administrator") 
128               
129            return render('ndg.security.kid', 'ndg.security.error')
Note: See TracBrowser for help on using the repository browser.