Rework authentication for the 3.0 client and multiple server versions
When authentication failures, MongoDB Java client throws a timeout exception whose cause is a failed command exception which carries a reason. Still not great at authentication failure notification.
This commit is contained in:
parent
6ca5b9d4ba
commit
8b2fd956e4
2 changed files with 22 additions and 36 deletions
|
|
@ -19,7 +19,8 @@
|
||||||
* http://clojuremongodb.info/articles/gridfs.html"
|
* http://clojuremongodb.info/articles/gridfs.html"
|
||||||
(:refer-clojure :exclude [count])
|
(:refer-clojure :exclude [count])
|
||||||
(:require [monger.conversion :refer :all])
|
(:require [monger.conversion :refer :all])
|
||||||
(:import [com.mongodb MongoClient MongoClientURI DB WriteConcern DBObject DBCursor Bytes MongoClientOptions MongoClientOptions$Builder ServerAddress MapReduceOutput MongoException]
|
(:import [com.mongodb MongoClient MongoClientURI MongoCredential DB WriteConcern DBObject DBCursor Bytes
|
||||||
|
MongoClientOptions MongoClientOptions$Builder ServerAddress MapReduceOutput MongoException]
|
||||||
[com.mongodb.gridfs GridFS]
|
[com.mongodb.gridfs GridFS]
|
||||||
[java.util Map ArrayList]))
|
[java.util Map ArrayList]))
|
||||||
|
|
||||||
|
|
@ -46,7 +47,7 @@
|
||||||
{:arglists '([]
|
{:arglists '([]
|
||||||
[server-address options]
|
[server-address options]
|
||||||
[[server-address & more] options]
|
[[server-address & more] options]
|
||||||
[{ :keys [host port uri] :or { host *mongodb-host* port *mongodb-port* }}])}
|
[{:keys [host port uri] :or { host *mongodb-host* port *mongodb-port*}}])}
|
||||||
([]
|
([]
|
||||||
(MongoClient.))
|
(MongoClient.))
|
||||||
([server-address ^MongoClientOptions options]
|
([server-address ^MongoClientOptions options]
|
||||||
|
|
@ -61,13 +62,23 @@
|
||||||
credentials
|
credentials
|
||||||
[credentials])]
|
[credentials])]
|
||||||
(if (coll? server-address)
|
(if (coll? server-address)
|
||||||
(let [server-list ^ArrayList (ArrayList. ^java.util.Collection server-address)
|
(let [server-list ^ArrayList (ArrayList. ^java.util.Collection server-address)]
|
||||||
]
|
|
||||||
(MongoClient. server-list creds options))
|
(MongoClient. server-list creds options))
|
||||||
(MongoClient. ^ServerAddress server-address options))))
|
(MongoClient. ^ServerAddress server-address options))))
|
||||||
([{ :keys [host port uri] :or { host *mongodb-host* port *mongodb-port* }}]
|
([{ :keys [host port uri] :or { host *mongodb-host* port *mongodb-port* }}]
|
||||||
(MongoClient. ^String host ^Long port)))
|
(MongoClient. ^String host ^Long port)))
|
||||||
|
|
||||||
|
(defn ^MongoClient connect-with-credentials
|
||||||
|
"Connect with provided credentials and default options"
|
||||||
|
([credentials]
|
||||||
|
(connect-with-credentials *mongodb-host* *mongodb-port* credentials))
|
||||||
|
([^String hostname credentials]
|
||||||
|
(connect-with-credentials hostname *mongodb-port* credentials))
|
||||||
|
([^String hostname port credentials]
|
||||||
|
(MongoClient. [(ServerAddress. hostname port)]
|
||||||
|
(if (coll? credentials)
|
||||||
|
credentials
|
||||||
|
[credentials]))))
|
||||||
|
|
||||||
(defn get-db-names
|
(defn get-db-names
|
||||||
"Gets a list of all database names present on the server"
|
"Gets a list of all database names present on the server"
|
||||||
|
|
@ -155,15 +166,6 @@
|
||||||
(alter-var-root #'*mongodb-write-concern* (constantly wc)))
|
(alter-var-root #'*mongodb-write-concern* (constantly wc)))
|
||||||
|
|
||||||
|
|
||||||
(defn authenticate
|
|
||||||
([^DB db ^String username ^chars password]
|
|
||||||
(try
|
|
||||||
(.authenticate db username password)
|
|
||||||
;; MongoDB Java driver's exception hierarchy is a little crazy
|
|
||||||
;; and the exception we want is not a public class. MK.
|
|
||||||
(catch Exception _
|
|
||||||
false))))
|
|
||||||
|
|
||||||
(defn connect-via-uri
|
(defn connect-via-uri
|
||||||
"Connects to MongoDB using a URI, returns the connection and database as a map with :conn and :db.
|
"Connects to MongoDB using a URI, returns the connection and database as a map with :conn and :db.
|
||||||
Commonly used for PaaS-based applications, for example, running on Heroku.
|
Commonly used for PaaS-based applications, for example, running on Heroku.
|
||||||
|
|
@ -171,12 +173,7 @@
|
||||||
[^String uri-string]
|
[^String uri-string]
|
||||||
(let [uri (MongoClientURI. uri-string)
|
(let [uri (MongoClientURI. uri-string)
|
||||||
conn (MongoClient. uri)
|
conn (MongoClient. uri)
|
||||||
db (.getDB conn (.getDatabase uri))
|
db (.getDB conn (.getDatabase uri))]
|
||||||
user (.getUsername uri)
|
|
||||||
pwd (.getPassword uri)]
|
|
||||||
(when (and user pwd)
|
|
||||||
(when-not (authenticate db user pwd)
|
|
||||||
(throw (IllegalArgumentException. (format "Could not authenticate with MongoDB. Either database name or credentials are invalid. Database name: %s, username: %s" (.getName db) user)))))
|
|
||||||
{:conn conn :db db}))
|
{:conn conn :db db}))
|
||||||
|
|
||||||
(defn ^com.mongodb.CommandResult command
|
(defn ^com.mongodb.CommandResult command
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
(ns monger.test.authentication-test
|
(ns monger.test.authentication-test
|
||||||
(:require [monger util db]
|
(:require [monger util db]
|
||||||
|
[monger.credentials :as mcr]
|
||||||
[monger.core :as mg]
|
[monger.core :as mg]
|
||||||
[monger.collection :as mc]
|
[monger.collection :as mc]
|
||||||
[clojure.test :refer :all]))
|
[clojure.test :refer :all]))
|
||||||
|
|
@ -33,21 +34,9 @@
|
||||||
;; Regular connecton
|
;; Regular connecton
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(let [conn (mg/connect)
|
(deftest ^{:authentication true} test-authentication-with-valid-credentials
|
||||||
db (mg/get-db conn "monger-test")]
|
|
||||||
(deftest ^{:authentication true} test-authentication-with-valid-credentials-on-the-default-db
|
|
||||||
;; see ./bin/ci/before_script.sh. MK.
|
;; see ./bin/ci/before_script.sh. MK.
|
||||||
(let [username "clojurewerkz/monger"
|
(doseq [s ["monger-test" "monger-test2" "monger-test3" "monger-test4"]]
|
||||||
pwd "monger"]
|
(let [creds (mcr/for "clojurewerkz/monger" "monger-test" "monger")
|
||||||
(is (mg/authenticate db username (.toCharArray pwd)))))
|
conn (mg/connect-with-credentials "127.0.0.1" creds)]
|
||||||
|
(mc/remove (mg/get-db conn "monger-test") "documents"))))
|
||||||
(deftest ^{:authentication true} test-authentication-with-valid-credentials-on-an-arbitrary-db
|
|
||||||
;; see ./bin/ci/before_script.sh. MK.
|
|
||||||
(let [username "clojurewerkz/monger"
|
|
||||||
pwd "monger"]
|
|
||||||
(is (mg/authenticate (mg/get-db conn "monger-test") username (.toCharArray pwd)))))
|
|
||||||
|
|
||||||
(deftest ^{:authentication true} test-authentication-with-invalid-credentials
|
|
||||||
(let [username "monger"
|
|
||||||
^String pwd (monger.util/random-str 128 32)]
|
|
||||||
(is (not (mg/authenticate (mg/get-db conn "monger-test2") username (.toCharArray pwd)))))))
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue