mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 15:32:49 +08:00
LDAP: Add skip_org_role_sync
configuration option (#56679)
* LDAP: Add skip_org_role_sync option * Document the new config option * Nit on docs * Update docs/sources/setup-grafana/configure-security/configure-authentication/ldap.md Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com> * Docs suggestions Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com> Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Add test, Fix disabled user when no role Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com> Co-authored-by: Jguer <joao.guerreiro@grafana.com>
This commit is contained in:
@ -10,6 +10,8 @@ import (
|
||||
"gopkg.in/ldap.v3"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models/roletype"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
@ -221,6 +223,122 @@ func TestServer_Users(t *testing.T) {
|
||||
require.Len(t, res, 1)
|
||||
assert.Equal(t, "Grot the First", res[0].Name)
|
||||
})
|
||||
|
||||
t.Run("org role mapping", func(t *testing.T) {
|
||||
conn := &MockConnection{}
|
||||
|
||||
usersOU := "ou=users,dc=example,dc=org"
|
||||
grootDN := "dn=groot," + usersOU
|
||||
grootSearch := ldap.SearchResult{Entries: []*ldap.Entry{{DN: grootDN,
|
||||
Attributes: []*ldap.EntryAttribute{
|
||||
{Name: "username", Values: []string{"groot"}},
|
||||
{Name: "name", Values: []string{"I am Groot"}},
|
||||
}}}}
|
||||
peterDN := "dn=peter," + usersOU
|
||||
peterSearch := ldap.SearchResult{Entries: []*ldap.Entry{{DN: peterDN,
|
||||
Attributes: []*ldap.EntryAttribute{
|
||||
{Name: "username", Values: []string{"peter"}},
|
||||
{Name: "name", Values: []string{"Peter"}},
|
||||
}}}}
|
||||
groupsOU := "ou=groups,dc=example,dc=org"
|
||||
creaturesDN := "dn=creatures," + groupsOU
|
||||
grootGroups := ldap.SearchResult{Entries: []*ldap.Entry{{DN: creaturesDN,
|
||||
Attributes: []*ldap.EntryAttribute{
|
||||
{Name: "member", Values: []string{grootDN}},
|
||||
}}},
|
||||
}
|
||||
humansDN := "dn=humans," + groupsOU
|
||||
peterGroups := ldap.SearchResult{Entries: []*ldap.Entry{{DN: humansDN,
|
||||
Attributes: []*ldap.EntryAttribute{
|
||||
{Name: "member", Values: []string{peterDN}},
|
||||
}}},
|
||||
}
|
||||
|
||||
conn.setSearchFunc(func(request *ldap.SearchRequest) (*ldap.SearchResult, error) {
|
||||
switch request.BaseDN {
|
||||
case usersOU:
|
||||
switch request.Filter {
|
||||
case "(|(username=groot))":
|
||||
return &grootSearch, nil
|
||||
case "(|(username=peter))":
|
||||
return &peterSearch, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("test case not defined for user filter: '%s'", request.Filter)
|
||||
}
|
||||
case groupsOU:
|
||||
switch request.Filter {
|
||||
case "(member=groot)":
|
||||
return &grootGroups, nil
|
||||
case "(member=peter)":
|
||||
return &peterGroups, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("test case not defined for group filter: '%s'", request.Filter)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("test case not defined for baseDN: '%s'", request.BaseDN)
|
||||
}
|
||||
})
|
||||
|
||||
server := &Server{
|
||||
Config: &ServerConfig{
|
||||
Attr: AttributeMap{
|
||||
Username: "username",
|
||||
Name: "name",
|
||||
},
|
||||
SearchBaseDNs: []string{usersOU},
|
||||
SearchFilter: "(username=%s)",
|
||||
GroupSearchFilter: "(member=%s)",
|
||||
GroupSearchBaseDNs: []string{groupsOU},
|
||||
Groups: []*GroupToOrgRole{
|
||||
{
|
||||
GroupDN: creaturesDN,
|
||||
OrgId: 2,
|
||||
IsGrafanaAdmin: new(bool),
|
||||
OrgRole: "Admin",
|
||||
},
|
||||
},
|
||||
},
|
||||
Connection: conn,
|
||||
log: log.New("test-logger"),
|
||||
}
|
||||
|
||||
t.Run("disable user with no mapping", func(t *testing.T) {
|
||||
res, err := server.Users([]string{"peter"})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, res, 1)
|
||||
require.Equal(t, "Peter", res[0].Name)
|
||||
require.ElementsMatch(t, res[0].Groups, []string{humansDN})
|
||||
require.Empty(t, res[0].OrgRoles)
|
||||
require.True(t, res[0].IsDisabled)
|
||||
})
|
||||
t.Run("skip org role sync", func(t *testing.T) {
|
||||
backup := setting.LDAPSkipOrgRoleSync
|
||||
defer func() {
|
||||
setting.LDAPSkipOrgRoleSync = backup
|
||||
}()
|
||||
setting.LDAPSkipOrgRoleSync = true
|
||||
|
||||
res, err := server.Users([]string{"groot"})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, res, 1)
|
||||
require.Equal(t, "I am Groot", res[0].Name)
|
||||
require.ElementsMatch(t, res[0].Groups, []string{creaturesDN})
|
||||
require.Empty(t, res[0].OrgRoles)
|
||||
require.False(t, res[0].IsDisabled)
|
||||
})
|
||||
t.Run("sync org role", func(t *testing.T) {
|
||||
res, err := server.Users([]string{"groot"})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, res, 1)
|
||||
require.Equal(t, "I am Groot", res[0].Name)
|
||||
require.ElementsMatch(t, res[0].Groups, []string{creaturesDN})
|
||||
require.Len(t, res[0].OrgRoles, 1)
|
||||
role, mappingExist := res[0].OrgRoles[2]
|
||||
require.True(t, mappingExist)
|
||||
require.Equal(t, roletype.RoleAdmin, role)
|
||||
require.False(t, res[0].IsDisabled)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServer_UserBind(t *testing.T) {
|
||||
|
Reference in New Issue
Block a user