source: TI12-security/trunk/python/NDG/SecurityCGI.py @ 1331

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/NDG/SecurityCGI.py@1331
Revision 1331, 31.2 KB checked in by pjkersha, 14 years ago (diff)

NDG/SecurityCGI.py: split into interface classes for service provider and identity provider with a common
_SecurityCGI base class.

NDG/Session.py: changed interface to UserSession?.createSecurityCookie so that caller doesn't need to explicitly
know cookie security tags names but can pass key/val pairs as a dictionary.

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2
3"""NDG Security CGI services
4
5NERC Data Grid Project
6
7P J Kershaw 23/05/06
8
9Copyright (C) 2006 CCLRC & NERC
10
11This software may be distributed under the terms of the Q Public License,
12version 1.0 or later.
13"""
14from Cookie import SimpleCookie
15
16import sys
17import cgi
18import os
19import base64
20
21# Set cookie expiry
22from datetime import datetime
23from datetime import timedelta
24
25from NDG.SecurityClient import *
26from NDG.Session import UserSession
27from NDG.Session import UserSessionError
28
29
30class SecurityCGIError(Exception):
31    """Exception handling for NDG Security CGI class."""
32    pass
33
34   
35class _SecurityCGI(cgi.FieldStorage):
36    """CGI interface base class for NDG Security
37   
38    Terms used throughout:       
39        Service Provider   - where user is accessing resources
40        Identity Provider  - where user's credentials are held or they login
41    """
42
43    acAllowMapping = "allowMapping"
44    acAllowMappingWithPrompt = "allowMappingWithPrompt"
45    acNoMapping = "noMapping"
46   
47    acMappingFlags = [acAllowMapping, acAllowMappingWithPrompt, acNoMapping]
48   
49    #_________________________________________________________________________
50    def __init__(self,
51                 smWSDL,
52                 smPubKeyFilePath=None,
53                 clntPubKeyFilePath=None,
54                 clntPriKeyFilePath=None,
55                 clntPriKeyPwd=None,
56                 scriptName=__file__,
57                 wsDebug=False,
58                 **cgiFieldStorageKwArgs):
59        """smWSDL:            URI For Session Manager WSDL used for user
60                              authentication
61        wsDebug:              print output from WS transactions to stderr"""
62
63        self.smWSDL = smWSDL
64        self.smClnt = None
65       
66        self.smPubKeyFilePath = smPubKeyFilePath
67       
68        self.clntPubKeyFilePath = clntPubKeyFilePath
69        self.clntPriKeyFilePath = clntPriKeyFilePath
70        self.clntPriKeyPwd = clntPriKeyPwd
71
72        self.scriptName = scriptName
73
74        self._wsDebug = False       
75        self.acMappingFlag = None
76        self.attCert = None
77               
78        cgi.FieldStorage.__init__(self, **cgiFieldStorageKwArgs)
79
80 
81    #_________________________________________________________________________
82    def processFields(self, **kwargs):
83        """Call appropriate actions according to the fields set"""       
84        raise NotImplementedError, \
85            self.processFields.__doc__.replace('\n       ','')
86   
87   
88    #_________________________________________________________________________
89    # Use instance name as an alias to processFields method
90    __call__ = processFields
91
92
93    #_________________________________________________________________________
94    def __getACmappingFlag(self):
95        """Flag determines whether mapping is permitted when contacting an
96        Attribute Authority to get an Attribute Certificate"""
97        return self.__acMappingFlag
98
99
100    def __setACmappingFlag(self, acMappingFlag):
101        """Flag determines whether mapping is permitted when contacting an
102        Attribute Authority to get an Attribute Certificate"""
103       
104        if acMappingFlag not in self.acMappingFlags:
105            raise AttributeError, \
106                "\"%s\" is invalid for acMappingFlag" % \
107                self.acMappingFlags
108               
109        self.__acMappingFlag = acMappingFlag
110 
111       
112    def __delACmappingFlag(self):
113        """Prevent certificate mapping flag from being deleted."""
114        raise AttributeError, \
115                        "\"acMappingFlag\" attribute cannot be deleted"
116       
117   
118    acMappingFlag = property(fget=__getACmappingFlag,
119                            fset=__setACmappingFlag,
120                            fdel=__delACmappingFlag,
121                            doc="mapping flag for AttCert requests to an AA")
122   
123   
124    #_________________________________________________________________________
125    def _getAttCert(self, sessCookie=None, reqRole=None):
126        """Contact Attribute Authority to get Attribute Certificate for data
127        access
128
129        sessCookie:     NDG security session cookie
130        reqRole:        specify the required role to get authorisation.  Set
131                        this to optimise the process for getting the required
132                        AC from a trusted host in order to perform mapping"""
133
134        # Check for session cookie input
135        if not sessCookie:
136            # No cookie set as input argument check for environment variable
137            if 'HTTP_COOKIE' in os.environ:
138                sessCookie = SimpleCookie(os.environ['HTTP_COOKIE'])   
139            else:
140                raise SecurityCGIError, \
141                    "Attribute certificate request requires a security cookie"
142
143        # Check cookie is valid
144        try:
145            UserSession.isValidSecurityCookie(sessCookie, raiseExcep=True)
146           
147        except UserSessionError, e:
148            raise SecurityCGIError, 'Checking existing session cookie: %s' % e
149
150
151        # Configure flags for attribute certificate request.  This determines
152        # whether mapping of certificates from trusted hosts is allowed
153        if self.acMappingFlag == self.acAllowMapping:
154            bMapFromTrustedHosts = True
155            bRtnExtAttCertList = False
156
157        elif self.acMappingFlag == self.acAllowMappingWithPrompt:
158            bMapFromTrustedHosts = False
159            bRtnExtAttCertList = True
160        else:
161            bMapFromTrustedHosts = False
162            bRtnExtAttCertList = False
163
164
165        # Instantiate WS proxy and request authorisation
166        try:
167            if not self.smClnt:
168                self.smClnt = SessionClient(\
169                            smWSDL=self.smWSDL,
170                            smPubKeyFilePath=self.smPubKeyFilePath,
171                            clntPubKeyFilePath=self.clntPubKeyFilePath,
172                            clntPriKeyFilePath=self.clntPriKeyFilePath,
173                            traceFile=self._wsDebug and sys.stderr or None)
174
175            authzResp = self.smClnt.reqAuthorisation(sessCookie=sessCookie,
176                                    aaWSDL=self.aaWSDL,
177                                    aaPubKey=self.aaPubKey,
178                                    reqRole=reqRole,
179                                    mapFromTrustedHosts=bMapFromTrustedHosts,
180                                    rtnExtAttCertList=bRtnExtAttCertList,
181                                    clntPriKeyPwd=self.clntPriKeyPwd)
182        except Exception, e:
183            raise SecurityCGIError, "Attribute Certificate request: %s" % e
184
185
186        if authzResp['statCode'] == authzResp.AccessGranted:
187            self.onAttCertGranted(authzResp['attCert'])
188       
189        elif authzResp['statCode'] == authzResp.AccessDenied:
190            self.onAttCertDenied(authzResp['extAttCertList'], 
191                                 authzResp['errMsg'])
192           
193        elif authzResp['statCode'] == authzResp.AccessError:
194            raise SecurityCGIError, authzResp['errMsg']
195           
196   
197    #_________________________________________________________________________
198    def onAttCertGranted(self, attCert):
199        """Callback invoked by getAttCert - handle case where an Attribute
200        Authority has granted a new attribute certificate to the user.  Derive
201        from this class and override this method as required.
202        """
203        pass
204   
205   
206    #_________________________________________________________________________
207    def onAttCertDenied(self, extAttCertList, errMsg):
208        """Callback invoked by getAttCert - handle case where an Attribute
209        Authority has denied an attribute certificate to the user.  Derive
210        from this class and override this method as required.
211       
212        extAttCertList:    a list of attribute certificates from trusted
213                           hosts.  Any of these could be selected and
214                           presented back to the target AA in order to get
215                           a mapped certificate.  This list may be None if
216                           no ACs could be obtained or if the
217                           mapFromTrustedHosts flag in the call to the Session
218                           Manager WS reqAuthorisation method was set to
219                           False.
220                           
221        errMsg:            the error message returned from the call to the
222                           AA to get an AC."""
223       
224        if not extAttCertList:
225            self.showLogin(pageTitle="Access denied by Attribute Authority")
226            raise SecurityCGIError, errMsg
227       
228        else:
229            # Display list of attCerts to choose from
230            print \
231"""Content-type: text/html
232
233<html>
234<head>
235    <title>Select an Attribute Certificate</title>
236    <style type=\"text/css\">
237    <!--
238    .al {
239    text-align: justify
240    }
241    a{
242    text-decoration:none;
243    }
244    a:hover{
245    color:#0000FF;
246    }
247        body { font-family: Verdana, sans-serif; font-size: 11}
248        table { font-family: Verdana, sans-serif; font-size: 11}
249    -->
250    </style>
251</head>
252<body>
253    <form action="%s" method="POST">
254    <table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
255    <tbody>"""
256   
257            for attCert in extAttCertList:
258                print \
259"""    <tr>
260        <td>%s</td>
261    </tr>""" % attCert['issuer']
262               
263                print \
264"""    </tbody>
265    </table>
266    </form>
267</body>
268</html>"""
269   
270        # end of onAttCertDenied()
271       
272
273#_____________________________________________________________________________
274class ServiceProviderSecurityCGI(_SecurityCGI):
275
276    #_________________________________________________________________________
277    def __init__(self,
278                 smWSDL,
279                 aaWSDL,
280                 smPubKeyFilePath=None,
281                 aaPubKeyFilePath=None,
282                 trustedHostInfo=None,
283                 cookieLifetimeHrs=8,
284                 **securityCGIKwArgs):
285        """smWSDL:            URI For Session Manager WSDL used for user
286                              authentication
287        aaWSDL:               URI for Attribute Authority WSDL used to get a
288                              list of login URI for trusted hosts
289        trustedHostInfo:      dictionary of URIs for trusted hosts indexed by
290                              hostname
291        cookieLifetimeHrs:    cookie lifetime in hours
292        wsDebug:              print output from WS transactions to stderr"""
293
294        self.smWSDL = smWSDL
295        self.smClnt = None
296       
297        self.aaWSDL = aaWSDL
298        self.aaClnt = None
299       
300        self.smPubKeyFilePath = smPubKeyFilePath
301        self.aaPubKeyFilePath = aaPubKeyFilePath
302
303        self.trustedHostInfo = trustedHostInfo
304        self.cookieLifetimeHrs = cookieLifetimeHrs
305
306        # Work out expiry time offset from the time this script is run
307        self.dtCookieExpiry = datetime.utcnow() + \
308                            timedelta(seconds=self.cookieLifetimeHrs*60*60)
309
310        self._wsDebug = False       
311        self.acMappingFlag = None
312        self.attCert = None
313               
314        super(self.__class__, self).__init__(self, **securityCGIKwArgs)
315
316 
317    #_________________________________________________________________________
318    def processFields(self, **kwargs):
319        """Call appropriate actions according to the fields set"""
320
321        if 'requestURI' in self:
322            # Request credentials from user's identity provider
323            self._requestCreds(**kwargs)
324
325        elif not [True for tag in UserSession.cookieTags if tag not in self]:
326            # Credentials tags were set -  set a new cookie at service
327            # provider site
328            encodedExpiry='expires' in self and self['expires'].value or None
329
330            self._receiveCredsResponse(encodedExpiry=encodedExpiry,
331                                       **kwargs)
332   
333   
334    #_________________________________________________________________________
335    def showHomeSiteSelect(self,
336                           trustedHostInfo=None,
337                           scriptName=None,
338                           contentTypeHdr=False,
339                           htmlTag=False,
340                           hdrTag=False,
341                           hdrTxt='',
342                           bodyTag=False,
343                           pageTitle=""):
344
345        if trustedHostInfo:
346            self.trustedHostInfo = trustedHostInfo
347
348        if not self.trustedHostInfo:
349            self.getTrustedHostInfo()
350           
351        if scriptName:
352            self.scriptName = scriptName
353           
354               
355        if contentTypeHdr:
356            print "Content-type: text/html\n\n"
357               
358        if htmlTag:
359            print "<html>\n"
360
361        if hdrTag:           
362            if not hdrTxt:
363                hdrTxt = """    <style type=\"text/css\">
364<!--
365.al {
366text-align: justify
367}
368a{
369text-decoration:none;
370}
371a:hover{
372color:#0000FF;
373}
374    body { font-family: Verdana, sans-serif; font-size: 11}
375    table { font-family: Verdana, sans-serif; font-size: 11}
376-->
377</style>"""
378
379            print """<head>
380           
381    <title>%s</title>
382    %s
383</head>""" % (pageTitle, hdrTxt)
384   
385   
386        if bodyTag:
387            print "<body>\n"
388
389            print """
390    <form action="%s" method="POST">
391    <table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
392    <tbody>
393    <tr>
394      <td>
395        <select name="requestURI">       
396          <option value="">Select your home site...""" % self.scriptName
397         
398            for hostname, info in self.trustedHostInfo.items():
399                print "<option value=\"%s\">%s" % (info['loginURI'], hostname)
400               
401            print \
402"""        </select>
403      </td>
404      <td align="right">
405        <input type=submit value="Go">
406      </td>
407    </tr>
408    </tbody>
409    </table>
410    </form>"""
411
412        if bodyTag:
413            print "</body>\n"
414
415        if htmlTag:
416            print "</html>\n"
417   
418        # end of showHomeSiteSelect()
419
420
421    #_________________________________________________________________________
422    def showCredsReceived(self, sessCookie):
423        """Called from _receiveCredsResponse() once a cookie has been created.
424        Makes a page to set the cookie and display to the user that they have
425        been authenticated.  Derived class should override this method as
426        required"""
427        print """Content-type: text/html"
428%s
429
430<html>
431<head>
432<title>Credentials Received</title>
433</head>
434<body>
435    Credentials Received
436</body>
437</html>""" % sessCookie.output()
438
439
440    #_________________________________________________________________________
441    def getTrustedHostInfo(self):
442        """Call Attribute Authority to find out trusted hosts.  These can be
443        use to populate list for use to select Identity Provider for login"""
444       
445        try:
446            if not self.aaClnt:
447                self.aaClnt = AttAuthorityClient(aaWSDL=self.aaWSDL,
448                            aaPubKeyFilePath=self.aaPubKeyFilePath,
449                            clntPubKeyFilePath=self.clntPubKeyFilePath,
450                            clntPriKeyFilePath=self.clntPriKeyFilePath,
451                            traceFile=self._wsDebug and sys.stderr or None)
452           
453            self.trustedHostInfo = self.aaClnt.getTrustedHostInfo(
454                                           clntPriKeyPwd=self.clntPriKeyPwd)
455        except Exception, e:
456            raise SecurityCGIError, "Attribute Authority client: %s" % e
457
458   
459    #_________________________________________________________________________
460    def _createCookie(self, encodedExpiry=None):
461        """Convert credentials passed over URI from users Identity Provider
462        into a new cookie"""
463
464        if encodedExpiry:
465            # Expiry is taken from encoded value passed over URI
466            dtExpiry = None
467            expiryStr = base64.urlsafe_b64decode(encodedExpiry)
468        else:
469            # Expiry is set from life time in hours input in __init__
470            dtExpiry = self.dtCookieExpiry
471            expiryStr = None
472
473       
474        try:
475            tagsDict = dict([(tag, self[tag].value) \
476                             for tag in UserSession.cookieTags])
477        except KeyError, e:
478            raise SecurityCGIError, "Missing cookie tag: %s" % e
479       
480        sessCookie =  UserSession.createSecurityCookie(dtExpiry=dtExpiry,
481                                                       expiryStr=expiryStr,
482                                                       **tagsDict)
483       
484        return sessCookie
485   
486
487    #_________________________________________________________________________
488    def _requestCreds(self,
489                      requestURI=None,
490                      returnURI=None,
491                      pageTitle='',
492                      headTags='',
493                      delayTime=0,
494                      redirectMsg=''):
495        """Request credentials from a user's Identity Provider
496       
497        requestURI:   site to request credentials from - default is
498                      'requestURI' CGI form value
499        pageTitle:    Give the redirect page a title
500        headTags:     Optionally add additional tags in <head/> section
501        delayTime:    time in seconds before carrying out redirect - redirect
502                      page will be displayed in this interval
503        redirectMsg:  Message to put on redirect page.  Can be plain text or
504                      formatted HTML"""
505
506        if returnURI is None:
507            returnURI = self['returnURI'].value
508
509        if requestURI is None:
510            requestURI = self['requestURI'].value
511
512        print """Content-type: text/html
513
514<html>
515<head>
516<title>%s</title>
517<meta http-equiv="REFRESH" content="%d; url=%s?returnURI=%s">
518%s
519</head>
520<body>
521%s
522</body>
523</html>""" % \
524    (pageTitle, delayTime, requestURI, returnURI, headTags, redirectMsg)
525
526
527    #_________________________________________________________________________
528    def _receiveCredsResponse(self, encodedExpiry=None):
529        """Remote site receives returned credentials and creates a new cookie
530        for its domain"""
531        sessCookie = self._createCookie(encodedExpiry=encodedExpiry)
532        self.showCredsReceived(sessCookie)
533       
534
535#_____________________________________________________________________________
536class IdentityProviderSecurityCGI(_SecurityCGI):
537
538    #_________________________________________________________________________
539    def __init__(self, smWSDL, **securityCGIKwArgs):
540        """smWSDL:            URI For Session Manager WSDL used for user
541                              authentication"""
542
543        self.smWSDL = smWSDL
544        self.smClnt = None
545       
546        self.userName = userName
547        self.passPhrase = passPhrase
548       
549        self.smPubKeyFilePath = smPubKeyFilePath
550                               
551        super(self.__class__, self).__init__(self, **securityCGIKwArgs)
552
553   
554    #_________________________________________________________________________
555    def processFields(self, **kwargs):
556        """Call appropriate actions according to the fields set"""
557
558   
559        bAuthorise = "authorise" in self
560       
561        if 'returnURI' in self:
562            # Identity provider receives request from remote site for
563            # credentials and returns them
564            self._processCredsRequest(**kwargs)
565
566        elif 'authenticate' in self:
567            # User has entered login details - now authenticate using the
568            # Session Manager WS
569            sessCookie = self._authenticate()
570           
571            if bAuthorise:
572                # Authorisation and authentication arguments were set -
573                # Now call authorisation passing the session cookie
574                self._getAttCert(sessCookie)
575           
576            if 'returnURI' in self:
577                # The authentication process is as a result of a redirect
578                # request from another site - redirect back to the remote site
579                # returning the credentials contained in the NDG security
580                self._processCredsRequest(sessCookie=sessCookie,
581                                          setCookie=True, 
582                                          **kwargs)
583               
584        elif bAuthorise:
585            # Handle a get attribute certificate request
586            self._getAttCert()
587                   
588        else:
589            # Remote site presents possible sites for user to get their
590            # credentials from
591            self.showHomeSiteSelect(**kwargs)
592
593
594    #_________________________________________________________________________
595    def _processCredsRequest(self,
596                             returnURI=None,
597                             bAuthorise=False, 
598                             sessCookie=None, 
599                             **returnCredsResponseKwArgs):
600        """Receive request from remote site for credentials.  Process and
601        return via a redirect"""
602
603        if returnURI is None:
604            returnURI = self['returnURI'].value
605                                                         
606        # Check for cookie in environment
607        if sessCookie is None and 'HTTP_COOKIE' in os.environ:
608   
609            # Get session ID from existing cookie
610            sessCookie = SimpleCookie(os.environ['HTTP_COOKIE'])
611
612        # Check for NDG cookie
613        if sessCookie and UserSession.isValidSecurityCookie(sessCookie):
614               
615            # Return cookie to requestor
616            self.returnCredsResponse(sessCookie, 
617                                     returnURI, 
618                                     **returnCredsResponseKwArgs)
619
620        else:
621            # No cookie present - display login.  Submit must redirect back to
622            # this script with '?authenticate=1&returnURI=<...>'
623            self.showLogin(returnURI=returnURI,
624                           bAuthorise=bAuthorise, 
625                           pageTitle="NDG Login")
626
627   
628    #_________________________________________________________________________
629    def _returnCredsResponse(self,
630                            sessCookie, 
631                            returnURI=None,
632                            pageTitle='',
633                            hdrTxt='',
634                            delayTime=0,
635                            redirectMsg='',
636                            setCookie=False):
637        """User's Identity Provider returns credentials to requestor via a
638        HTTP redirect
639       
640        sessCookie:   NDG Session cookie
641        pageTitle:    Give the redirect page a title
642        headTags:     Optionally add additional tags in <head/> section
643        delayTime:    time in seconds before carrying out redirect - redirect
644                      page will be displayed in this interval
645        redirectMsg:  Message to put on redirect page.  Can be plain text or
646                      formatted HTML"""
647
648        if returnURI is None:
649            returnURI = self['returnURI'].value
650                                         
651        if setCookie:
652            cookieTxt = sessCookie.output() + os.linesep
653        else:
654            cookieTxt = ''
655
656        # Check to see if the returnURI is in the same domain - if so there's
657        # no need to return any credentials in the redirect
658        cookieDomain = sessCookie[UserSession.cookieTags[0]]['domain']
659        if cookieDomain and cookieDomain in returnURI:
660            print """Content-type: text/html
661%s
662<html>
663<head>
664<title>%s</title>
665<meta http-equiv="REFRESH"
666content="%d; url=%s">
667%s
668</head>
669<body>
670%s
671</body>
672</html>""" % ( cookieTxt,
673               pageTitle,
674               delayTime,
675               returnURI,
676               hdrTxt,
677               redirectMsg)
678           
679        else:
680            # returnURI is in a different domain - return the credentials
681            #
682            # Allow for case where return URI already includes some args
683            if '?' in returnURI:
684                argSeparator = '&'
685            else:
686                argSeparator = '?'
687   
688   
689            print """Content-type: text/html
690%s
691<html>
692<head>
693<title>%s</title>
694<meta http-equiv="REFRESH"
695content="%d; url=%s%sNDG-ID1=%s&NDG-ID2=%s&expires=%s">
696%s
697</head>
698<body>
699%s
700</body>
701</html>""" % ( cookieTxt,
702               pageTitle,
703               delayTime,
704               returnURI,
705               argSeparator,
706               sessCookie['NDG-ID1'].value,
707               sessCookie['NDG-ID2'].value,
708               base64.urlsafe_b64encode(sessCookie['NDG-ID1']['expires']),
709               hdrTxt,
710               redirectMsg)
711   
712   
713    #_________________________________________________________________________
714    def _authenticate(self, bAuthorise=False):
715        """Authenticate username and passphrase input from preceeding login
716        form
717
718        bAuthorise: set to True so that if an error occurs, login will be
719                    recalled followed by authorisation"""
720
721        self.userName = 'userName' in self and self['userName'].value or None
722        self.passPhrase = \
723                    'passPhrase' in self and self['passPhrase'].value or None
724                   
725        returnURI = 'returnURI' in self and self['returnURI'].value or None
726           
727           
728        if self.userName is None:
729            self.showLogin(returnURI=returnURI,
730                           bAuthorise=bAuthorise,
731                           pageTitle="Login - error no username set")
732            raise SecurityCGIError, "no username set for authentication"
733
734        if self.passPhrase is None:
735            self.showLogin(returnURI=returnURI,
736                           bAuthorise=bAuthorise,
737                           pageTitle="Login - error no pass-phrase set")
738            raise SecurityCGIError, "no pass-phrase set for authentication"
739
740
741        # Instantiate WS proxy and request connection
742        try:
743            if not self.smClnt:
744                self.smClnt = SessionClient(smWSDL=self.smWSDL,
745                               smPubKeyFilePath=self.smPubKeyFilePath,
746                               clntPubKeyFilePath=self.clntPubKeyFilePath,
747                               clntPriKeyFilePath=self.clntPriKeyFilePath,
748                               traceFile=self._wsDebug and sys.stderr or None)
749
750            sSessCookie = self.smClnt.connect(userName=self.userName,
751                                         pPhrase=self.passPhrase,
752                                         clntPriKeyPwd=self.clntPriKeyPwd)
753            sessCookie = SimpleCookie(sSessCookie)
754            return sessCookie
755
756        except Exception, e:
757            self.showLogin(returnURI=returnURI,
758                           bAuthorise=bAuthorise,
759                           pageTitle="Login - internal error")
760            raise SecurityCGIError, "Session client: %s" % e
761
762   
763    #_________________________________________________________________________
764    def showLogin(self,
765                  returnURI=None,
766                  contentTypeHdr=True,
767                  htmlTag=True,
768                  pageTitle='',
769                  hdrTxt='',
770                  headTag=True,
771                  bodyTag=True,
772                  bAuthorise=False):
773        """Display initial NDG login form"""
774   
775        if contentTypeHdr: print "Content-type: text/html\n\n"
776       
777        if htmlTag: print "<html>"
778   
779        if headTag:
780            if not hdrTxt:
781                hdrTxt = """    <style type=\"text/css\">
782<!--
783.al {
784text-align: justify
785}
786a{
787text-decoration:none;
788}
789a:hover{
790color:#0000FF;
791}
792    body { font-family: Verdana, sans-serif; font-size: 11}
793    table { font-family: Verdana, sans-serif; font-size: 11}
794-->
795</style>"""
796                   
797            print """<head>
798        <title>%s</title>
799        %s
800    </head>""" % (pageTitle, hdrTxt)
801   
802   
803        if bodyTag: print "<body>"
804
805
806        if returnURI is None and 'returnURI' in self:
807            returnURI = self['returnURI'].value
808
809        if returnURI:
810            returnURIfield = \
811                "<input type=hidden name=returnURI value=\"%s\">" % returnURI
812        else:
813            returnURIfield = ''
814       
815   
816        if bAuthorise:
817            authoriseArg = "<input type=hidden name=authorise value=\"1\">"
818        else:
819            authoriseArg = ""
820   
821   
822        # Set authorisation method default
823        acMappingFlagChkBox = {}.fromkeys(self.acMappingFlag, '')
824   
825        if self.acMappingFlag is None:
826            # Default to safest option for user
827            acMappingFlagChkBox[self.acAllowMappingWithPrompt] = ' checked'
828        else:
829            acMappingFlagChkBox[self.acMappingFlag] = ' checked'
830   
831        print \
832    """<script language="javascript">
833    <!--
834        function toggleLayer(layerId)
835        {
836            if (document.getElementById)
837            {
838                // Standard
839                var style = document.getElementById(layerId).style;
840            }
841            else if (document.all)
842            {
843                // Old msie versions
844                var style = document.all[whichLayer].style;
845            }
846            else if (document.layers)
847            {
848                // nn4
849                var style = document.layers[whichLayer].style;
850            }
851            style.visibility = style.visibility == "visible" ?
852"hidden":"visible";        }
853    //-->
854    </script>
855    <h3>NERC Data Grid Site Login (Test)<BR clear=all></h3>
856    <hr>
857   
858    <form action="%s" method="POST">
859   
860    <table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
861    <tbody>
862    <tr><td>User Name:</td> <td><input type=text name=userName value="">
863    </td></tr>
864    <tr>
865        <td>Password:</td>
866        <td><input type=password name=passPhrase></td>
867    </tr>
868    <tr>
869        <td colspan="2" align="right">
870            <a href="javascript:toggleLayer('advSettings');">Advanced
871Settings</a>            <input type=submit value="Login">
872        </td>
873    </tr>
874    <input type=hidden name=authenticate value="1">
875    %s"""  % (self.scriptName, returnURIfield)
876   
877        print \
878    """</tbody></table>
879    <br>
880    <div id="advSettings" style="position: relative; visibility: hidden;">
881        <h4>Role Mapping for access to other trusted sites</h4>
882        <p>Your account has roles or <i>privileges</i> which determine what
883        data you have access to.  If you access data at another NDG trusted
884        site, these roles can be mapped to local roles at that site to help
885        you gain access:
886        </p>   
887        <table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
888        <tbody>
889        <tr>
890            <td>
891                <input type="radio" name="authorisationMethod" value="%s"%s>
892            </td>
893            <td>
894            Allow my roles to be mapped to local roles at other NDG trusted
895            sites.
896            </td>
897        </tr>
898        <tr>
899            <td>
900                <input type="radio" name="authorisationMethod" value="%s"%s>            </td>
901            <td>
902            Allow my roles to be mapped, but prompt me so that I may choose
903            which roles to map before gaining access.
904            </td>
905        <tr>
906            <td>
907                <input type="radio" name="authorisationMethod" value="%s"%s>
908            </td>
909            <td>
910                Don't allow mapping of my roles.
911            </td>
912        </tr>
913        </tbody>
914        </table>
915    </div>
916    </form>
917    """ % (self.acAllowMapping,
918           acMappingFlagChkBox[self.acAllowMapping], 
919           self.acAllowMappingWithPrompt,
920           acMappingFlagChkBox[self.acAllowMappingWithPrompt],
921           self.acNoMapping,
922           acMappingFlagChkBox[self.acNoMapping])
923   
924        if bodyTag: print "</body>"
925        if htmlTag: print "</html>"
926   
927        # end of showLogin()
Note: See TracBrowser for help on using the repository browser.