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

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

Support for the new hostinfo call in security

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