1 | #!/usr/bin/env python |
---|
2 | # CGI Script to support prototype NDG MOLES_Portal (Browse) functionality |
---|
3 | # Bryan Lawrence, April, 2006 |
---|
4 | |
---|
5 | import cgi |
---|
6 | #import cgitb;ctitb.enable() |
---|
7 | |
---|
8 | import os |
---|
9 | import ElementTree as ET |
---|
10 | |
---|
11 | from insecure import * |
---|
12 | from secure import * |
---|
13 | from stubB import * |
---|
14 | |
---|
15 | from renderEntity import renderEntity |
---|
16 | from renderPage import renderPage |
---|
17 | from Utilities import * |
---|
18 | |
---|
19 | import Cookie |
---|
20 | |
---|
21 | class BrowseSession: |
---|
22 | |
---|
23 | ''' Holds the browse history and contact details for the NDG session manager, designed |
---|
24 | to work with the discovery portal as well ''' |
---|
25 | |
---|
26 | def __init__(self,cookie,url,config): |
---|
27 | |
---|
28 | '''Instantiate with an unsecured browse session (security only |
---|
29 | required if a secure resource is the target) ''' |
---|
30 | self.config=config |
---|
31 | self.rawCookie=cookie |
---|
32 | self.cookie=Cookie.SimpleCookie(cookie) |
---|
33 | self.history=RingBuffer(10) |
---|
34 | self.__loadBrowseHistory() |
---|
35 | |
---|
36 | def makeGateway(self): |
---|
37 | ''' Make connection to NDG security ''' |
---|
38 | self.ndgGate=gateway2NDGsession(self.rawCookie,self.config) |
---|
39 | |
---|
40 | def __toXML(self): |
---|
41 | ''' Used to serialise the history into a cookie string ''' |
---|
42 | xml='<BH>' |
---|
43 | for uri,name in self.getHistory(): |
---|
44 | xml+='<i><u>%s</u><n>%s</n></i>'%(uri,name) |
---|
45 | xml+='</BH>' |
---|
46 | return xml |
---|
47 | |
---|
48 | def __loadBrowseHistory(self): |
---|
49 | ''' get the string of URI values out of the cookie (if it's there)''' |
---|
50 | try: |
---|
51 | self.tree=ET.fromstring(self.cookie['BrowseHistory'].value) |
---|
52 | for item in self.tree: |
---|
53 | self.addToHistory(item.find('u').text,item.find('n').text,ignore=True) |
---|
54 | except: |
---|
55 | pass |
---|
56 | def addToHistory(self,uri,name,ignore=False): |
---|
57 | ''' Add a URI to the session history''' |
---|
58 | if not ignore: |
---|
59 | current=self.getHistory() |
---|
60 | if (uri,name) not in current: |
---|
61 | self.history.append((uri,name)) |
---|
62 | else: |
---|
63 | self.history.append((uri,name)) |
---|
64 | def getHistory(self): |
---|
65 | ''' Return a list of the items in the history ''' |
---|
66 | return self.history.tolist() |
---|
67 | def getCredentials(self): |
---|
68 | '''Obtain the attribute certificate from the wallet ''' |
---|
69 | return 'empty attribute certificate' |
---|
70 | def makeCookie(self): |
---|
71 | ''' Create a local cookie ''' |
---|
72 | import md5,time,base64 |
---|
73 | # start by creating a unique session id |
---|
74 | m=md5.new() |
---|
75 | m.update('this is a seed string') |
---|
76 | m.update(str(time.time())) |
---|
77 | cookie=Cookie.SimpleCookie() |
---|
78 | cookie['session']=base64.encodestring(m.digest())[:-3].replace("/", "$") |
---|
79 | cookie['BrowseHistory']=self.__toXML() |
---|
80 | return cookie |
---|
81 | |
---|
82 | class CGIcontroller: |
---|
83 | ''' Currently holds the cgi environment and controls ''' |
---|
84 | |
---|
85 | def __init__(self): |
---|
86 | ''' Instantiate the CGI environment''' |
---|
87 | self.env=os.environ |
---|
88 | self.path=self.env.get('PATH_INFO','/') |
---|
89 | self.FieldStorage=cgi.FieldStorage() |
---|
90 | self.config=myConfig('cgi/browse.config') |
---|
91 | self.response=Response() |
---|
92 | |
---|
93 | def goforit(self): |
---|
94 | ''' This method actually responds to the user''' |
---|
95 | |
---|
96 | #Instantiate the Session Environment |
---|
97 | self.cookie=self.env.get('HTTP_COOKIE',None) |
---|
98 | |
---|
99 | #this will do for the moment, although I'd rather the whole |
---|
100 | #URI was self consistent ... |
---|
101 | |
---|
102 | if self.FieldStorage.has_key('uri'): |
---|
103 | self.uri=self.FieldStorage['uri'].value |
---|
104 | else: |
---|
105 | return self.error('No valid URI') |
---|
106 | |
---|
107 | self.session=BrowseSession(self.cookie,self.uri,self.config) |
---|
108 | if self.config.logfile is not None: self.config.log(self.cookie) |
---|
109 | |
---|
110 | #Handle authorisation |
---|
111 | self.ac=self.session.getCredentials() |
---|
112 | |
---|
113 | #get the xml document |
---|
114 | db=self.config.get('db','exist',None) |
---|
115 | xml=insecureGetDoc(self.uri,db) |
---|
116 | |
---|
117 | #create stub-b instance |
---|
118 | self.b=stubB(xml,makeHTML=renderEntity) |
---|
119 | |
---|
120 | if self.b.xml is None: |
---|
121 | content=self.error('Unable to obtain stub-B from database') |
---|
122 | else: |
---|
123 | self.session.addToHistory(self.b.Burl,self.b.abbreviation) |
---|
124 | self.response.cookie=self.session.makeCookie() |
---|
125 | if self.b.constraints.exist: |
---|
126 | # we need to evaluate them |
---|
127 | access=self.session.ndgGate.check(self.b.constraints.SimpleCondition) |
---|
128 | else: |
---|
129 | access=1 |
---|
130 | if access: |
---|
131 | content=self.b.toHTML() |
---|
132 | else: |
---|
133 | content=self.error('No access to Secure Metadata') |
---|
134 | |
---|
135 | historyHTML='<p>' |
---|
136 | for item in self.session.getHistory(): |
---|
137 | historyHTML+='<a href="%s">%s</a><br/>'%item |
---|
138 | historyHTML+='</p>' |
---|
139 | self.response.content=renderPage( |
---|
140 | content,historyHTML,historyHTML,self.b.name,self.config) |
---|
141 | return self.response |
---|
142 | |
---|
143 | def error(self,message): |
---|
144 | ''' Construct a nice formal response, but don't throw a 404 ... ''' |
---|
145 | return '<p>Error: %s</p>'%message |
---|
146 | |
---|