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-08-25 13:49:12 -0700 (Fri, 25 Aug 2000) $'
11
 * '$Revision: 411 $'
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
        String groupname = (String)this.session.getAttribute("groupname");
191
        out.append("  " + groupname + "\n");
192

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

    
211
    }
212

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

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

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

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

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

    
286
//        try {
287
//            wait(5000);
288
//        } catch (Exception e) {}
289
//        try {
290
//            notifyAll();
291
//        } catch (Exception e) {}    
292
        return true; 
293

    
294
//      } // end of synchronized(this)
295
    }
296

    
297
    // get the Groupname of connected user
298
    private String getGroupname (int conn, String username) 
299
                throws RemoteException
300
    {
301

    
302
	    String[] qval;
303
	    int[] qvalInx;
304
	    int[] selVal;
305

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

    
311
	    qvalInx = new int[3];
312
	    qvalInx[0] = USER_NAME;
313
	    qvalInx[1] = USER_NAME;
314
	    qvalInx[2] = USER_GROUP_NAME;
315

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

    
327
    // get all users and groups from MCAT
328
    private Stack getUsersGroups (int conn) 
329
                throws RemoteException
330
    {
331

    
332
	    String[] qval;
333
	    int[] qvalInx;
334
	    int[] selVal;
335

    
336
	    qval = new String [1];
337
	    qval[0] = new String (" not like  '%$deleted%'");
338
	    //qval[1] = new String (" <> 'public'");
339

    
340
	    qvalInx = new int[1];
341
	    qvalInx[0] = USER_NAME;
342
	    //qvalInx[1] = USER_GROUP_NAME;
343

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

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

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

    
405

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

    
415
}
(20-20/27)