Skip to content

Commit bb548a5

Browse files
rfblue2Roland Fong
authored andcommitted
Add Auth Spec tests
GODRIVER-142 Change-Id: I75dd6c46bbf37913e7e19c63aad1edd58108f75a
1 parent 6ef364f commit bb548a5

File tree

5 files changed

+576
-19
lines changed

5 files changed

+576
-19
lines changed

core/auth/plain.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ import (
1616
const PLAIN = "PLAIN"
1717

1818
func newPlainAuthenticator(cred *Cred) (Authenticator, error) {
19-
if cred.Source != "" && cred.Source != "$external" {
20-
return nil, newAuthError("PLAIN source must be empty or $external", nil)
21-
}
22-
2319
return &PlainAuthenticator{
2420
Username: cred.Username,
2521
Password: cred.Password,

core/connstring/connstring.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,16 @@ func (p *parser) parse(original string) error {
247247
}
248248
}
249249

250+
err = p.setDefaultAuthParams(extractedDatabase.db)
251+
if err != nil {
252+
return err
253+
}
254+
255+
err = p.validateAuth()
256+
if err != nil {
257+
return err
258+
}
259+
250260
// Check for invalid write concern (i.e. w=0 and j=true)
251261
if p.WNumberSet && p.WNumber == 0 && p.JSet && p.J {
252262
return writeconcern.ErrInconsistent
@@ -260,6 +270,116 @@ func (p *parser) parse(original string) error {
260270
return nil
261271
}
262272

273+
func (p *parser) setDefaultAuthParams(dbName string) error {
274+
switch strings.ToLower(p.AuthMechanism) {
275+
case "plain":
276+
if p.AuthSource == "" {
277+
p.AuthSource = dbName
278+
if p.AuthSource == "" {
279+
p.AuthSource = "$external"
280+
}
281+
}
282+
case "gssapi":
283+
if p.AuthMechanismProperties == nil {
284+
p.AuthMechanismProperties = map[string]string{
285+
"SERVICE_NAME": "mongodb",
286+
}
287+
} else if v, ok := p.AuthMechanismProperties["SERVICE_NAME"]; !ok || v == "" {
288+
p.AuthMechanismProperties["SERVICE_NAME"] = "mongodb"
289+
}
290+
fallthrough
291+
case "mongodb-x509":
292+
if p.AuthSource == "" {
293+
p.AuthSource = "$external"
294+
} else if p.AuthSource != "$external" {
295+
return fmt.Errorf("auth source must be $external")
296+
}
297+
case "mongodb-cr":
298+
fallthrough
299+
case "scram-sha-1":
300+
fallthrough
301+
case "scram-sha-256":
302+
if p.AuthSource == "" {
303+
p.AuthSource = dbName
304+
if p.AuthSource == "" {
305+
p.AuthSource = "admin"
306+
}
307+
}
308+
case "":
309+
if p.AuthSource == "" {
310+
p.AuthSource = "admin"
311+
}
312+
default:
313+
return fmt.Errorf("invalid auth mechanism")
314+
}
315+
return nil
316+
}
317+
318+
func (p *parser) validateAuth() error {
319+
switch strings.ToLower(p.AuthMechanism) {
320+
case "mongodb-cr":
321+
if p.Username == "" {
322+
return fmt.Errorf("username required for MONGO-CR")
323+
}
324+
if p.Password == "" {
325+
return fmt.Errorf("password required for MONGO-CR")
326+
}
327+
if p.AuthMechanismProperties != nil {
328+
return fmt.Errorf("MONGO-CR cannot have mechanism properties")
329+
}
330+
case "mongodb-x509":
331+
if p.Password != "" {
332+
return fmt.Errorf("password cannot be specified for MONGO-X509")
333+
}
334+
if p.AuthMechanismProperties != nil {
335+
return fmt.Errorf("MONGO-X509 cannot have mechanism properties")
336+
}
337+
case "gssapi":
338+
if p.Username == "" {
339+
return fmt.Errorf("username required for GSSAPI")
340+
}
341+
for k := range p.AuthMechanismProperties {
342+
if k != "SERVICE_NAME" && k != "CANONICALIZE_HOST_NAME" && k != "SERVICE_REALM" {
343+
return fmt.Errorf("invalid auth property for GSSAPI")
344+
}
345+
}
346+
case "plain":
347+
if p.Username == "" {
348+
return fmt.Errorf("username required for PLAIN")
349+
}
350+
if p.Password == "" {
351+
return fmt.Errorf("password required for PLAIN")
352+
}
353+
if p.AuthMechanismProperties != nil {
354+
return fmt.Errorf("PLAIN cannot have mechanism properties")
355+
}
356+
case "scram-sha-1":
357+
if p.Username == "" {
358+
return fmt.Errorf("username required for SCRAM-SHA-1")
359+
}
360+
if p.Password == "" {
361+
return fmt.Errorf("password required for SCRAM-SHA-1")
362+
}
363+
if p.AuthMechanismProperties != nil {
364+
return fmt.Errorf("SCRAM-SHA-1 cannot have mechanism properties")
365+
}
366+
case "scram-sha-256":
367+
if p.Username == "" {
368+
return fmt.Errorf("username required for SCRAM-SHA-256")
369+
}
370+
if p.Password == "" {
371+
return fmt.Errorf("password required for SCRAM-SHA-256")
372+
}
373+
if p.AuthMechanismProperties != nil {
374+
return fmt.Errorf("SCRAM-SHA-256 cannot have mechanism properties")
375+
}
376+
case "":
377+
default:
378+
return fmt.Errorf("invalid auth mechanism")
379+
}
380+
return nil
381+
}
382+
263383
func fetchSeedlistFromSRV(host string) ([]string, error) {
264384
var err error
265385

core/connstring/connstring_spec_test.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ type testContainer struct {
4242
Tests []testCase
4343
}
4444

45-
const testsDir string = "../../data/connection-string/"
45+
const connstringTestsDir = "../../data/connection-string/"
46+
47+
// Note a test supporting the deprecated gssapiServiceName property was removed from data/auth/auth_tests.json
48+
const authTestsDir = "../../data/auth/"
4649

4750
func (h *host) toString() string {
4851
switch h.Type {
@@ -77,8 +80,8 @@ func hostsToStrings(hosts []host) []string {
7780
return out
7881
}
7982

80-
func runTestsInFile(t *testing.T, filename string) {
81-
filepath := path.Join(testsDir, filename)
83+
func runTestsInFile(t *testing.T, dirname string, filename string) {
84+
filepath := path.Join(dirname, filename)
8285
content, err := ioutil.ReadFile(filepath)
8386
require.NoError(t, err)
8487

@@ -106,7 +109,10 @@ func runTest(t *testing.T, filename string, test *testCase) {
106109
}
107110

108111
require.Equal(t, test.URI, cs.Original)
109-
require.Equal(t, hostsToStrings(test.Hosts), cs.Hosts)
112+
113+
if test.Hosts != nil {
114+
require.Equal(t, hostsToStrings(test.Hosts), cs.Hosts)
115+
}
110116

111117
if test.Auth != nil {
112118
require.Equal(t, test.Auth.Username, cs.Username)
@@ -118,7 +124,11 @@ func runTest(t *testing.T, filename string, test *testCase) {
118124
require.Equal(t, *test.Auth.Password, cs.Password)
119125
}
120126

121-
require.Equal(t, test.Auth.DB, cs.Database)
127+
if test.Auth.DB != cs.Database {
128+
require.Equal(t, test.Auth.DB, cs.AuthSource)
129+
} else {
130+
require.Equal(t, test.Auth.DB, cs.Database)
131+
}
122132
}
123133

124134
// Check that all options are present.
@@ -140,14 +150,11 @@ func runTest(t *testing.T, filename string, test *testCase) {
140150

141151
// Test case for all connection string spec tests.
142152
func TestConnStringSpec(t *testing.T) {
143-
entries, err := ioutil.ReadDir(testsDir)
144-
require.NoError(t, err)
145-
146-
for _, entry := range entries {
147-
if entry.IsDir() || path.Ext(entry.Name()) != ".json" {
148-
continue
149-
}
153+
for _, file := range testhelpers.FindJSONFilesInDir(t, connstringTestsDir) {
154+
runTestsInFile(t, connstringTestsDir, file)
155+
}
150156

151-
runTestsInFile(t, entry.Name())
157+
for _, file := range testhelpers.FindJSONFilesInDir(t, authTestsDir) {
158+
runTestsInFile(t, authTestsDir, file)
152159
}
153160
}

core/connstring/connstring_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ func TestAuthMechanism(t *testing.T) {
4949
}{
5050
{s: "authMechanism=scram-sha-1", expected: "scram-sha-1"},
5151
{s: "authMechanism=mongodb-CR", expected: "mongodb-CR"},
52-
{s: "authMechanism=LDAP", expected: "LDAP"},
52+
{s: "authMechanism=plain", expected: "plain"},
5353
}
5454

5555
for _, test := range tests {
56-
s := fmt.Sprintf("mongodb://localhost/?%s", test.s)
56+
s := fmt.Sprintf("mongodb://user:pass@localhost/?%s", test.s)
5757
t.Run(s, func(t *testing.T) {
5858
cs, err := connstring.Parse(s)
5959
if test.err {

0 commit comments

Comments
 (0)