From 532e4a48063ed0d2f86c50be838d3e98cdbcdf43 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 11 Nov 2010 12:25:51 +0100 Subject: [PATCH] Support for authentication via MongoTemplate and a new execute method that doesn't start and finish a request --- .../CannotGetMongoDbConnectionException.java | 4 ++ .../data/document/mongodb/MongoDbUtils.java | 30 ++++++++++- .../data/document/mongodb/MongoTemplate.java | 54 +++++++++++++++++-- 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/CannotGetMongoDbConnectionException.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/CannotGetMongoDbConnectionException.java index 7feb98f21..54d84ae9a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/CannotGetMongoDbConnectionException.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/CannotGetMongoDbConnectionException.java @@ -23,4 +23,8 @@ public class CannotGetMongoDbConnectionException extends DataAccessResourceFailu super(msg, cause); } + public CannotGetMongoDbConnectionException(String msg) { + super(msg); + } + } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoDbUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoDbUtils.java index 2ec5add79..938c411ac 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoDbUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoDbUtils.java @@ -75,11 +75,32 @@ public class MongoDbUtils { return null; } + /** + * Obtains a {@link DB} connection for the given {@link Mongo} instance and database name + * + * @param mongo The {@link Mongo} instance + * @param databaseName The database name + * @return The {@link DB} connection + */ public static DB getDB(Mongo mongo, String databaseName) { - return doGetDB(mongo, databaseName, true); + return doGetDB(mongo, databaseName,null,null, true); } - public static DB doGetDB(Mongo mongo, String databaseName, boolean allowCreate) { + /** + * + * Obtains a {@link DB} connection for the given {@link Mongo} instance and database name + * + * @param mongo The {@link Mongo} instance + * @param databaseName The database name + * @param username The username to authenticate with + * @param password The password to authenticate with + * @return The {@link DB} connection + */ + public static DB getDB(Mongo mongo, String databaseName, String username, char[] password) { + return doGetDB(mongo, databaseName,username,password, true); + } + + public static DB doGetDB(Mongo mongo, String databaseName, String username, char[] password, boolean allowCreate) { Assert.notNull(mongo, "No Mongo instance specified"); DBHolder dbHolder = (DBHolder) TransactionSynchronizationManager.getResource(mongo); @@ -103,6 +124,11 @@ public class MongoDbUtils { logger.debug("Opening Mongo DB"); DB db = mongo.getDB(databaseName); + if(username != null && password != null) { + if(!db.authenticate(username, password)) { + throw new CannotGetMongoDbConnectionException("Failed to authenticate with Mongo using the given credentials"); + } + } // Use same Session for further Mongo actions within the transaction. // Thread object will get removed by synchronization at transaction completion. if (TransactionSynchronizationManager.isSynchronizationActive()) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java index 7511994f8..48e0163e7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java @@ -51,6 +51,10 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate implements private String databaseName; + private String username; + + private char[] password; + public MongoTemplate(Mongo mongo, String databaseName) { this(mongo, databaseName, null, null); @@ -71,6 +75,25 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate implements this.databaseName = databaseName; } + + /** + * Sets the username to use to connect to the Mongo database + * + * @param username The username to use + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * Sets the password to use to authenticate with the Mongo database + * + * @param password The password to use + */ + public void setPassword(char[] password) { + this.password = password; + } + public void setDefaultCollectionName(String defaultCollectionName) { this.defaultCollectionName = defaultCollectionName; } @@ -83,6 +106,12 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate implements return defaultCollectionName; } + /** + * @return The default collection used by this template + */ + public DBCollection getDefaultCollection() { + return getConnection().getCollection(getDefaultCollectionName()); + } public void executeCommand(String jsonCommand) { executeCommand((DBObject)JSON.parse(jsonCommand)); @@ -97,15 +126,31 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate implements } } + /** + * Executes a {@link DBCallback} translating any exceptions as necessary + * + * @param The return type + * @param action The action to execute + * + * @return The return value of the {@link DBCallback} + */ + public T execute(DBCallback action) { + DB db = getConnection(); + + try { + return action.doInDB(db); + } catch (MongoException e) { + throw MongoDbUtils.translateMongoExceptionIfPossible(e); + } + } + public T executeInSession(DBCallback action) { DB db = getConnection(); db.requestStart(); try { return action.doInDB(db); } catch (MongoException e) { - //TODO refine exception thrown to capture last error. - CommandResult result = db.getLastError(); - throw new InvalidDataAccessApiUsageException("Error accessing DB " + db + ":" + e.getMessage(), e); + throw MongoDbUtils.translateMongoExceptionIfPossible(e); } finally { db.requestDone(); } @@ -276,6 +321,9 @@ public class MongoTemplate extends AbstractDocumentStoreTemplate implements @Override public DB getConnection() { + if(username != null && password != null) { + return MongoDbUtils.getDB(mongo, databaseName, username, password); + } return MongoDbUtils.getDB(mongo, databaseName); }