Template
1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo synced 2024-11-25 11:16:11 +01:00
forgejo/cmd/admin_auth_ldap_test.go
Lauris BH 37c3db7be6
Add restricted user filter to LDAP authentication (#10600)
* Add restricted user filter to LDAP authentification

* Fix unit test cases
2020-03-05 08:30:33 +02:00

1359 lines
34 KiB
Go

// 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)",
"--restricted-filter", "(memberOf=cn=restricted-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)",
RestrictedFilter: "(memberOf=cn=restricted-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)",
"--restricted-filter", "(memberOf=cn=restricted-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)",
RestrictedFilter: "(memberOf=cn=restricted-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)",
"--restricted-filter", "(memberOf=cn=restricted-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)",
RestrictedFilter: "(memberOf=cn=restricted-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)",
"--restricted-filter", "(memberOf=cn=restricted-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)",
RestrictedFilter: "(memberOf=cn=restricted-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)
}
}
}