source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/sso/sso/lib/openid_util.py @ 4900

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/sso/sso/lib/openid_util.py@4900
Revision 4900, 5.9 KB checked in by pjkersha, 11 years ago (diff)
  • fixed occurred typo
  • fixed badcpage.kid login/logout link
Line 
1import pylons
2from pylons.templating import Buffet
3from pylons import config, request, session
4import ndg.security.server.sso.sso.lib.helpers as h
5from ndg.security.server.sso.sso.lib.app_globals import Globals
6
7import logging
8log = logging.getLogger(__name__)
9
10log.debug("Defining MyBuffet for OpenID template ...")
11
12class MyBuffet(Buffet):
13    def _update_names(self, ns):
14        return ns
15
16def_eng = config['buffet.template_engines'][0]
17log.info("def_eng = %s" % def_eng)
18buffet = MyBuffet(
19    def_eng['engine'],
20    template_root=def_eng['template_root'],
21    **def_eng['template_options']
22)
23
24for e in config['buffet.template_engines'][1:]:
25    buffet.prepare(
26        e['engine'],
27        template_root=e['template_root'],
28        alias=e['alias'],
29        **e['template_options']
30    )
31
32class State:
33    '''Collection of variables to set in templates'''
34    def __init__(self):
35        self.openid = 'None'
36        self.title = "Login"
37        self.xml = ''
38        self.doc = 'logged in'
39        self.providers = {}
40        self.loggedIn = False
41        self.errorPageHeading = ''
42
43
44# State variable for WAYF kid file set-up
45c = State()
46
47import base64
48
49def make_template():
50    '''Make kid template for OpenID login - the NDG WAYF piggy backs this.
51   
52    It's triggered by a HTTP 401 authorisation error and called explicitly
53    via the WAYF controller'''
54   
55    g = config['pylons.g']
56   
57    # Check for return from OpenID login
58    try:
59        userSet = 'REMOTE_USER' in request.environ
60    except TypeError, e:
61        # Request object may not be registered - crude fix here wrapping it a
62        # catch
63        # TODO: referencing environ outside a controller
64        log.info("Keying 'REMOTE_USER' in request.environ: %s" % e)
65        userSet = False
66       
67    if userSet:
68        if not g.ndg.security.common.sso.state.returnToURL:
69            log.error("No returnToURL set for redirect following OpenID "
70                      "login")
71        else:
72            log.info("Redirecting to [%s] following OpenID login ..." %
73                     g.ndg.security.common.sso.state.returnToURL)
74            h.redirect_to(g.ndg.security.common.sso.state.returnToURL)
75
76    state = g.ndg.security.common.sso.state
77    cfg =  g.ndg.security.common.sso.cfg
78   
79    # Set encoded return to address - ensure login can return to an address
80    # over https to preserve confidentiality of credentials
81    # TODO: revisit - at the moment a redirect back from https -> http at the
82    # client to the IdP is rejected
83#    if state.returnToURL and cfg.server in state.returnToURL:
84#        state.returnToURL = state.returnToURL.replace(cfg.server,
85#                                                      cfg.sslServer)
86#        log.debug("make_template: switched return to address to https = %s" %
87#                                                            state.returnToURL)
88
89    state.b64encReturnToURL = base64.urlsafe_b64encode(str(state.returnToURL))       
90   
91    # Retrieve IdP details
92    _getTrustedIdPs(g)
93   
94    return _render("ndg.security.wayf", h=h, g=g, c=c)
95
96
97def _render(templateName, **kw):
98    '''TODO: Wrapper to enable substitution of $message and $css_class used by
99    AuthKit open_id module'''
100    rendering = buffet.render('ndg.security.kid', 
101                              template_name=templateName,
102                              namespace=kw)
103    # Add $message and $css_class here somehow
104    return rendering
105
106
107from ndg.security.server.wsgi.utils.attributeauthorityclient import \
108    WSGIAttributeAuthorityClient
109
110def _getTrustedIdPs(g):
111    '''Retrieve list of trusted login sites for user to select - calls
112    Attribute Authority WS'''
113
114    # Get references to globals
115    state = g.ndg.security.common.sso.state
116    cfg =  g.ndg.security.server.sso.cfg
117                               
118    # Check for cached copy and return if set to avoid recalling
119    # Attribute Authority - This has the consequence that if the list
120    # of trusted hosts in the Map Configuration changes, the Attribute
121    # Authority and THIS service must be restarted.
122    if len(g.ndg.security.server.sso.state.trustedIdPs) > 0:
123        return
124   
125    log.debug("Initialising connection to Attribute Authority [%s]"%cfg.aaURI)
126   
127    try:
128        aaClnt = WSGIAttributeAuthorityClient(environ=pylons.request.environ,
129                                        uri=cfg.aaURI,
130                                        environKey=cfg.aaEnvironKey,
131                                        tracefile=cfg.tracefile,
132                                        httpProxyHost=cfg.httpProxyHost,
133                                        noHttpProxyList=cfg.noHttpProxyList,
134                                        **cfg.wss)
135    except Exception, e:
136        log.error("Initialising AttributeAuthorityClient for "
137                  "getAllHostsInfo call: %s" % e)
138        return
139
140    # Get list of login uris for trusted sites including THIS one
141    log.debug("Calling Attribute Authority getAllHostsInfo for wayf ...")
142
143    try:
144        hosts = aaClnt.getTrustedHostInfo() 
145    except Exception, e:
146        log.error("AttributeAuthorityClient getAllHostsInfo call: %s" % e) 
147        return
148       
149    # Pick out siteName for as it should be set to a more user friendly
150    # description of the site.  Site name may not be set so if unavailable,
151    # default to host name identifier.
152    g.ndg.security.server.sso.state.trustedIdPs = \
153                        dict([(v['siteName'] or k, v['loginURI']) 
154                                 for k, v in hosts.items()])
155
156
157from ndg.security.common.pylons.security_util import setSecuritySession
158from urlparse import urlsplit
159
160def url2user(environ, url):
161    '''Function picked up by authkit.openid.urltouser config setting.  It
162    sets a username from the users OpenID URL following login'''
163    log.info("OpenID sign in with [%s]" % url)
164   
165    # Remove protocol prefix and strip /'s
166    username = ''.join(urlsplit(url)[1:]).strip('/').replace('/', '-')
167    return username
Note: See TracBrowser for help on using the repository browser.