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-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
}
(20-20/27)