1
|
/**
|
2
|
* '$RCSfile$'
|
3
|
* Purpose: A Class that tracks sessions for MetaCatServlet users.
|
4
|
* Copyright: 2000 Regents of the University of California and the
|
5
|
* National Center for Ecological Analysis and Synthesis
|
6
|
* Authors: Matt Jones
|
7
|
* Release: @release@
|
8
|
*
|
9
|
* '$Author: bojilova $'
|
10
|
* '$Date: 2000-09-13 13:07:55 -0700 (Wed, 13 Sep 2000) $'
|
11
|
* '$Revision: 446 $'
|
12
|
*/
|
13
|
|
14
|
package edu.ucsb.nceas.metacat;
|
15
|
|
16
|
import javax.servlet.http.HttpSession;
|
17
|
import javax.servlet.http.HttpServletRequest;
|
18
|
import javax.servlet.http.HttpServletResponse;
|
19
|
import java.util.Properties;
|
20
|
import java.util.PropertyResourceBundle;
|
21
|
import java.util.Stack;
|
22
|
import java.io.FileInputStream;
|
23
|
import java.io.PrintWriter;
|
24
|
import java.rmi.*;
|
25
|
import SrbJavaGlueInterface;
|
26
|
import RMIControllerInterface;
|
27
|
|
28
|
/**
|
29
|
* A Class that implements session tracking for MetaCatServlet users.
|
30
|
* User's login data are stored in the session object.
|
31
|
* User authentication is made through SRB RMI Connection.
|
32
|
*/
|
33
|
public class MetaCatSession {
|
34
|
|
35
|
static String debug = null;
|
36
|
HttpSession session = null;
|
37
|
|
38
|
// DCS-ATTRIBUTE-INDEX
|
39
|
// They are from mdasC_db2_externs.h.
|
40
|
final static int USER_NAME = 7;
|
41
|
final static int USER_GROUP_NAME = 3;
|
42
|
|
43
|
// JNI (Java Native Interface) routines for SRB
|
44
|
static String srbHost;
|
45
|
static String srbPort;
|
46
|
static String RMIhost;
|
47
|
static RMIControllerInterface rmicon;
|
48
|
static SrbJavaGlueInterface srbJG;
|
49
|
static {
|
50
|
try {
|
51
|
PropertyResourceBundle SRBProps = null;
|
52
|
// SRB properties that tells about the location of SRB RMI Server
|
53
|
// srbProps.properties should reside on metacat server
|
54
|
SRBProps = (PropertyResourceBundle)
|
55
|
PropertyResourceBundle.getBundle("edu.ucsb.nceas.metacat.srbProps");
|
56
|
srbHost = (String)SRBProps.handleGetObject("host");
|
57
|
srbPort = (String)SRBProps.handleGetObject("port");
|
58
|
// should handle missing RMIhost name here
|
59
|
RMIhost = (String)SRBProps.handleGetObject("RMIhost");
|
60
|
String name = "//" + RMIhost + "/RMIController";
|
61
|
rmicon = (RMIControllerInterface)Naming.lookup(name);
|
62
|
name = "//" + RMIhost + "/SrbJavaGlue";
|
63
|
srbJG = (SrbJavaGlueInterface)Naming.lookup(name);
|
64
|
} catch (Exception e) {
|
65
|
System.err.println("MetaCatSession static: " + e.getMessage());
|
66
|
System.exit(0);
|
67
|
}
|
68
|
}
|
69
|
|
70
|
/** Construct a MetaCatSession
|
71
|
*
|
72
|
* @param request the request made from the client
|
73
|
* @param username the username entered when login
|
74
|
* @param password the password entered when login
|
75
|
*/
|
76
|
public MetaCatSession (HttpServletRequest request,
|
77
|
String username, String password)
|
78
|
throws IllegalStateException {
|
79
|
// create a new HTTPSession object
|
80
|
this.session = getSession(request, username, password);
|
81
|
}
|
82
|
|
83
|
/** Get new HttpSession and store username & password in it */
|
84
|
private HttpSession getSession(HttpServletRequest request,
|
85
|
String username, String password)
|
86
|
throws IllegalStateException {
|
87
|
|
88
|
// get the current session object, create one if necessary
|
89
|
HttpSession sess = request.getSession(true);
|
90
|
// if it is still in use unvalidate and get a new one
|
91
|
if ( !sess.isNew() ) {
|
92
|
sess.invalidate();
|
93
|
sess = request.getSession(true);
|
94
|
}
|
95
|
// store username & password in the session for later use if necessary
|
96
|
sess.setMaxInactiveInterval(-1);
|
97
|
sess.setAttribute("username", username);
|
98
|
sess.setAttribute("password", password);
|
99
|
|
100
|
return sess;
|
101
|
}
|
102
|
|
103
|
/** handle Login action for MetaCatServlet
|
104
|
*/
|
105
|
public String userLogin(HttpServletResponse response,
|
106
|
String username, String password,
|
107
|
String action, String htmlpath) {
|
108
|
|
109
|
String out = null;
|
110
|
|
111
|
// for public connection only
|
112
|
// this does not go through auth checking in SRB
|
113
|
// the final implementation will need auth checking in SRB for public
|
114
|
if ( username.equals("public") ) {
|
115
|
try {
|
116
|
if (action.equals("Login Client")) {
|
117
|
String message = "User Authentication successful";
|
118
|
out = formatOutput("success", message);
|
119
|
return out;
|
120
|
} else {
|
121
|
response.sendRedirect(
|
122
|
response.encodeRedirectUrl(htmlpath + "/index.html"));
|
123
|
}
|
124
|
} catch ( java.io.IOException ioe) {
|
125
|
disconnect();
|
126
|
String message = "MetaCatSession.userLogin() - " +
|
127
|
"Error on redirect of HttpServletResponse: " +
|
128
|
ioe.getMessage();
|
129
|
out = formatOutput("error", message);
|
130
|
return out;
|
131
|
}
|
132
|
}
|
133
|
|
134
|
// Auth checking in SRB.
|
135
|
// It fails if not registered user provided.
|
136
|
// It gets all users/groups from MCAT for implementing ACL for MetaCat
|
137
|
// The last one probably will need to be done on separate MetaCatServlet
|
138
|
// action instead on Login action
|
139
|
try {
|
140
|
if ( userAuth(username, password) ) {
|
141
|
try {
|
142
|
if (action.equals("Login Client")) {
|
143
|
|
144
|
String message = "User Authentication successful";
|
145
|
out = formatOutput("success", message);
|
146
|
|
147
|
} else {
|
148
|
response.sendRedirect(
|
149
|
response.encodeRedirectUrl(htmlpath + "/metacat.html"));
|
150
|
}
|
151
|
} catch ( java.io.IOException ioe) {
|
152
|
disconnect();
|
153
|
String message = "MetaCatSession.userLogin() - " +
|
154
|
"Error on redirect of HttpServletResponse: " +
|
155
|
ioe.getMessage();
|
156
|
out = formatOutput("error", message);
|
157
|
}
|
158
|
// the user has not been authenticated by SRB
|
159
|
} else {
|
160
|
disconnect();
|
161
|
String message = "SRB Connection failed. " +
|
162
|
"SRB RMI Server is not running now or " +
|
163
|
"user " + username +
|
164
|
" has not been authenticated to use the system.";
|
165
|
out = formatOutput("error", message);
|
166
|
}
|
167
|
} catch ( java.rmi.RemoteException re) {
|
168
|
disconnect();
|
169
|
String message = "SRB Connection failed. " + re.getMessage();
|
170
|
out = formatOutput("error", message);
|
171
|
}
|
172
|
|
173
|
return out;
|
174
|
}
|
175
|
|
176
|
/* format the output in xml for processing from client appl
|
177
|
*/
|
178
|
private String formatOutput(String tag, String message) {
|
179
|
|
180
|
StringBuffer out = new StringBuffer();
|
181
|
|
182
|
out.append("<?xml version=\"1.0\"?>\n");
|
183
|
out.append("<" + tag + ">");
|
184
|
if ( tag.equals("error") ) {
|
185
|
out.append(message);
|
186
|
} else {
|
187
|
out.append("\n <message>" + message + "</message>\n");
|
188
|
String username = (String)this.session.getAttribute("username");
|
189
|
out.append(" <username>" + username + "</username>\n");
|
190
|
if ( username.equals("public") ) {
|
191
|
out.append("</" + tag + ">");
|
192
|
return out.toString();
|
193
|
}
|
194
|
String groupname = (String)this.session.getAttribute("groupname");
|
195
|
out.append(" " + groupname + "\n");
|
196
|
|
197
|
Stack usersGroups = new Stack();
|
198
|
usersGroups = (Stack)this.session.getAttribute("usersgroups");
|
199
|
String val = "";
|
200
|
StringBuffer res = new StringBuffer();
|
201
|
while ( !usersGroups.empty() ) {
|
202
|
val = " " + (String)usersGroups.pop() + "\n" + val;
|
203
|
if ( val.startsWith(" <groupname>") ) {
|
204
|
val = " <group>\n" + val + " </group>\n";
|
205
|
res.insert(0, val);
|
206
|
val = "";
|
207
|
}
|
208
|
}
|
209
|
out.append(res.toString());
|
210
|
}
|
211
|
out.append("</" + tag + ">");
|
212
|
|
213
|
return out.toString();
|
214
|
|
215
|
}
|
216
|
|
217
|
/** Try to make user authentication through SRB RMI Connection
|
218
|
* Using that connection to get:
|
219
|
* . the groupname of connected user;
|
220
|
* . a whole list of all groups and users in MCAT.
|
221
|
*/
|
222
|
private boolean userAuth(String username, String password)
|
223
|
throws RemoteException {
|
224
|
// synchronized(this) {
|
225
|
int srbconn = 0;
|
226
|
|
227
|
// look up for SRBJavaGlue
|
228
|
try {
|
229
|
String name = "//" + RMIhost + "/SrbJavaGlue";
|
230
|
srbJG = (SrbJavaGlueInterface)Naming.lookup(name);
|
231
|
} catch (Exception e) {
|
232
|
try {
|
233
|
rmicon.restart();
|
234
|
} catch (Exception rmie) {}
|
235
|
// The SRB server is not running or it is busy now
|
236
|
throw new
|
237
|
RemoteException("MetaCatSession look up for SrbJavaGlue failed");
|
238
|
}
|
239
|
|
240
|
// try SRB RMI Connection
|
241
|
// integer value of the SBR Connection ID is returned only
|
242
|
try {
|
243
|
srbconn = srbJG.rmiConnectJ( srbHost, srbPort, password, username );
|
244
|
} catch (RemoteException e) {
|
245
|
try {
|
246
|
rmicon.restart();
|
247
|
} catch (Exception rmie) {}
|
248
|
throw new RemoteException("MetaCatSession.userAuth() - " +
|
249
|
"Error on rmiConnectJ(): " + e.getMessage());
|
250
|
}
|
251
|
|
252
|
// check if successfull
|
253
|
if ( srbconn == 0 ) {
|
254
|
throw new RemoteException("The SRB Server is not running or it is busy now");
|
255
|
} else if ( srbconn < 0 ) {
|
256
|
try {
|
257
|
rmicon.restart();
|
258
|
} catch (Exception rmie) {}
|
259
|
return false;
|
260
|
}
|
261
|
|
262
|
// get the Group name of connected user;
|
263
|
String groupname = null;
|
264
|
try {
|
265
|
groupname = getGroupname(srbconn, username);
|
266
|
this.session.setAttribute("groupname", groupname);
|
267
|
} catch (RemoteException e) {
|
268
|
throw new RemoteException("MetaCatSession.userAuth() - " +
|
269
|
"Error on getGroupname(): " + e.getMessage());
|
270
|
}
|
271
|
// get all users and groups from MCAT
|
272
|
Stack usersGroupsList = new Stack();
|
273
|
try {
|
274
|
usersGroupsList = getUsersGroups(srbconn);
|
275
|
this.session.setAttribute("usersgroups", usersGroupsList);
|
276
|
} catch (RemoteException e) {
|
277
|
throw new RemoteException("MetaCatSession.userAuth() - " +
|
278
|
"Error on getUsersGroups(): " + e.getMessage());
|
279
|
}
|
280
|
|
281
|
|
282
|
// we don't need that connection. close it.
|
283
|
try {
|
284
|
int err = srbJG.rmiFinishJ( srbconn );
|
285
|
} catch (RemoteException e) {}
|
286
|
|
287
|
// store SRB Connection in the session for later use if necessary
|
288
|
this.session.setAttribute("srbconnection", new Integer(srbconn));
|
289
|
|
290
|
// try {
|
291
|
// wait(5000);
|
292
|
// } catch (Exception e) {}
|
293
|
// try {
|
294
|
// notifyAll();
|
295
|
// } catch (Exception e) {}
|
296
|
return true;
|
297
|
|
298
|
// } // end of synchronized(this)
|
299
|
}
|
300
|
|
301
|
// get the Groupname of connected user
|
302
|
private String getGroupname (int conn, String username)
|
303
|
throws RemoteException
|
304
|
{
|
305
|
|
306
|
String[] qval;
|
307
|
int[] qvalInx;
|
308
|
int[] selVal;
|
309
|
|
310
|
qval = new String [3];
|
311
|
qval[0] = new String (" not like '%$deleted%'");
|
312
|
qval[1] = new String (" = '" + username + "'");
|
313
|
qval[2] = new String (" <> 'public'");
|
314
|
|
315
|
qvalInx = new int[3];
|
316
|
qvalInx[0] = USER_NAME;
|
317
|
qvalInx[1] = USER_NAME;
|
318
|
qvalInx[2] = USER_GROUP_NAME;
|
319
|
|
320
|
selVal = new int[2];
|
321
|
selVal[0] = USER_GROUP_NAME;
|
322
|
selVal[1] = USER_NAME;
|
323
|
|
324
|
// generate a query and get the resultset
|
325
|
Stack selRes = new Stack();
|
326
|
selRes = getGenQueResult (conn, qval, qvalInx, selVal);
|
327
|
String dummy = (String)selRes.pop();
|
328
|
return (String)selRes.pop();
|
329
|
}
|
330
|
|
331
|
// get all users and groups from MCAT
|
332
|
private Stack getUsersGroups (int conn)
|
333
|
throws RemoteException
|
334
|
{
|
335
|
|
336
|
String[] qval;
|
337
|
int[] qvalInx;
|
338
|
int[] selVal;
|
339
|
|
340
|
qval = new String [1];
|
341
|
qval[0] = new String (" not like '%$deleted%'");
|
342
|
//qval[1] = new String (" <> 'public'");
|
343
|
|
344
|
qvalInx = new int[1];
|
345
|
qvalInx[0] = USER_NAME;
|
346
|
//qvalInx[1] = USER_GROUP_NAME;
|
347
|
|
348
|
selVal = new int[2];
|
349
|
selVal[0] = USER_GROUP_NAME;
|
350
|
selVal[1] = USER_NAME;
|
351
|
|
352
|
// generate a query and get the resultset
|
353
|
Stack selRes = new Stack();
|
354
|
selRes = getGenQueResult (conn, qval, qvalInx, selVal);
|
355
|
return selRes;
|
356
|
}
|
357
|
|
358
|
// try to generate query and run and retrieve all rows
|
359
|
private Stack getGenQueResult(int conn, String[] qval,
|
360
|
int qvalInx[], int selVal[])
|
361
|
throws RemoteException
|
362
|
{
|
363
|
|
364
|
int queResultCount = 0;
|
365
|
int queResultIndex = 0;
|
366
|
int selLen = selVal.length;
|
367
|
String[] queResult = new String[selLen];
|
368
|
Stack resultset = new Stack();
|
369
|
String currGroupname = null;
|
370
|
|
371
|
// get first row
|
372
|
try {
|
373
|
queResultCount = srbJG.srbGenQuery( conn, 0, qval, qvalInx, selVal);
|
374
|
for (int i = 0; i < selLen; i++) {
|
375
|
queResult[i] = srbJG.getGenQueResultJ(i, queResultIndex);
|
376
|
}
|
377
|
resultset.push("<groupname>" + queResult[0] + "</groupname>");
|
378
|
resultset.push("<username>" + queResult[1] + "</username>");
|
379
|
currGroupname = queResult[0];
|
380
|
queResultIndex++;
|
381
|
|
382
|
// get next rows
|
383
|
while (queResult != null) {
|
384
|
if ( queResultIndex >= queResultCount ) {
|
385
|
queResultIndex = 0;
|
386
|
queResultCount = srbJG.getMoreGenQueRowsJ( conn, 0);
|
387
|
if (queResultCount <= 0) {
|
388
|
return resultset;
|
389
|
}
|
390
|
}
|
391
|
|
392
|
for (int i = 0; i < selLen; i++) {
|
393
|
queResult[i] = srbJG.getGenQueResultJ(i, queResultIndex);
|
394
|
}
|
395
|
if ( !currGroupname.equals(queResult[0]) ) {
|
396
|
resultset.push("<groupname>" + queResult[0] + "</groupname>");
|
397
|
currGroupname = queResult[0];
|
398
|
}
|
399
|
resultset.push("<username>" + queResult[1] + "</username>");
|
400
|
queResultIndex++;
|
401
|
}
|
402
|
} catch (RemoteException e) {
|
403
|
throw new RemoteException(e.getMessage());
|
404
|
}
|
405
|
|
406
|
return resultset;
|
407
|
}
|
408
|
|
409
|
|
410
|
/**
|
411
|
* Invalidate this HTTPSession object.
|
412
|
* All objects stored in the session are unbound
|
413
|
*/
|
414
|
private void disconnect() {
|
415
|
|
416
|
this.session.invalidate();
|
417
|
}
|
418
|
|
419
|
}
|