code.gitea.io/gitea@v1.22.3/cmd/admin_auth_ldap_test.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package cmd 5 6 import ( 7 "context" 8 "testing" 9 10 "code.gitea.io/gitea/models/auth" 11 "code.gitea.io/gitea/services/auth/source/ldap" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/urfave/cli/v2" 15 ) 16 17 func TestAddLdapBindDn(t *testing.T) { 18 // Mock cli functions to do not exit on error 19 osExiter := cli.OsExiter 20 defer func() { cli.OsExiter = osExiter }() 21 cli.OsExiter = func(code int) {} 22 23 // Test cases 24 cases := []struct { 25 args []string 26 source *auth.Source 27 errMsg string 28 }{ 29 // case 0 30 { 31 args: []string{ 32 "ldap-test", 33 "--name", "ldap (via Bind DN) source full", 34 "--not-active", 35 "--security-protocol", "ldaps", 36 "--skip-tls-verify", 37 "--host", "ldap-bind-server full", 38 "--port", "9876", 39 "--user-search-base", "ou=Users,dc=full-domain-bind,dc=org", 40 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)", 41 "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)", 42 "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-bind,dc=org)", 43 "--username-attribute", "uid-bind full", 44 "--firstname-attribute", "givenName-bind full", 45 "--surname-attribute", "sn-bind full", 46 "--email-attribute", "mail-bind full", 47 "--public-ssh-key-attribute", "publickey-bind full", 48 "--avatar-attribute", "avatar-bind full", 49 "--bind-dn", "cn=readonly,dc=full-domain-bind,dc=org", 50 "--bind-password", "secret-bind-full", 51 "--attributes-in-bind", 52 "--synchronize-users", 53 "--page-size", "99", 54 }, 55 source: &auth.Source{ 56 Type: auth.LDAP, 57 Name: "ldap (via Bind DN) source full", 58 IsActive: false, 59 IsSyncEnabled: true, 60 Cfg: &ldap.Source{ 61 Name: "ldap (via Bind DN) source full", 62 Host: "ldap-bind-server full", 63 Port: 9876, 64 SecurityProtocol: ldap.SecurityProtocol(1), 65 SkipVerify: true, 66 BindDN: "cn=readonly,dc=full-domain-bind,dc=org", 67 BindPassword: "secret-bind-full", 68 UserBase: "ou=Users,dc=full-domain-bind,dc=org", 69 AttributeUsername: "uid-bind full", 70 AttributeName: "givenName-bind full", 71 AttributeSurname: "sn-bind full", 72 AttributeMail: "mail-bind full", 73 AttributesInBind: true, 74 AttributeSSHPublicKey: "publickey-bind full", 75 AttributeAvatar: "avatar-bind full", 76 SearchPageSize: 99, 77 Filter: "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)", 78 AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)", 79 RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-bind,dc=org)", 80 Enabled: true, 81 }, 82 }, 83 }, 84 // case 1 85 { 86 args: []string{ 87 "ldap-test", 88 "--name", "ldap (via Bind DN) source min", 89 "--security-protocol", "unencrypted", 90 "--host", "ldap-bind-server min", 91 "--port", "1234", 92 "--user-search-base", "ou=Users,dc=min-domain-bind,dc=org", 93 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=min-domain-bind,dc=org)", 94 "--email-attribute", "mail-bind min", 95 }, 96 source: &auth.Source{ 97 Type: auth.LDAP, 98 Name: "ldap (via Bind DN) source min", 99 IsActive: true, 100 Cfg: &ldap.Source{ 101 Name: "ldap (via Bind DN) source min", 102 Host: "ldap-bind-server min", 103 Port: 1234, 104 SecurityProtocol: ldap.SecurityProtocol(0), 105 UserBase: "ou=Users,dc=min-domain-bind,dc=org", 106 AttributeMail: "mail-bind min", 107 Filter: "(memberOf=cn=user-group,ou=example,dc=min-domain-bind,dc=org)", 108 Enabled: true, 109 }, 110 }, 111 }, 112 // case 2 113 { 114 args: []string{ 115 "ldap-test", 116 "--name", "ldap (via Bind DN) source", 117 "--security-protocol", "zzzzz", 118 "--host", "ldap-server", 119 "--port", "1234", 120 "--user-search-base", "ou=Users,dc=domain,dc=org", 121 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", 122 "--email-attribute", "mail", 123 }, 124 errMsg: "Unknown security protocol name: zzzzz", 125 }, 126 // case 3 127 { 128 args: []string{ 129 "ldap-test", 130 "--security-protocol", "unencrypted", 131 "--host", "ldap-server", 132 "--port", "1234", 133 "--user-search-base", "ou=Users,dc=domain,dc=org", 134 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", 135 "--email-attribute", "mail", 136 }, 137 errMsg: "name is not set", 138 }, 139 // case 4 140 { 141 args: []string{ 142 "ldap-test", 143 "--name", "ldap (via Bind DN) source", 144 "--host", "ldap-server", 145 "--port", "1234", 146 "--user-search-base", "ou=Users,dc=domain,dc=org", 147 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", 148 "--email-attribute", "mail", 149 }, 150 errMsg: "security-protocol is not set", 151 }, 152 // case 5 153 { 154 args: []string{ 155 "ldap-test", 156 "--name", "ldap (via Bind DN) source", 157 "--security-protocol", "unencrypted", 158 "--port", "1234", 159 "--user-search-base", "ou=Users,dc=domain,dc=org", 160 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", 161 "--email-attribute", "mail", 162 }, 163 errMsg: "host is not set", 164 }, 165 // case 6 166 { 167 args: []string{ 168 "ldap-test", 169 "--name", "ldap (via Bind DN) source", 170 "--security-protocol", "unencrypted", 171 "--host", "ldap-server", 172 "--user-search-base", "ou=Users,dc=domain,dc=org", 173 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", 174 "--email-attribute", "mail", 175 }, 176 errMsg: "port is not set", 177 }, 178 // case 7 179 { 180 args: []string{ 181 "ldap-test", 182 "--name", "ldap (via Bind DN) source", 183 "--security-protocol", "unencrypted", 184 "--host", "ldap-server", 185 "--port", "1234", 186 "--user-search-base", "ou=Users,dc=domain,dc=org", 187 "--email-attribute", "mail", 188 }, 189 errMsg: "user-filter is not set", 190 }, 191 // case 8 192 { 193 args: []string{ 194 "ldap-test", 195 "--name", "ldap (via Bind DN) source", 196 "--security-protocol", "unencrypted", 197 "--host", "ldap-server", 198 "--port", "1234", 199 "--user-search-base", "ou=Users,dc=domain,dc=org", 200 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", 201 }, 202 errMsg: "email-attribute is not set", 203 }, 204 } 205 206 for n, c := range cases { 207 // Mock functions. 208 var createdAuthSource *auth.Source 209 service := &authService{ 210 initDB: func(context.Context) error { 211 return nil 212 }, 213 createAuthSource: func(ctx context.Context, authSource *auth.Source) error { 214 createdAuthSource = authSource 215 return nil 216 }, 217 updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { 218 assert.FailNow(t, "case %d: should not call updateAuthSource", n) 219 return nil 220 }, 221 getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { 222 assert.FailNow(t, "case %d: should not call getAuthSourceByID", n) 223 return nil, nil 224 }, 225 } 226 227 // Create a copy of command to test 228 app := cli.NewApp() 229 app.Flags = microcmdAuthAddLdapBindDn.Flags 230 app.Action = service.addLdapBindDn 231 232 // Run it 233 err := app.Run(c.args) 234 if c.errMsg != "" { 235 assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) 236 } else { 237 assert.NoError(t, err, "case %d: should have no errors", n) 238 assert.Equal(t, c.source, createdAuthSource, "case %d: wrong authSource", n) 239 } 240 } 241 } 242 243 func TestAddLdapSimpleAuth(t *testing.T) { 244 // Mock cli functions to do not exit on error 245 osExiter := cli.OsExiter 246 defer func() { cli.OsExiter = osExiter }() 247 cli.OsExiter = func(code int) {} 248 249 // Test cases 250 cases := []struct { 251 args []string 252 authSource *auth.Source 253 errMsg string 254 }{ 255 // case 0 256 { 257 args: []string{ 258 "ldap-test", 259 "--name", "ldap (simple auth) source full", 260 "--not-active", 261 "--security-protocol", "starttls", 262 "--skip-tls-verify", 263 "--host", "ldap-simple-server full", 264 "--port", "987", 265 "--user-search-base", "ou=Users,dc=full-domain-simple,dc=org", 266 "--user-filter", "(&(objectClass=posixAccount)(full-simple-cn=%s))", 267 "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)", 268 "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)", 269 "--username-attribute", "uid-simple full", 270 "--firstname-attribute", "givenName-simple full", 271 "--surname-attribute", "sn-simple full", 272 "--email-attribute", "mail-simple full", 273 "--public-ssh-key-attribute", "publickey-simple full", 274 "--avatar-attribute", "avatar-simple full", 275 "--user-dn", "cn=%s,ou=Users,dc=full-domain-simple,dc=org", 276 }, 277 authSource: &auth.Source{ 278 Type: auth.DLDAP, 279 Name: "ldap (simple auth) source full", 280 IsActive: false, 281 Cfg: &ldap.Source{ 282 Name: "ldap (simple auth) source full", 283 Host: "ldap-simple-server full", 284 Port: 987, 285 SecurityProtocol: ldap.SecurityProtocol(2), 286 SkipVerify: true, 287 UserDN: "cn=%s,ou=Users,dc=full-domain-simple,dc=org", 288 UserBase: "ou=Users,dc=full-domain-simple,dc=org", 289 AttributeUsername: "uid-simple full", 290 AttributeName: "givenName-simple full", 291 AttributeSurname: "sn-simple full", 292 AttributeMail: "mail-simple full", 293 AttributeSSHPublicKey: "publickey-simple full", 294 AttributeAvatar: "avatar-simple full", 295 Filter: "(&(objectClass=posixAccount)(full-simple-cn=%s))", 296 AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)", 297 RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)", 298 Enabled: true, 299 }, 300 }, 301 }, 302 // case 1 303 { 304 args: []string{ 305 "ldap-test", 306 "--name", "ldap (simple auth) source min", 307 "--security-protocol", "unencrypted", 308 "--host", "ldap-simple-server min", 309 "--port", "123", 310 "--user-filter", "(&(objectClass=posixAccount)(min-simple-cn=%s))", 311 "--email-attribute", "mail-simple min", 312 "--user-dn", "cn=%s,ou=Users,dc=min-domain-simple,dc=org", 313 }, 314 authSource: &auth.Source{ 315 Type: auth.DLDAP, 316 Name: "ldap (simple auth) source min", 317 IsActive: true, 318 Cfg: &ldap.Source{ 319 Name: "ldap (simple auth) source min", 320 Host: "ldap-simple-server min", 321 Port: 123, 322 SecurityProtocol: ldap.SecurityProtocol(0), 323 UserDN: "cn=%s,ou=Users,dc=min-domain-simple,dc=org", 324 AttributeMail: "mail-simple min", 325 Filter: "(&(objectClass=posixAccount)(min-simple-cn=%s))", 326 Enabled: true, 327 }, 328 }, 329 }, 330 // case 2 331 { 332 args: []string{ 333 "ldap-test", 334 "--name", "ldap (simple auth) source", 335 "--security-protocol", "zzzzz", 336 "--host", "ldap-server", 337 "--port", "123", 338 "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", 339 "--email-attribute", "mail", 340 "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", 341 }, 342 errMsg: "Unknown security protocol name: zzzzz", 343 }, 344 // case 3 345 { 346 args: []string{ 347 "ldap-test", 348 "--security-protocol", "unencrypted", 349 "--host", "ldap-server", 350 "--port", "123", 351 "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", 352 "--email-attribute", "mail", 353 "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", 354 }, 355 errMsg: "name is not set", 356 }, 357 // case 4 358 { 359 args: []string{ 360 "ldap-test", 361 "--name", "ldap (simple auth) source", 362 "--host", "ldap-server", 363 "--port", "123", 364 "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", 365 "--email-attribute", "mail", 366 "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", 367 }, 368 errMsg: "security-protocol is not set", 369 }, 370 // case 5 371 { 372 args: []string{ 373 "ldap-test", 374 "--name", "ldap (simple auth) source", 375 "--security-protocol", "unencrypted", 376 "--port", "123", 377 "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", 378 "--email-attribute", "mail", 379 "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", 380 }, 381 errMsg: "host is not set", 382 }, 383 // case 6 384 { 385 args: []string{ 386 "ldap-test", 387 "--name", "ldap (simple auth) source", 388 "--security-protocol", "unencrypted", 389 "--host", "ldap-server", 390 "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", 391 "--email-attribute", "mail", 392 "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", 393 }, 394 errMsg: "port is not set", 395 }, 396 // case 7 397 { 398 args: []string{ 399 "ldap-test", 400 "--name", "ldap (simple auth) source", 401 "--security-protocol", "unencrypted", 402 "--host", "ldap-server", 403 "--port", "123", 404 "--email-attribute", "mail", 405 "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", 406 }, 407 errMsg: "user-filter is not set", 408 }, 409 // case 8 410 { 411 args: []string{ 412 "ldap-test", 413 "--name", "ldap (simple auth) source", 414 "--security-protocol", "unencrypted", 415 "--host", "ldap-server", 416 "--port", "123", 417 "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", 418 "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", 419 }, 420 errMsg: "email-attribute is not set", 421 }, 422 // case 9 423 { 424 args: []string{ 425 "ldap-test", 426 "--name", "ldap (simple auth) source", 427 "--security-protocol", "unencrypted", 428 "--host", "ldap-server", 429 "--port", "123", 430 "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", 431 "--email-attribute", "mail", 432 }, 433 errMsg: "user-dn is not set", 434 }, 435 } 436 437 for n, c := range cases { 438 // Mock functions. 439 var createdAuthSource *auth.Source 440 service := &authService{ 441 initDB: func(context.Context) error { 442 return nil 443 }, 444 createAuthSource: func(ctx context.Context, authSource *auth.Source) error { 445 createdAuthSource = authSource 446 return nil 447 }, 448 updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { 449 assert.FailNow(t, "case %d: should not call updateAuthSource", n) 450 return nil 451 }, 452 getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { 453 assert.FailNow(t, "case %d: should not call getAuthSourceByID", n) 454 return nil, nil 455 }, 456 } 457 458 // Create a copy of command to test 459 app := cli.NewApp() 460 app.Flags = microcmdAuthAddLdapSimpleAuth.Flags 461 app.Action = service.addLdapSimpleAuth 462 463 // Run it 464 err := app.Run(c.args) 465 if c.errMsg != "" { 466 assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) 467 } else { 468 assert.NoError(t, err, "case %d: should have no errors", n) 469 assert.Equal(t, c.authSource, createdAuthSource, "case %d: wrong authSource", n) 470 } 471 } 472 } 473 474 func TestUpdateLdapBindDn(t *testing.T) { 475 // Mock cli functions to do not exit on error 476 osExiter := cli.OsExiter 477 defer func() { cli.OsExiter = osExiter }() 478 cli.OsExiter = func(code int) {} 479 480 // Test cases 481 cases := []struct { 482 args []string 483 id int64 484 existingAuthSource *auth.Source 485 authSource *auth.Source 486 errMsg string 487 }{ 488 // case 0 489 { 490 args: []string{ 491 "ldap-test", 492 "--id", "23", 493 "--name", "ldap (via Bind DN) source full", 494 "--not-active", 495 "--security-protocol", "LDAPS", 496 "--skip-tls-verify", 497 "--host", "ldap-bind-server full", 498 "--port", "9876", 499 "--user-search-base", "ou=Users,dc=full-domain-bind,dc=org", 500 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)", 501 "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)", 502 "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-bind,dc=org)", 503 "--username-attribute", "uid-bind full", 504 "--firstname-attribute", "givenName-bind full", 505 "--surname-attribute", "sn-bind full", 506 "--email-attribute", "mail-bind full", 507 "--public-ssh-key-attribute", "publickey-bind full", 508 "--avatar-attribute", "avatar-bind full", 509 "--bind-dn", "cn=readonly,dc=full-domain-bind,dc=org", 510 "--bind-password", "secret-bind-full", 511 "--synchronize-users", 512 "--page-size", "99", 513 }, 514 id: 23, 515 existingAuthSource: &auth.Source{ 516 Type: auth.LDAP, 517 IsActive: true, 518 Cfg: &ldap.Source{ 519 Enabled: true, 520 }, 521 }, 522 authSource: &auth.Source{ 523 Type: auth.LDAP, 524 Name: "ldap (via Bind DN) source full", 525 IsActive: false, 526 IsSyncEnabled: true, 527 Cfg: &ldap.Source{ 528 Name: "ldap (via Bind DN) source full", 529 Host: "ldap-bind-server full", 530 Port: 9876, 531 SecurityProtocol: ldap.SecurityProtocol(1), 532 SkipVerify: true, 533 BindDN: "cn=readonly,dc=full-domain-bind,dc=org", 534 BindPassword: "secret-bind-full", 535 UserBase: "ou=Users,dc=full-domain-bind,dc=org", 536 AttributeUsername: "uid-bind full", 537 AttributeName: "givenName-bind full", 538 AttributeSurname: "sn-bind full", 539 AttributeMail: "mail-bind full", 540 AttributesInBind: false, 541 AttributeSSHPublicKey: "publickey-bind full", 542 AttributeAvatar: "avatar-bind full", 543 SearchPageSize: 99, 544 Filter: "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)", 545 AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)", 546 RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-bind,dc=org)", 547 Enabled: true, 548 }, 549 }, 550 }, 551 // case 1 552 { 553 args: []string{ 554 "ldap-test", 555 "--id", "1", 556 }, 557 authSource: &auth.Source{ 558 Type: auth.LDAP, 559 Cfg: &ldap.Source{}, 560 }, 561 }, 562 // case 2 563 { 564 args: []string{ 565 "ldap-test", 566 "--id", "1", 567 "--name", "ldap (via Bind DN) source", 568 }, 569 authSource: &auth.Source{ 570 Type: auth.LDAP, 571 Name: "ldap (via Bind DN) source", 572 Cfg: &ldap.Source{ 573 Name: "ldap (via Bind DN) source", 574 }, 575 }, 576 }, 577 // case 3 578 { 579 args: []string{ 580 "ldap-test", 581 "--id", "1", 582 "--not-active", 583 }, 584 existingAuthSource: &auth.Source{ 585 Type: auth.LDAP, 586 IsActive: true, 587 Cfg: &ldap.Source{}, 588 }, 589 authSource: &auth.Source{ 590 Type: auth.LDAP, 591 IsActive: false, 592 Cfg: &ldap.Source{}, 593 }, 594 }, 595 // case 4 596 { 597 args: []string{ 598 "ldap-test", 599 "--id", "1", 600 "--security-protocol", "LDAPS", 601 }, 602 authSource: &auth.Source{ 603 Type: auth.LDAP, 604 Cfg: &ldap.Source{ 605 SecurityProtocol: ldap.SecurityProtocol(1), 606 }, 607 }, 608 }, 609 // case 5 610 { 611 args: []string{ 612 "ldap-test", 613 "--id", "1", 614 "--skip-tls-verify", 615 }, 616 authSource: &auth.Source{ 617 Type: auth.LDAP, 618 Cfg: &ldap.Source{ 619 SkipVerify: true, 620 }, 621 }, 622 }, 623 // case 6 624 { 625 args: []string{ 626 "ldap-test", 627 "--id", "1", 628 "--host", "ldap-server", 629 }, 630 authSource: &auth.Source{ 631 Type: auth.LDAP, 632 Cfg: &ldap.Source{ 633 Host: "ldap-server", 634 }, 635 }, 636 }, 637 // case 7 638 { 639 args: []string{ 640 "ldap-test", 641 "--id", "1", 642 "--port", "389", 643 }, 644 authSource: &auth.Source{ 645 Type: auth.LDAP, 646 Cfg: &ldap.Source{ 647 Port: 389, 648 }, 649 }, 650 }, 651 // case 8 652 { 653 args: []string{ 654 "ldap-test", 655 "--id", "1", 656 "--user-search-base", "ou=Users,dc=domain,dc=org", 657 }, 658 authSource: &auth.Source{ 659 Type: auth.LDAP, 660 Cfg: &ldap.Source{ 661 UserBase: "ou=Users,dc=domain,dc=org", 662 }, 663 }, 664 }, 665 // case 9 666 { 667 args: []string{ 668 "ldap-test", 669 "--id", "1", 670 "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", 671 }, 672 authSource: &auth.Source{ 673 Type: auth.LDAP, 674 Cfg: &ldap.Source{ 675 Filter: "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", 676 }, 677 }, 678 }, 679 // case 10 680 { 681 args: []string{ 682 "ldap-test", 683 "--id", "1", 684 "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)", 685 }, 686 authSource: &auth.Source{ 687 Type: auth.LDAP, 688 Cfg: &ldap.Source{ 689 AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)", 690 }, 691 }, 692 }, 693 // case 11 694 { 695 args: []string{ 696 "ldap-test", 697 "--id", "1", 698 "--username-attribute", "uid", 699 }, 700 authSource: &auth.Source{ 701 Type: auth.LDAP, 702 Cfg: &ldap.Source{ 703 AttributeUsername: "uid", 704 }, 705 }, 706 }, 707 // case 12 708 { 709 args: []string{ 710 "ldap-test", 711 "--id", "1", 712 "--firstname-attribute", "givenName", 713 }, 714 authSource: &auth.Source{ 715 Type: auth.LDAP, 716 Cfg: &ldap.Source{ 717 AttributeName: "givenName", 718 }, 719 }, 720 }, 721 // case 13 722 { 723 args: []string{ 724 "ldap-test", 725 "--id", "1", 726 "--surname-attribute", "sn", 727 }, 728 authSource: &auth.Source{ 729 Type: auth.LDAP, 730 Cfg: &ldap.Source{ 731 AttributeSurname: "sn", 732 }, 733 }, 734 }, 735 // case 14 736 { 737 args: []string{ 738 "ldap-test", 739 "--id", "1", 740 "--email-attribute", "mail", 741 }, 742 authSource: &auth.Source{ 743 Type: auth.LDAP, 744 Cfg: &ldap.Source{ 745 AttributeMail: "mail", 746 }, 747 }, 748 }, 749 // case 15 750 { 751 args: []string{ 752 "ldap-test", 753 "--id", "1", 754 "--attributes-in-bind", 755 }, 756 authSource: &auth.Source{ 757 Type: auth.LDAP, 758 Cfg: &ldap.Source{ 759 AttributesInBind: true, 760 }, 761 }, 762 }, 763 // case 16 764 { 765 args: []string{ 766 "ldap-test", 767 "--id", "1", 768 "--public-ssh-key-attribute", "publickey", 769 }, 770 authSource: &auth.Source{ 771 Type: auth.LDAP, 772 Cfg: &ldap.Source{ 773 AttributeSSHPublicKey: "publickey", 774 }, 775 }, 776 }, 777 // case 17 778 { 779 args: []string{ 780 "ldap-test", 781 "--id", "1", 782 "--bind-dn", "cn=readonly,dc=domain,dc=org", 783 }, 784 authSource: &auth.Source{ 785 Type: auth.LDAP, 786 Cfg: &ldap.Source{ 787 BindDN: "cn=readonly,dc=domain,dc=org", 788 }, 789 }, 790 }, 791 // case 18 792 { 793 args: []string{ 794 "ldap-test", 795 "--id", "1", 796 "--bind-password", "secret", 797 }, 798 authSource: &auth.Source{ 799 Type: auth.LDAP, 800 Cfg: &ldap.Source{ 801 BindPassword: "secret", 802 }, 803 }, 804 }, 805 // case 19 806 { 807 args: []string{ 808 "ldap-test", 809 "--id", "1", 810 "--synchronize-users", 811 }, 812 authSource: &auth.Source{ 813 Type: auth.LDAP, 814 IsSyncEnabled: true, 815 Cfg: &ldap.Source{}, 816 }, 817 }, 818 // case 20 819 { 820 args: []string{ 821 "ldap-test", 822 "--id", "1", 823 "--page-size", "12", 824 }, 825 authSource: &auth.Source{ 826 Type: auth.LDAP, 827 Cfg: &ldap.Source{ 828 SearchPageSize: 12, 829 }, 830 }, 831 }, 832 // case 21 833 { 834 args: []string{ 835 "ldap-test", 836 "--id", "1", 837 "--security-protocol", "xxxxx", 838 }, 839 errMsg: "Unknown security protocol name: xxxxx", 840 }, 841 // case 22 842 { 843 args: []string{ 844 "ldap-test", 845 }, 846 errMsg: "id is not set", 847 }, 848 // case 23 849 { 850 args: []string{ 851 "ldap-test", 852 "--id", "1", 853 }, 854 existingAuthSource: &auth.Source{ 855 Type: auth.OAuth2, 856 Cfg: &ldap.Source{}, 857 }, 858 errMsg: "Invalid authentication type. expected: LDAP (via BindDN), actual: OAuth2", 859 }, 860 // case 24 861 { 862 args: []string{ 863 "ldap-test", 864 "--id", "24", 865 "--name", "ldap (via Bind DN) flip 'active' and 'user sync' attributes", 866 "--active", 867 "--disable-synchronize-users", 868 }, 869 id: 24, 870 existingAuthSource: &auth.Source{ 871 Type: auth.LDAP, 872 IsActive: false, 873 IsSyncEnabled: true, 874 Cfg: &ldap.Source{ 875 Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes", 876 Enabled: true, 877 }, 878 }, 879 authSource: &auth.Source{ 880 Type: auth.LDAP, 881 Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes", 882 IsActive: true, 883 IsSyncEnabled: false, 884 Cfg: &ldap.Source{ 885 Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes", 886 Enabled: true, 887 }, 888 }, 889 }, 890 } 891 892 for n, c := range cases { 893 // Mock functions. 894 var updatedAuthSource *auth.Source 895 service := &authService{ 896 initDB: func(context.Context) error { 897 return nil 898 }, 899 createAuthSource: func(ctx context.Context, authSource *auth.Source) error { 900 assert.FailNow(t, "case %d: should not call createAuthSource", n) 901 return nil 902 }, 903 updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { 904 updatedAuthSource = authSource 905 return nil 906 }, 907 getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { 908 if c.id != 0 { 909 assert.Equal(t, c.id, id, "case %d: wrong id", n) 910 } 911 if c.existingAuthSource != nil { 912 return c.existingAuthSource, nil 913 } 914 return &auth.Source{ 915 Type: auth.LDAP, 916 Cfg: &ldap.Source{}, 917 }, nil 918 }, 919 } 920 921 // Create a copy of command to test 922 app := cli.NewApp() 923 app.Flags = microcmdAuthUpdateLdapBindDn.Flags 924 app.Action = service.updateLdapBindDn 925 926 // Run it 927 err := app.Run(c.args) 928 if c.errMsg != "" { 929 assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) 930 } else { 931 assert.NoError(t, err, "case %d: should have no errors", n) 932 assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n) 933 } 934 } 935 } 936 937 func TestUpdateLdapSimpleAuth(t *testing.T) { 938 // Mock cli functions to do not exit on error 939 osExiter := cli.OsExiter 940 defer func() { cli.OsExiter = osExiter }() 941 cli.OsExiter = func(code int) {} 942 943 // Test cases 944 cases := []struct { 945 args []string 946 id int64 947 existingAuthSource *auth.Source 948 authSource *auth.Source 949 errMsg string 950 }{ 951 // case 0 952 { 953 args: []string{ 954 "ldap-test", 955 "--id", "7", 956 "--name", "ldap (simple auth) source full", 957 "--not-active", 958 "--security-protocol", "starttls", 959 "--skip-tls-verify", 960 "--host", "ldap-simple-server full", 961 "--port", "987", 962 "--user-search-base", "ou=Users,dc=full-domain-simple,dc=org", 963 "--user-filter", "(&(objectClass=posixAccount)(full-simple-cn=%s))", 964 "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)", 965 "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)", 966 "--username-attribute", "uid-simple full", 967 "--firstname-attribute", "givenName-simple full", 968 "--surname-attribute", "sn-simple full", 969 "--email-attribute", "mail-simple full", 970 "--public-ssh-key-attribute", "publickey-simple full", 971 "--avatar-attribute", "avatar-simple full", 972 "--user-dn", "cn=%s,ou=Users,dc=full-domain-simple,dc=org", 973 }, 974 id: 7, 975 authSource: &auth.Source{ 976 Type: auth.DLDAP, 977 Name: "ldap (simple auth) source full", 978 IsActive: false, 979 Cfg: &ldap.Source{ 980 Name: "ldap (simple auth) source full", 981 Host: "ldap-simple-server full", 982 Port: 987, 983 SecurityProtocol: ldap.SecurityProtocol(2), 984 SkipVerify: true, 985 UserDN: "cn=%s,ou=Users,dc=full-domain-simple,dc=org", 986 UserBase: "ou=Users,dc=full-domain-simple,dc=org", 987 AttributeUsername: "uid-simple full", 988 AttributeName: "givenName-simple full", 989 AttributeSurname: "sn-simple full", 990 AttributeMail: "mail-simple full", 991 AttributeSSHPublicKey: "publickey-simple full", 992 AttributeAvatar: "avatar-simple full", 993 Filter: "(&(objectClass=posixAccount)(full-simple-cn=%s))", 994 AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)", 995 RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)", 996 }, 997 }, 998 }, 999 // case 1 1000 { 1001 args: []string{ 1002 "ldap-test", 1003 "--id", "1", 1004 }, 1005 authSource: &auth.Source{ 1006 Type: auth.DLDAP, 1007 Cfg: &ldap.Source{}, 1008 }, 1009 }, 1010 // case 2 1011 { 1012 args: []string{ 1013 "ldap-test", 1014 "--id", "1", 1015 "--name", "ldap (simple auth) source", 1016 }, 1017 authSource: &auth.Source{ 1018 Type: auth.DLDAP, 1019 Name: "ldap (simple auth) source", 1020 Cfg: &ldap.Source{ 1021 Name: "ldap (simple auth) source", 1022 }, 1023 }, 1024 }, 1025 // case 3 1026 { 1027 args: []string{ 1028 "ldap-test", 1029 "--id", "1", 1030 "--not-active", 1031 }, 1032 existingAuthSource: &auth.Source{ 1033 Type: auth.DLDAP, 1034 IsActive: true, 1035 Cfg: &ldap.Source{}, 1036 }, 1037 authSource: &auth.Source{ 1038 Type: auth.DLDAP, 1039 IsActive: false, 1040 Cfg: &ldap.Source{}, 1041 }, 1042 }, 1043 // case 4 1044 { 1045 args: []string{ 1046 "ldap-test", 1047 "--id", "1", 1048 "--security-protocol", "starttls", 1049 }, 1050 authSource: &auth.Source{ 1051 Type: auth.DLDAP, 1052 Cfg: &ldap.Source{ 1053 SecurityProtocol: ldap.SecurityProtocol(2), 1054 }, 1055 }, 1056 }, 1057 // case 5 1058 { 1059 args: []string{ 1060 "ldap-test", 1061 "--id", "1", 1062 "--skip-tls-verify", 1063 }, 1064 authSource: &auth.Source{ 1065 Type: auth.DLDAP, 1066 Cfg: &ldap.Source{ 1067 SkipVerify: true, 1068 }, 1069 }, 1070 }, 1071 // case 6 1072 { 1073 args: []string{ 1074 "ldap-test", 1075 "--id", "1", 1076 "--host", "ldap-server", 1077 }, 1078 authSource: &auth.Source{ 1079 Type: auth.DLDAP, 1080 Cfg: &ldap.Source{ 1081 Host: "ldap-server", 1082 }, 1083 }, 1084 }, 1085 // case 7 1086 { 1087 args: []string{ 1088 "ldap-test", 1089 "--id", "1", 1090 "--port", "987", 1091 }, 1092 authSource: &auth.Source{ 1093 Type: auth.DLDAP, 1094 Cfg: &ldap.Source{ 1095 Port: 987, 1096 }, 1097 }, 1098 }, 1099 // case 8 1100 { 1101 args: []string{ 1102 "ldap-test", 1103 "--id", "1", 1104 "--user-search-base", "ou=Users,dc=domain,dc=org", 1105 }, 1106 authSource: &auth.Source{ 1107 Type: auth.DLDAP, 1108 Cfg: &ldap.Source{ 1109 UserBase: "ou=Users,dc=domain,dc=org", 1110 }, 1111 }, 1112 }, 1113 // case 9 1114 { 1115 args: []string{ 1116 "ldap-test", 1117 "--id", "1", 1118 "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", 1119 }, 1120 authSource: &auth.Source{ 1121 Type: auth.DLDAP, 1122 Cfg: &ldap.Source{ 1123 Filter: "(&(objectClass=posixAccount)(cn=%s))", 1124 }, 1125 }, 1126 }, 1127 // case 10 1128 { 1129 args: []string{ 1130 "ldap-test", 1131 "--id", "1", 1132 "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)", 1133 }, 1134 authSource: &auth.Source{ 1135 Type: auth.DLDAP, 1136 Cfg: &ldap.Source{ 1137 AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)", 1138 }, 1139 }, 1140 }, 1141 // case 11 1142 { 1143 args: []string{ 1144 "ldap-test", 1145 "--id", "1", 1146 "--username-attribute", "uid", 1147 }, 1148 authSource: &auth.Source{ 1149 Type: auth.DLDAP, 1150 Cfg: &ldap.Source{ 1151 AttributeUsername: "uid", 1152 }, 1153 }, 1154 }, 1155 // case 12 1156 { 1157 args: []string{ 1158 "ldap-test", 1159 "--id", "1", 1160 "--firstname-attribute", "givenName", 1161 }, 1162 authSource: &auth.Source{ 1163 Type: auth.DLDAP, 1164 Cfg: &ldap.Source{ 1165 AttributeName: "givenName", 1166 }, 1167 }, 1168 }, 1169 // case 13 1170 { 1171 args: []string{ 1172 "ldap-test", 1173 "--id", "1", 1174 "--surname-attribute", "sn", 1175 }, 1176 authSource: &auth.Source{ 1177 Type: auth.DLDAP, 1178 Cfg: &ldap.Source{ 1179 AttributeSurname: "sn", 1180 }, 1181 }, 1182 }, 1183 // case 14 1184 { 1185 args: []string{ 1186 "ldap-test", 1187 "--id", "1", 1188 "--email-attribute", "mail", 1189 }, 1190 authSource: &auth.Source{ 1191 Type: auth.DLDAP, 1192 Cfg: &ldap.Source{ 1193 AttributeMail: "mail", 1194 }, 1195 }, 1196 }, 1197 // case 15 1198 { 1199 args: []string{ 1200 "ldap-test", 1201 "--id", "1", 1202 "--public-ssh-key-attribute", "publickey", 1203 }, 1204 authSource: &auth.Source{ 1205 Type: auth.DLDAP, 1206 Cfg: &ldap.Source{ 1207 AttributeSSHPublicKey: "publickey", 1208 }, 1209 }, 1210 }, 1211 // case 16 1212 { 1213 args: []string{ 1214 "ldap-test", 1215 "--id", "1", 1216 "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", 1217 }, 1218 authSource: &auth.Source{ 1219 Type: auth.DLDAP, 1220 Cfg: &ldap.Source{ 1221 UserDN: "cn=%s,ou=Users,dc=domain,dc=org", 1222 }, 1223 }, 1224 }, 1225 // case 17 1226 { 1227 args: []string{ 1228 "ldap-test", 1229 "--id", "1", 1230 "--security-protocol", "xxxxx", 1231 }, 1232 errMsg: "Unknown security protocol name: xxxxx", 1233 }, 1234 // case 18 1235 { 1236 args: []string{ 1237 "ldap-test", 1238 }, 1239 errMsg: "id is not set", 1240 }, 1241 // case 19 1242 { 1243 args: []string{ 1244 "ldap-test", 1245 "--id", "1", 1246 }, 1247 existingAuthSource: &auth.Source{ 1248 Type: auth.PAM, 1249 Cfg: &ldap.Source{}, 1250 }, 1251 errMsg: "Invalid authentication type. expected: LDAP (simple auth), actual: PAM", 1252 }, 1253 // case 20 1254 { 1255 args: []string{ 1256 "ldap-test", 1257 "--id", "20", 1258 "--name", "ldap (simple auth) flip 'active' attribute", 1259 "--active", 1260 }, 1261 id: 20, 1262 existingAuthSource: &auth.Source{ 1263 Type: auth.DLDAP, 1264 IsActive: false, 1265 Cfg: &ldap.Source{ 1266 Name: "ldap (simple auth) flip 'active' attribute", 1267 Enabled: true, 1268 }, 1269 }, 1270 authSource: &auth.Source{ 1271 Type: auth.DLDAP, 1272 Name: "ldap (simple auth) flip 'active' attribute", 1273 IsActive: true, 1274 Cfg: &ldap.Source{ 1275 Name: "ldap (simple auth) flip 'active' attribute", 1276 Enabled: true, 1277 }, 1278 }, 1279 }, 1280 } 1281 1282 for n, c := range cases { 1283 // Mock functions. 1284 var updatedAuthSource *auth.Source 1285 service := &authService{ 1286 initDB: func(context.Context) error { 1287 return nil 1288 }, 1289 createAuthSource: func(ctx context.Context, authSource *auth.Source) error { 1290 assert.FailNow(t, "case %d: should not call createAuthSource", n) 1291 return nil 1292 }, 1293 updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { 1294 updatedAuthSource = authSource 1295 return nil 1296 }, 1297 getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { 1298 if c.id != 0 { 1299 assert.Equal(t, c.id, id, "case %d: wrong id", n) 1300 } 1301 if c.existingAuthSource != nil { 1302 return c.existingAuthSource, nil 1303 } 1304 return &auth.Source{ 1305 Type: auth.DLDAP, 1306 Cfg: &ldap.Source{}, 1307 }, nil 1308 }, 1309 } 1310 1311 // Create a copy of command to test 1312 app := cli.NewApp() 1313 app.Flags = microcmdAuthUpdateLdapSimpleAuth.Flags 1314 app.Action = service.updateLdapSimpleAuth 1315 1316 // Run it 1317 err := app.Run(c.args) 1318 if c.errMsg != "" { 1319 assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) 1320 } else { 1321 assert.NoError(t, err, "case %d: should have no errors", n) 1322 assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n) 1323 } 1324 } 1325 }