outpost/ldap: check access based on Group Membership

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer
2021-05-05 00:03:19 +02:00
parent d84d7c26ca
commit 32934fcd38
4 changed files with 32 additions and 27 deletions

View File

@ -4,8 +4,8 @@ import (
"errors"
"fmt"
"strings"
"sync"
"github.com/go-openapi/strfmt"
log "github.com/sirupsen/logrus"
"goauthentik.io/outpost/pkg/client/outposts"
)
@ -23,15 +23,14 @@ func (ls *LDAPServer) Refresh() error {
userDN := strings.ToLower(fmt.Sprintf("cn=users,%s", provider.BaseDn))
groupDN := strings.ToLower(fmt.Sprintf("cn=groups,%s", provider.BaseDn))
providers[idx] = &ProviderInstance{
BaseDN: provider.BaseDn,
GroupDN: groupDN,
UserDN: userDN,
appSlug: *provider.ApplicationSlug,
flowSlug: *provider.BindFlowSlug,
s: ls,
log: log.WithField("logger", "authentik.outpost.ldap").WithField("provider", provider.Name),
boundUsersMutex: sync.RWMutex{},
boundUsers: make(map[string]UserFlags),
BaseDN: provider.BaseDn,
GroupDN: groupDN,
UserDN: userDN,
appSlug: *provider.ApplicationSlug,
flowSlug: *provider.BindFlowSlug,
searchAllowedGroups: []*strfmt.UUID{provider.SearchGroup},
s: ls,
log: log.WithField("logger", "authentik.outpost.ldap").WithField("provider", provider.Name),
}
}
ls.providers = providers

View File

@ -15,6 +15,7 @@ import (
"github.com/nmcclain/ldap"
"goauthentik.io/outpost/pkg/client/core"
"goauthentik.io/outpost/pkg/client/flows"
"goauthentik.io/outpost/pkg/models"
)
const ContextUserKey = "ak_user"
@ -88,13 +89,25 @@ func (pi *ProviderInstance) Bind(username string, bindPW string, conn net.Conn)
pi.boundUsersMutex.Lock()
pi.boundUsers[username] = UserFlags{
UserInfo: userInfo.Payload.User,
CanSearch: userInfo.Payload.User.Attributes.(map[string]bool)["goauthentik.io/ldap/can-search"],
CanSearch: pi.SearchAccessCheck(userInfo.Payload.User),
}
pi.boundUsersMutex.Unlock()
pi.delayDeleteUserInfo(username)
return ldap.LDAPResultSuccess, nil
}
// SearchAccessCheck Check if the current user is allowed to search
func (pi *ProviderInstance) SearchAccessCheck(user *models.User) bool {
for _, group := range user.Groups {
for _, allowedGroup := range pi.searchAllowedGroups {
if &group.Pk == allowedGroup {
pi.log.WithField("group", group.Name).Info("Allowed access to search")
return true
}
}
}
return false
}
func (pi *ProviderInstance) delayDeleteUserInfo(dn string) {
ticker := time.NewTicker(30 * time.Second)
quit := make(chan struct{})

View File

@ -3,6 +3,7 @@ package ldap
import (
"sync"
"github.com/go-openapi/strfmt"
log "github.com/sirupsen/logrus"
"goauthentik.io/outpost/pkg/ak"
"goauthentik.io/outpost/pkg/models"
@ -19,13 +20,14 @@ type ProviderInstance struct {
UserDN string
GroupDN string
appSlug string
flowSlug string
s *LDAPServer
log *log.Entry
appSlug string
flowSlug string
s *LDAPServer
log *log.Entry
boundUsersMutex sync.RWMutex
boundUsers map[string]UserFlags
searchAllowedGroups []*strfmt.UUID
boundUsersMutex sync.RWMutex
boundUsers map[string]UserFlags
}
type UserFlags struct {