From: Sebastian B. <bo...@us...> - 2004-09-03 09:05:42
|
Update of /cvsroot/exist/eXist-1.0/src/org/exist/xmldb In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12598/src/org/exist/xmldb Modified Files: DatabaseImpl.java RemoteCollection.java Log Message: Make DatabaseImpl's RPCClient cache aware of different user identities. This fixes bug #1021687. Index: DatabaseImpl.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xmldb/DatabaseImpl.java,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** DatabaseImpl.java 12 Jul 2004 20:27:56 -0000 1.19 --- DatabaseImpl.java 3 Sep 2004 09:05:32 -0000 1.20 *************** *** 24,27 **** --- 24,28 ---- import java.io.File; import java.net.MalformedURLException; + import java.util.HashMap; import java.util.StringTokenizer; *************** *** 69,73 **** protected String dbName = DEFAULT_NAME; protected String selector = dbName + ':'; ! protected XmlRpcClient rpcClient; protected ShutdownListener shutdown = null; protected int mode = 0; --- 70,76 ---- protected String dbName = DEFAULT_NAME; protected String selector = dbName + ':'; ! //protected XmlRpcClient rpcClient; ! private HashMap rpcClients = new HashMap(); ! protected ShutdownListener shutdown = null; protected int mode = 0; *************** *** 144,223 **** Collection current = null; if ( c.startsWith( "///" ) ) { ! mode = LOCAL; ! // use local database instance ! if ( !BrokerPool.isConfigured( dbName ) ) { ! if ( autoCreate ) ! configure(); ! else ! throw new XMLDBException( ErrorCodes.COLLECTION_CLOSED, ! "local database server not running" ); ! } ! BrokerPool pool; ! try { ! pool = BrokerPool.getInstance( dbName ); ! } catch ( EXistException e ) { ! throw new XMLDBException( ErrorCodes.VENDOR_ERROR, ! "db not correctly initialized", ! e ); ! } ! User u = null; ! if ( user == null ) { ! user = "guest"; ! password = "guest"; ! } ! if ( user != null ) { ! u = pool.getSecurityManager().getUser( user ); ! if ( u == null ) { ! throw new XMLDBException( ErrorCodes.PERMISSION_DENIED, ! "user " + user + " does not exist" ); ! } ! if ( !u.validate( password ) ) { ! throw new XMLDBException( ErrorCodes.PERMISSION_DENIED, ! "invalid password" ); ! } ! } ! try { ! current = new LocalCollection( u, pool, c.substring( 2 ) ); ! return ( current != null ) ! ? current : null; ! } catch ( XMLDBException e ) { ! switch ( e.errorCode ) { ! case ErrorCodes.NO_SUCH_RESOURCE: ! case ErrorCodes.NO_SUCH_COLLECTION: ! case ErrorCodes.INVALID_COLLECTION: ! case ErrorCodes.INVALID_RESOURCE: ! return null; ! default: ! throw e; ! } ! } } else if ( c.startsWith( "//" ) ) { ! // use remote database via XML-RPC ! mode = REMOTE; ! if ( user == null ) { ! user = "guest"; ! password = "guest"; ! } else if(password == null) ! password = ""; ! // try to figure out server address ! int p = 0; ! if ( ( p = c.indexOf( "/db", 2 ) ) > -1 ) { ! address = "http://" + c.substring( 2, p ); ! c = c.substring( p ); ! } ! else ! throw new XMLDBException( ErrorCodes.INVALID_DATABASE, ! "malformed url: " + address ); ! if ( rpcClient == null ) ! try { ! rpcClient = new XmlRpcClient( address ); ! } catch ( MalformedURLException e ) { ! throw new XMLDBException( ErrorCodes.INVALID_DATABASE, ! "malformed url: " + address, ! e ); ! } ! rpcClient.setBasicAuthentication( user, password ); ! return readCollection( c, rpcClient, address ); } else --- 147,154 ---- Collection current = null; if ( c.startsWith( "///" ) ) { ! return getLocalCollection(user, password, c); } else if ( c.startsWith( "//" ) ) { ! return getRemoteCollection(user, password, address, c); } else *************** *** 225,228 **** --- 156,281 ---- "malformed url: " + address ); } + + /** + * @param user + * @param password + * @param address + * @param c + * @return + * @throws XMLDBException + */ + private Collection getRemoteCollection(String user, String password, String address, String c) throws XMLDBException { + // use remote database via XML-RPC + mode = REMOTE; + if ( user == null ) { + user = "guest"; + password = "guest"; + } else if(password == null) + password = ""; + // try to figure out server address + int p = 0; + if ( ( p = c.indexOf( "/db", 2 ) ) > -1 ) { + address = "http://" + c.substring( 2, p ); + c = c.substring( p ); + } + else + throw new XMLDBException( ErrorCodes.INVALID_DATABASE, + "malformed url: " + address ); + XmlRpcClient rpcClient = getRpcClient(user, password, address); + return readCollection( c, rpcClient, address ); + } + + /** + * @param user + * @param c + * @return + * @throws XMLDBException + */ + private Collection getLocalCollection(String user, String password, String c) throws XMLDBException { + Collection current; + mode = LOCAL; + // use local database instance + if ( !BrokerPool.isConfigured( dbName ) ) { + if ( autoCreate ) + configure(); + else + throw new XMLDBException( ErrorCodes.COLLECTION_CLOSED, + "local database server not running" ); + } + BrokerPool pool; + try { + pool = BrokerPool.getInstance( dbName ); + } catch ( EXistException e ) { + throw new XMLDBException( ErrorCodes.VENDOR_ERROR, + "db not correctly initialized", + e ); + } + User u = getUser(user, password, pool); + try { + current = new LocalCollection( u, pool, c.substring( 2 ) ); + return ( current != null ) + ? current : null; + } catch ( XMLDBException e ) { + switch ( e.errorCode ) { + case ErrorCodes.NO_SUCH_RESOURCE: + case ErrorCodes.NO_SUCH_COLLECTION: + case ErrorCodes.INVALID_COLLECTION: + case ErrorCodes.INVALID_RESOURCE: + return null; + default: + throw e; + } + } + } + + /** + * @param user + * @param pool + * @return the User object corresponding to the username in <code>user</code> + * @throws XMLDBException + */ + private User getUser(String user, String password, BrokerPool pool) throws XMLDBException { + User u = null; + if ( user == null ) { + user = "guest"; + password = "guest"; + } + if ( user != null ) { + u = pool.getSecurityManager().getUser( user ); + if ( u == null ) { + throw new XMLDBException( ErrorCodes.PERMISSION_DENIED, + "user " + user + " does not exist" ); + } + if ( !u.validate( password ) ) { + throw new XMLDBException( ErrorCodes.PERMISSION_DENIED, + "invalid password" ); + } + } + return u; + } + + /** + * RpcClients are cached by address+user. The password is transparently changed. + * @param user + * @param password + * @param address + * @throws XMLDBException + */ + private XmlRpcClient getRpcClient(String user, String password, String address) throws XMLDBException { + String key = user + "@" + address; + XmlRpcClient client = (XmlRpcClient) rpcClients.get(key); + if ( client == null ) { + try { + client = new XmlRpcClient( address ); + } catch ( MalformedURLException e ) { + throw new XMLDBException( ErrorCodes.INVALID_DATABASE, "malformed url: " + address, e ); + } + if (client != null) + rpcClients.put(key, client); + } + if (client != null) + client.setBasicAuthentication(user, password); + return client; + } public String getConformanceLevel() throws XMLDBException { Index: RemoteCollection.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xmldb/RemoteCollection.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** RemoteCollection.java 12 Aug 2004 16:11:08 -0000 1.17 --- RemoteCollection.java 3 Sep 2004 09:05:32 -0000 1.18 *************** *** 431,436 **** rpcClient.execute("storeBinary", params); } catch (XmlRpcException xre) { throw new XMLDBException( ! ErrorCodes.INVALID_RESOURCE, xre == null ? "unknown error" : xre.getMessage(), xre); --- 431,441 ---- rpcClient.execute("storeBinary", params); } catch (XmlRpcException xre) { + /* the error code previously was INVALID_RESOURCE, but this was also thrown + * in case of insufficient persmissions. As you cannot tell here any more what the + * error really was, use UNKNOWN_ERROR. The reason is in XmlRpcResponseProcessor#processException + * which will only pass on the error message. + */ throw new XMLDBException( ! ErrorCodes.UNKNOWN_ERROR, xre == null ? "unknown error" : xre.getMessage(), xre); |