1

In Go, I am adding a user to mongo and want to create a role, which grants access only to a specific collection. I am new to mongo, so not sure exactly how to do this. My attempt is to use the RunCommand. Below is what I tried, but I am getting a:
runtime error: invalid memory address or nil pointer dereference

Below my code, I verified that the values for database and id are properly set.

createRoleResult := client.Database(db).RunCommand(ctx, bson.D{{"createRole", id},
        {"privileges", []bson.M{
            {
                "resource": bson.A{bson.M{"db": db}, bson.M{"collection": id}, bson.M{"actions": bson.A{"update", "insert", "remove"}}},
            },
    }}})

This code results in the same:

    createRoleResult := client.Database(db).RunCommand(ctx, bson.D{{"createRole", id},
        {"privileges", []bson.A{
            {
                bson.D{bson.E{"resource", bson.A{bson.D{bson.E{"db", db}}, bson.D{bson.E{"collection", id}}, bson.E{"actions", bson.A{"update", "insert", "remove"}}}}},
            },
        }}})

Any advice would be appreciated! If there are better approaches to this, I'm all ears.

Working shell code:

db.createRole(
   {
     role: "ABC",
     privileges: [
       { resource: { db: "MyDB", collection: "ABC" }, actions: [ "update", "insert", "remove", "find" ] }
     ],
     roles: []
   }
)

Thanks!

Hyggelik
  • 13
  • 3
  • (1) Ideally, database administrative commands are run from console based clients like `mongosh` or `mongo` shell. Once, able to run the command from shell, one can use a language driver to translate the query - the chances of errors are reduced in such case. (2) Note that the `createRole` command expects a field `roles` of type _array_ - in case there are no roles to be specified, there must be an empty array. (3) Note the usage of [bson.A](https://pkg.go.dev/go.mongodb.org/mongo-driver@v1.8.0/bson#A). – prasad_ Feb 21 '22 at 16:35
  • What is your MongoDB version? For clarification about the command refer this: https://docs.mongodb.com/manual/reference/command/createRole/ – prasad_ Feb 21 '22 at 17:50
  • Thanks for the feedback, my version is 5.05 Community edition. I got the command to work in the shell, but am still struggling to to translate that into Go. When I use a struct with bson tags, I get the following when trying to pass that into the RunCommand portion: `var userRole UserRole cannot use userRole (variable of type UserRole) as primitive.E value in array or slice`. You mention a "language driver" to translate? Is that a tool or just generally to convert the shell command into any other language? Thanks! – Hyggelik Feb 21 '22 at 18:33
  • Maybe, you can include the working shell query in the question post - it might help someone to suggest fixes in the Go code. – prasad_ Feb 21 '22 at 18:43

1 Answers1

0

You can try this Golang code:

var commandResult bson.M
command := bson.D{{ "createRole", "ABC" }, { "privileges", bson.A{ bson.D{{ "resource", bson.D{{ "db", "MyDB" }, { "collection", "ABC" }}}, { "actions", bson.A{ "update", "insert" }}}}}, { "roles", bson.A{}}}
err = client.Database("test").RunCommand(context.TODO(), command).Decode(&commandResult)

if err != nil {
    log.Fatal(err)
}

fmt.Println(commandResult)
prasad_
  • 12,755
  • 2
  • 24
  • 36
  • I think this must be close, but I am still getting the same error. I'll play around with this some more and keep you posted. – Hyggelik Feb 21 '22 at 20:14
  • When I print out the command, it looks like this: ```[{createRole 6213f30856b03a7d17a15e61} {privileges [[{resource [{db PM} {collection 6213f30856b03a7d17a15e61}]} {actions [update insert]}]]} {roles []}]``` – Hyggelik Feb 21 '22 at 20:20
  • The code doesn't have any syntax errors, and I had used with MongoDB v 4.2.8 and the latest Golang driver . – prasad_ Feb 22 '22 at 04:10
  • Thanks for your help! Got it to work with your syntax. Was pointing to the wrong database after all, but I would have still struggled with finding the correct syntax. – Hyggelik Feb 22 '22 at 09:36