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

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

Tests/AttAuthorityIOtest.py: added testTrustedHosts3 to test results from livglue

Tests/security.py: returnURI input to init isn't needed - it can be picked up from as a form variable.

NDG/SecurityCGI.py: returnCreds renamed to returnCredsResponse. This method now checks the domain of the input
cookie. If this matches that of the returnURI, then there is no need to return the cookie information as they
can share the cookie.

NDG/Session.py: Created a metaclass _MetaUserSession for UserSession?. This enables UserSession? to have read-
only class variables - e.g. "cookieTags"

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