Files
authentik/internal/outpost/ldap/instance.go
Jens L. 5b66dbe890 flows: provider invalidation (#5048)
* add initial

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add web stage for session end

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate saml and tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* cleanup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* group flow settings when providers have multiple flows

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* adjust name for default provider invalidation

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* re-make migrations

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add invalidation_flow to saml importer

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* re-do migrations again

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update web stuff to get rid of old libraries

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make unbind flow for ldap configurable

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* unrelated: fix flow inspector

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* handle invalidation_flow as optional, as it should be

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* also fix ldap outpost

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* don't generate URL in client

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* actually make it work???

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix migration breaking things...?

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* start fixing tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix fallback

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* re-migrate

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix duplicate flow setting

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add migration

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix race condition with brand

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix oauth test

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix SAML tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add to wizard, fix required

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update docs

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make required, start release notes

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-10-14 15:35:12 +02:00

146 lines
3.8 KiB
Go

package ldap
import (
"crypto/tls"
"strings"
"sync"
log "github.com/sirupsen/logrus"
"goauthentik.io/api/v3"
"goauthentik.io/internal/outpost/ldap/bind"
ldapConstants "goauthentik.io/internal/outpost/ldap/constants"
"goauthentik.io/internal/outpost/ldap/flags"
"goauthentik.io/internal/outpost/ldap/search"
"goauthentik.io/internal/outpost/ldap/utils"
)
type ProviderInstance struct {
BaseDN string
UserDN string
VirtualGroupDN string
GroupDN string
searcher search.Searcher
binder bind.Binder
appSlug string
authenticationFlowSlug string
invalidationFlowSlug *string
s *LDAPServer
log *log.Entry
tlsServerName *string
cert *tls.Certificate
certUUID string
outpostName string
providerPk int32
boundUsersMutex *sync.RWMutex
boundUsers map[string]*flags.UserFlags
uidStartNumber int32
gidStartNumber int32
mfaSupport bool
}
func (pi *ProviderInstance) GetAPIClient() *api.APIClient {
return pi.s.ac.Client
}
func (pi *ProviderInstance) GetBaseDN() string {
return pi.BaseDN
}
func (pi *ProviderInstance) GetBaseGroupDN() string {
return pi.GroupDN
}
func (pi *ProviderInstance) GetBaseVirtualGroupDN() string {
return pi.VirtualGroupDN
}
func (pi *ProviderInstance) GetBaseUserDN() string {
return pi.UserDN
}
func (pi *ProviderInstance) GetOutpostName() string {
return pi.outpostName
}
func (pi *ProviderInstance) GetMFASupport() bool {
return pi.mfaSupport
}
func (pi *ProviderInstance) GetFlags(dn string) *flags.UserFlags {
pi.boundUsersMutex.RLock()
defer pi.boundUsersMutex.RUnlock()
flags, ok := pi.boundUsers[dn]
if !ok {
return nil
}
return flags
}
func (pi *ProviderInstance) SetFlags(dn string, flag *flags.UserFlags) {
pi.boundUsersMutex.Lock()
if flag == nil {
delete(pi.boundUsers, dn)
} else {
pi.boundUsers[dn] = flag
}
pi.boundUsersMutex.Unlock()
}
func (pi *ProviderInstance) GetAppSlug() string {
return pi.appSlug
}
func (pi *ProviderInstance) GetAuthenticationFlowSlug() string {
return pi.authenticationFlowSlug
}
func (pi *ProviderInstance) GetInvalidationFlowSlug() *string {
return pi.invalidationFlowSlug
}
func (pi *ProviderInstance) GetProviderID() int32 {
return pi.providerPk
}
func (pi *ProviderInstance) GetNeededObjects(scope int, baseDN string, filterOC string) (bool, bool) {
needUsers := false
needGroups := false
// We only want to load users/groups if we're actually going to be asked
// for at least one user or group based on the search's base DN and scope.
//
// If our requested base DN doesn't match any of the container DNs, then
// we're probably loading a user or group. If it does, then make sure our
// scope will eventually take us to users or groups.
if (strings.EqualFold(baseDN, pi.BaseDN) || utils.HasSuffixNoCase(baseDN, pi.UserDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetUserOCs()) {
if baseDN != pi.UserDN && baseDN != pi.BaseDN ||
strings.EqualFold(baseDN, pi.BaseDN) && scope > 1 ||
strings.EqualFold(baseDN, pi.UserDN) && scope > 0 {
needUsers = true
}
}
if (strings.EqualFold(baseDN, pi.BaseDN) || utils.HasSuffixNoCase(baseDN, pi.GroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetGroupOCs()) {
if baseDN != pi.GroupDN && baseDN != pi.BaseDN ||
strings.EqualFold(baseDN, pi.BaseDN) && scope > 1 ||
strings.EqualFold(baseDN, pi.GroupDN) && scope > 0 {
needGroups = true
}
}
if (strings.EqualFold(baseDN, pi.BaseDN) || utils.HasSuffixNoCase(baseDN, pi.VirtualGroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetVirtualGroupOCs()) {
if baseDN != pi.VirtualGroupDN && baseDN != pi.BaseDN ||
strings.EqualFold(baseDN, pi.BaseDN) && scope > 1 ||
strings.EqualFold(baseDN, pi.VirtualGroupDN) && scope > 0 {
needUsers = true
}
}
return needUsers, needGroups
}