github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/third_party/labix.org/v2/mgo/auth_test.go (about) 1 // mgo - MongoDB driver for Go 2 // 3 // Copyright (c) 2010-2012 - Gustavo Niemeyer <gustavo@niemeyer.net> 4 // 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions are met: 9 // 10 // 1. Redistributions of source code must retain the above copyright notice, this 11 // list of conditions and the following disclaimer. 12 // 2. Redistributions in binary form must reproduce the above copyright notice, 13 // this list of conditions and the following disclaimer in the documentation 14 // and/or other materials provided with the distribution. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 package mgo_test 28 29 import ( 30 "camlistore.org/third_party/labix.org/v2/mgo" 31 . "camlistore.org/third_party/launchpad.net/gocheck" 32 "fmt" 33 "sync" 34 "time" 35 ) 36 37 func (s *S) TestAuthLogin(c *C) { 38 // Test both with a normal database and with an authenticated shard. 39 for _, addr := range []string{"localhost:40002", "localhost:40203"} { 40 session, err := mgo.Dial(addr) 41 c.Assert(err, IsNil) 42 defer session.Close() 43 44 coll := session.DB("mydb").C("mycoll") 45 err = coll.Insert(M{"n": 1}) 46 c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") 47 48 admindb := session.DB("admin") 49 50 err = admindb.Login("root", "wrong") 51 c.Assert(err, ErrorMatches, "auth fails") 52 53 err = admindb.Login("root", "rapadura") 54 c.Assert(err, IsNil) 55 56 err = coll.Insert(M{"n": 1}) 57 c.Assert(err, IsNil) 58 } 59 } 60 61 func (s *S) TestAuthLoginLogout(c *C) { 62 // Test both with a normal database and with an authenticated shard. 63 for _, addr := range []string{"localhost:40002", "localhost:40203"} { 64 session, err := mgo.Dial(addr) 65 c.Assert(err, IsNil) 66 defer session.Close() 67 68 admindb := session.DB("admin") 69 err = admindb.Login("root", "rapadura") 70 c.Assert(err, IsNil) 71 72 admindb.Logout() 73 74 coll := session.DB("mydb").C("mycoll") 75 err = coll.Insert(M{"n": 1}) 76 c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") 77 78 // Must have dropped auth from the session too. 79 session = session.Copy() 80 defer session.Close() 81 82 coll = session.DB("mydb").C("mycoll") 83 err = coll.Insert(M{"n": 1}) 84 c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") 85 } 86 } 87 88 func (s *S) TestAuthLoginLogoutAll(c *C) { 89 session, err := mgo.Dial("localhost:40002") 90 c.Assert(err, IsNil) 91 defer session.Close() 92 93 admindb := session.DB("admin") 94 err = admindb.Login("root", "rapadura") 95 c.Assert(err, IsNil) 96 97 session.LogoutAll() 98 99 coll := session.DB("mydb").C("mycoll") 100 err = coll.Insert(M{"n": 1}) 101 c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") 102 103 // Must have dropped auth from the session too. 104 session = session.Copy() 105 defer session.Close() 106 107 coll = session.DB("mydb").C("mycoll") 108 err = coll.Insert(M{"n": 1}) 109 c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") 110 } 111 112 func (s *S) TestAuthUpsertUserErrors(c *C) { 113 session, err := mgo.Dial("localhost:40002") 114 c.Assert(err, IsNil) 115 defer session.Close() 116 117 admindb := session.DB("admin") 118 err = admindb.Login("root", "rapadura") 119 c.Assert(err, IsNil) 120 121 mydb := session.DB("mydb") 122 123 err = mydb.UpsertUser(&mgo.User{}) 124 c.Assert(err, ErrorMatches, "user has no Username") 125 126 err = mydb.UpsertUser(&mgo.User{Username: "user", Password: "pass", UserSource: "source"}) 127 c.Assert(err, ErrorMatches, "user has both Password/PasswordHash and UserSource set") 128 129 err = mydb.UpsertUser(&mgo.User{Username: "user", Password: "pass", OtherDBRoles: map[string][]mgo.Role{"db": nil}}) 130 c.Assert(err, ErrorMatches, "user with OtherDBRoles is only supported in admin database") 131 } 132 133 func (s *S) TestAuthUpsertUser(c *C) { 134 if !s.versionAtLeast(2, 4) { 135 c.Skip("UpsertUser only works on 2.4+") 136 } 137 session, err := mgo.Dial("localhost:40002") 138 c.Assert(err, IsNil) 139 defer session.Close() 140 141 admindb := session.DB("admin") 142 err = admindb.Login("root", "rapadura") 143 c.Assert(err, IsNil) 144 145 mydb := session.DB("mydb") 146 myotherdb := session.DB("myotherdb") 147 148 ruser := &mgo.User{ 149 Username: "myruser", 150 Password: "mypass", 151 Roles: []mgo.Role{mgo.RoleRead}, 152 } 153 rwuser := &mgo.User{ 154 Username: "myrwuser", 155 Password: "mypass", 156 Roles: []mgo.Role{mgo.RoleReadWrite}, 157 } 158 rwuserother := &mgo.User{ 159 Username: "myrwuser", 160 UserSource: "mydb", 161 Roles: []mgo.Role{mgo.RoleRead}, 162 } 163 164 err = mydb.UpsertUser(ruser) 165 c.Assert(err, IsNil) 166 err = mydb.UpsertUser(rwuser) 167 c.Assert(err, IsNil) 168 err = myotherdb.UpsertUser(rwuserother) 169 c.Assert(err, IsNil) 170 171 err = mydb.Login("myruser", "mypass") 172 c.Assert(err, IsNil) 173 174 admindb.Logout() 175 176 coll := session.DB("mydb").C("mycoll") 177 err = coll.Insert(M{"n": 1}) 178 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 179 180 err = mydb.Login("myrwuser", "mypass") 181 c.Assert(err, IsNil) 182 183 err = coll.Insert(M{"n": 1}) 184 c.Assert(err, IsNil) 185 186 // Test indirection via UserSource: we can't write to it, because 187 // the roles for myrwuser are different there. 188 othercoll := myotherdb.C("myothercoll") 189 err = othercoll.Insert(M{"n": 1}) 190 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 191 192 // Reading works, though. 193 err = othercoll.Find(nil).One(nil) 194 c.Assert(err, Equals, mgo.ErrNotFound) 195 196 // Can't login directly into the database using UserSource, though. 197 err = myotherdb.Login("myrwuser", "mypass") 198 c.Assert(err, ErrorMatches, "auth fails") 199 } 200 201 func (s *S) TestAuthUpserUserOtherDBRoles(c *C) { 202 if !s.versionAtLeast(2, 4) { 203 c.Skip("UpsertUser only works on 2.4+") 204 } 205 session, err := mgo.Dial("localhost:40002") 206 c.Assert(err, IsNil) 207 defer session.Close() 208 209 admindb := session.DB("admin") 210 err = admindb.Login("root", "rapadura") 211 c.Assert(err, IsNil) 212 213 ruser := &mgo.User{ 214 Username: "myruser", 215 Password: "mypass", 216 OtherDBRoles: map[string][]mgo.Role{"mydb": []mgo.Role{mgo.RoleRead}}, 217 } 218 219 err = admindb.UpsertUser(ruser) 220 c.Assert(err, IsNil) 221 defer admindb.RemoveUser("myruser") 222 223 admindb.Logout() 224 err = admindb.Login("myruser", "mypass") 225 226 coll := session.DB("mydb").C("mycoll") 227 err = coll.Insert(M{"n": 1}) 228 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 229 230 err = coll.Find(nil).One(nil) 231 c.Assert(err, Equals, mgo.ErrNotFound) 232 } 233 234 func (s *S) TestAuthUpserUserUnsetFields(c *C) { 235 if !s.versionAtLeast(2, 4) { 236 c.Skip("UpsertUser only works on 2.4+") 237 } 238 session, err := mgo.Dial("localhost:40002") 239 c.Assert(err, IsNil) 240 defer session.Close() 241 242 admindb := session.DB("admin") 243 err = admindb.Login("root", "rapadura") 244 c.Assert(err, IsNil) 245 246 // Insert a user with most fields set. 247 user := &mgo.User{ 248 Username: "myruser", 249 Password: "mypass", 250 Roles: []mgo.Role{mgo.RoleRead}, 251 OtherDBRoles: map[string][]mgo.Role{"mydb": []mgo.Role{mgo.RoleRead}}, 252 } 253 err = admindb.UpsertUser(user) 254 c.Assert(err, IsNil) 255 defer admindb.RemoveUser("myruser") 256 257 // Now update the user with few things set. 258 user = &mgo.User{ 259 Username: "myruser", 260 UserSource: "mydb", 261 } 262 err = admindb.UpsertUser(user) 263 c.Assert(err, IsNil) 264 265 // Everything that was unset must have been dropped. 266 var userm M 267 err = admindb.C("system.users").Find(M{"user": "myruser"}).One(&userm) 268 c.Assert(err, IsNil) 269 delete(userm, "_id") 270 c.Assert(userm, DeepEquals, M{"user": "myruser", "userSource": "mydb", "roles": []interface{}{}}) 271 272 // Now set password again... 273 user = &mgo.User{ 274 Username: "myruser", 275 Password: "mypass", 276 } 277 err = admindb.UpsertUser(user) 278 c.Assert(err, IsNil) 279 280 // ... and assert that userSource has been dropped. 281 err = admindb.C("system.users").Find(M{"user": "myruser"}).One(&userm) 282 _, found := userm["userSource"] 283 c.Assert(found, Equals, false) 284 } 285 286 func (s *S) TestAuthAddUser(c *C) { 287 session, err := mgo.Dial("localhost:40002") 288 c.Assert(err, IsNil) 289 defer session.Close() 290 291 admindb := session.DB("admin") 292 err = admindb.Login("root", "rapadura") 293 c.Assert(err, IsNil) 294 295 mydb := session.DB("mydb") 296 err = mydb.AddUser("myruser", "mypass", true) 297 c.Assert(err, IsNil) 298 err = mydb.AddUser("mywuser", "mypass", false) 299 c.Assert(err, IsNil) 300 301 err = mydb.Login("myruser", "mypass") 302 c.Assert(err, IsNil) 303 304 admindb.Logout() 305 306 coll := session.DB("mydb").C("mycoll") 307 err = coll.Insert(M{"n": 1}) 308 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 309 310 err = mydb.Login("mywuser", "mypass") 311 c.Assert(err, IsNil) 312 313 err = coll.Insert(M{"n": 1}) 314 c.Assert(err, IsNil) 315 } 316 317 func (s *S) TestAuthAddUserReplaces(c *C) { 318 session, err := mgo.Dial("localhost:40002") 319 c.Assert(err, IsNil) 320 defer session.Close() 321 322 admindb := session.DB("admin") 323 err = admindb.Login("root", "rapadura") 324 c.Assert(err, IsNil) 325 326 mydb := session.DB("mydb") 327 err = mydb.AddUser("myuser", "myoldpass", false) 328 c.Assert(err, IsNil) 329 err = mydb.AddUser("myuser", "mynewpass", true) 330 c.Assert(err, IsNil) 331 332 admindb.Logout() 333 334 err = mydb.Login("myuser", "myoldpass") 335 c.Assert(err, ErrorMatches, "auth fails") 336 err = mydb.Login("myuser", "mynewpass") 337 c.Assert(err, IsNil) 338 339 // ReadOnly flag was changed too. 340 err = mydb.C("mycoll").Insert(M{"n": 1}) 341 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 342 } 343 344 func (s *S) TestAuthRemoveUser(c *C) { 345 session, err := mgo.Dial("localhost:40002") 346 c.Assert(err, IsNil) 347 defer session.Close() 348 349 admindb := session.DB("admin") 350 err = admindb.Login("root", "rapadura") 351 c.Assert(err, IsNil) 352 353 mydb := session.DB("mydb") 354 err = mydb.AddUser("myuser", "mypass", true) 355 c.Assert(err, IsNil) 356 err = mydb.RemoveUser("myuser") 357 c.Assert(err, IsNil) 358 359 err = mydb.Login("myuser", "mypass") 360 c.Assert(err, ErrorMatches, "auth fails") 361 } 362 363 func (s *S) TestAuthLoginTwiceDoesNothing(c *C) { 364 session, err := mgo.Dial("localhost:40002") 365 c.Assert(err, IsNil) 366 defer session.Close() 367 368 admindb := session.DB("admin") 369 err = admindb.Login("root", "rapadura") 370 c.Assert(err, IsNil) 371 372 oldStats := mgo.GetStats() 373 374 err = admindb.Login("root", "rapadura") 375 c.Assert(err, IsNil) 376 377 newStats := mgo.GetStats() 378 c.Assert(newStats.SentOps, Equals, oldStats.SentOps) 379 } 380 381 func (s *S) TestAuthLoginLogoutLoginDoesNothing(c *C) { 382 session, err := mgo.Dial("localhost:40002") 383 c.Assert(err, IsNil) 384 defer session.Close() 385 386 admindb := session.DB("admin") 387 err = admindb.Login("root", "rapadura") 388 c.Assert(err, IsNil) 389 390 oldStats := mgo.GetStats() 391 392 admindb.Logout() 393 err = admindb.Login("root", "rapadura") 394 c.Assert(err, IsNil) 395 396 newStats := mgo.GetStats() 397 c.Assert(newStats.SentOps, Equals, oldStats.SentOps) 398 } 399 400 func (s *S) TestAuthLoginSwitchUser(c *C) { 401 session, err := mgo.Dial("localhost:40002") 402 c.Assert(err, IsNil) 403 defer session.Close() 404 405 admindb := session.DB("admin") 406 err = admindb.Login("root", "rapadura") 407 c.Assert(err, IsNil) 408 409 coll := session.DB("mydb").C("mycoll") 410 err = coll.Insert(M{"n": 1}) 411 c.Assert(err, IsNil) 412 413 err = admindb.Login("reader", "rapadura") 414 c.Assert(err, IsNil) 415 416 // Can't write. 417 err = coll.Insert(M{"n": 1}) 418 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 419 420 // But can read. 421 result := struct{ N int }{} 422 err = coll.Find(nil).One(&result) 423 c.Assert(err, IsNil) 424 c.Assert(result.N, Equals, 1) 425 } 426 427 func (s *S) TestAuthLoginChangePassword(c *C) { 428 session, err := mgo.Dial("localhost:40002") 429 c.Assert(err, IsNil) 430 defer session.Close() 431 432 admindb := session.DB("admin") 433 err = admindb.Login("root", "rapadura") 434 c.Assert(err, IsNil) 435 436 mydb := session.DB("mydb") 437 err = mydb.AddUser("myuser", "myoldpass", false) 438 c.Assert(err, IsNil) 439 440 err = mydb.Login("myuser", "myoldpass") 441 c.Assert(err, IsNil) 442 443 err = mydb.AddUser("myuser", "mynewpass", true) 444 c.Assert(err, IsNil) 445 446 err = mydb.Login("myuser", "mynewpass") 447 c.Assert(err, IsNil) 448 449 admindb.Logout() 450 451 // The second login must be in effect, which means read-only. 452 err = mydb.C("mycoll").Insert(M{"n": 1}) 453 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 454 } 455 456 func (s *S) TestAuthLoginCachingWithSessionRefresh(c *C) { 457 session, err := mgo.Dial("localhost:40002") 458 c.Assert(err, IsNil) 459 defer session.Close() 460 461 admindb := session.DB("admin") 462 err = admindb.Login("root", "rapadura") 463 c.Assert(err, IsNil) 464 465 session.Refresh() 466 467 coll := session.DB("mydb").C("mycoll") 468 err = coll.Insert(M{"n": 1}) 469 c.Assert(err, IsNil) 470 } 471 472 func (s *S) TestAuthLoginCachingWithSessionCopy(c *C) { 473 session, err := mgo.Dial("localhost:40002") 474 c.Assert(err, IsNil) 475 defer session.Close() 476 477 admindb := session.DB("admin") 478 err = admindb.Login("root", "rapadura") 479 c.Assert(err, IsNil) 480 481 session = session.Copy() 482 defer session.Close() 483 484 coll := session.DB("mydb").C("mycoll") 485 err = coll.Insert(M{"n": 1}) 486 c.Assert(err, IsNil) 487 } 488 489 func (s *S) TestAuthLoginCachingWithSessionClone(c *C) { 490 session, err := mgo.Dial("localhost:40002") 491 c.Assert(err, IsNil) 492 defer session.Close() 493 494 admindb := session.DB("admin") 495 err = admindb.Login("root", "rapadura") 496 c.Assert(err, IsNil) 497 498 session = session.Clone() 499 defer session.Close() 500 501 coll := session.DB("mydb").C("mycoll") 502 err = coll.Insert(M{"n": 1}) 503 c.Assert(err, IsNil) 504 } 505 506 func (s *S) TestAuthLoginCachingWithNewSession(c *C) { 507 session, err := mgo.Dial("localhost:40002") 508 c.Assert(err, IsNil) 509 defer session.Close() 510 511 admindb := session.DB("admin") 512 err = admindb.Login("root", "rapadura") 513 c.Assert(err, IsNil) 514 515 session = session.New() 516 defer session.Close() 517 518 coll := session.DB("mydb").C("mycoll") 519 err = coll.Insert(M{"n": 1}) 520 c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized for .*") 521 } 522 523 func (s *S) TestAuthLoginCachingAcrossPool(c *C) { 524 // Logins are cached even when the conenction goes back 525 // into the pool. 526 527 session, err := mgo.Dial("localhost:40002") 528 c.Assert(err, IsNil) 529 defer session.Close() 530 531 admindb := session.DB("admin") 532 err = admindb.Login("root", "rapadura") 533 c.Assert(err, IsNil) 534 535 // Add another user to test the logout case at the same time. 536 mydb := session.DB("mydb") 537 err = mydb.AddUser("myuser", "mypass", false) 538 c.Assert(err, IsNil) 539 540 err = mydb.Login("myuser", "mypass") 541 c.Assert(err, IsNil) 542 543 // Logout root explicitly, to test both cases. 544 admindb.Logout() 545 546 // Give socket back to pool. 547 session.Refresh() 548 549 // Brand new session, should use socket from the pool. 550 other := session.New() 551 defer other.Close() 552 553 oldStats := mgo.GetStats() 554 555 err = other.DB("admin").Login("root", "rapadura") 556 c.Assert(err, IsNil) 557 err = other.DB("mydb").Login("myuser", "mypass") 558 c.Assert(err, IsNil) 559 560 // Both logins were cached, so no ops. 561 newStats := mgo.GetStats() 562 c.Assert(newStats.SentOps, Equals, oldStats.SentOps) 563 564 // And they actually worked. 565 err = other.DB("mydb").C("mycoll").Insert(M{"n": 1}) 566 c.Assert(err, IsNil) 567 568 other.DB("admin").Logout() 569 570 err = other.DB("mydb").C("mycoll").Insert(M{"n": 1}) 571 c.Assert(err, IsNil) 572 } 573 574 func (s *S) TestAuthLoginCachingAcrossPoolWithLogout(c *C) { 575 // Now verify that logouts are properly flushed if they 576 // are not revalidated after leaving the pool. 577 578 session, err := mgo.Dial("localhost:40002") 579 c.Assert(err, IsNil) 580 defer session.Close() 581 582 admindb := session.DB("admin") 583 err = admindb.Login("root", "rapadura") 584 c.Assert(err, IsNil) 585 586 // Add another user to test the logout case at the same time. 587 mydb := session.DB("mydb") 588 err = mydb.AddUser("myuser", "mypass", true) 589 c.Assert(err, IsNil) 590 591 err = mydb.Login("myuser", "mypass") 592 c.Assert(err, IsNil) 593 594 // Just some data to query later. 595 err = session.DB("mydb").C("mycoll").Insert(M{"n": 1}) 596 c.Assert(err, IsNil) 597 598 // Give socket back to pool. 599 session.Refresh() 600 601 // Brand new session, should use socket from the pool. 602 other := session.New() 603 defer other.Close() 604 605 oldStats := mgo.GetStats() 606 607 err = other.DB("mydb").Login("myuser", "mypass") 608 c.Assert(err, IsNil) 609 610 // Login was cached, so no ops. 611 newStats := mgo.GetStats() 612 c.Assert(newStats.SentOps, Equals, oldStats.SentOps) 613 614 // Can't write, since root has been implicitly logged out 615 // when the collection went into the pool, and not revalidated. 616 err = other.DB("mydb").C("mycoll").Insert(M{"n": 1}) 617 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 618 619 // But can read due to the revalidated myuser login. 620 result := struct{ N int }{} 621 err = other.DB("mydb").C("mycoll").Find(nil).One(&result) 622 c.Assert(err, IsNil) 623 c.Assert(result.N, Equals, 1) 624 } 625 626 func (s *S) TestAuthEventual(c *C) { 627 // Eventual sessions don't keep sockets around, so they are 628 // an interesting test case. 629 session, err := mgo.Dial("localhost:40002") 630 c.Assert(err, IsNil) 631 defer session.Close() 632 633 admindb := session.DB("admin") 634 err = admindb.Login("root", "rapadura") 635 c.Assert(err, IsNil) 636 637 err = session.DB("mydb").C("mycoll").Insert(M{"n": 1}) 638 c.Assert(err, IsNil) 639 640 var wg sync.WaitGroup 641 wg.Add(20) 642 643 for i := 0; i != 10; i++ { 644 go func() { 645 defer wg.Done() 646 var result struct{ N int } 647 err := session.DB("mydb").C("mycoll").Find(nil).One(&result) 648 c.Assert(err, IsNil) 649 c.Assert(result.N, Equals, 1) 650 }() 651 } 652 653 for i := 0; i != 10; i++ { 654 go func() { 655 defer wg.Done() 656 err := session.DB("mydb").C("mycoll").Insert(M{"n": 1}) 657 c.Assert(err, IsNil) 658 }() 659 } 660 661 wg.Wait() 662 } 663 664 func (s *S) TestAuthURL(c *C) { 665 session, err := mgo.Dial("mongodb://root:rapadura@localhost:40002/") 666 c.Assert(err, IsNil) 667 defer session.Close() 668 669 err = session.DB("mydb").C("mycoll").Insert(M{"n": 1}) 670 c.Assert(err, IsNil) 671 } 672 673 func (s *S) TestAuthURLWrongCredentials(c *C) { 674 session, err := mgo.Dial("mongodb://root:wrong@localhost:40002/") 675 if session != nil { 676 session.Close() 677 } 678 c.Assert(err, ErrorMatches, "auth fails") 679 c.Assert(session, IsNil) 680 } 681 682 func (s *S) TestAuthURLWithNewSession(c *C) { 683 // When authentication is in the URL, the new session will 684 // actually carry it on as well, even if logged out explicitly. 685 session, err := mgo.Dial("mongodb://root:rapadura@localhost:40002/") 686 c.Assert(err, IsNil) 687 defer session.Close() 688 689 session.DB("admin").Logout() 690 691 // Do it twice to ensure it passes the needed data on. 692 session = session.New() 693 defer session.Close() 694 session = session.New() 695 defer session.Close() 696 697 err = session.DB("mydb").C("mycoll").Insert(M{"n": 1}) 698 c.Assert(err, IsNil) 699 } 700 701 func (s *S) TestAuthURLWithDatabase(c *C) { 702 session, err := mgo.Dial("mongodb://root:rapadura@localhost:40002") 703 c.Assert(err, IsNil) 704 defer session.Close() 705 706 mydb := session.DB("mydb") 707 err = mydb.AddUser("myruser", "mypass", true) 708 c.Assert(err, IsNil) 709 710 usession, err := mgo.Dial("mongodb://myruser:mypass@localhost:40002/mydb") 711 c.Assert(err, IsNil) 712 defer usession.Close() 713 714 ucoll := usession.DB("mydb").C("mycoll") 715 err = ucoll.FindId(0).One(nil) 716 c.Assert(err, Equals, mgo.ErrNotFound) 717 err = ucoll.Insert(M{"n": 1}) 718 c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") 719 } 720 721 func (s *S) TestDefaultDatabase(c *C) { 722 tests := []struct{ url, db string }{ 723 {"mongodb://root:rapadura@localhost:40002", "test"}, 724 {"mongodb://root:rapadura@localhost:40002/admin", "admin"}, 725 {"mongodb://localhost:40001", "test"}, 726 {"mongodb://localhost:40001/", "test"}, 727 {"mongodb://localhost:40001/mydb", "mydb"}, 728 } 729 730 for _, test := range tests { 731 session, err := mgo.Dial(test.url) 732 c.Assert(err, IsNil) 733 defer session.Close() 734 735 c.Logf("test: %#v", test) 736 c.Assert(session.DB("").Name, Equals, test.db) 737 738 scopy := session.Copy() 739 c.Check(scopy.DB("").Name, Equals, test.db) 740 scopy.Close() 741 } 742 } 743 744 func (s *S) TestAuthDirect(c *C) { 745 // Direct connections must work to the master and slaves. 746 for _, port := range []string{"40031", "40032", "40033"} { 747 url := fmt.Sprintf("mongodb://root:rapadura@localhost:%s/?connect=direct", port) 748 session, err := mgo.Dial(url) 749 c.Assert(err, IsNil) 750 defer session.Close() 751 752 session.SetMode(mgo.Monotonic, true) 753 754 var result struct{} 755 err = session.DB("mydb").C("mycoll").Find(nil).One(&result) 756 c.Assert(err, Equals, mgo.ErrNotFound) 757 } 758 } 759 760 func (s *S) TestAuthDirectWithLogin(c *C) { 761 // Direct connections must work to the master and slaves. 762 for _, port := range []string{"40031", "40032", "40033"} { 763 url := fmt.Sprintf("mongodb://localhost:%s/?connect=direct", port) 764 session, err := mgo.Dial(url) 765 c.Assert(err, IsNil) 766 defer session.Close() 767 768 session.SetMode(mgo.Monotonic, true) 769 session.SetSyncTimeout(3 * time.Second) 770 771 err = session.DB("admin").Login("root", "rapadura") 772 c.Assert(err, IsNil) 773 774 var result struct{} 775 err = session.DB("mydb").C("mycoll").Find(nil).One(&result) 776 c.Assert(err, Equals, mgo.ErrNotFound) 777 } 778 }