AccessControllerImpl.java
0001 /*
0002  *  AccessControllerImpl.java
0003  *
0004  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
0005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
0006  *
0007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
0008  *  software, licenced under the GNU Library General Public License,
0009  *  Version 2, June 1991 (in the distribution as file licence.html,
0010  *  and also available at http://gate.ac.uk/gate/licence.html).
0011  *
0012  *  Marin Dimitrov, 19/Sep/2001
0013  *
0014  *  $Id: AccessControllerImpl.java 12006 2009-12-01 17:24:28Z thomas_heitz $
0015  */
0016 
0017 package gate.security;
0018 
0019 import java.sql.*;
0020 import java.util.*;
0021 
0022 import junit.framework.Assert;
0023 
0024 import gate.Gate;
0025 import gate.event.*;
0026 import gate.persist.DBHelper;
0027 import gate.persist.PersistenceException;
0028 import gate.util.MethodNotImplementedException;
0029 
0030 
0031 public class AccessControllerImpl
0032   implements AccessController, ObjectModificationListener {
0033 
0034   public static final int DEFAULT_SESSION_TIMEOUT_MIN = 4*60;
0035 
0036   public static final int LOGIN_OK = 1;
0037   public static final int LOGIN_FAILED = 2;
0038 
0039   private static long MY_VERY_SECRET_CONSTANT;
0040   private static final int RANDOM_MAX = 1024;
0041 
0042   private HashMap     sessions;
0043   private HashMap     sessionLastUsed;
0044   private HashMap     sessionTimeouts;
0045 
0046   private Connection  jdbcConn;
0047   private String      jdbcURL;
0048   private String      jdbcSchema;
0049   protected int       dbType;
0050 
0051   private HashMap     usersByID;
0052   private HashMap     usersByName;
0053 
0054   private HashMap     groupsByID;
0055   private HashMap     groupsByName;
0056 
0057   private static Random r;
0058   private boolean isPooled;
0059 
0060   private int refCnt;
0061 
0062   /** --- */
0063   private Vector omModificationListeners;
0064   /** --- */
0065   private Vector omCreationListeners;
0066   /** --- */
0067   private Vector omDeletionListeners;
0068 
0069 
0070   static {
0071     r = new Random();
0072     MY_VERY_SECRET_CONSTANT = r.nextInt(RANDOM_MAX* r.nextInt(RANDOM_MAX)
0073                                   + Math.round(Math.PI * Math.E);
0074   }
0075 
0076   /** --- */
0077   public AccessControllerImpl(String jdbcURL) {
0078 
0079     Assert.assertNotNull(jdbcURL);
0080 
0081     this.refCnt = 0;
0082     this.jdbcURL = jdbcURL;
0083     this.jdbcSchema = DBHelper.getSchemaPrefix(this.jdbcURL);
0084     this.dbType = DBHelper.getDatabaseType(this.jdbcURL);
0085 
0086     Assert.assertNotNull(this.jdbcSchema);
0087     Assert.assertTrue(this.dbType == DBHelper.ORACLE_DB ||
0088                       this.dbType == DBHelper.POSTGRES_DB);
0089 
0090     sessions = new HashMap();
0091     sessionLastUsed = new HashMap();
0092     sessionTimeouts = new HashMap();
0093 
0094     usersByID =  new HashMap();
0095     usersByName=  new HashMap();
0096 
0097     groupsByID = new HashMap();
0098     groupsByName = new HashMap();
0099 
0100     this.omModificationListeners = new Vector();
0101     this.omCreationListeners = new Vector();
0102     this.omDeletionListeners = new Vector();
0103   }
0104 
0105   /** --- */
0106   public void open()
0107     throws PersistenceException{
0108 
0109     synchronized(this) {
0110       if (refCnt++ == 0) {
0111         //open connection
0112         try {
0113           //1. get connection to the database
0114           jdbcConn = DBHelper.connect(this.jdbcURL);
0115 
0116           Assert.assertNotNull(jdbcConn);
0117 
0118           //2. initialize group/user collections
0119           //init, i.e. read users and groups from DB
0120           init();
0121         }
0122         catch(SQLException sqle) {
0123           throw new PersistenceException("could not get DB connection ["+ sqle.getMessage() +"]");
0124         }
0125         catch(ClassNotFoundException clse) {
0126           throw new PersistenceException("cannot locate JDBC driver ["+ clse.getMessage() +"]");
0127         }
0128       }
0129     }
0130 
0131 
0132   }
0133 
0134   /** --- */
0135   public void close()
0136     throws PersistenceException{
0137 
0138     if (--this.refCnt == 0) {
0139 
0140       //0. Invalidate all sessions
0141       this.sessions.clear();
0142       this.sessionLastUsed.clear();
0143       this.sessionTimeouts.clear();
0144 
0145       //1. deregister self as listener for groups
0146       Set groupMappings = this.groupsByName.entrySet();
0147       Iterator itGroups = groupMappings.iterator();
0148 
0149       while (itGroups.hasNext()) {
0150         Map.Entry mapEntry = (Map.Entry)itGroups.next();
0151         GroupImpl  grp = (GroupImpl)mapEntry.getValue();
0152         grp.unregisterObjectModificationListener(this,
0153                                                ObjectModificationEvent.OBJECT_MODIFIED);
0154       }
0155 
0156       //1.1. deregister self as listener for users
0157       Set userMappings = this.usersByName.entrySet();
0158       Iterator itUsers = userMappings.iterator();
0159 
0160       while (itUsers.hasNext()) {
0161         Map.Entry mapEntry = (Map.Entry)itUsers.next();
0162         UserImpl  usr = (UserImpl)mapEntry.getValue();
0163         usr.unregisterObjectModificationListener(this,
0164                                              ObjectModificationEvent.OBJECT_MODIFIED);
0165       }
0166 
0167       //1.2 release all listeners registered for this object
0168       this.omCreationListeners.removeAllElements();
0169       this.omDeletionListeners.removeAllElements();
0170       this.omModificationListeners.removeAllElements();
0171 
0172       //2. delete all groups/users collections
0173       this.groupsByID.clear();
0174       this.groupsByName.clear();
0175       this.usersByID.clear();
0176       this.groupsByName.clear();
0177 
0178       //3.close connection (if not pooled)
0179       try {
0180         if (false == this.isPooled) {
0181           this.jdbcConn.close();
0182         }
0183       }
0184       catch(SQLException sqle) {
0185         throw new PersistenceException("can't close connection to DB:["+
0186                                         sqle.getMessage()+"]");
0187       }
0188     }
0189   }
0190 
0191   /** --- */
0192   public Group findGroup(String name)
0193     throws PersistenceException,SecurityException{
0194 
0195     Group grp = (Group)this.groupsByName.get(name);
0196 
0197     if (null == grp) {
0198       throw new SecurityException("No such group");
0199     }
0200 
0201     return grp;
0202   }
0203 
0204   /** --- */
0205   public Group findGroup(Long id)
0206     throws PersistenceException,SecurityException {
0207 
0208     Group grp = (Group)this.groupsByID.get(id);
0209 
0210     if (null == grp) {
0211       throw new SecurityException("No such group");
0212     }
0213 
0214     return grp;
0215   }
0216 
0217   /** --- */
0218   public User findUser(String name)
0219     throws PersistenceException,SecurityException {
0220 
0221     User usr = (User)this.usersByName.get(name);
0222 
0223     if (null == usr) {
0224       throw new SecurityException("No such user (" + name + ")");
0225     }
0226 
0227     return usr;
0228   }
0229 
0230   /** --- */
0231   public User findUser(Long id)
0232     throws PersistenceException,SecurityException {
0233 
0234     User usr = (User)this.usersByID.get(id);
0235 
0236     if (null == usr) {
0237       throw new SecurityException("No such user");
0238     }
0239 
0240     return usr;
0241   }
0242 
0243   /** --- */
0244   public Session findSession(Long id)
0245     throws SecurityException {
0246 
0247     Session s = (Session)this.sessions.get(id);
0248 
0249     if (null==s) {
0250       throw new SecurityException("No such session ID!");
0251     }
0252 
0253     return s;
0254   }
0255 
0256   /** --- */
0257   public Group createGroup(String name,Session s)
0258     throws PersistenceException, SecurityException {
0259 
0260     Assert.assertNotNull(name);
0261 
0262     //-1. check session
0263     if (false == isValidSession(s)) {
0264       throw new SecurityException("invalid session supplied");
0265     }
0266 
0267     //0. check privileges
0268     if (false == s.isPrivilegedSession()) {
0269       throw new SecurityException("insufficient privileges");
0270     }
0271 
0272 
0273     //1. create group in DB
0274     CallableStatement stmt = null;
0275     PreparedStatement pstmt = null;
0276     ResultSet rs = null;
0277     Long new_id;
0278 
0279     //Oracle / Postgres ?
0280 
0281     if (this.dbType == DBHelper.ORACLE_DB) {
0282 
0283       try {
0284         stmt = this.jdbcConn.prepareCall(
0285                 "{ call "+Gate.DB_OWNER+".security.create_group(?,?)} ");
0286         stmt.setString(1,name);
0287         //numbers generated from Oracle sequences are BIGINT
0288         stmt.registerOutParameter(2,java.sql.Types.BIGINT);
0289         stmt.execute();
0290         new_id = new Long(stmt.getLong(2));
0291       }
0292       catch(SQLException sqle) {
0293 
0294         //check for more specifi exceptions
0295         switch(sqle.getErrorCode()) {
0296 
0297           case DBHelper.X_ORACLE_DUPLICATE_GROUP_NAME:
0298             throw new PersistenceException(
0299                   "can't create a group in DB, name is not unique: ["
0300                   + sqle.getMessage()+"]");
0301 
0302           default:
0303             throw new PersistenceException(
0304                 "can't create a group in DB: ["+ sqle.getMessage()+"]");
0305         }
0306       }
0307       finally {
0308         DBHelper.cleanup(stmt);
0309       }
0310     }
0311     else if (this.dbType == DBHelper.POSTGRES_DB) {
0312       try {
0313         String sql = "select security_create_group(?) ";
0314         pstmt = this.jdbcConn.prepareStatement(sql);
0315         pstmt.setString(1,name);
0316         pstmt.execute();
0317         rs = pstmt.getResultSet();
0318 
0319         if (false == rs.next()) {
0320           throw new PersistenceException("empty resultset");
0321         }
0322 
0323         new_id = new Long(rs.getLong(1));
0324       }
0325       catch(SQLException sqle) {
0326 
0327         //check for more specifi exceptions
0328         switch(sqle.getErrorCode()) {
0329 
0330           case DBHelper.X_ORACLE_DUPLICATE_GROUP_NAME:
0331             throw new PersistenceException(
0332                   "can't create a group in DB, name is not unique: ["
0333                   + sqle.getMessage()+"]");
0334 
0335           default:
0336             throw new PersistenceException(
0337                 "can't create a group in DB: ["+ sqle.getMessage()+"]");
0338         }
0339       }
0340       finally {
0341         DBHelper.cleanup(rs);
0342         DBHelper.cleanup(pstmt);
0343       }
0344 
0345     }
0346     else {
0347       throw new IllegalArgumentException();
0348     }
0349 
0350     //2. create GroupImpl for the new group and
0351     // users list is empty
0352     GroupImpl grp = new GroupImpl(new_id,name,new Vector(),this,this.jdbcConn);
0353 
0354     //3. register as objectModification listener for this group
0355     //we care only about name changes
0356     grp.registerObjectModificationListener(this,ObjectModificationEvent.OBJECT_MODIFIED);
0357 
0358     //4.put in collections
0359     this.groupsByID.put(new_id,grp);
0360     this.groupsByName.put(name,grp);
0361 
0362     return grp;
0363   }
0364 
0365   /** --- */
0366   public void deleteGroup(Long id, Session s)
0367     throws PersistenceException,SecurityException {
0368 
0369     Group grp = (Group)this.groupsByID.get(id);
0370     if (null == grp) {
0371       throw new SecurityException("incorrect group id supplied ( id = ["+id+"])");
0372     }
0373 
0374     //delegate
0375     deleteGroup(grp,s);
0376   }
0377 
0378   /** --- */
0379   public void deleteGroup(Group grp, Session s)
0380     throws PersistenceException,SecurityException {
0381 
0382     //1. check session
0383     if (false == isValidSession(s)) {
0384       throw new SecurityException("invalid session supplied");
0385     }
0386 
0387     //2. check privileges
0388     if (false == s.isPrivilegedSession()) {
0389       throw new SecurityException("insufficient privileges");
0390     }
0391 
0392     //3. delete in DB
0393     CallableStatement stmt = null;
0394     PreparedStatement pstmt = null;
0395 
0396     //Oracle /Postgres ?
0397     if (this.dbType == DBHelper.ORACLE_DB) {
0398 
0399       try {
0400         stmt = this.jdbcConn.prepareCall(
0401                   "{ call "+Gate.DB_OWNER+".security.delete_group(?) } ");
0402         stmt.setLong(1,grp.getID().longValue());
0403         stmt.execute();
0404       }
0405       catch(SQLException sqle) {
0406         //check for more specific exceptions
0407         switch(sqle.getErrorCode()) {
0408 
0409           case DBHelper.X_ORACLE_GROUP_OWNS_RESOURCES:
0410             throw new PersistenceException(
0411                   "can't delete a group from DB, the group owns LR(s): ["
0412                     + sqle.getMessage()+"]");
0413 
0414           default:
0415             throw new PersistenceException(
0416                   "can't delete a group from DB: ["+ sqle.getMessage()+"]");
0417         }
0418       }
0419       finally {
0420         DBHelper.cleanup(stmt);
0421       }
0422     }
0423 
0424     else if (this.dbType == DBHelper.POSTGRES_DB) {
0425 
0426       try {
0427         String sql = "select security_delete_group(?)";
0428         pstmt = this.jdbcConn.prepareStatement(sql);
0429         pstmt.setLong(1,grp.getID().longValue());
0430         pstmt.execute();
0431       }
0432       catch(SQLException sqle) {
0433         //check for more specific exceptions
0434         switch(sqle.getErrorCode()) {
0435 
0436           case DBHelper.X_ORACLE_GROUP_OWNS_RESOURCES:
0437             throw new PersistenceException(
0438                   "can't delete a group from DB, the group owns LR(s): ["
0439                     + sqle.getMessage()+"]");
0440 
0441           default:
0442             throw new PersistenceException(
0443                   "can't delete a group from DB: ["+ sqle.getMessage()+"]");
0444         }
0445       }
0446       finally {
0447         DBHelper.cleanup(pstmt);
0448       }
0449 
0450     }
0451     else {
0452       throw new IllegalArgumentException();
0453     }
0454 
0455 
0456     //4. delete from collections
0457     this.groupsByID.remove(grp.getID());
0458     this.groupsByName.remove(grp.getName());
0459 
0460     //5. notify all other listeners
0461     //this one is tricky - sent OBJECT_DELETED event to all who care
0462     //but note that the SOURCE is not us but the object being deleted
0463     ObjectModificationEvent e = new ObjectModificationEvent(
0464                       grp,
0465                       ObjectModificationEvent.OBJECT_DELETED,
0466                       0);
0467 
0468     fireObjectDeletedEvent(e);
0469 
0470     //6. this one is tricky: invalidate all sessions
0471     //that are for user logged in as members of this group
0472     Set sessionMappings = this.sessions.entrySet();
0473     Iterator itSessions = sessionMappings.iterator();
0474 
0475     //6.1 to avoid ConcurrentModificationException store the sessions
0476     //found in a temp vector
0477     Vector sessionsToDelete = new Vector();
0478     while (itSessions.hasNext()) {
0479       Map.Entry mapEntry = (Map.Entry)itSessions.next();
0480       SessionImpl  ses = (SessionImpl)mapEntry.getValue();
0481       if (ses.getGroup().equals(grp)) {
0482         //logout(ses); --> this will cause ConcurrentModificationException
0483         sessionsToDelete.add(ses);
0484       }
0485     }
0486     //6.2 now delete sessions
0487     for (int i=0; i< sessionsToDelete.size(); i++) {
0488       Session ses = (Session)sessionsToDelete.elementAt(i);
0489       logout(ses);
0490     }
0491 
0492   }
0493 
0494   /** --- */
0495   public User createUser(String name, String passwd,Session s)
0496     throws PersistenceException,SecurityException {
0497 
0498     Assert.assertNotNull(name);
0499 
0500     //-1. check session
0501     if (false == isValidSession(s)) {
0502       throw new SecurityException("invalid session supplied");
0503     }
0504 
0505     //0. check privileges
0506     if (false == s.isPrivilegedSession()) {
0507       throw new SecurityException("insufficient privileges");
0508     }
0509 
0510     //1. create user in DB
0511     CallableStatement stmt = null;
0512     PreparedStatement pstmt = null;
0513     ResultSet rs = null;
0514 
0515     Long new_id;
0516 
0517     if (this.dbType == DBHelper.ORACLE_DB) {
0518 
0519       try {
0520         stmt = this.jdbcConn.prepareCall(
0521                   "{ call "+Gate.DB_OWNER+".security.create_user(?,?,?)} ");
0522         stmt.setString(1,name);
0523         stmt.setString(2,passwd);
0524         //numbers generated from Oracle sequences are BIGINT
0525         stmt.registerOutParameter(3,java.sql.Types.BIGINT);
0526         stmt.execute();
0527         new_id = new Long(stmt.getLong(3));
0528       }
0529       catch(SQLException sqle) {
0530         //check for more specific exceptions
0531         switch(sqle.getErrorCode()) {
0532 
0533           case DBHelper.X_ORACLE_DUPLICATE_USER_NAME:
0534             throw new PersistenceException(
0535                   "can't create a user in DB, name is not unique: ["
0536                     + sqle.getMessage()+"]");
0537           default:
0538             throw new PersistenceException(
0539                   "can't create a user in DB: ["+ sqle.getMessage()+"]");
0540         }
0541       }
0542       finally {
0543         DBHelper.cleanup(stmt);
0544       }
0545     }
0546 
0547     else if (this.dbType == DBHelper.POSTGRES_DB) {
0548 
0549       try {
0550         String sql = "select security_create_user(?,?) ";
0551         pstmt = this.jdbcConn.prepareStatement(sql);
0552         pstmt.setString(1,name);
0553         pstmt.setString(2,passwd);
0554         pstmt.execute();
0555         rs = pstmt.getResultSet();
0556 
0557         if (false == rs.next()) {
0558           throw new PersistenceException("empty resultset");
0559         }
0560 
0561         new_id = new Long(rs.getLong(1));
0562       }
0563       catch(SQLException sqle) {
0564         //check for more specific exceptions
0565         switch(sqle.getErrorCode()) {
0566 
0567           case DBHelper.X_ORACLE_DUPLICATE_USER_NAME:
0568             throw new PersistenceException(
0569                   "can't create a user in DB, name is not unique: ["
0570                     + sqle.getMessage()+"]");
0571           default:
0572             throw new PersistenceException(
0573                   "can't create a user in DB: ["+ sqle.getMessage()+"]");
0574         }
0575       }
0576       finally {
0577         DBHelper.cleanup(rs);
0578         DBHelper.cleanup(pstmt);
0579       }
0580 
0581     }
0582 
0583     else {
0584       throw new IllegalArgumentException();
0585     }
0586 
0587     //2. create UserImpl for the new user
0588     // groups list is empty
0589     UserImpl usr = new UserImpl(new_id,name,new Vector(),this,this.jdbcConn);
0590 
0591     //3. register as objectModification listener for this user
0592     //we care only about user changing name
0593     usr.registerObjectModificationListener(this,ObjectModificationEvent.OBJECT_MODIFIED);
0594 
0595     //4. put in collections
0596     this.usersByID.put(new_id,usr);
0597     this.usersByName.put(name,usr);
0598 
0599     return usr;
0600   }
0601 
0602   /** --- */
0603   public void deleteUser(User usr, Session s)
0604     throws PersistenceException,SecurityException {
0605 
0606     //1. check session
0607     if (false == isValidSession(s)) {
0608       throw new SecurityException("invalid session supplied");
0609     }
0610 
0611     //2. check privileges
0612     if (false == s.isPrivilegedSession()) {
0613       throw new SecurityException("insufficient privileges");
0614     }
0615 
0616     //3. delete in DB
0617     CallableStatement cstmt = null;
0618     PreparedStatement pstmt = null;
0619 
0620     if (this.dbType == DBHelper.ORACLE_DB) {
0621 
0622       try {
0623         cstmt = this.jdbcConn.prepareCall(
0624                     "{ call "+Gate.DB_OWNER+".security.delete_user(?) } ");
0625         cstmt.setLong(1,usr.getID().longValue());
0626         cstmt.execute();
0627       }
0628       catch(SQLException sqle) {
0629         switch(sqle.getErrorCode()) {
0630 
0631           case DBHelper.X_ORACLE_USER_OWNS_RESOURCES:
0632             throw new PersistenceException(
0633                   "can't delete user from DB, the user owns LR(s): ["
0634                     + sqle.getMessage()+"]");
0635           default:
0636             throw new PersistenceException(
0637                   "can't delete user from DB: ["+ sqle.getMessage()+"]");
0638         }
0639       }
0640       finally {
0641         DBHelper.cleanup(cstmt);
0642       }
0643     }
0644 
0645     else if (this.dbType == DBHelper.POSTGRES_DB) {
0646 
0647       try {
0648         String sql = "select security_delete_user(?) ";
0649         pstmt = this.jdbcConn.prepareStatement(sql);
0650         pstmt.setLong(1,usr.getID().longValue());
0651         pstmt.execute();
0652       }
0653       catch(SQLException sqle) {
0654         switch(sqle.getErrorCode()) {
0655 
0656           case DBHelper.X_ORACLE_USER_OWNS_RESOURCES:
0657             throw new PersistenceException(
0658                   "can't delete user from DB, the user owns LR(s): ["
0659                     + sqle.getMessage()+"]");
0660           default:
0661             throw new PersistenceException(
0662                   "can't delete user from DB: ["+ sqle.getMessage()+"]");
0663         }
0664       }
0665       finally {
0666         DBHelper.cleanup(pstmt);
0667       }
0668 
0669     }
0670 
0671     else {
0672       throw new IllegalArgumentException();
0673     }
0674 
0675 
0676     //4. delete from collections
0677     this.usersByID.remove(usr.getID());
0678     this.usersByName.remove(usr.getName());
0679 
0680     //6. notify all other listeners
0681     //this one is tricky - sent OBJECT_DELETED event to all who care
0682     //but note that the SOURCE is not us but the object being deleted
0683     ObjectModificationEvent e = new ObjectModificationEvent(
0684                       usr,
0685                       ObjectModificationEvent.OBJECT_DELETED,
0686                       0);
0687 
0688     fireObjectDeletedEvent(e);
0689 
0690     //7. this one is tricky: invalidate all sessions for the user
0691     Set sessionMappings = this.sessions.entrySet();
0692     Iterator itSessions = sessionMappings.iterator();
0693 
0694     //7.1 to avoid ConcurrentModificationException store the sessions
0695     //found in a temp vector
0696     Vector sessionsToDelete = new Vector();
0697     while (itSessions.hasNext()) {
0698       Map.Entry mapEntry = (Map.Entry)itSessions.next();
0699       SessionImpl  ses = (SessionImpl)mapEntry.getValue();
0700       if (ses.getUser().equals(usr)) {
0701         //logout(ses); --> this will cause ConcurrentModificationException
0702         sessionsToDelete.add(ses);
0703       }
0704     }
0705     //7.2 now delete sessions
0706     for (int i=0; i< sessionsToDelete.size(); i++) {
0707       Session ses = (Session)sessionsToDelete.elementAt(i);
0708       logout(ses);
0709     }
0710 
0711   }
0712 
0713 
0714   /** --- */
0715   public void deleteUser(Long id, Session s)
0716     throws PersistenceException,SecurityException {
0717 
0718     User usr = (User)usersByID.get(id);
0719     if (null == usr) {
0720       throw new SecurityException("incorrect user id supplied ( id = ["+id+"])");
0721     }
0722 
0723     //delegate
0724     deleteUser(usr,s);
0725   }
0726 
0727   /** --- */
0728   public Session login(String usr_name, String passwd,Long prefGroupID)
0729     throws PersistenceException,SecurityException {
0730 
0731     //1. check the user locally
0732     User usr = (User)this.usersByName.get(usr_name);
0733     if (null == usr) {
0734       throw new SecurityException("no such user (username=["+usr_name+"])");
0735     }
0736 
0737     //2. check group localy
0738     Group grp = (Group)this.groupsByID.get(prefGroupID);
0739     if (null == grp) {
0740       throw new SecurityException("no such group (id=["+prefGroupID+"])");
0741     }
0742 
0743     //2. check user/pass in DB
0744     CallableStatement cstmt = null;
0745     PreparedStatement pstmt = null;
0746     ResultSet rs = null;
0747 
0748     boolean isPrivilegedUser = false;
0749 
0750     if (this.dbType == DBHelper.ORACLE_DB) {
0751 
0752       try {
0753         cstmt = this.jdbcConn.prepareCall(
0754                   "{ call "+Gate.DB_OWNER+".security.login(?,?,?,?)} ");
0755         cstmt.setString(1,usr_name);
0756         cstmt.setString(2,passwd);
0757         cstmt.setLong(3,prefGroupID.longValue());
0758         cstmt.registerOutParameter(4,java.sql.Types.NUMERIC);
0759         cstmt.execute();
0760         isPrivilegedUser = (cstmt.getInt(4== DBHelper.FALSE ? false true );
0761       }
0762       catch(SQLException sqle) {
0763         switch(sqle.getErrorCode())
0764         {
0765           case DBHelper.X_ORACLE_INVALID_USER_NAME :
0766             throw new SecurityException("Login failed: incorrect user");
0767           case DBHelper.X_ORACLE_INVALID_USER_PASS :
0768             throw new SecurityException("Login failed: incorrect password");
0769           case DBHelper.X_ORACLE_INVALID_USER_GROUP :
0770             throw new SecurityException("Login failed: incorrect group");
0771           default:
0772             throw new PersistenceException("can't login user, DB error is: ["+
0773                                             sqle.getMessage()+"]");
0774         }
0775       }
0776       finally {
0777         DBHelper.cleanup(cstmt);
0778       }
0779     }
0780 
0781     else if (this.dbType == DBHelper.POSTGRES_DB) {
0782 
0783       try {
0784         String sql = "select security_login(?,?,?) ";
0785         pstmt = this.jdbcConn.prepareStatement(sql);
0786         pstmt.setString(1,usr_name);
0787         pstmt.setString(2,passwd);
0788         pstmt.setLong(3,prefGroupID.longValue());
0789         pstmt.execute();
0790         rs = pstmt.getResultSet();
0791 
0792         if (false == rs.next()) {
0793           throw new PersistenceException("empty resultset");
0794         }
0795 
0796         isPrivilegedUser = rs.getBoolean(1);
0797       }
0798       catch(SQLException sqle) {
0799         switch(sqle.getErrorCode())
0800         {
0801           case DBHelper.X_ORACLE_INVALID_USER_NAME :
0802             throw new SecurityException("Login failed: incorrect user");
0803           case DBHelper.X_ORACLE_INVALID_USER_PASS :
0804             throw new SecurityException("Login failed: incorrect password");
0805           case DBHelper.X_ORACLE_INVALID_USER_GROUP :
0806             throw new SecurityException("Login failed: incorrect group");
0807           default:
0808             throw new PersistenceException("can't login user, DB error is: ["+
0809                                             sqle.getMessage()+"]");
0810         }
0811       }
0812       finally {
0813         DBHelper.cleanup(rs);
0814         DBHelper.cleanup(pstmt);
0815       }
0816     }
0817 
0818     else {
0819       throw new IllegalArgumentException();
0820     }
0821 
0822     //3. create a Session and set User/Group
0823     Long sessionID = createSessionID();
0824     while (this.sessions.containsKey(sessionID)) {
0825       sessionID = createSessionID();
0826     }
0827 
0828     SessionImpl s = new SessionImpl(sessionID,
0829                                     usr,
0830                                     grp,
0831                                     DEFAULT_SESSION_TIMEOUT_MIN,
0832                                     isPrivilegedUser);
0833 
0834     //4. add session to session collections
0835     this.sessions.put(s.getID(),s);
0836 
0837     //5. set the session timeouts and keep alives
0838     this.sessionTimeouts.put(sessionID,new Long(DEFAULT_SESSION_TIMEOUT_MIN));
0839     touchSession(s)//this one changes the keepAlive time
0840 
0841     return s;
0842   }
0843 
0844   /** --- */
0845   public void logout(Session s)
0846     throws SecurityException {
0847 
0848     Assert.assertNotNull(s);
0849     Long SID = s.getID();
0850 
0851     //1.sessions
0852     Session removedSession = (Session)this.sessions.remove(SID);
0853     Assert.assertNotNull(removedSession);
0854 
0855     //2. keep alives
0856     Object lastUsed = this.sessionLastUsed.remove(SID);
0857     Assert.assertNotNull(lastUsed);
0858 
0859     //3. timeouts
0860     Object timeout = this.sessionTimeouts.remove(SID);
0861     Assert.assertNotNull(timeout);
0862   }
0863 
0864   /** --- */
0865   public void setSessionTimeout(Session s, int timeoutMins)
0866     throws SecurityException {
0867 
0868     this.sessionTimeouts.put(s.getID(),new Long(timeoutMins));
0869   }
0870 
0871   /** --- */
0872   public boolean isValidSession(Session s) {
0873 
0874     //1. do we have such session?
0875     if (false == this.sessions.containsKey(s.getID())) {
0876       return false;
0877     }
0878 
0879     //2. has it expired meanwhile?
0880     Assert.assertNotNull(this.sessionLastUsed.get(s.getID()));
0881 
0882     long lastUsedMS = ((Long)this.sessionLastUsed.get(s.getID())).longValue();
0883     long sessTimeoutMin = ((Long)this.sessionTimeouts.get(s.getID())).longValue();
0884     long currTimeMS = System.currentTimeMillis();
0885     //timeout is in minutes
0886     long lastUsedMin = (currTimeMS-lastUsedMS)/(1000*60);
0887 
0888     if (lastUsedMin > sessTimeoutMin) {
0889       //oops, session expired
0890       //invalidate it and fail
0891       try {
0892         logout(s);
0893       }
0894       catch(SecurityException se) {
0895         //well, this can happen only if logout() was called together
0896         //with isValidSesion() but the possibility it too low to care
0897         //and synchronize access
0898         ;
0899       }
0900 
0901       return false;
0902     }
0903 
0904     //everything ok
0905     //touch session
0906     touchSession(s);
0907 
0908     return true;
0909   }
0910 
0911   /** -- */
0912   public List listGroups()
0913     throws PersistenceException {
0914 
0915     //1. read all groups from DB
0916     Statement stmt = null;
0917     ResultSet rs = null;
0918     String    sql;
0919     Vector    result = new Vector();
0920 
0921     try {
0922       stmt = this.jdbcConn.createStatement();
0923 
0924       //1.1 read groups
0925       sql = " SELECT grp_name "+
0926             " FROM   "+this.jdbcSchema+"t_group "+
0927             " ORDER BY grp_name ASC";
0928       rs = stmt.executeQuery(sql);
0929 
0930       while (rs.next()) {
0931         //access by index is faster
0932         //first column index is 1
0933         String grp_name = rs.getString(1);
0934         result.add(grp_name);
0935       }
0936 
0937       return result;
0938     }
0939     catch (SQLException sqle) {
0940       throw new PersistenceException("cannot read groups from DB :["+
0941                                         sqle.getMessage() +"]");
0942     }
0943     finally {
0944       DBHelper.cleanup(rs);
0945       DBHelper.cleanup(stmt);
0946     }
0947   }
0948 
0949   /** -- */
0950   public List listUsers()
0951     throws PersistenceException {
0952 
0953     //1. read all users from DB
0954     Statement stmt = null;
0955     ResultSet rs = null;
0956     String    sql;
0957     Vector    result = new Vector();
0958 
0959     try {
0960       stmt = this.jdbcConn.createStatement();
0961 
0962       //1.1 read groups
0963       sql = " SELECT usr_login "+
0964             " FROM   "+this.jdbcSchema+"t_user "+
0965             " ORDER BY usr_login DESC";
0966       rs = stmt.executeQuery(sql);
0967 
0968       while (rs.next()) {
0969         //access by index is faster
0970         //first column index is 1
0971         String usr_name = rs.getString(1);
0972         result.add(usr_name);
0973       }
0974 
0975       return result;
0976     }
0977     catch (SQLException sqle) {
0978       throw new PersistenceException("cannot read groups from DB :["+
0979                                         sqle.getMessage() +"]");
0980     }
0981     finally {
0982       DBHelper.cleanup(rs);
0983       DBHelper.cleanup(stmt);
0984     }
0985   }
0986 
0987 
0988 
0989   /*  private methods */
0990 
0991   private void touchSession(Session s) {
0992 
0993     this.sessionLastUsed.put(s.getID(),  new Long(System.currentTimeMillis()));
0994   }
0995 
0996 
0997   private Long createSessionID() {
0998 
0999     //need a hint?
1000     return new Long(((System.currentTimeMillis() << 16>> 16)*
1001                       (r.nextInt(RANDOM_MAX))*
1002                           Runtime.getRuntime().freeMemory()*
1003                               MY_VERY_SECRET_CONSTANT);
1004   }
1005 
1006 
1007   private boolean canDeleteGroup(Group grp)
1008     throws PersistenceException, SecurityException{
1009 
1010     //1. check group localy
1011     if (false == this.groupsByID.containsValue(grp)) {
1012       throw new SecurityException("no such group (id=["+grp.getID()+"])");
1013     }
1014 
1015     //2. check DB
1016     CallableStatement stmt = null;
1017     PreparedStatement pstmt = null;
1018     ResultSet rs = null;
1019 
1020     if (this.dbType == DBHelper.ORACLE_DB) {
1021 
1022       try {
1023         stmt = this.jdbcConn.prepareCall(
1024                   "{ ? = call "+Gate.DB_OWNER+".security.can_delete_group(?) }");
1025         stmt.registerOutParameter(1,java.sql.Types.INTEGER);
1026         stmt.setLong(2,grp.getID().longValue());
1027         stmt.execute();
1028         boolean res = stmt.getBoolean(1);
1029 
1030         return res;
1031       }
1032       catch(SQLException sqle) {
1033         throw new PersistenceException("can't perform document checks, DB error is: ["+
1034                                             sqle.getMessage()+"]");
1035       }
1036       finally {
1037         DBHelper.cleanup(stmt);
1038       }
1039     }
1040 
1041     else if (this.dbType == DBHelper.POSTGRES_DB) {
1042 
1043       try {
1044         String sql = "select security_can_delete_group(?)";
1045         pstmt = this.jdbcConn.prepareCall(sql);
1046         pstmt.setLong(1,grp.getID().longValue());
1047         pstmt.execute();
1048         rs = pstmt.getResultSet();
1049 
1050         if (false == rs.next()) {
1051           throw new PersistenceException("empty resultset");
1052         }
1053 
1054         boolean res = rs.getBoolean(1);
1055 
1056         return res;
1057       }
1058       catch(SQLException sqle) {
1059         throw new PersistenceException("can't perform document checks, DB error is: ["+
1060                                             sqle.getMessage()+"]");
1061       }
1062       finally {
1063         DBHelper.cleanup(rs);
1064         DBHelper.cleanup(pstmt);
1065       }
1066 
1067     }
1068 
1069     else {
1070       throw new IllegalArgumentException();
1071     }
1072   }
1073 
1074 
1075   private boolean canDeleteUser(User usr)
1076     throws PersistenceException, SecurityException{
1077 
1078     //1. check group localy
1079     if (false == this.usersByID.containsValue(usr)) {
1080       throw new SecurityException("no such user (id=["+usr.getID()+"])");
1081     }
1082 
1083     //2. check DB
1084     CallableStatement stmt = null;
1085     PreparedStatement pstmt = null;
1086     ResultSet rs = null;
1087 
1088     if (this.dbType == DBHelper.ORACLE_DB) {
1089 
1090       try {
1091         stmt = this.jdbcConn.prepareCall(
1092                   "{ ? = call "+Gate.DB_OWNER+".security.can_delete_user(?) }");
1093 
1094         stmt.registerOutParameter(1,java.sql.Types.INTEGER);
1095         stmt.setLong(2,usr.getID().longValue());
1096         stmt.execute();
1097         boolean res = stmt.getBoolean(1);
1098 
1099         return res;
1100       }
1101       catch(SQLException sqle) {
1102         throw new PersistenceException("can't perform document checks, DB error is: ["+
1103                                             sqle.getMessage()+"]");
1104       }
1105       finally {
1106         DBHelper.cleanup(stmt);
1107       }
1108     }
1109 
1110     else if (this.dbType == DBHelper.POSTGRES_DB) {
1111 
1112       try {
1113         String sql = "select security_can_delete_user(?) ";
1114         pstmt = this.jdbcConn.prepareCall(sql);
1115         pstmt.setLong(1,usr.getID().longValue());
1116         pstmt.execute();
1117         boolean res = rs.getBoolean(1);
1118 
1119         return res;
1120       }
1121       catch(SQLException sqle) {
1122         throw new PersistenceException("can't perform document checks, DB error is: ["+
1123                                             sqle.getMessage()+"]");
1124       }
1125       finally {
1126         DBHelper.cleanup(rs);
1127         DBHelper.cleanup(pstmt);
1128       }
1129 
1130     }
1131 
1132     else {
1133       throw new IllegalArgumentException();
1134     }
1135 
1136   }
1137 
1138   private void init()
1139     throws PersistenceException {
1140 
1141     //1. read all groups and users from DB
1142     Statement stmt = null;
1143     ResultSet rs = null;
1144     String    sql;
1145     Hashtable   groupNames = new Hashtable();
1146     Hashtable   groupMembers= new Hashtable();
1147     Hashtable   userNames= new Hashtable();
1148     Hashtable   userGroups= new Hashtable();
1149 
1150     try {
1151       stmt = this.jdbcConn.createStatement();
1152 
1153       //1.1 read groups
1154       sql = " SELECT grp_id, " +
1155             "        grp_name "+
1156             " FROM   "+this.jdbcSchema+"t_group";
1157       rs = stmt.executeQuery(sql);
1158 
1159 
1160 
1161       while (rs.next()) {
1162         //access by index is faster
1163         //first column index is 1
1164         long grp_id = rs.getLong(1);
1165         String grp_name = rs.getString(2);
1166         groupNames.put(new Long(grp_id),grp_name);
1167         groupMembers.put(new Long(grp_id),new Vector());
1168       }
1169       DBHelper.cleanup(rs);
1170 
1171 
1172       //1.2 read users
1173       sql = " SELECT usr_id, " +
1174             "        usr_login "+
1175             " FROM   "+this.jdbcSchema+"t_user";
1176       rs = stmt.executeQuery(sql);
1177 
1178       while (rs.next()) {
1179         //access by index is faster
1180         //first column index is 1
1181         long usr_id = rs.getLong(1);
1182         String usr_name = rs.getString(2);
1183         userNames.put(new Long(usr_id),usr_name);
1184         userGroups.put(new Long(usr_id),new Vector());
1185       }
1186       DBHelper.cleanup(rs);
1187 
1188 
1189       //1.3 read user/group relations
1190       sql = " SELECT    UGRP_GROUP_ID, " +
1191             "           UGRP_USER_ID "+
1192             " FROM      "+this.jdbcSchema+"t_user_group " +
1193             " ORDER BY  UGRP_GROUP_ID asc";
1194       rs = stmt.executeQuery(sql);
1195 
1196       while (rs.next()) {
1197         //access by index is faster
1198         //first column index is 1
1199         Long grp_id = new Long(rs.getLong(1));
1200         Long usr_id = new Long(rs.getLong(2));
1201 
1202         //append user to group members list
1203         Vector currMembers = (Vector)groupMembers.get(grp_id);
1204         currMembers.add(usr_id);
1205 
1206         Vector currGroups = (Vector)userGroups.get(usr_id);
1207         currGroups.add(grp_id);
1208       }
1209       DBHelper.cleanup(rs);
1210     }
1211     catch(SQLException sqle) {
1212       throw new PersistenceException("DB error is: ["+
1213                                           sqle.getMessage()+"]");
1214     }
1215     finally {
1216       DBHelper.cleanup(rs);
1217       DBHelper.cleanup(stmt);
1218     }
1219 
1220     //2. create USerImpl's and GroupImpl's and put them in collections
1221 
1222     //2.1 create Groups
1223     Vector toBeInitializedGroups = new Vector();
1224 
1225     Enumeration enGroups = groupNames.keys();
1226     while (enGroups.hasMoreElements()) {
1227       Long grpId = (Long)enGroups.nextElement();
1228 //      Vector grpMembers = (Vector)groupMembers.get(grpId);
1229       String grpName = (String)groupNames.get(grpId);
1230 
1231       //note that the Vector with group members is empty
1232       //will beinitalized later (ugly hack for bad desgin)
1233       GroupImpl grp = new GroupImpl(grpId,grpName,new Vector(),this,this.jdbcConn);
1234       //register as listener for thsi group
1235       //we care only about name changes
1236       grp.registerObjectModificationListener(this,ObjectModificationEvent.OBJECT_MODIFIED);
1237 
1238       //add to collection
1239       this.groupsByID.put(grp.getID(),grp);
1240       this.groupsByName.put(grp.getName(),grp);
1241 
1242       //add to vector of the objects to be initialized
1243       toBeInitializedGroups.add(grp);
1244     }
1245 
1246     //2.2 create Users
1247     Vector toBeInitializedUsers = new Vector();
1248 
1249     Enumeration enUsers = userNames.keys();
1250     while (enUsers.hasMoreElements()) {
1251       Long usrId = (Long)enUsers.nextElement();
1252 //      Vector usrGroups = (Vector)userGroups.get(usrId);
1253       String usrName = (String)userNames.get(usrId);
1254 
1255       //note that the Vector with user's group is empty
1256       //will be initalized later (ugly hack for bad desgin)
1257       UserImpl usr = new UserImpl(usrId,usrName,new Vector(),this,this.jdbcConn);
1258       //register as listener for thsi user
1259       //we care only about user changing name
1260       usr.registerObjectModificationListener(this,ObjectModificationEvent.OBJECT_MODIFIED);
1261 
1262       //add to collection
1263       this.usersByID.put(usr.getID(),usr);
1264       this.usersByName.put(usr.getName(),usr);
1265 
1266       //add to vector of the objects to be initialized
1267       toBeInitializedUsers.add(usr);
1268     }
1269 
1270     //3. the hack itself:
1271     //all the groups and users are not fully initialized yet
1272     //(the groups/users Vectors are empty)
1273     //initialize them now
1274 
1275     //3.1 initialize groups
1276     for (int i=0; i< toBeInitializedGroups.size(); i++) {
1277       GroupImpl grp = (GroupImpl)toBeInitializedGroups.elementAt(i);
1278       grp.setUsers((Vector)groupMembers.get(grp.getID()));
1279     }
1280 
1281     //3.2 initialize users
1282     for (int i=0; i< toBeInitializedUsers.size(); i++) {
1283       UserImpl usr = (UserImpl)toBeInitializedUsers.elementAt(i);
1284       usr.setGroups((Vector)userGroups.get(usr.getID()));
1285     }
1286 
1287   }
1288 
1289 
1290   private void fireObjectCreatedEvent(ObjectModificationEvent e) {
1291 
1292     //sanity check
1293     if (e.getType() != ObjectModificationEvent.OBJECT_CREATED) {
1294       throw new IllegalArgumentException();
1295     }
1296 
1297     for (int i=0; i< this.omCreationListeners.size(); i++) {
1298       ((ObjectModificationListener)this.omCreationListeners.elementAt(i)).objectCreated(e);
1299     }
1300   }
1301 
1302 
1303   private void fireObjectDeletedEvent(ObjectModificationEvent e) {
1304 
1305     //sanity check
1306     if (e.getType() != ObjectModificationEvent.OBJECT_DELETED) {
1307       throw new IllegalArgumentException();
1308     }
1309 
1310     for (int i=0; i< this.omDeletionListeners.size(); i++) {
1311       ((ObjectModificationListener)this.omDeletionListeners.elementAt(i)).objectDeleted(e);
1312     }
1313   }
1314 
1315 
1316   private void fireObjectModifiedEvent(ObjectModificationEvent e) {
1317 
1318     //sanity check
1319     if (e.getType() != ObjectModificationEvent.OBJECT_MODIFIED) {
1320       throw new IllegalArgumentException();
1321     }
1322 
1323     for (int i=0; i< this.omModificationListeners.size(); i++) {
1324       ((ObjectModificationListener)omModificationListeners.elementAt(i)).objectModified(e);
1325     }
1326   }
1327 
1328 
1329 
1330 
1331   public void registerObjectModificationListener(ObjectModificationListener l,
1332                                                  int eventType) {
1333 
1334     if (eventType != ObjectModificationEvent.OBJECT_CREATED &&
1335         eventType != ObjectModificationEvent.OBJECT_DELETED &&
1336         eventType != ObjectModificationEvent.OBJECT_MODIFIED) {
1337 
1338         throw new IllegalArgumentException();
1339     }
1340 
1341     switch(eventType) {
1342       case ObjectModificationEvent.OBJECT_CREATED :
1343         this.omCreationListeners.add(l);
1344         break;
1345       case ObjectModificationEvent.OBJECT_DELETED :
1346         this.omDeletionListeners.add(l);
1347         break;
1348       case ObjectModificationEvent.OBJECT_MODIFIED :
1349         this.omModificationListeners.add(l);
1350         break;
1351       default:
1352         Assert.fail();
1353     }
1354 
1355   }
1356 
1357   public void unregisterObjectModificationListener(ObjectModificationListener l,
1358                                                    int eventType) {
1359 
1360     if (eventType != ObjectModificationEvent.OBJECT_CREATED &&
1361         eventType != ObjectModificationEvent.OBJECT_DELETED &&
1362         eventType != ObjectModificationEvent.OBJECT_MODIFIED) {
1363 
1364         throw new IllegalArgumentException();
1365     }
1366 
1367     switch(eventType) {
1368       case ObjectModificationEvent.OBJECT_CREATED :
1369         this.omCreationListeners.remove(l);
1370         break;
1371       case ObjectModificationEvent.OBJECT_DELETED :
1372         this.omDeletionListeners.remove(l);
1373         break;
1374       case ObjectModificationEvent.OBJECT_MODIFIED :
1375         this.omModificationListeners.remove(l);
1376         break;
1377       default:
1378         Assert.fail();
1379     }
1380 
1381   }
1382 
1383 
1384 
1385 
1386   /* ObjectModificationListener methods */
1387 
1388   public void objectCreated(ObjectModificationEvent e) {
1389     //I've never registered for these events
1390     Assert.fail();
1391   }
1392 
1393   public void objectModified(ObjectModificationEvent e) {
1394 
1395     Object source = e.getSource();
1396     int type = e.getType();
1397     int subtype = e.getSubType();
1398 
1399     //sanity checks
1400     if (type != ObjectModificationEvent.OBJECT_MODIFIED) {
1401       throw new IllegalArgumentException();
1402     }
1403 
1404     //I'm interested only in Groups and Users
1405     if (false == source instanceof Group &&
1406         false == source instanceof User) {
1407 
1408       throw new IllegalArgumentException();
1409     }
1410 
1411 
1412     if (source instanceof Group) {
1413 
1414       Assert.assertTrue(subtype == Group.OBJECT_CHANGE_ADDUSER ||
1415                     subtype == Group.OBJECT_CHANGE_NAME ||
1416                     subtype == Group.OBJECT_CHANGE_REMOVEUSER);
1417 
1418       //the name of the group could be different now (IDs are fixed)
1419       if (subtype == Group.OBJECT_CHANGE_NAME) {
1420         //rehash
1421         //any better idea how to do it?
1422         Set mappings = this.groupsByName.entrySet();
1423         Iterator it = mappings.iterator();
1424 
1425         boolean found = false;
1426         while (it.hasNext()) {
1427           Map.Entry mapEntry = (Map.Entry)it.next();
1428           String key = (String)mapEntry.getKey();
1429           Group  grp = (Group)mapEntry.getValue();
1430 
1431           if (false == key.equals(grp.getName())) {
1432             //gotcha
1433             this.groupsByName.remove(key);
1434             this.groupsByName.put(grp.getName(),grp);
1435             found = true;
1436             break;
1437           }
1438         }
1439 
1440         Assert.assertTrue(found);
1441       }
1442     }
1443     else {
1444 
1445       Assert.assertTrue(source instanceof User);
1446 
1447       //the name of the user could be different now (IDs are fixed)
1448 
1449       Assert.assertTrue(subtype == User.OBJECT_CHANGE_NAME);
1450 
1451       //the name of the group could be different now (IDs are fixed)
1452       if (subtype == User.OBJECT_CHANGE_NAME) {
1453         //rehash
1454         //any better idea how to do it?
1455         Set mappings = this.usersByName.entrySet();
1456         Iterator it = mappings.iterator();
1457 
1458         boolean found = false;
1459         while (it.hasNext()) {
1460           Map.Entry mapEntry = (Map.Entry)it.next();
1461           String key = (String)mapEntry.getKey();
1462           User  usr = (User)mapEntry.getValue();
1463 
1464           if (false == key.equals(usr.getName())) {
1465             //gotcha
1466             this.usersByName.remove(key);
1467             this.usersByName.put(usr.getName(),usr);
1468             found = true;
1469             break;
1470           }
1471         }
1472 
1473         Assert.assertTrue(found);
1474       }
1475     }
1476 
1477 
1478   }
1479 
1480   public void objectDeleted(ObjectModificationEvent e) {
1481     //I've never registered for these events
1482     Assert.fail();
1483   }
1484 
1485   public void processGateEvent(GateEvent e){
1486     throw new MethodNotImplementedException();
1487   }
1488 
1489   /** -- */
1490   public boolean isValidSecurityInfo(SecurityInfo si) {
1491 
1492     switch(si.getAccessMode()) {
1493 
1494       case SecurityInfo.ACCESS_WR_GW:
1495       case SecurityInfo.ACCESS_GR_GW:
1496         return (null != si.getGroup());
1497 
1498       case SecurityInfo.ACCESS_GR_OW:
1499         return (null != si.getGroup() &&
1500                 null != si.getUser());
1501 
1502       case SecurityInfo.ACCESS_OR_OW:
1503         return (null != si.getUser());
1504 
1505       default:
1506         throw new IllegalArgumentException();
1507     }
1508   }
1509 
1510   public void finalize() {
1511     //close connection
1512     try {
1513       this.jdbcConn.close();
1514     }
1515     catch(SQLException sqle) {}
1516 
1517   }
1518 
1519 }