how do I test to see if I have user-permissions problem?

42 views
Skip to first unread message

lawrenc...@gmail.com

unread,
Feb 15, 2014, 3:27:19 PM2/15/14
to clojure...@googlegroups.com

Working on my Mac, I installed MongoDb with Homebrew. In the Mongo shell, I created a database "tma" and a collection "tma" and I added a user: 

use tma; 
db.addUser( { user: "tma",
              pwd: "xxx",
              roles: [ "readWrite" ]
            } ) ;

and I also: 

use admin;
db.addUser( { user: "admin",
              pwd: "xxx",
              roles: [ "userAdminAnyDatabase" ]
            } ) ;

If I start MongoDb in a Terminal window, I log in without needing to authenticate, and I can do any operation, including inserts and updates. 

When I was done with the app I was working on, I did "lein uberjar" and then I started the app so it was running on my Mac. This is a webapp so I could point my browser at it. I saw all the pages I expected -- Monger was able to fetch data from MongoDb. However, I could not do inserts. 

From Monger, I have a simple function to do inserts:

(defn persist-this-item [item]
  {:pre [
         (map? item)
         (= (type (:item-name item)) java.lang.String)
         (= (type (:item-type item)) java.lang.String)
         (if (:created-at item)
           (= (type (:created-at item)) org.joda.time.DateTime)
           true)
         ]}
  (println " in monger/persist-this-item the item is: ")
  (pp/pprint item)
  (let [item (if (nil? (:created-at item))
               (assoc item :created-at (tyme/current-time-as-datetime))
               item)
        item (assoc item :updated-at (tyme/current-time-as-datetime))]
    (mc/insert "tma" (assoc item :_id (ObjectId.)))))
    

Where I have "pprint" I see the document I expected, but nothing ever appears in the database, as I can verify by looking at the command line. There are no errors, no exceptions. 

I assume I am facing some user permission issues, but I am not sure how to test this. Any thoughts? 




lawrenc...@gmail.com

unread,
Feb 17, 2014, 8:21:25 PM2/17/14
to clojure...@googlegroups.com

I have not been able to solve this. I have restarted mongodb, on a remote server, with auth set to true. Now I connect to MongoDb like this:



(def credentials {
 :db "xxx"
 :username "xxx"
 :password "xxx"
                  })

(defn establish-database-connection []
  (let [uri (str "mongodb://" (:username credentials) ":" (:password credentials) "@tailormadeanswers.com/tma")]
    (println uri)
    (monger.core/connect-via-uri! uri)))

This seems to work. I can see data coming out of the remote database. 

But now, when I try to insert a record, I get this :

"Exception in the main function: " #<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.Named>
java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.Named
 at clojure.core$name.invoke (core.clj:1505)
    monger.collection$update.doInvoke (collection.clj:392)
    clojure.lang.RestFn.invoke (RestFn.java:494)
    calculate_user_profile_aggregates.mongo$persist_document_to_database.invoke (mongo.clj:68)
    calculate_user_profile_aggregates.core$add_this_record_to_mongo.invoke (core.clj:38)
    calculate_user_profile_aggregates.core$add_record_to_mongo$fn__17$fn__18.invoke (core.clj:48)
    clojure.java.jdbc$with_query_results_STAR_.invoke (jdbc.clj:673)
    calculate_user_profile_aggregates.core$add_record_to_mongo$fn__17.invoke (core.clj:45)
    clojure.java.jdbc$with_connection_STAR_.invoke (jdbc.clj:302)
    calculate_user_profile_aggregates.core$add_record_to_mongo.invoke (core.clj:44)
    calculate_user_profile_aggregates.core$each_site_update.invoke (core.clj:51)
    calculate_user_profile_aggregates.core$iterate_through_all_of_the_sites.invoke (core.clj:92)
    calculate_user_profile_aggregates.core$calculate_user_profile_aggregates.invoke (core.clj:99)
    calculate_user_profile_aggregates.core$_main.doInvoke (core.clj:141)
    clojure.lang.RestFn.invoke (RestFn.java:397)
    clojure.lang.AFn.applyToHelper (AFn.java:159)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    calculate_user_profile_aggregates.core.main (:-1)

The record is:

{:item-name "wpquestions-affiliates-1",
 :community "wpquestions",
 :item-type "affiliates",
 :updated_at #inst "2010-01-19T14:47:17.000000000-00:00",
 :created_at #inst "2010-01-19T14:47:17.000000000-00:00",
 :new_user_id 418,
 :owning_user_id 4,
 :id 1}

My insert function is: 

(defn persist-document-to-database [item]
  (println " in monger/persist-this-item the item is: ")
  (let [item (if (nil? (:created-at item))
               (assoc item :created-at (tyme/current-time-as-datetime))
               item)
        item (assoc item :updated-at (tyme/current-time-as-datetime))]
    (mc/insert "tma" (assoc item :_id (ObjectId.)))))
    

The line " in monger/persist-this-item the item is: " never appears in the output log. 

The function that calls this looks like this:

(defn add-this-record-to-mongo [db record item-type]
  (let [record (assoc record :item-type item-type)
        record (assoc record :community (:user db))
        record (if (= (type (:vote record)) java.math.BigDecimal)
                 (assoc record :vote (str (:vote record)))
                 record)
        item-name (str (:community record) "-" (:item-type record) "-" (:id record))
        record (assoc record :item-name item-name)]
    (println " we will now try to persist this document calling the monger namespace: ")
    (pp/pprint record)
    (mongo/persist-document-to-database record)))

The output of these 2 lines do appear in the output log:

    (println " we will now try to persist this document calling the monger namespace: ")
    (pp/pprint record)

I :require the mongo namespace:

            [calculate-user-profile-aggregates.mongo :as mongo]


As you can see in the stack trace, the last line before the exception is:

    monger.collection$update.doInvoke (collection.clj:392)

What could this error mean? Is it a connection error? A format error?

lawrenc...@gmail.com

unread,
Feb 17, 2014, 8:26:41 PM2/17/14
to clojure...@googlegroups.com

I am not sure how I should dig further on this issue. The line before this:

   (mongo/persist-document-to-database record)

prints data to the output log, yet the first line inside of persist-document-to-database never prints. Suggestions about what I should try? 

lawrenc...@gmail.com

unread,
Feb 17, 2014, 8:27:22 PM2/17/14
to clojure...@googlegroups.com

Could it cause an error to try to log in remotely, when the app is sitting on the same server as the mongodb database? 


On Monday, February 17, 2014 8:21:25 PM UTC-5, lawrenc...@gmail.com wrote:

lawrenc...@gmail.com

unread,
Feb 17, 2014, 8:32:10 PM2/17/14
to clojure...@googlegroups.com
This is a strange line, from the stacktrace:

    monger.collection$update.doInvoke (collection.clj:392)

I am not doing an update, so why would that be in the stacktrace? 

lawrenc...@gmail.com

unread,
Feb 17, 2014, 9:22:04 PM2/17/14
to clojure...@googlegroups.com

Ah, I see. I had a namespace collision, with symbols from one namespace clobbering another. I managed to get this all working, finally. 

lawrenc...@gmail.com

unread,
Feb 25, 2014, 11:17:53 PM2/25/14
to clojure...@googlegroups.com

I can not figure out if I have a MongoDb problem or a Monger problem. Over the last few days I decided to try to find a way forward with this problem by changing everything. Whereas I was previously running MongoDb on my Mac, and doing all development locally, I decided to instead move MongoDb to a remote server. I thought the change might help me pinpoint what the problem is. So I moved my data to a remote webserver, running Ubuntu. I now connect with: 

(defn establish-database-connection []
  (let [credentials (read-string (slurp (clojure.java.io/resource "config/credentials.edn")))                    
        uri (str "mongodb://" (:username credentials) ":" (:password credentials) "@example.com/tma")]
    (println uri)
    (monger.core/connect-via-uri! uri)))

This works fine, for reading data. I can compile my app on my Mac, and boot it up with "java -jar myapp.jar". It connects to the remote server, reads the data and shows it to me in HTML pages. That part works fine. 

However, when I try to make a change, nothing happens. I use this function:

(defn persist-this-item [item]
  {:pre [
         (map? item)
         (= (type (:item-name item)) java.lang.String)
         (= (type (:item-type item)) java.lang.String)
         (if (:created-at item)
           (= (type (:created-at item)) org.joda.time.DateTime)
           true)
         ]}
  (println " in monger/persist-this-item the item is: ")
  (pp/pprint item)
  (let [item (if (nil? (:created-at item))
               (assoc item :created-at (tyme/current-time-as-datetime))
               item)
        item (assoc item :updated-at (tyme/current-time-as-datetime))]
    (mc/insert "tma" (assoc item :_id (ObjectId.)))))

The pprint line shows me the item, and it is exactly the data I am expecting. 

I would assume this was a user permission problem, but the user was created with this command: 

db.addUser( { user: "xxx",
              pwd: "xxx",
              roles: [ "readWrite" ]
            } );

The readWrite role should let me do inserts, yes? I can certainly read the data fine with this user. 

Any thoughts about what I might have done wrong? 

lawrenc...@gmail.com

unread,
Feb 25, 2014, 11:52:55 PM2/25/14
to clojure...@googlegroups.com

Hmm, I ssh to the server and log into MongoDb as a user that has admin credentials. I create a new user with wide open permissions:

use admin;
db.addUser( { user: "god",
                  pwd: "xxx",
                  roles: [ "clusterAdmin", "userAdminAnyDatabase", "readWriteAnyDatabase" ] } );

Then I exit the mongo shell. Then I restart MongoDb:

sudo service mongodb stop

sudo service mongodb start

Then I log back into the mongo shell. I authenticate as this new user. I seem to have the power to do anything. 

I then change the credentials in my Clojure app so that my app uses this users credentials. I recompile the app and then launch it again. And now it seems to lack the power to read or write from the database. 

What have I done wrong? 

lawrenc...@gmail.com

unread,
Feb 25, 2014, 11:58:56 PM2/25/14
to clojure...@googlegroups.com

I now get:

com.mongodb.MongoException: not authorized for query on tma.tma
at com.mongodb.MongoException.parse(MongoException.java:82)

So, with this new user, I seem to have an auth problem. But previously, I got no error at all. The records would not insert, but I got no error. Can anyone think what the problem might be for the user account that generates no error? 

lawrenc...@gmail.com

unread,
Feb 26, 2014, 12:02:51 AM2/26/14
to clojure...@googlegroups.com

If I run an app on the server itself (the server that is running MongoDb) and I copy and paste my connection code to that app:

(def credentials  {:db "tma"
                         :username "xxx"
                         :password "xxx"})

(defn establish-database-connection []
  (let [uri (str "mongodb://" (:username credentials) ":" (:password credentials) "@example.com/tma")]
    (println uri)
    (monger.core/connect-via-uri! uri)))


Then everything works fine. The app can read and write to the MongoDb database. But when I run an app on my Mac and connect to the server remotely, using those same credentials, I can read from the database, but my insert() statement never writes to the database. 

Any thoughts about where the point of failure might be? 




On Tuesday, February 25, 2014 11:52:55 PM UTC-5, lawrenc...@gmail.com wrote:

Michael Klishin

unread,
Feb 26, 2014, 1:33:31 AM2/26/14
to Monger, a Clojure MongoDB driver
2014-02-26 8:58 GMT+04:00 <lawrenc...@gmail.com>:
So, with this new user, I seem to have an auth problem. But previously, I got no error at all. The records would not insert, but I got no error. Can anyone think what the problem might be for the user account that generates no error?

Did you try monger.core/get-last-error?

MongoDB's error reporting for writes depends on the active write concern and the lowest
one does not even report network issues.

I'd recommend running mongod with extra verbose logging to find out more.
--
MK

http://github.com/michaelklishin
http://twitter.com/michaelklishin

lawrenc...@gmail.com

unread,
Feb 26, 2014, 1:56:20 AM2/26/14
to clojure...@googlegroups.com
Thanks. I adjusted the function to this:


(defn persist-this-item [item]
  {:pre [
         (map? item)
         (= (type (:item-name item)) java.lang.String)
         (= (type (:item-type item)) java.lang.String)
         (if (:created-at item)
           (= (type (:created-at item)) org.joda.time.DateTime)
           true)
         ]}
  (let [item (if (nil? (:created-at item))
               (assoc item :created-at (tyme/current-time-as-datetime))
               item)
        item (assoc item :updated-at (tyme/current-time-as-datetime))
        item (assoc item :_id (ObjectId.))]

    (println "about to save this item:")
    (pp/pprint item)
    
    (pp/pprint (mc/insert-and-return "tma" item))
    (println " the last error from monger, if any: ")
    (pp/pprint  mg/get-last-error)
        (println " saved this item:")
    ))


These 2 lines print:

    (println "about to save this item:")
    (pp/pprint item)


Nothing after that prints to the terminal. I don't seem to be catching/disposing an error anywhere. There is a top level try/catch that wraps the whole app, but it just logs the output to the terminal, so I would see the exception, if there was one. 

I'll check the mongo log on the server, but I think the problem has to be in the app. The println statements should show up in the terminal, regardless of what MongoDb is doing. 

lawrenc...@gmail.com

unread,
Feb 26, 2014, 1:58:06 AM2/26/14
to clojure...@googlegroups.com
Checked /var/log/mongodb/mongodb.log

I didn't see any error that would explain the problems I'm seeing. 

lawrenc...@gmail.com

unread,
Feb 26, 2014, 2:01:16 AM2/26/14
to clojure...@googlegroups.com
Fixed this:


(defn persist-this-item [item]
  {:pre [
         (map? item)
         (= (type (:item-name item)) java.lang.String)
         (= (type (:item-type item)) java.lang.String)
         (if (:created-at item)
           (= (type (:created-at item)) org.joda.time.DateTime)
           true)
         ]}
  (let [item (if (nil? (:created-at item))
               (assoc item :created-at (tyme/current-time-as-datetime))
               item)
        item (assoc item :updated-at (tyme/current-time-as-datetime))
        item (assoc item :_id (ObjectId.))]

    (println "about to save this item:")
    (pp/pprint item)
    
    (pp/pprint (mc/insert-and-return "tma" item))
    (println " the last error from monger, if any: ")
    (pp/pprint  ( mg/get-last-error))
        (println " saved this item:")

    ))

Still the same problem. None of the printlns appear after the insert-and-return. 


On Wednesday, February 26, 2014 1:56:20 AM UTC-5, lawrenc...@gmail.com wrote:

lawrenc...@gmail.com

unread,
Feb 26, 2014, 2:17:43 AM2/26/14
to clojure...@googlegroups.com
Ah, sorry to waste your time. I was using Lamina to do the inserts asynchronously, and apparently Lamina has its own philosophy about handling exceptions: 


Apparently the closure I put on the Lamina queue needs to have its own try/catch, or Lamina requires me to do some special handling. 

Everything now works. I wasted many hours looking at the wrong thing: MongoDb and user permissions. But all of that was fine. 

Again, sorry to waste your time. 
Reply all
Reply to author
Forward
0 new messages