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.ViewTextOnly,self.ViewXML=0,0 |
---|
108 | if self.FieldStorage.has_key('text'): |
---|
109 | self.ViewTextOnly=1 |
---|
110 | elif self.FieldStorage.has_key('xml'): |
---|
111 | self.ViewXML=1 |
---|
112 | |
---|
113 | self.session=BrowseSession(self.cookie,self.uri,self.config) |
---|
114 | if self.config.logfile is not None: self.config.log(self.cookie) |
---|
115 | |
---|
116 | #Handle authorisation |
---|
117 | self.ac=self.session.getCredentials() |
---|
118 | |
---|
119 | #get the xml document |
---|
120 | db=self.config.get('db','exist',None) |
---|
121 | xml=insecureGetDoc(self.uri,db) |
---|
122 | |
---|
123 | #create stub-b instance |
---|
124 | self.b=stubB(xml,makeHTML=renderEntity) |
---|
125 | |
---|
126 | if self.b.xml is None: |
---|
127 | content=self.error('Unable to obtain stub-B from database') |
---|
128 | else: |
---|
129 | self.session.addToHistory(self.b.Burl,self.b.abbreviation) |
---|
130 | self.response.cookie=self.session.makeCookie() |
---|
131 | if self.b.constraints.exist: |
---|
132 | # we need to evaluate them |
---|
133 | access=self.session.ndgGate.check(self.b.constraints.SimpleCondition) |
---|
134 | else: |
---|
135 | access=1 |
---|
136 | if access: |
---|
137 | if self.ViewTextOnly: |
---|
138 | self.response.contentType='text/text' |
---|
139 | content=et2text(self.b.tree) |
---|
140 | elif self.ViewXML=1: |
---|
141 | content=et2HTML(self.b.tree) |
---|
142 | else: |
---|
143 | content=self.b.toHTML() |
---|
144 | else: |
---|
145 | content=self.error('No access to Secure Metadata') |
---|
146 | |
---|
147 | if not self.ViewTextOnly: |
---|
148 | historyHTML='<p>' |
---|
149 | for item in self.session.getHistory(): |
---|
150 | historyHTML+='<a href="%s">%s</a><br/>'%item |
---|
151 | historyHTML+='</p>' |
---|
152 | self.response.content=renderPage( |
---|
153 | content,historyHTML,historyHTML,self.b.name,self.config) |
---|
154 | |
---|
155 | return self.response |
---|
156 | |
---|
157 | def error(self,message): |
---|
158 | ''' Construct a nice formal response, but don't throw a 404 ... ''' |
---|
159 | return '<p>Error: %s</p>'%message |
---|
160 | |
---|