Project

General

Profile

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-10-24 09:07:59 -0700 (Tue, 24 Oct 2000) $'
11
 * '$Revision: 502 $'
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
        }    
67
    }    
68

    
69
    /** Construct a MetaCatSession
70
     *
71
     * @param request the request made from the client
72
     * @param username the username entered when login
73
     * @param password the password entered when login
74
     */
75
    public MetaCatSession (HttpServletRequest request, 
76
                            String username, String password)
77
                            throws IllegalStateException {
78
      // create a new HTTPSession object
79
      this.session = getSession(request, username, password);
80
    }
81

    
82
    /** Get new HttpSession and store username & password in it */
83
    private HttpSession getSession(HttpServletRequest request, 
84
                            String username, String password)  
85
                            throws IllegalStateException {
86
                                      
87
      // get the current session object, create one if necessary
88
      HttpSession sess = request.getSession(true);
89
      // if it is still in use unvalidate and get a new one
90
      if ( !sess.isNew() ) {
91
        sess.invalidate();
92
        sess = request.getSession(true);
93
      }
94
      // store username & password in the session for later use if necessary
95
      sess.setMaxInactiveInterval(-1);
96
      sess.setAttribute("username", username);
97
      sess.setAttribute("password", password);
98
      
99
      return sess; 
100
    }
101

    
102
    /** handle Login action for MetaCatServlet
103
      */
104
    public String userLogin(HttpServletResponse response,
105
                            String username, String password,
106
                            String action, String htmlpath) { 
107
    
108
      String out = null; 
109
   
110
      // for public connection only
111
      // this does not go through auth checking in SRB
112
      // the final implementation will need auth checking in SRB for public
113
      if ( username.equals("public") ) {
114
        try {
115
          if (action.equals("Login Client")) {
116
            String message = "User Authentication successful";
117
            out = formatOutput("success", message);
118
            return out;
119
          } else {
120
            response.sendRedirect(
121
                     response.encodeRedirectUrl(htmlpath + "/index.html"));
122
          }    
123
        } catch ( java.io.IOException ioe) {
124
          disconnect();            
125
          String message = "MetaCatSession.userLogin() - " +
126
                      "Error on redirect of HttpServletResponse: " + 
127
                      ioe.getMessage();
128
          out = formatOutput("error", message);
129
          return out;
130
        }                
131
      }    
132

    
133
      // Auth checking in SRB.
134
      // It fails if not registered user provided.
135
      // It gets all users/groups from MCAT for implementing ACL for MetaCat
136
      // The last one probably will need to be done on separate MetaCatServlet
137
      // action instead on Login action
138
      try { 
139
        if ( userAuth(username, password) ) {
140
          try {
141
            if (action.equals("Login Client")) {
142

    
143
              String message = "User Authentication successful";
144
              out = formatOutput("success", message);
145

    
146
            } else {
147
              response.sendRedirect(
148
                       response.encodeRedirectUrl(htmlpath + "/metacat.html"));
149
            }    
150
          } catch ( java.io.IOException ioe) {
151
            disconnect();            
152
            String message = "MetaCatSession.userLogin() - " +
153
                       "Error on redirect of HttpServletResponse: " + 
154
                       ioe.getMessage();
155
            out = formatOutput("error", message);
156
          }                
157
        // the user has not been authenticated by SRB
158
        } else {  
159
            disconnect();            
160
            String message = "SRB Connection failed. " +
161
                       "SRB RMI Server is not running now or " +
162
                       "user " + username + 
163
                       " has not been authenticated to use the system.";
164
            out = formatOutput("error", message);
165
        }    
166
      } catch ( java.rmi.RemoteException re) {
167
        disconnect();            
168
        String message = "SRB Connection failed. " + re.getMessage();
169
        out = formatOutput("error", message);
170
      }
171
      
172
      return out;
173
    }
174

    
175
    /* format the output in xml for processing from client appl
176
     */
177
    private String formatOutput(String tag, String message) {
178
    
179
      StringBuffer out = new StringBuffer();
180
      
181
      out.append("<?xml version=\"1.0\"?>\n");
182
      out.append("<" + tag + ">");
183
      if ( tag.equals("error") ) {
184
        out.append(message);
185
      } else {
186
        out.append("\n  <message>" + message + "</message>\n");
187
        String username = (String)this.session.getAttribute("username");
188
        out.append("  <username>" + username + "</username>\n");
189
        if ( username.equals("public") ) { 
190
          out.append("</" + tag + ">");
191
          return out.toString();
192
        }
193
        String groupname = (String)this.session.getAttribute("groupname");
194
        out.append("  " + groupname + "\n");
195

    
196
        Stack usersGroups = new Stack();
197
        usersGroups = (Stack)this.session.getAttribute("usersgroups");
198
        String val = "";
199
        StringBuffer res = new StringBuffer(); 
200
        while ( !usersGroups.empty() ) {
201
          val = "    " + (String)usersGroups.pop() + "\n" + val;
202
          if ( val.startsWith("    <groupname>") ) {
203
            val = "  <group>\n" + val + "  </group>\n";
204
            res.insert(0, val);
205
            val = "";
206
          }  
207
        }  
208
        out.append(res.toString());
209
      }  
210
      out.append("</" + tag + ">");
211
      
212
      return out.toString();
213

    
214
    }
215

    
216
    /** Try to make user authentication through SRB RMI Connection 
217
      * Using that connection to get:
218
      *  . the groupname of connected user;
219
      *  . a whole list of all groups and users in MCAT.
220
      */
221
    private boolean userAuth(String username, String password)
222
                    throws RemoteException  { 
223
//      synchronized(this) {
224
        int srbconn = 0;
225

    
226
        // look up for SRBJavaGlue
227
        try {
228
          String name = "//" + RMIhost + "/SrbJavaGlue";
229
          srbJG = (SrbJavaGlueInterface)Naming.lookup(name);
230
        } catch (Exception e) {
231
          try {
232
            rmicon.restart();
233
          } catch (Exception rmie) {}
234
          // The SRB server is not running or it is busy now
235
          throw new 
236
            RemoteException("MetaCatSession look up for SrbJavaGlue failed");
237
        }
238

    
239
        // try SRB RMI Connection
240
        // integer value of the SBR Connection ID is returned only
241
        try { 
242
          srbconn = srbJG.rmiConnectJ( srbHost, srbPort, password, username );
243
        } catch (RemoteException e) {
244
          try {
245
            rmicon.restart();
246
          } catch (Exception rmie) {}
247
          throw new RemoteException("MetaCatSession.userAuth() - " +
248
                                  "Error on rmiConnectJ(): " + e.getMessage());
249
        }
250
      
251
        // check if successfull
252
        if ( srbconn == 0 ) {
253
          throw new RemoteException("The SRB Server is not running or it is busy now");
254
        } else if ( srbconn < 0 ) {
255
          try {
256
            rmicon.restart();
257
          } catch (Exception rmie) {}
258
          return false;
259
        }
260

    
261
        // get the Group name of connected user;
262
        String groupname = null;
263
        try {
264
          groupname = getGroupname(srbconn, username);
265
          this.session.setAttribute("groupname", groupname);
266
        } catch (RemoteException e) { 
267
          throw new RemoteException("MetaCatSession.userAuth() - " +
268
                    "Error on getGroupname(): " + e.getMessage());
269
        }
270
        // get all users and groups from MCAT
271
        Stack usersGroupsList = new Stack();
272
        try {
273
          usersGroupsList = getUsersGroups(srbconn);
274
          this.session.setAttribute("usersgroups", usersGroupsList);
275
        } catch (RemoteException e) { 
276
          throw new RemoteException("MetaCatSession.userAuth() - " +
277
                    "Error on getUsersGroups(): " + e.getMessage());
278
        }
279
        
280

    
281
        // we don't need that connection. close it.
282
        try {
283
          int err = srbJG.rmiFinishJ( srbconn );
284
        } catch (RemoteException e) {}
285
      
286
        // store SRB Connection in the session for later use if necessary
287
        this.session.setAttribute("srbconnection", new Integer(srbconn));
288

    
289
//        try {
290
//            wait(5000);
291
//        } catch (Exception e) {}
292
//        try {
293
//            notifyAll();
294
//        } catch (Exception e) {}    
295
        return true; 
296

    
297
//      } // end of synchronized(this)
298
    }
299

    
300
    // get the Groupname of connected user
301
    private String getGroupname (int conn, String username) 
302
                throws RemoteException
303
    {
304

    
305
	    String[] qval;
306
	    int[] qvalInx;
307
	    int[] selVal;
308

    
309
	    qval = new String [3];
310
	    qval[0] = new String (" not like  '%$deleted%'");
311
	    qval[1] = new String (" = '" + username + "'");
312
	    qval[2] = new String (" <> 'public'");
313

    
314
	    qvalInx = new int[3];
315
	    qvalInx[0] = USER_NAME;
316
	    qvalInx[1] = USER_NAME;
317
	    qvalInx[2] = USER_GROUP_NAME;
318

    
319
	    selVal = new int[2];
320
      selVal[0] = USER_GROUP_NAME;
321
      selVal[1] = USER_NAME;
322
	
323
	    // generate a query and get the resultset
324
	    Stack selRes = new Stack();
325
	    selRes = getGenQueResult (conn, qval, qvalInx, selVal);
326
	    String dummy = (String)selRes.pop();
327
      return (String)selRes.pop();
328
    }
329

    
330
    // get all users and groups from MCAT
331
    private Stack getUsersGroups (int conn) 
332
                throws RemoteException
333
    {
334

    
335
	    String[] qval;
336
	    int[] qvalInx;
337
	    int[] selVal;
338

    
339
	    qval = new String [1];
340
	    qval[0] = new String (" not like  '%$deleted%'");
341
	    //qval[1] = new String (" <> 'public'");
342

    
343
	    qvalInx = new int[1];
344
	    qvalInx[0] = USER_NAME;
345
	    //qvalInx[1] = USER_GROUP_NAME;
346

    
347
	    selVal = new int[2];
348
      selVal[0] = USER_GROUP_NAME;
349
      selVal[1] = USER_NAME;
350
	
351
	    // generate a query and get the resultset
352
	    Stack selRes = new Stack();
353
	    selRes = getGenQueResult (conn, qval, qvalInx, selVal);
354
      return selRes;
355
    }
356

    
357
    // try to generate query and run and retrieve all rows
358
    private Stack getGenQueResult(int conn, String[] qval,
359
                                int qvalInx[], int selVal[])
360
                throws RemoteException
361
    {
362
    
363
        int queResultCount = 0;
364
        int queResultIndex = 0;
365
        int selLen = selVal.length;
366
        String[] queResult = new String[selLen];
367
        Stack resultset = new Stack();
368
        String currGroupname = null;
369
 
370
        // get first row
371
        try {
372
          queResultCount = srbJG.srbGenQuery( conn, 0, qval, qvalInx, selVal);
373
          for (int i = 0; i < selLen; i++) {
374
            queResult[i] = srbJG.getGenQueResultJ(i, queResultIndex);
375
          } 
376
          resultset.push("<groupname>" + queResult[0] + "</groupname>"); 
377
          resultset.push("<username>" + queResult[1] + "</username>");
378
          currGroupname = queResult[0];
379
          queResultIndex++;
380
          
381
          // get next rows
382
          while (queResult != null) {
383
            if ( queResultIndex >= queResultCount ) {
384
                queResultIndex = 0;
385
                queResultCount = srbJG.getMoreGenQueRowsJ( conn, 0);
386
                if (queResultCount <= 0) {
387
                  return resultset;
388
                }  
389
            } 
390

    
391
            for (int i = 0; i < selLen; i++) {
392
                queResult[i] = srbJG.getGenQueResultJ(i, queResultIndex);
393
            }    
394
            if ( !currGroupname.equals(queResult[0]) ) {
395
              resultset.push("<groupname>" + queResult[0] + "</groupname>");
396
              currGroupname = queResult[0];
397
            }  
398
            resultset.push("<username>" + queResult[1] + "</username>");
399
            queResultIndex++;
400
          }  
401
        } catch (RemoteException e) {
402
          throw new RemoteException(e.getMessage());
403
        }
404
        
405
        return resultset;
406
    }
407

    
408

    
409
    /**
410
     * Invalidate this HTTPSession object. 
411
     * All objects stored in the session are unbound 
412
     */
413
    private void disconnect() {
414
        
415
        this.session.invalidate();
416
    }    
417

    
418
}
(23-23/32)