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

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

Putting browse code into a module to make it easier
to coexist with other cgi scripts etc ...

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                trustedHostDict=AA.getTrustedHostInfo(role=parsedSimpleCondition[0])
107                loginHostList=[]
108                for key in trustedHostDict:
109                    loginHostList.append((key,trustedHostDict[key]['loginURI']))
110               
111                return self.__showSiteList(loginHostList)
112               
113        def __reEstablish(self):
114                ''' bind to local session manager which acts as a proxy '''
115               
116                self.__loadKeys()
117                smWSDL=self.config.get('security','localSM',None)
118                try:
119                        #set up session client
120                        # (all these keys to do message level encryption while talking to server,
121                        # see __loadKeys for more details)
122                        self.smClient = SessionClient(smWSDL=smWSDL,
123                                    smPubKeyFilePath=self.__localSessionManagerPublicKey,
124                                    clntPubKeyFilePath=self.__thisCGIpublicKey,
125                                    clntPriKeyFilePath=self.__thisCGIprivateKey)
126                        self.connected=1
127                except Exception, e:
128                        # Socket error returns tuple - reformat to just give msg
129                        #raise SecurityCGIError("Session client: " + str(e))
130                        pass # for now we don't have the libraries or code attached
131       
132        def __loadKeys(self):
133                ''' Load security keys '''
134               
135                # We (potentially) need the public and private keys of this cgi script
136                # and the public key of the session client if our communication goes
137                # out over the public network and we want to deploy message
138                # level encryption.
139                 
140                #However, for the first installation, we will assume both the CGI and
141                #the session manager are running behind the same firewall.
142               
143                self.__thisCGIpublicKey=None
144                self.__thisCGIprivateKey=None
145               
146                #these are the things I need to talk to my local session manager
147                self.__localSessionManagerPublicKey=None
148                self.__localSessionManagerProxyWSDL=self.config.get('Security','localSM',None)
149               
150                #we need to call out to smWSDL to get their public key as a first step?
151                #self.__remoteSessionManagerPublicKey=self.__getKey(smWSDL)
152               
153                return
154       
155        def __getPublicKey(self,smWSDL):
156                ''' Given the WSDL address of a session manager object, get the public key associated
157                with it '''
158                return None
159       
160        def __showSiteList(self,loginList,heading=''):
161            '''Show the user a list of trusted hosts, and redirect to one of them '''
162            html='''<p> Access to resource [<b>%s</b>] requires credentials, please login ...'
163                    <hr>
164                    <form action="https://glue.badc.rl.ac.uk/cgi-bin/security.py" method="POST">
165                    <table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
166                    <tbody><tr>
167                    <td><select name="requestURI">
168                    <option value="">Select your home site...'''%self.url
169            for i,j in loginList:
170                html+='<option value="%s">%s'%(j,i)
171            html+='''</select></td>
172                    <td align="right"><input type=submit value="Login"></td>
173                    </tr></tbody>
174                    </table>
175                    <input type="hidden" name="returnURI" value="%s">
176                    </form>
177                    </body>
178                    </html>'''%self.url
179            return html
180
181   
182   
Note: See TracBrowser for help on using the repository browser.