mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 05:19:25 +08:00

* Feature: add cron setting for the ldap settings * Move ldap configuration read to special function * Introduce cron setting (no docs for it yet, pending approval) * Chore: duplicate ldap module as a service * Feature: implement active sync This is very early preliminary implementation of active sync. There is only one thing that's going right for this code - it works. Aside from that, there is no tests, error handling, docs, transactions, it's very much duplicative and etc. But this is the overall direction with architecture I'm going for * Chore: introduce login service * Chore: gradually switch to ldap service * Chore: use new approach for auth_proxy * Chore: use new approach along with refactoring * Chore: use new ldap interface for auth_proxy * Chore: improve auth_proxy and subsequently ldap * Chore: more of the refactoring bits * Chore: address comments from code review * Chore: more refactoring stuff * Chore: make linter happy * Chore: add cron dep for grafana enterprise * Chore: initialize config package var * Chore: disable gosec for now * Chore: update dependencies * Chore: remove unused module * Chore: address review comments * Chore: make linter happy
166 lines
4.1 KiB
Go
166 lines
4.1 KiB
Go
package ldap
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
"gopkg.in/ldap.v3"
|
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/services/login"
|
|
)
|
|
|
|
type mockLdapConn struct {
|
|
result *ldap.SearchResult
|
|
searchCalled bool
|
|
searchAttributes []string
|
|
bindProvider func(username, password string) error
|
|
unauthenticatedBindProvider func(username string) error
|
|
}
|
|
|
|
func (c *mockLdapConn) Bind(username, password string) error {
|
|
if c.bindProvider != nil {
|
|
return c.bindProvider(username, password)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *mockLdapConn) UnauthenticatedBind(username string) error {
|
|
if c.unauthenticatedBindProvider != nil {
|
|
return c.unauthenticatedBindProvider(username)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *mockLdapConn) Close() {}
|
|
|
|
func (c *mockLdapConn) setSearchResult(result *ldap.SearchResult) {
|
|
c.result = result
|
|
}
|
|
|
|
func (c *mockLdapConn) Search(sr *ldap.SearchRequest) (*ldap.SearchResult, error) {
|
|
c.searchCalled = true
|
|
c.searchAttributes = sr.Attributes
|
|
return c.result, nil
|
|
}
|
|
|
|
func (c *mockLdapConn) StartTLS(*tls.Config) error {
|
|
return nil
|
|
}
|
|
|
|
func AuthScenario(desc string, fn scenarioFunc) {
|
|
Convey(desc, func() {
|
|
defer bus.ClearBusHandlers()
|
|
|
|
sc := &scenarioContext{
|
|
loginUserQuery: &models.LoginUserQuery{
|
|
Username: "user",
|
|
Password: "pwd",
|
|
IpAddress: "192.168.1.1:56433",
|
|
},
|
|
}
|
|
|
|
hookDial = func(auth *Auth) error {
|
|
return nil
|
|
}
|
|
|
|
loginService := &login.LoginService{
|
|
Bus: bus.GetBus(),
|
|
}
|
|
|
|
bus.AddHandler("test", loginService.UpsertUser)
|
|
|
|
bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.SyncTeamsCommand) error {
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandlerCtx("test", func(ctx context.Context, cmd *models.UpdateUserPermissionsCommand) error {
|
|
sc.updateUserPermissionsCmd = cmd
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandler("test", func(cmd *models.GetUserByAuthInfoQuery) error {
|
|
sc.getUserByAuthInfoQuery = cmd
|
|
sc.getUserByAuthInfoQuery.Result = &models.User{Login: cmd.Login}
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandler("test", func(cmd *models.GetUserOrgListQuery) error {
|
|
sc.getUserOrgListQuery = cmd
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandler("test", func(cmd *models.CreateUserCommand) error {
|
|
sc.createUserCmd = cmd
|
|
sc.createUserCmd.Result = models.User{Login: cmd.Login}
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandler("test", func(cmd *models.AddOrgUserCommand) error {
|
|
sc.addOrgUserCmd = cmd
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandler("test", func(cmd *models.UpdateOrgUserCommand) error {
|
|
sc.updateOrgUserCmd = cmd
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandler("test", func(cmd *models.RemoveOrgUserCommand) error {
|
|
sc.removeOrgUserCmd = cmd
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandler("test", func(cmd *models.UpdateUserCommand) error {
|
|
sc.updateUserCmd = cmd
|
|
return nil
|
|
})
|
|
|
|
bus.AddHandler("test", func(cmd *models.SetUsingOrgCommand) error {
|
|
sc.setUsingOrgCmd = cmd
|
|
return nil
|
|
})
|
|
|
|
fn(sc)
|
|
})
|
|
}
|
|
|
|
type scenarioContext struct {
|
|
loginUserQuery *models.LoginUserQuery
|
|
getUserByAuthInfoQuery *models.GetUserByAuthInfoQuery
|
|
getUserOrgListQuery *models.GetUserOrgListQuery
|
|
createUserCmd *models.CreateUserCommand
|
|
addOrgUserCmd *models.AddOrgUserCommand
|
|
updateOrgUserCmd *models.UpdateOrgUserCommand
|
|
removeOrgUserCmd *models.RemoveOrgUserCommand
|
|
updateUserCmd *models.UpdateUserCommand
|
|
setUsingOrgCmd *models.SetUsingOrgCommand
|
|
updateUserPermissionsCmd *models.UpdateUserPermissionsCommand
|
|
}
|
|
|
|
func (sc *scenarioContext) userQueryReturns(user *models.User) {
|
|
bus.AddHandler("test", func(query *models.GetUserByAuthInfoQuery) error {
|
|
if user == nil {
|
|
return models.ErrUserNotFound
|
|
}
|
|
query.Result = user
|
|
return nil
|
|
})
|
|
bus.AddHandler("test", func(query *models.SetAuthInfoCommand) error {
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (sc *scenarioContext) userOrgsQueryReturns(orgs []*models.UserOrgDTO) {
|
|
bus.AddHandler("test", func(query *models.GetUserOrgListQuery) error {
|
|
query.Result = orgs
|
|
return nil
|
|
})
|
|
}
|
|
|
|
type scenarioFunc func(c *scenarioContext)
|