source: TI07-MOLES/trunk/StubB/XSLT/browse/portal/cgi/secure.py @ 991

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI07-MOLES/trunk/StubB/XSLT/browse/portal/cgi/secure.py@991
Revision 991, 8.0 KB checked in by lawrence, 13 years ago (diff)

Browse now goes through to prompting the user for
a login host (from a made up list)

Line 
1from Utilities import wrapGetText
2from NDG.SecurityClient import *
3
4
5class AccessControl:
6       
7        ''' Handle the access control metadata and provide three attributes of the
8        access control: exists (existence), status (modified elsewhere for whether
9        user can access data), and html (a message about the constraints). '''
10       
11        def __init__(self,e):
12                if e is None:
13                        self.status=1
14                        self.exist=0
15                        self.html=''
16                else:
17                        #for now assume everything with a simplecondition is deny
18                        self.html=wrapGetText(e,'dgSecurityCondition/conditionExplanationText')
19                        sc='dgSecurityCondition/simpleCondition/'
20                        self.SimpleCondition=(wrapGetText(e,sc+'attrauthRole'),
21                                              wrapGetText(e,sc+'dgAttributeAuthority'))
22                        if self.SimpleCondition==('',''): self.SimpleCondition=None
23                        self.status=0
24                        self.exist=1
25               
26class gateway2NDGsession:
27       
28        ''' This class provides a gateway to the NDG session manager and methods upon it '''
29
30        def __init__(self,url,config,desiredAA=None,cookie=None,cmdLine=None):
31               
32                ''' The use case is that we attempt to establish a gateway to an
33                existing NDG session. If it exists, fine, if it doesn't, then we
34                don't do anything, but wait til a check call before attempting
35                to establish a connection ... that way we can prompt with an appropriate
36                set of hosts.
37               
38                If an NDG cookie exists, or we have it on the commandline, we use it
39                by reEstablishing to the existing session.
40                '''
41               
42                #First we have to see if the ndgsecurity info is in the cooki
43                self.url=url
44                self.connected=0
45                self.config=config
46                if cookie is not None:
47                    if self.__SecCookie(): 
48                        self.__reEstablish(cookie=cookie)
49                        return
50                if cmdLine is not None:
51                    self.__reEstablish(cmdLine=cmdLine)
52               
53               
54        def check(self, parsedSimpleCondition):
55                ''' can the credentials in the wallet support access to the resource requiring
56                the role at wsdlAA - parsedSimpleCondition is a tuple - (role, wsdlAA) '''
57                #connect using cookie
58
59                #first make sure we've got real conditions, if not, deny ...
60                if parsedSimpleCondition is None: return 0
61
62                #if not connected, get connected
63                if not self.connected: return self.__Establish(parsedSimpleCondition)
64
65                resp = self.smClient.reqAuthorisation(sessCookie=cookieObj,
66                                    aaWSDL=wsdlAA,
67                                    aaPubKey=None, # the session client can get that from the WSDL
68                                    reqRole=role,
69                                    rtnExtAttCertList=None, #auto select role map for now
70                                    clntPriKeyPwd=None # not using encrypted yet
71                                    )
72                return 'AccessGranted'
73               
74        def __SecCookie(self):
75                ''' Check the current cookie and see if it contains security information, but
76                we (the CGI) don't need to parse it - that's done in the NDG session client'''
77                if self.cookie is None:
78                    return 0
79                else:
80                    try:
81                        for i in ('NDG-ID1','NDG-ID2'): 
82                            if i not in self.cookie: return 0
83                    except: 
84                        return 0
85                return 1
86                       
87        def __map2loginHosts(self,trustedHostList):
88            ''' Map from a list of attribute authority wsdl (which is what you get from
89            the attempt to obtain access) to a list of session manager wsdl addresses
90            and short names ''' 
91            # requires a new method on the AA wsdl ...
92            # what would happen if one of these requests timed out? How would we time it out?
93            result=[]
94            #following line for testing only - forces login at BADC
95            result.append(('BADC','http://glue.badc.rl.ac.uk/sessionMgr.wsdl'))
96            return result
97            for role,host in trustedHostList:
98                AA=AttAuthorityClient(aaWSDL=host)
99                loginName,loginURL=AA.getLoginHost()
100                result.append((loginName,loginURL))
101            return result
102                                               
103        def __Establish(self,parsedSimpleCondition):
104                ''' Establish an NDG security session. We work out who to login
105                with by getting the list of trusted hosts from the parsedSimpleCondition
106                (which is just a tuple - role, attribute authority). This results in
107                a redirect to a user chosen host, after which we get back a URI with
108                the cookie posted as a (hidden) uri argument '''
109               
110                AA=AttAuthorityClient(aaWSDL=parsedSimpleCondition[1])
111                trustedHostList=AA.getTrustedHostInfo(role=parsedSimpleCondition[0])
112                loginHostList=self.__map2loginHosts(trustedHostList)   
113                return self.__showSiteList(loginHostList)
114               
115        def __reEstablish(self,cookie=None,cmdLine=None):
116                ''' bind to the existing WSDL '''
117               
118                if cmdLine is not None:
119                    sessID,encrSessMgrWDLURI=urldecode(cmdLine)
120               
121                self.__loadKeys()
122                try:
123                        #set up session client
124                        # (all these keys to do message level encryption while talking to server,
125                        # see __loadKeys for more details)
126                        self.smClient = SessionClient(
127                                    sessCookie=cookie,
128                                    encrSessMgrWSDLuri=WSDLuri,
129                                    sessID=sessID,
130                                    smPubKeyFilePath=self.__localSessionManagerPublicKey,
131                                    clntPubKeyFilePath=self.__thisCGIpublicKey,
132                                    clntPriKeyFilePath=self.__thisCGIprivateKey,
133                            traceFile=traceFile)
134                        self.connected=1
135                except Exception, e:
136                        # Socket error returns tuple - reformat to just give msg
137                        #raise SecurityCGIError("Session client: " + str(e))
138                        pass # for now we don't have the libraries or code attached
139
140       
141       
142        def __loadKeys(self):
143                ''' Load security keys '''
144               
145                # We (potentially) need the public and private keys of this cgi script
146                # and the public key of the session client if our communication goes
147                # out over the public network and we want to deploy message
148                # level encryption.
149                 
150                #However, for the first installation, we will assume both the CGI and
151                #the session manager are running behind the same firewall.
152               
153                self.__thisCGIpublicKey=None
154                self.__thisCGIprivateKey=None
155               
156                #these are the things I need to talk to my local session manager
157                self.__localSessionManagerPublicKey=None
158                self.__localSessionManagerProxyWSDL=self.config.get('Security','localSM',None)
159               
160                #we need to call out to smWSDL to get their public key as a first step?
161                #self.__remoteSessionManagerPublicKey=self.__getKey(smWSDL)
162               
163                return
164       
165        def __getPublicKey(self,smWSDL):
166                ''' Given the WSDL address of a session manager object, get the public key associated
167                with it '''
168                return None
169       
170        def __showSiteList(self,loginList,heading=''):
171            '''Show the user a list of trusted hosts, and redirect to one of them '''
172            html='''<p> Access to resource [<b>%s</b>] requires credentials from one of
173                the following sites, please login ...'
174                    <hr>
175                    <form action="./xNDGtransfer.py" method="POST">
176                    <table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
177                    <tbody><tr>
178                    <td><select name="requestURI">
179                    <option value="">Select your home site...'''%self.url
180            for i,j in loginList:
181                html+='<option value="%s">%s'%(j,i)
182            html+='''</select></td>
183                    <td align="right"><input type=submit value="Login"></td>
184                    </tr></tbody>
185                    </table>
186                    <input type="hidden" name="returnURL" value="%s">
187                    </form>
188                    </body>
189                    </html>'''%self.url
190            return html
191
192   
193   
Note: See TracBrowser for help on using the repository browser.