89 lines
3.0 KiB
Go
89 lines
3.0 KiB
Go
package ldap
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/go-openapi/strfmt"
|
|
log "github.com/sirupsen/logrus"
|
|
"goauthentik.io/api"
|
|
directbind "goauthentik.io/internal/outpost/ldap/bind/direct"
|
|
"goauthentik.io/internal/outpost/ldap/constants"
|
|
"goauthentik.io/internal/outpost/ldap/flags"
|
|
directsearch "goauthentik.io/internal/outpost/ldap/search/direct"
|
|
memorysearch "goauthentik.io/internal/outpost/ldap/search/memory"
|
|
)
|
|
|
|
func (ls *LDAPServer) getCurrentProvider(pk int32) *ProviderInstance {
|
|
for _, p := range ls.providers {
|
|
if p.outpostPk == pk {
|
|
return p
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (ls *LDAPServer) Refresh() error {
|
|
outposts, _, err := ls.ac.Client.OutpostsApi.OutpostsLdapList(context.Background()).Execute()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(outposts.Results) < 1 {
|
|
return errors.New("no ldap provider defined")
|
|
}
|
|
providers := make([]*ProviderInstance, len(outposts.Results))
|
|
for idx, provider := range outposts.Results {
|
|
userDN := strings.ToLower(fmt.Sprintf("ou=%s,%s", constants.OUUsers, *provider.BaseDn))
|
|
groupDN := strings.ToLower(fmt.Sprintf("ou=%s,%s", constants.OUGroups, *provider.BaseDn))
|
|
virtualGroupDN := strings.ToLower(fmt.Sprintf("ou=%s,%s", constants.OUVirtualGroups, *provider.BaseDn))
|
|
logger := log.WithField("logger", "authentik.outpost.ldap").WithField("provider", provider.Name)
|
|
|
|
// Get existing instance so we can transfer boundUsers
|
|
existing := ls.getCurrentProvider(provider.Pk)
|
|
users := make(map[string]flags.UserFlags)
|
|
if existing != nil {
|
|
existing.boundUsersMutex.Unlock()
|
|
users = existing.boundUsers
|
|
}
|
|
|
|
providers[idx] = &ProviderInstance{
|
|
BaseDN: *provider.BaseDn,
|
|
VirtualGroupDN: virtualGroupDN,
|
|
GroupDN: groupDN,
|
|
UserDN: userDN,
|
|
appSlug: provider.ApplicationSlug,
|
|
flowSlug: provider.BindFlowSlug,
|
|
searchAllowedGroups: []*strfmt.UUID{(*strfmt.UUID)(provider.SearchGroup.Get())},
|
|
boundUsersMutex: sync.RWMutex{},
|
|
boundUsers: users,
|
|
s: ls,
|
|
log: logger,
|
|
tlsServerName: provider.TlsServerName,
|
|
uidStartNumber: *provider.UidStartNumber,
|
|
gidStartNumber: *provider.GidStartNumber,
|
|
outpostName: ls.ac.Outpost.Name,
|
|
outpostPk: provider.Pk,
|
|
}
|
|
if provider.Certificate.Get() != nil {
|
|
kp := provider.Certificate.Get()
|
|
err := ls.cs.AddKeypair(*kp)
|
|
if err != nil {
|
|
ls.log.WithError(err).Warning("Failed to initially fetch certificate")
|
|
}
|
|
providers[idx].cert = ls.cs.Get(*kp)
|
|
}
|
|
if *provider.SearchMode.Ptr() == api.SEARCHMODEENUM_CACHED {
|
|
providers[idx].searcher = memorysearch.NewMemorySearcher(providers[idx])
|
|
} else if *provider.SearchMode.Ptr() == api.SEARCHMODEENUM_DIRECT {
|
|
providers[idx].searcher = directsearch.NewDirectSearcher(providers[idx])
|
|
}
|
|
providers[idx].binder = directbind.NewDirectBinder(providers[idx])
|
|
}
|
|
ls.providers = providers
|
|
ls.log.Info("Update providers")
|
|
return nil
|
|
}
|