Skip to content

Commit 593df06

Browse files
timvaillancourtdomodwyer
authored andcommitted
Add 3.6+ user authenticationRestrictions (#229)
* Add 3.6 user authenticationRestrictions * Add struct-field comment * Add struct-field comment #2 * Add struct-field comment #3 * Add documentation link * Fix comment * Fix comment #2 * add to README.md * add to README.md #2 * add to README.md #3 * Add positive/negative authentication restrictions user test * Use denyUser for negative test * Correct message * Fix error match * Fix close on nil/closed session * Simplify test, last change :) * Simplify test, last change :) #2 * Simplify test, last change :) #3 * Fix := error
1 parent 5af851b commit 593df06

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ A [sub-package](https://godoc.org/github.com/globalsign/mgo/bson) that implement
5858
* Support setting `writeConcern` for `findAndModify` operations ([details](https://github.com/globalsign/mgo/pull/185))
5959
* Add `ssl` to the dial string options ([details](https://github.com/globalsign/mgo/pull/184))
6060
* Support connecting via Unix sockets ([details](https://github.com/globalsign/mgo/pull/129))
61-
61+
* Support MongoDB User authenticationRestrictions ([details](https://github.com/globalsign/mgo/pull/229))
6262

6363
---
6464

Diff for: auth_test.go

+51
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,57 @@ func (s *S) TestAuthUpsertUserUpdates(c *C) {
341341
c.Assert(err, IsNil)
342342
}
343343

344+
func (s *S) TestAuthUpsertUserAuthenticationRestrictions(c *C) {
345+
if !s.versionAtLeast(3, 6) {
346+
c.Skip("UpsertUser with user 'authenticationRestrictions' only works on 3.6+")
347+
}
348+
session, err := mgo.Dial("localhost:40002")
349+
c.Assert(err, IsNil)
350+
defer session.Close()
351+
352+
admindb := session.DB("admin")
353+
err = admindb.Login("root", "rapadura")
354+
355+
allowUser := &mgo.User{
356+
Username: "authRestrictionUser",
357+
Password: "123456",
358+
Roles: []mgo.Role{mgo.RoleReadWrite},
359+
AuthenticationRestrictions: []mgo.AuthenticationRestriction{
360+
{
361+
ClientSource: []string{"127.0.0.1"},
362+
ServerAddress: []string{"127.0.0.1"},
363+
},
364+
},
365+
}
366+
err = admindb.UpsertUser(allowUser)
367+
c.Assert(err, IsNil)
368+
369+
// Dial again to ensure the positive authentication restriction allows the connection
370+
allowSession, err := mgo.Dial("mongodb://authRestrictionUser:[email protected]:40002/admin")
371+
c.Assert(err, IsNil)
372+
c.Assert(allowSession.Ping(), IsNil)
373+
defer allowSession.Close()
374+
375+
// this user should fail authentication restrictions
376+
denyUser := &mgo.User{
377+
Username: "denyUser",
378+
Password: "123456",
379+
Roles: []mgo.Role{mgo.RoleReadWrite},
380+
AuthenticationRestrictions: []mgo.AuthenticationRestriction{
381+
{
382+
ClientSource: []string{"1.2.3.4"},
383+
ServerAddress: []string{"4.3.2.1"},
384+
},
385+
},
386+
}
387+
err = admindb.UpsertUser(denyUser)
388+
c.Assert(err, IsNil)
389+
390+
// Dial again to ensure the authentication restriction blocks the connections.
391+
_, err = mgo.Dial("mongodb://denyUser:[email protected]:40002/admin")
392+
c.Assert(err, ErrorMatches, ".*Authentication failed.")
393+
}
394+
344395
func (s *S) TestAuthAddUser(c *C) {
345396
session, err := mgo.Dial("localhost:40002")
346397
c.Assert(err, IsNil)

Diff for: session.go

+25
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,19 @@ func (s *Session) LogoutAll() {
11681168
s.m.Unlock()
11691169
}
11701170

1171+
// AuthenticationRestriction represents an authentication restriction
1172+
// for a MongoDB User. Authentication Restrictions was added in version
1173+
// 3.6.
1174+
//
1175+
// Relevant documentation:
1176+
//
1177+
// https://docs.mongodb.com/manual/reference/method/db.createUser/#authentication-restrictions
1178+
//
1179+
type AuthenticationRestriction struct {
1180+
ClientSource []string `bson:"clientSource,omitempty"`
1181+
ServerAddress []string `bson:"serverAddress,omitempty"`
1182+
}
1183+
11711184
// User represents a MongoDB user.
11721185
//
11731186
// Relevant documentation:
@@ -1208,6 +1221,15 @@ type User struct {
12081221
// WARNING: This setting was only ever supported in MongoDB 2.4,
12091222
// and is now obsolete.
12101223
UserSource string `bson:"userSource,omitempty"`
1224+
1225+
// AuthenticationRestrictions represents authentication restrictions
1226+
// the server enforces on the created user. Specifies a list of IP
1227+
// addresses and CIDR ranges from which the user is allowed to connect
1228+
// to the server or from which the server can accept users.
1229+
//
1230+
// WARNING: Authentication Restrictions are only supported in version
1231+
// 3.6 and above.
1232+
AuthenticationRestrictions []AuthenticationRestriction `bson:"authenticationRestrictions,omitempty"`
12111233
}
12121234

12131235
// Role available role for users
@@ -1370,6 +1392,9 @@ func (db *Database) runUserCmd(cmdName string, user *User) error {
13701392
if roles != nil || user.Roles != nil || cmdName == "createUser" {
13711393
cmd = append(cmd, bson.DocElem{Name: "roles", Value: roles})
13721394
}
1395+
if user.AuthenticationRestrictions != nil && len(user.AuthenticationRestrictions) > 0 {
1396+
cmd = append(cmd, bson.DocElem{Name: "authenticationRestrictions", Value: user.AuthenticationRestrictions})
1397+
}
13731398
err := db.Run(cmd, nil)
13741399
if !isNoCmd(err) && user.UserSource != "" && (user.UserSource != "$external" || db.Name != "$external") {
13751400
return fmt.Errorf("MongoDB 2.6+ does not support the UserSource setting")

0 commit comments

Comments
 (0)