diff options
author | ngourdon <ngourdon@gmail.com> | 2019-06-17 20:32:20 +0200 |
---|---|---|
committer | techknowlogick <hello@techknowlogick.com> | 2019-06-17 14:32:20 -0400 |
commit | a618df8d8474efb9148d29c4ce6cf8ec14cfca7a (patch) | |
tree | 439f8f1c96693cba29b7a598ae5bd2ad21a4686c /cmd/admin_auth_ldap_test.go | |
parent | a200ca15519d6f23a0b64c062f23000c347ce7b6 (diff) | |
download | gitea-a618df8d8474efb9148d29c4ce6cf8ec14cfca7a.tar.gz gitea-a618df8d8474efb9148d29c4ce6cf8ec14cfca7a.zip |
Add CLI commands to manage LDAP authentication source (#6681)
* add CLI commands to manage LDAP authentication source
* delete Gogs copyright
* remove unused return value of func parseLoginSource
* fix comment
Co-Authored-By: ngourdon <31291059+ngourdon@users.noreply.github.com>
* remove config flag already present in global flags
* remove config flag from ldap commands in docs
* remove config flag handling
Diffstat (limited to 'cmd/admin_auth_ldap_test.go')
-rw-r--r-- | cmd/admin_auth_ldap_test.go | 1350 |
1 files changed, 1350 insertions, 0 deletions
diff --git a/cmd/admin_auth_ldap_test.go b/cmd/admin_auth_ldap_test.go new file mode 100644 index 0000000000..4af9f167c3 --- /dev/null +++ b/cmd/admin_auth_ldap_test.go @@ -0,0 +1,1350 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cmd + +import ( + "testing" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/auth/ldap" + + "github.com/stretchr/testify/assert" + "github.com/urfave/cli" +) + +func TestAddLdapBindDn(t *testing.T) { + // Mock cli functions to do not exit on error + var osExiter = cli.OsExiter + defer func() { cli.OsExiter = osExiter }() + cli.OsExiter = func(code int) {} + + // Test cases + var cases = []struct { + args []string + loginSource *models.LoginSource + errMsg string + }{ + // case 0 + { + args: []string{ + "ldap-test", + "--name", "ldap (via Bind DN) source full", + "--not-active", + "--security-protocol", "ldaps", + "--skip-tls-verify", + "--host", "ldap-bind-server full", + "--port", "9876", + "--user-search-base", "ou=Users,dc=full-domain-bind,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)", + "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)", + "--username-attribute", "uid-bind full", + "--firstname-attribute", "givenName-bind full", + "--surname-attribute", "sn-bind full", + "--email-attribute", "mail-bind full", + "--public-ssh-key-attribute", "publickey-bind full", + "--bind-dn", "cn=readonly,dc=full-domain-bind,dc=org", + "--bind-password", "secret-bind-full", + "--attributes-in-bind", + "--synchronize-users", + "--page-size", "99", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Name: "ldap (via Bind DN) source full", + IsActived: false, + IsSyncEnabled: true, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Name: "ldap (via Bind DN) source full", + Host: "ldap-bind-server full", + Port: 9876, + SecurityProtocol: ldap.SecurityProtocol(1), + SkipVerify: true, + BindDN: "cn=readonly,dc=full-domain-bind,dc=org", + BindPassword: "secret-bind-full", + UserBase: "ou=Users,dc=full-domain-bind,dc=org", + AttributeUsername: "uid-bind full", + AttributeName: "givenName-bind full", + AttributeSurname: "sn-bind full", + AttributeMail: "mail-bind full", + AttributesInBind: true, + AttributeSSHPublicKey: "publickey-bind full", + SearchPageSize: 99, + Filter: "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)", + AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)", + Enabled: true, + }, + }, + }, + }, + // case 1 + { + args: []string{ + "ldap-test", + "--name", "ldap (via Bind DN) source min", + "--security-protocol", "unencrypted", + "--host", "ldap-bind-server min", + "--port", "1234", + "--user-search-base", "ou=Users,dc=min-domain-bind,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=min-domain-bind,dc=org)", + "--email-attribute", "mail-bind min", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Name: "ldap (via Bind DN) source min", + IsActived: true, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Name: "ldap (via Bind DN) source min", + Host: "ldap-bind-server min", + Port: 1234, + SecurityProtocol: ldap.SecurityProtocol(0), + UserBase: "ou=Users,dc=min-domain-bind,dc=org", + AttributeMail: "mail-bind min", + Filter: "(memberOf=cn=user-group,ou=example,dc=min-domain-bind,dc=org)", + Enabled: true, + }, + }, + }, + }, + // case 2 + { + args: []string{ + "ldap-test", + "--name", "ldap (via Bind DN) source", + "--security-protocol", "zzzzz", + "--host", "ldap-server", + "--port", "1234", + "--user-search-base", "ou=Users,dc=domain,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", + "--email-attribute", "mail", + }, + errMsg: "Unknown security protocol name: zzzzz", + }, + // case 3 + { + args: []string{ + "ldap-test", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--port", "1234", + "--user-search-base", "ou=Users,dc=domain,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", + "--email-attribute", "mail", + }, + errMsg: "name is not set", + }, + // case 4 + { + args: []string{ + "ldap-test", + "--name", "ldap (via Bind DN) source", + "--host", "ldap-server", + "--port", "1234", + "--user-search-base", "ou=Users,dc=domain,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", + "--email-attribute", "mail", + }, + errMsg: "security-protocol is not set", + }, + // case 5 + { + args: []string{ + "ldap-test", + "--name", "ldap (via Bind DN) source", + "--security-protocol", "unencrypted", + "--port", "1234", + "--user-search-base", "ou=Users,dc=domain,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", + "--email-attribute", "mail", + }, + errMsg: "host is not set", + }, + // case 6 + { + args: []string{ + "ldap-test", + "--name", "ldap (via Bind DN) source", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--user-search-base", "ou=Users,dc=domain,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", + "--email-attribute", "mail", + }, + errMsg: "port is not set", + }, + // case 7 + { + args: []string{ + "ldap-test", + "--name", "ldap (via Bind DN) source", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--port", "1234", + "--user-search-base", "ou=Users,dc=domain,dc=org", + "--email-attribute", "mail", + }, + errMsg: "user-filter is not set", + }, + // case 8 + { + args: []string{ + "ldap-test", + "--name", "ldap (via Bind DN) source", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--port", "1234", + "--user-search-base", "ou=Users,dc=domain,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", + }, + errMsg: "email-attribute is not set", + }, + } + + for n, c := range cases { + // Mock functions. + var createdLoginSource *models.LoginSource + service := &authService{ + initDB: func() error { + return nil + }, + createLoginSource: func(loginSource *models.LoginSource) error { + createdLoginSource = loginSource + return nil + }, + updateLoginSource: func(loginSource *models.LoginSource) error { + assert.FailNow(t, "case %d: should not call updateLoginSource", n) + return nil + }, + getLoginSourceByID: func(id int64) (*models.LoginSource, error) { + assert.FailNow(t, "case %d: should not call getLoginSourceByID", n) + return nil, nil + }, + } + + // Create a copy of command to test + app := cli.NewApp() + app.Flags = cmdAuthAddLdapBindDn.Flags + app.Action = service.addLdapBindDn + + // Run it + err := app.Run(c.args) + if c.errMsg != "" { + assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) + } else { + assert.NoError(t, err, "case %d: should have no errors", n) + assert.Equal(t, c.loginSource, createdLoginSource, "case %d: wrong loginSource", n) + } + } +} + +func TestAddLdapSimpleAuth(t *testing.T) { + // Mock cli functions to do not exit on error + var osExiter = cli.OsExiter + defer func() { cli.OsExiter = osExiter }() + cli.OsExiter = func(code int) {} + + // Test cases + var cases = []struct { + args []string + loginSource *models.LoginSource + errMsg string + }{ + // case 0 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source full", + "--not-active", + "--security-protocol", "starttls", + "--skip-tls-verify", + "--host", "ldap-simple-server full", + "--port", "987", + "--user-search-base", "ou=Users,dc=full-domain-simple,dc=org", + "--user-filter", "(&(objectClass=posixAccount)(full-simple-cn=%s))", + "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)", + "--username-attribute", "uid-simple full", + "--firstname-attribute", "givenName-simple full", + "--surname-attribute", "sn-simple full", + "--email-attribute", "mail-simple full", + "--public-ssh-key-attribute", "publickey-simple full", + "--user-dn", "cn=%s,ou=Users,dc=full-domain-simple,dc=org", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Name: "ldap (simple auth) source full", + IsActived: false, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Name: "ldap (simple auth) source full", + Host: "ldap-simple-server full", + Port: 987, + SecurityProtocol: ldap.SecurityProtocol(2), + SkipVerify: true, + UserDN: "cn=%s,ou=Users,dc=full-domain-simple,dc=org", + UserBase: "ou=Users,dc=full-domain-simple,dc=org", + AttributeUsername: "uid-simple full", + AttributeName: "givenName-simple full", + AttributeSurname: "sn-simple full", + AttributeMail: "mail-simple full", + AttributeSSHPublicKey: "publickey-simple full", + Filter: "(&(objectClass=posixAccount)(full-simple-cn=%s))", + AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)", + Enabled: true, + }, + }, + }, + }, + // case 1 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source min", + "--security-protocol", "unencrypted", + "--host", "ldap-simple-server min", + "--port", "123", + "--user-filter", "(&(objectClass=posixAccount)(min-simple-cn=%s))", + "--email-attribute", "mail-simple min", + "--user-dn", "cn=%s,ou=Users,dc=min-domain-simple,dc=org", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Name: "ldap (simple auth) source min", + IsActived: true, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Name: "ldap (simple auth) source min", + Host: "ldap-simple-server min", + Port: 123, + SecurityProtocol: ldap.SecurityProtocol(0), + UserDN: "cn=%s,ou=Users,dc=min-domain-simple,dc=org", + AttributeMail: "mail-simple min", + Filter: "(&(objectClass=posixAccount)(min-simple-cn=%s))", + Enabled: true, + }, + }, + }, + }, + // case 2 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source", + "--security-protocol", "zzzzz", + "--host", "ldap-server", + "--port", "123", + "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", + "--email-attribute", "mail", + "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", + }, + errMsg: "Unknown security protocol name: zzzzz", + }, + // case 3 + { + args: []string{ + "ldap-test", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--port", "123", + "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", + "--email-attribute", "mail", + "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", + }, + errMsg: "name is not set", + }, + // case 4 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source", + "--host", "ldap-server", + "--port", "123", + "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", + "--email-attribute", "mail", + "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", + }, + errMsg: "security-protocol is not set", + }, + // case 5 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source", + "--security-protocol", "unencrypted", + "--port", "123", + "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", + "--email-attribute", "mail", + "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", + }, + errMsg: "host is not set", + }, + // case 6 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", + "--email-attribute", "mail", + "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", + }, + errMsg: "port is not set", + }, + // case 7 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--port", "123", + "--email-attribute", "mail", + "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", + }, + errMsg: "user-filter is not set", + }, + // case 8 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--port", "123", + "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", + "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", + }, + errMsg: "email-attribute is not set", + }, + // case 9 + { + args: []string{ + "ldap-test", + "--name", "ldap (simple auth) source", + "--security-protocol", "unencrypted", + "--host", "ldap-server", + "--port", "123", + "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", + "--email-attribute", "mail", + }, + errMsg: "user-dn is not set", + }, + } + + for n, c := range cases { + // Mock functions. + var createdLoginSource *models.LoginSource + service := &authService{ + initDB: func() error { + return nil + }, + createLoginSource: func(loginSource *models.LoginSource) error { + createdLoginSource = loginSource + return nil + }, + updateLoginSource: func(loginSource *models.LoginSource) error { + assert.FailNow(t, "case %d: should not call updateLoginSource", n) + return nil + }, + getLoginSourceByID: func(id int64) (*models.LoginSource, error) { + assert.FailNow(t, "case %d: should not call getLoginSourceByID", n) + return nil, nil + }, + } + + // Create a copy of command to test + app := cli.NewApp() + app.Flags = cmdAuthAddLdapSimpleAuth.Flags + app.Action = service.addLdapSimpleAuth + + // Run it + err := app.Run(c.args) + if c.errMsg != "" { + assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) + } else { + assert.NoError(t, err, "case %d: should have no errors", n) + assert.Equal(t, c.loginSource, createdLoginSource, "case %d: wrong loginSource", n) + } + } +} + +func TestUpdateLdapBindDn(t *testing.T) { + // Mock cli functions to do not exit on error + var osExiter = cli.OsExiter + defer func() { cli.OsExiter = osExiter }() + cli.OsExiter = func(code int) {} + + // Test cases + var cases = []struct { + args []string + id int64 + existingLoginSource *models.LoginSource + loginSource *models.LoginSource + errMsg string + }{ + // case 0 + { + args: []string{ + "ldap-test", + "--id", "23", + "--name", "ldap (via Bind DN) source full", + "--not-active", + "--security-protocol", "LDAPS", + "--skip-tls-verify", + "--host", "ldap-bind-server full", + "--port", "9876", + "--user-search-base", "ou=Users,dc=full-domain-bind,dc=org", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)", + "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)", + "--username-attribute", "uid-bind full", + "--firstname-attribute", "givenName-bind full", + "--surname-attribute", "sn-bind full", + "--email-attribute", "mail-bind full", + "--public-ssh-key-attribute", "publickey-bind full", + "--bind-dn", "cn=readonly,dc=full-domain-bind,dc=org", + "--bind-password", "secret-bind-full", + "--synchronize-users", + "--page-size", "99", + }, + id: 23, + existingLoginSource: &models.LoginSource{ + Type: models.LoginLDAP, + IsActived: true, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Enabled: true, + }, + }, + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Name: "ldap (via Bind DN) source full", + IsActived: false, + IsSyncEnabled: true, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Name: "ldap (via Bind DN) source full", + Host: "ldap-bind-server full", + Port: 9876, + SecurityProtocol: ldap.SecurityProtocol(1), + SkipVerify: true, + BindDN: "cn=readonly,dc=full-domain-bind,dc=org", + BindPassword: "secret-bind-full", + UserBase: "ou=Users,dc=full-domain-bind,dc=org", + AttributeUsername: "uid-bind full", + AttributeName: "givenName-bind full", + AttributeSurname: "sn-bind full", + AttributeMail: "mail-bind full", + AttributesInBind: false, + AttributeSSHPublicKey: "publickey-bind full", + SearchPageSize: 99, + Filter: "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)", + AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)", + Enabled: true, + }, + }, + }, + }, + // case 1 + { + args: []string{ + "ldap-test", + "--id", "1", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + }, + // case 2 + { + args: []string{ + "ldap-test", + "--id", "1", + "--name", "ldap (via Bind DN) source", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Name: "ldap (via Bind DN) source", + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Name: "ldap (via Bind DN) source", + }, + }, + }, + }, + // case 3 + { + args: []string{ + "ldap-test", + "--id", "1", + "--not-active", + }, + existingLoginSource: &models.LoginSource{ + Type: models.LoginLDAP, + IsActived: true, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + IsActived: false, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + }, + // case 4 + { + args: []string{ + "ldap-test", + "--id", "1", + "--security-protocol", "LDAPS", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + SecurityProtocol: ldap.SecurityProtocol(1), + }, + }, + }, + }, + // case 5 + { + args: []string{ + "ldap-test", + "--id", "1", + "--skip-tls-verify", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + SkipVerify: true, + }, + }, + }, + }, + // case 6 + { + args: []string{ + "ldap-test", + "--id", "1", + "--host", "ldap-server", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Host: "ldap-server", + }, + }, + }, + }, + // case 7 + { + args: []string{ + "ldap-test", + "--id", "1", + "--port", "389", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Port: 389, + }, + }, + }, + }, + // case 8 + { + args: []string{ + "ldap-test", + "--id", "1", + "--user-search-base", "ou=Users,dc=domain,dc=org", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + UserBase: "ou=Users,dc=domain,dc=org", + }, + }, + }, + }, + // case 9 + { + args: []string{ + "ldap-test", + "--id", "1", + "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Filter: "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)", + }, + }, + }, + }, + // case 10 + { + args: []string{ + "ldap-test", + "--id", "1", + "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)", + }, + }, + }, + }, + // case 11 + { + args: []string{ + "ldap-test", + "--id", "1", + "--username-attribute", "uid", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeUsername: "uid", + }, + }, + }, + }, + // case 12 + { + args: []string{ + "ldap-test", + "--id", "1", + "--firstname-attribute", "givenName", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeName: "givenName", + }, + }, + }, + }, + // case 13 + { + args: []string{ + "ldap-test", + "--id", "1", + "--surname-attribute", "sn", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeSurname: "sn", + }, + }, + }, + }, + // case 14 + { + args: []string{ + "ldap-test", + "--id", "1", + "--email-attribute", "mail", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeMail: "mail", + }, + }, + }, + }, + // case 15 + { + args: []string{ + "ldap-test", + "--id", "1", + "--attributes-in-bind", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributesInBind: true, + }, + }, + }, + }, + // case 16 + { + args: []string{ + "ldap-test", + "--id", "1", + "--public-ssh-key-attribute", "publickey", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeSSHPublicKey: "publickey", + }, + }, + }, + }, + // case 17 + { + args: []string{ + "ldap-test", + "--id", "1", + "--bind-dn", "cn=readonly,dc=domain,dc=org", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + BindDN: "cn=readonly,dc=domain,dc=org", + }, + }, + }, + }, + // case 18 + { + args: []string{ + "ldap-test", + "--id", "1", + "--bind-password", "secret", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + BindPassword: "secret", + }, + }, + }, + }, + // case 19 + { + args: []string{ + "ldap-test", + "--id", "1", + "--synchronize-users", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + IsSyncEnabled: true, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + }, + // case 20 + { + args: []string{ + "ldap-test", + "--id", "1", + "--page-size", "12", + }, + loginSource: &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + SearchPageSize: 12, + }, + }, + }, + }, + // case 21 + { + args: []string{ + "ldap-test", + "--id", "1", + "--security-protocol", "xxxxx", + }, + errMsg: "Unknown security protocol name: xxxxx", + }, + // case 22 + { + args: []string{ + "ldap-test", + }, + errMsg: "id is not set", + }, + // case 23 + { + args: []string{ + "ldap-test", + "--id", "1", + }, + existingLoginSource: &models.LoginSource{ + Type: models.LoginOAuth2, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + errMsg: "Invalid authentication type. expected: LDAP (via BindDN), actual: OAuth2", + }, + } + + for n, c := range cases { + // Mock functions. + var updatedLoginSource *models.LoginSource + service := &authService{ + initDB: func() error { + return nil + }, + createLoginSource: func(loginSource *models.LoginSource) error { + assert.FailNow(t, "case %d: should not call createLoginSource", n) + return nil + }, + updateLoginSource: func(loginSource *models.LoginSource) error { + updatedLoginSource = loginSource + return nil + }, + getLoginSourceByID: func(id int64) (*models.LoginSource, error) { + if c.id != 0 { + assert.Equal(t, c.id, id, "case %d: wrong id", n) + } + if c.existingLoginSource != nil { + return c.existingLoginSource, nil + } + return &models.LoginSource{ + Type: models.LoginLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, nil + }, + } + + // Create a copy of command to test + app := cli.NewApp() + app.Flags = cmdAuthUpdateLdapBindDn.Flags + app.Action = service.updateLdapBindDn + + // Run it + err := app.Run(c.args) + if c.errMsg != "" { + assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) + } else { + assert.NoError(t, err, "case %d: should have no errors", n) + assert.Equal(t, c.loginSource, updatedLoginSource, "case %d: wrong loginSource", n) + } + } +} + +func TestUpdateLdapSimpleAuth(t *testing.T) { + // Mock cli functions to do not exit on error + var osExiter = cli.OsExiter + defer func() { cli.OsExiter = osExiter }() + cli.OsExiter = func(code int) {} + + // Test cases + var cases = []struct { + args []string + id int64 + existingLoginSource *models.LoginSource + loginSource *models.LoginSource + errMsg string + }{ + // case 0 + { + args: []string{ + "ldap-test", + "--id", "7", + "--name", "ldap (simple auth) source full", + "--not-active", + "--security-protocol", "starttls", + "--skip-tls-verify", + "--host", "ldap-simple-server full", + "--port", "987", + "--user-search-base", "ou=Users,dc=full-domain-simple,dc=org", + "--user-filter", "(&(objectClass=posixAccount)(full-simple-cn=%s))", + "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)", + "--username-attribute", "uid-simple full", + "--firstname-attribute", "givenName-simple full", + "--surname-attribute", "sn-simple full", + "--email-attribute", "mail-simple full", + "--public-ssh-key-attribute", "publickey-simple full", + "--user-dn", "cn=%s,ou=Users,dc=full-domain-simple,dc=org", + }, + id: 7, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Name: "ldap (simple auth) source full", + IsActived: false, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Name: "ldap (simple auth) source full", + Host: "ldap-simple-server full", + Port: 987, + SecurityProtocol: ldap.SecurityProtocol(2), + SkipVerify: true, + UserDN: "cn=%s,ou=Users,dc=full-domain-simple,dc=org", + UserBase: "ou=Users,dc=full-domain-simple,dc=org", + AttributeUsername: "uid-simple full", + AttributeName: "givenName-simple full", + AttributeSurname: "sn-simple full", + AttributeMail: "mail-simple full", + AttributeSSHPublicKey: "publickey-simple full", + Filter: "(&(objectClass=posixAccount)(full-simple-cn=%s))", + AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)", + }, + }, + }, + }, + // case 1 + { + args: []string{ + "ldap-test", + "--id", "1", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + }, + // case 2 + { + args: []string{ + "ldap-test", + "--id", "1", + "--name", "ldap (simple auth) source", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Name: "ldap (simple auth) source", + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Name: "ldap (simple auth) source", + }, + }, + }, + }, + // case 3 + { + args: []string{ + "ldap-test", + "--id", "1", + "--not-active", + }, + existingLoginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + IsActived: true, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + IsActived: false, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + }, + // case 4 + { + args: []string{ + "ldap-test", + "--id", "1", + "--security-protocol", "starttls", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + SecurityProtocol: ldap.SecurityProtocol(2), + }, + }, + }, + }, + // case 5 + { + args: []string{ + "ldap-test", + "--id", "1", + "--skip-tls-verify", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + SkipVerify: true, + }, + }, + }, + }, + // case 6 + { + args: []string{ + "ldap-test", + "--id", "1", + "--host", "ldap-server", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Host: "ldap-server", + }, + }, + }, + }, + // case 7 + { + args: []string{ + "ldap-test", + "--id", "1", + "--port", "987", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Port: 987, + }, + }, + }, + }, + // case 8 + { + args: []string{ + "ldap-test", + "--id", "1", + "--user-search-base", "ou=Users,dc=domain,dc=org", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + UserBase: "ou=Users,dc=domain,dc=org", + }, + }, + }, + }, + // case 9 + { + args: []string{ + "ldap-test", + "--id", "1", + "--user-filter", "(&(objectClass=posixAccount)(cn=%s))", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + Filter: "(&(objectClass=posixAccount)(cn=%s))", + }, + }, + }, + }, + // case 10 + { + args: []string{ + "ldap-test", + "--id", "1", + "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)", + }, + }, + }, + }, + // case 11 + { + args: []string{ + "ldap-test", + "--id", "1", + "--username-attribute", "uid", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeUsername: "uid", + }, + }, + }, + }, + // case 12 + { + args: []string{ + "ldap-test", + "--id", "1", + "--firstname-attribute", "givenName", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeName: "givenName", + }, + }, + }, + }, + // case 13 + { + args: []string{ + "ldap-test", + "--id", "1", + "--surname-attribute", "sn", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeSurname: "sn", + }, + }, + }, + }, + // case 14 + { + args: []string{ + "ldap-test", + "--id", "1", + "--email-attribute", "mail", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeMail: "mail", + }, + }, + }, + }, + // case 15 + { + args: []string{ + "ldap-test", + "--id", "1", + "--public-ssh-key-attribute", "publickey", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + AttributeSSHPublicKey: "publickey", + }, + }, + }, + }, + // case 16 + { + args: []string{ + "ldap-test", + "--id", "1", + "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org", + }, + loginSource: &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{ + UserDN: "cn=%s,ou=Users,dc=domain,dc=org", + }, + }, + }, + }, + // case 17 + { + args: []string{ + "ldap-test", + "--id", "1", + "--security-protocol", "xxxxx", + }, + errMsg: "Unknown security protocol name: xxxxx", + }, + // case 18 + { + args: []string{ + "ldap-test", + }, + errMsg: "id is not set", + }, + // case 19 + { + args: []string{ + "ldap-test", + "--id", "1", + }, + existingLoginSource: &models.LoginSource{ + Type: models.LoginPAM, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, + errMsg: "Invalid authentication type. expected: LDAP (simple auth), actual: PAM", + }, + } + + for n, c := range cases { + // Mock functions. + var updatedLoginSource *models.LoginSource + service := &authService{ + initDB: func() error { + return nil + }, + createLoginSource: func(loginSource *models.LoginSource) error { + assert.FailNow(t, "case %d: should not call createLoginSource", n) + return nil + }, + updateLoginSource: func(loginSource *models.LoginSource) error { + updatedLoginSource = loginSource + return nil + }, + getLoginSourceByID: func(id int64) (*models.LoginSource, error) { + if c.id != 0 { + assert.Equal(t, c.id, id, "case %d: wrong id", n) + } + if c.existingLoginSource != nil { + return c.existingLoginSource, nil + } + return &models.LoginSource{ + Type: models.LoginDLDAP, + Cfg: &models.LDAPConfig{ + Source: &ldap.Source{}, + }, + }, nil + }, + } + + // Create a copy of command to test + app := cli.NewApp() + app.Flags = cmdAuthUpdateLdapSimpleAuth.Flags + app.Action = service.updateLdapSimpleAuth + + // Run it + err := app.Run(c.args) + if c.errMsg != "" { + assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) + } else { + assert.NoError(t, err, "case %d: should have no errors", n) + assert.Equal(t, c.loginSource, updatedLoginSource, "case %d: wrong loginSource", n) + } + } +} |